video.js 854 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595959695979598959996009601960296039604960596069607960896099610961196129613961496159616961796189619962096219622962396249625962696279628962996309631963296339634963596369637963896399640964196429643964496459646964796489649965096519652965396549655965696579658965996609661966296639664966596669667966896699670967196729673967496759676967796789679968096819682968396849685968696879688968996909691969296939694969596969697969896999700970197029703970497059706970797089709971097119712971397149715971697179718971997209721972297239724972597269727972897299730973197329733973497359736973797389739974097419742974397449745974697479748974997509751975297539754975597569757975897599760976197629763976497659766976797689769977097719772977397749775977697779778977997809781978297839784978597869787978897899790979197929793979497959796979797989799980098019802980398049805980698079808980998109811981298139814981598169817981898199820982198229823982498259826982798289829983098319832983398349835983698379838983998409841984298439844984598469847984898499850985198529853985498559856985798589859986098619862986398649865986698679868986998709871987298739874987598769877987898799880988198829883988498859886988798889889989098919892989398949895989698979898989999009901990299039904990599069907990899099910991199129913991499159916991799189919992099219922992399249925992699279928992999309931993299339934993599369937993899399940994199429943994499459946994799489949995099519952995399549955995699579958995999609961996299639964996599669967996899699970997199729973997499759976997799789979998099819982998399849985998699879988998999909991999299939994999599969997999899991000010001100021000310004100051000610007100081000910010100111001210013100141001510016100171001810019100201002110022100231002410025100261002710028100291003010031100321003310034100351003610037100381003910040100411004210043100441004510046100471004810049100501005110052100531005410055100561005710058100591006010061100621006310064100651006610067100681006910070100711007210073100741007510076100771007810079100801008110082100831008410085100861008710088100891009010091100921009310094100951009610097100981009910100101011010210103101041010510106101071010810109101101011110112101131011410115101161011710118101191012010121101221012310124101251012610127101281012910130101311013210133101341013510136101371013810139101401014110142101431014410145101461014710148101491015010151101521015310154101551015610157101581015910160101611016210163101641016510166101671016810169101701017110172101731017410175101761017710178101791018010181101821018310184101851018610187101881018910190101911019210193101941019510196101971019810199102001020110202102031020410205102061020710208102091021010211102121021310214102151021610217102181021910220102211022210223102241022510226102271022810229102301023110232102331023410235102361023710238102391024010241102421024310244102451024610247102481024910250102511025210253102541025510256102571025810259102601026110262102631026410265102661026710268102691027010271102721027310274102751027610277102781027910280102811028210283102841028510286102871028810289102901029110292102931029410295102961029710298102991030010301103021030310304103051030610307103081030910310103111031210313103141031510316103171031810319103201032110322103231032410325103261032710328103291033010331103321033310334103351033610337103381033910340103411034210343103441034510346103471034810349103501035110352103531035410355103561035710358103591036010361103621036310364103651036610367103681036910370103711037210373103741037510376103771037810379103801038110382103831038410385103861038710388103891039010391103921039310394103951039610397103981039910400104011040210403104041040510406104071040810409104101041110412104131041410415104161041710418104191042010421104221042310424104251042610427104281042910430104311043210433104341043510436104371043810439104401044110442104431044410445104461044710448104491045010451104521045310454104551045610457104581045910460104611046210463104641046510466104671046810469104701047110472104731047410475104761047710478104791048010481104821048310484104851048610487104881048910490104911049210493104941049510496104971049810499105001050110502105031050410505105061050710508105091051010511105121051310514105151051610517105181051910520105211052210523105241052510526105271052810529105301053110532105331053410535105361053710538105391054010541105421054310544105451054610547105481054910550105511055210553105541055510556105571055810559105601056110562105631056410565105661056710568105691057010571105721057310574105751057610577105781057910580105811058210583105841058510586105871058810589105901059110592105931059410595105961059710598105991060010601106021060310604106051060610607106081060910610106111061210613106141061510616106171061810619106201062110622106231062410625106261062710628106291063010631106321063310634106351063610637106381063910640106411064210643106441064510646106471064810649106501065110652106531065410655106561065710658106591066010661106621066310664106651066610667106681066910670106711067210673106741067510676106771067810679106801068110682106831068410685106861068710688106891069010691106921069310694106951069610697106981069910700107011070210703107041070510706107071070810709107101071110712107131071410715107161071710718107191072010721107221072310724107251072610727107281072910730107311073210733107341073510736107371073810739107401074110742107431074410745107461074710748107491075010751107521075310754107551075610757107581075910760107611076210763107641076510766107671076810769107701077110772107731077410775107761077710778107791078010781107821078310784107851078610787107881078910790107911079210793107941079510796107971079810799108001080110802108031080410805108061080710808108091081010811108121081310814108151081610817108181081910820108211082210823108241082510826108271082810829108301083110832108331083410835108361083710838108391084010841108421084310844108451084610847108481084910850108511085210853108541085510856108571085810859108601086110862108631086410865108661086710868108691087010871108721087310874108751087610877108781087910880108811088210883108841088510886108871088810889108901089110892108931089410895108961089710898108991090010901109021090310904109051090610907109081090910910109111091210913109141091510916109171091810919109201092110922109231092410925109261092710928109291093010931109321093310934109351093610937109381093910940109411094210943109441094510946109471094810949109501095110952109531095410955109561095710958109591096010961109621096310964109651096610967109681096910970109711097210973109741097510976109771097810979109801098110982109831098410985109861098710988109891099010991109921099310994109951099610997109981099911000110011100211003110041100511006110071100811009110101101111012110131101411015110161101711018110191102011021110221102311024110251102611027110281102911030110311103211033110341103511036110371103811039110401104111042110431104411045110461104711048110491105011051110521105311054110551105611057110581105911060110611106211063110641106511066110671106811069110701107111072110731107411075110761107711078110791108011081110821108311084110851108611087110881108911090110911109211093110941109511096110971109811099111001110111102111031110411105111061110711108111091111011111111121111311114111151111611117111181111911120111211112211123111241112511126111271112811129111301113111132111331113411135111361113711138111391114011141111421114311144111451114611147111481114911150111511115211153111541115511156111571115811159111601116111162111631116411165111661116711168111691117011171111721117311174111751117611177111781117911180111811118211183111841118511186111871118811189111901119111192111931119411195111961119711198111991120011201112021120311204112051120611207112081120911210112111121211213112141121511216112171121811219112201122111222112231122411225112261122711228112291123011231112321123311234112351123611237112381123911240112411124211243112441124511246112471124811249112501125111252112531125411255112561125711258112591126011261112621126311264112651126611267112681126911270112711127211273112741127511276112771127811279112801128111282112831128411285112861128711288112891129011291112921129311294112951129611297112981129911300113011130211303113041130511306113071130811309113101131111312113131131411315113161131711318113191132011321113221132311324113251132611327113281132911330113311133211333113341133511336113371133811339113401134111342113431134411345113461134711348113491135011351113521135311354113551135611357113581135911360113611136211363113641136511366113671136811369113701137111372113731137411375113761137711378113791138011381113821138311384113851138611387113881138911390113911139211393113941139511396113971139811399114001140111402114031140411405114061140711408114091141011411114121141311414114151141611417114181141911420114211142211423114241142511426114271142811429114301143111432114331143411435114361143711438114391144011441114421144311444114451144611447114481144911450114511145211453114541145511456114571145811459114601146111462114631146411465114661146711468114691147011471114721147311474114751147611477114781147911480114811148211483114841148511486114871148811489114901149111492114931149411495114961149711498114991150011501115021150311504115051150611507115081150911510115111151211513115141151511516115171151811519115201152111522115231152411525115261152711528115291153011531115321153311534115351153611537115381153911540115411154211543115441154511546115471154811549115501155111552115531155411555115561155711558115591156011561115621156311564115651156611567115681156911570115711157211573115741157511576115771157811579115801158111582115831158411585115861158711588115891159011591115921159311594115951159611597115981159911600116011160211603116041160511606116071160811609116101161111612116131161411615116161161711618116191162011621116221162311624116251162611627116281162911630116311163211633116341163511636116371163811639116401164111642116431164411645116461164711648116491165011651116521165311654116551165611657116581165911660116611166211663116641166511666116671166811669116701167111672116731167411675116761167711678116791168011681116821168311684116851168611687116881168911690116911169211693116941169511696116971169811699117001170111702117031170411705117061170711708117091171011711117121171311714117151171611717117181171911720117211172211723117241172511726117271172811729117301173111732117331173411735117361173711738117391174011741117421174311744117451174611747117481174911750117511175211753117541175511756117571175811759117601176111762117631176411765117661176711768117691177011771117721177311774117751177611777117781177911780117811178211783117841178511786117871178811789117901179111792117931179411795117961179711798117991180011801118021180311804118051180611807118081180911810118111181211813118141181511816118171181811819118201182111822118231182411825118261182711828118291183011831118321183311834118351183611837118381183911840118411184211843118441184511846118471184811849118501185111852118531185411855118561185711858118591186011861118621186311864118651186611867118681186911870118711187211873118741187511876118771187811879118801188111882118831188411885118861188711888118891189011891118921189311894118951189611897118981189911900119011190211903119041190511906119071190811909119101191111912119131191411915119161191711918119191192011921119221192311924119251192611927119281192911930119311193211933119341193511936119371193811939119401194111942119431194411945119461194711948119491195011951119521195311954119551195611957119581195911960119611196211963119641196511966119671196811969119701197111972119731197411975119761197711978119791198011981119821198311984119851198611987119881198911990119911199211993119941199511996119971199811999120001200112002120031200412005120061200712008120091201012011120121201312014120151201612017120181201912020120211202212023120241202512026120271202812029120301203112032120331203412035120361203712038120391204012041120421204312044120451204612047120481204912050120511205212053120541205512056120571205812059120601206112062120631206412065120661206712068120691207012071120721207312074120751207612077120781207912080120811208212083120841208512086120871208812089120901209112092120931209412095120961209712098120991210012101121021210312104121051210612107121081210912110121111211212113121141211512116121171211812119121201212112122121231212412125121261212712128121291213012131121321213312134121351213612137121381213912140121411214212143121441214512146121471214812149121501215112152121531215412155121561215712158121591216012161121621216312164121651216612167121681216912170121711217212173121741217512176121771217812179121801218112182121831218412185121861218712188121891219012191121921219312194121951219612197121981219912200122011220212203122041220512206122071220812209122101221112212122131221412215122161221712218122191222012221122221222312224122251222612227122281222912230122311223212233122341223512236122371223812239122401224112242122431224412245122461224712248122491225012251122521225312254122551225612257122581225912260122611226212263122641226512266122671226812269122701227112272122731227412275122761227712278122791228012281122821228312284122851228612287122881228912290122911229212293122941229512296122971229812299123001230112302123031230412305123061230712308123091231012311123121231312314123151231612317123181231912320123211232212323123241232512326123271232812329123301233112332123331233412335123361233712338123391234012341123421234312344123451234612347123481234912350123511235212353123541235512356123571235812359123601236112362123631236412365123661236712368123691237012371123721237312374123751237612377123781237912380123811238212383123841238512386123871238812389123901239112392123931239412395123961239712398123991240012401124021240312404124051240612407124081240912410124111241212413124141241512416124171241812419124201242112422124231242412425124261242712428124291243012431124321243312434124351243612437124381243912440124411244212443124441244512446124471244812449124501245112452124531245412455124561245712458124591246012461124621246312464124651246612467124681246912470124711247212473124741247512476124771247812479124801248112482124831248412485124861248712488124891249012491124921249312494124951249612497124981249912500125011250212503125041250512506125071250812509125101251112512125131251412515125161251712518125191252012521125221252312524125251252612527125281252912530125311253212533125341253512536125371253812539125401254112542125431254412545125461254712548125491255012551125521255312554125551255612557125581255912560125611256212563125641256512566125671256812569125701257112572125731257412575125761257712578125791258012581125821258312584125851258612587125881258912590125911259212593125941259512596125971259812599126001260112602126031260412605126061260712608126091261012611126121261312614126151261612617126181261912620126211262212623126241262512626126271262812629126301263112632126331263412635126361263712638126391264012641126421264312644126451264612647126481264912650126511265212653126541265512656126571265812659126601266112662126631266412665126661266712668126691267012671126721267312674126751267612677126781267912680126811268212683126841268512686126871268812689126901269112692126931269412695126961269712698126991270012701127021270312704127051270612707127081270912710127111271212713127141271512716127171271812719127201272112722127231272412725127261272712728127291273012731127321273312734127351273612737127381273912740127411274212743127441274512746127471274812749127501275112752127531275412755127561275712758127591276012761127621276312764127651276612767127681276912770127711277212773127741277512776127771277812779127801278112782127831278412785127861278712788127891279012791127921279312794127951279612797127981279912800128011280212803128041280512806128071280812809128101281112812128131281412815128161281712818128191282012821128221282312824128251282612827128281282912830128311283212833128341283512836128371283812839128401284112842128431284412845128461284712848128491285012851128521285312854128551285612857128581285912860128611286212863128641286512866128671286812869128701287112872128731287412875128761287712878128791288012881128821288312884128851288612887128881288912890128911289212893128941289512896128971289812899129001290112902129031290412905129061290712908129091291012911129121291312914129151291612917129181291912920129211292212923129241292512926129271292812929129301293112932129331293412935129361293712938129391294012941129421294312944129451294612947129481294912950129511295212953129541295512956129571295812959129601296112962129631296412965129661296712968129691297012971129721297312974129751297612977129781297912980129811298212983129841298512986129871298812989129901299112992129931299412995129961299712998129991300013001130021300313004130051300613007130081300913010130111301213013130141301513016130171301813019130201302113022130231302413025130261302713028130291303013031130321303313034130351303613037130381303913040130411304213043130441304513046130471304813049130501305113052130531305413055130561305713058130591306013061130621306313064130651306613067130681306913070130711307213073130741307513076130771307813079130801308113082130831308413085130861308713088130891309013091130921309313094130951309613097130981309913100131011310213103131041310513106131071310813109131101311113112131131311413115131161311713118131191312013121131221312313124131251312613127131281312913130131311313213133131341313513136131371313813139131401314113142131431314413145131461314713148131491315013151131521315313154131551315613157131581315913160131611316213163131641316513166131671316813169131701317113172131731317413175131761317713178131791318013181131821318313184131851318613187131881318913190131911319213193131941319513196131971319813199132001320113202132031320413205132061320713208132091321013211132121321313214132151321613217132181321913220132211322213223132241322513226132271322813229132301323113232132331323413235132361323713238132391324013241132421324313244132451324613247132481324913250132511325213253132541325513256132571325813259132601326113262132631326413265132661326713268132691327013271132721327313274132751327613277132781327913280132811328213283132841328513286132871328813289132901329113292132931329413295132961329713298132991330013301133021330313304133051330613307133081330913310133111331213313133141331513316133171331813319133201332113322133231332413325133261332713328133291333013331133321333313334133351333613337133381333913340133411334213343133441334513346133471334813349133501335113352133531335413355133561335713358133591336013361133621336313364133651336613367133681336913370133711337213373133741337513376133771337813379133801338113382133831338413385133861338713388133891339013391133921339313394133951339613397133981339913400134011340213403134041340513406134071340813409134101341113412134131341413415134161341713418134191342013421134221342313424134251342613427134281342913430134311343213433134341343513436134371343813439134401344113442134431344413445134461344713448134491345013451134521345313454134551345613457134581345913460134611346213463134641346513466134671346813469134701347113472134731347413475134761347713478134791348013481134821348313484134851348613487134881348913490134911349213493134941349513496134971349813499135001350113502135031350413505135061350713508135091351013511135121351313514135151351613517135181351913520135211352213523135241352513526135271352813529135301353113532135331353413535135361353713538135391354013541135421354313544135451354613547135481354913550135511355213553135541355513556135571355813559135601356113562135631356413565135661356713568135691357013571135721357313574135751357613577135781357913580135811358213583135841358513586135871358813589135901359113592135931359413595135961359713598135991360013601136021360313604136051360613607136081360913610136111361213613136141361513616136171361813619136201362113622136231362413625136261362713628136291363013631136321363313634136351363613637136381363913640136411364213643136441364513646136471364813649136501365113652136531365413655136561365713658136591366013661136621366313664136651366613667136681366913670136711367213673136741367513676136771367813679136801368113682136831368413685136861368713688136891369013691136921369313694136951369613697136981369913700137011370213703137041370513706137071370813709137101371113712137131371413715137161371713718137191372013721137221372313724137251372613727137281372913730137311373213733137341373513736137371373813739137401374113742137431374413745137461374713748137491375013751137521375313754137551375613757137581375913760137611376213763137641376513766137671376813769137701377113772137731377413775137761377713778137791378013781137821378313784137851378613787137881378913790137911379213793137941379513796137971379813799138001380113802138031380413805138061380713808138091381013811138121381313814138151381613817138181381913820138211382213823138241382513826138271382813829138301383113832138331383413835138361383713838138391384013841138421384313844138451384613847138481384913850138511385213853138541385513856138571385813859138601386113862138631386413865138661386713868138691387013871138721387313874138751387613877138781387913880138811388213883138841388513886138871388813889138901389113892138931389413895138961389713898138991390013901139021390313904139051390613907139081390913910139111391213913139141391513916139171391813919139201392113922139231392413925139261392713928139291393013931139321393313934139351393613937139381393913940139411394213943139441394513946139471394813949139501395113952139531395413955139561395713958139591396013961139621396313964139651396613967139681396913970139711397213973139741397513976139771397813979139801398113982139831398413985139861398713988139891399013991139921399313994139951399613997139981399914000140011400214003140041400514006140071400814009140101401114012140131401414015140161401714018140191402014021140221402314024140251402614027140281402914030140311403214033140341403514036140371403814039140401404114042140431404414045140461404714048140491405014051140521405314054140551405614057140581405914060140611406214063140641406514066140671406814069140701407114072140731407414075140761407714078140791408014081140821408314084140851408614087140881408914090140911409214093140941409514096140971409814099141001410114102141031410414105141061410714108141091411014111141121411314114141151411614117141181411914120141211412214123141241412514126141271412814129141301413114132141331413414135141361413714138141391414014141141421414314144141451414614147141481414914150141511415214153141541415514156141571415814159141601416114162141631416414165141661416714168141691417014171141721417314174141751417614177141781417914180141811418214183141841418514186141871418814189141901419114192141931419414195141961419714198141991420014201142021420314204142051420614207142081420914210142111421214213142141421514216142171421814219142201422114222142231422414225142261422714228142291423014231142321423314234142351423614237142381423914240142411424214243142441424514246142471424814249142501425114252142531425414255142561425714258142591426014261142621426314264142651426614267142681426914270142711427214273142741427514276142771427814279142801428114282142831428414285142861428714288142891429014291142921429314294142951429614297142981429914300143011430214303143041430514306143071430814309143101431114312143131431414315143161431714318143191432014321143221432314324143251432614327143281432914330143311433214333143341433514336143371433814339143401434114342143431434414345143461434714348143491435014351143521435314354143551435614357143581435914360143611436214363143641436514366143671436814369143701437114372143731437414375143761437714378143791438014381143821438314384143851438614387143881438914390143911439214393143941439514396143971439814399144001440114402144031440414405144061440714408144091441014411144121441314414144151441614417144181441914420144211442214423144241442514426144271442814429144301443114432144331443414435144361443714438144391444014441144421444314444144451444614447144481444914450144511445214453144541445514456144571445814459144601446114462144631446414465144661446714468144691447014471144721447314474144751447614477144781447914480144811448214483144841448514486144871448814489144901449114492144931449414495144961449714498144991450014501145021450314504145051450614507145081450914510145111451214513145141451514516145171451814519145201452114522145231452414525145261452714528145291453014531145321453314534145351453614537145381453914540145411454214543145441454514546145471454814549145501455114552145531455414555145561455714558145591456014561145621456314564145651456614567145681456914570145711457214573145741457514576145771457814579145801458114582145831458414585145861458714588145891459014591145921459314594145951459614597145981459914600146011460214603146041460514606146071460814609146101461114612146131461414615146161461714618146191462014621146221462314624146251462614627146281462914630146311463214633146341463514636146371463814639146401464114642146431464414645146461464714648146491465014651146521465314654146551465614657146581465914660146611466214663146641466514666146671466814669146701467114672146731467414675146761467714678146791468014681146821468314684146851468614687146881468914690146911469214693146941469514696146971469814699147001470114702147031470414705147061470714708147091471014711147121471314714147151471614717147181471914720147211472214723147241472514726147271472814729147301473114732147331473414735147361473714738147391474014741147421474314744147451474614747147481474914750147511475214753147541475514756147571475814759147601476114762147631476414765147661476714768147691477014771147721477314774147751477614777147781477914780147811478214783147841478514786147871478814789147901479114792147931479414795147961479714798147991480014801148021480314804148051480614807148081480914810148111481214813148141481514816148171481814819148201482114822148231482414825148261482714828148291483014831148321483314834148351483614837148381483914840148411484214843148441484514846148471484814849148501485114852148531485414855148561485714858148591486014861148621486314864148651486614867148681486914870148711487214873148741487514876148771487814879148801488114882148831488414885148861488714888148891489014891148921489314894148951489614897148981489914900149011490214903149041490514906149071490814909149101491114912149131491414915149161491714918149191492014921149221492314924149251492614927149281492914930149311493214933149341493514936149371493814939149401494114942149431494414945149461494714948149491495014951149521495314954149551495614957149581495914960149611496214963149641496514966149671496814969149701497114972149731497414975149761497714978149791498014981149821498314984149851498614987149881498914990149911499214993149941499514996149971499814999150001500115002150031500415005150061500715008150091501015011150121501315014150151501615017150181501915020150211502215023150241502515026150271502815029150301503115032150331503415035150361503715038150391504015041150421504315044150451504615047150481504915050150511505215053150541505515056150571505815059150601506115062150631506415065150661506715068150691507015071150721507315074150751507615077150781507915080150811508215083150841508515086150871508815089150901509115092150931509415095150961509715098150991510015101151021510315104151051510615107151081510915110151111511215113151141511515116151171511815119151201512115122151231512415125151261512715128151291513015131151321513315134151351513615137151381513915140151411514215143151441514515146151471514815149151501515115152151531515415155151561515715158151591516015161151621516315164151651516615167151681516915170151711517215173151741517515176151771517815179151801518115182151831518415185151861518715188151891519015191151921519315194151951519615197151981519915200152011520215203152041520515206152071520815209152101521115212152131521415215152161521715218152191522015221152221522315224152251522615227152281522915230152311523215233152341523515236152371523815239152401524115242152431524415245152461524715248152491525015251152521525315254152551525615257152581525915260152611526215263152641526515266152671526815269152701527115272152731527415275152761527715278152791528015281152821528315284152851528615287152881528915290152911529215293152941529515296152971529815299153001530115302153031530415305153061530715308153091531015311153121531315314153151531615317153181531915320153211532215323153241532515326153271532815329153301533115332153331533415335153361533715338153391534015341153421534315344153451534615347153481534915350153511535215353153541535515356153571535815359153601536115362153631536415365153661536715368153691537015371153721537315374153751537615377153781537915380153811538215383153841538515386153871538815389153901539115392153931539415395153961539715398153991540015401154021540315404154051540615407154081540915410154111541215413154141541515416154171541815419154201542115422154231542415425154261542715428154291543015431154321543315434154351543615437154381543915440154411544215443154441544515446154471544815449154501545115452154531545415455154561545715458154591546015461154621546315464154651546615467154681546915470154711547215473154741547515476154771547815479154801548115482154831548415485154861548715488154891549015491154921549315494154951549615497154981549915500155011550215503155041550515506155071550815509155101551115512155131551415515155161551715518155191552015521155221552315524155251552615527155281552915530155311553215533155341553515536155371553815539155401554115542155431554415545155461554715548155491555015551155521555315554155551555615557155581555915560155611556215563155641556515566155671556815569155701557115572155731557415575155761557715578155791558015581155821558315584155851558615587155881558915590155911559215593155941559515596155971559815599156001560115602156031560415605156061560715608156091561015611156121561315614156151561615617156181561915620156211562215623156241562515626156271562815629156301563115632156331563415635156361563715638156391564015641156421564315644156451564615647156481564915650156511565215653156541565515656156571565815659156601566115662156631566415665156661566715668156691567015671156721567315674156751567615677156781567915680156811568215683156841568515686156871568815689156901569115692156931569415695156961569715698156991570015701157021570315704157051570615707157081570915710157111571215713157141571515716157171571815719157201572115722157231572415725157261572715728157291573015731157321573315734157351573615737157381573915740157411574215743157441574515746157471574815749157501575115752157531575415755157561575715758157591576015761157621576315764157651576615767157681576915770157711577215773157741577515776157771577815779157801578115782157831578415785157861578715788157891579015791157921579315794157951579615797157981579915800158011580215803158041580515806158071580815809158101581115812158131581415815158161581715818158191582015821158221582315824158251582615827158281582915830158311583215833158341583515836158371583815839158401584115842158431584415845158461584715848158491585015851158521585315854158551585615857158581585915860158611586215863158641586515866158671586815869158701587115872158731587415875158761587715878158791588015881158821588315884158851588615887158881588915890158911589215893158941589515896158971589815899159001590115902159031590415905159061590715908159091591015911159121591315914159151591615917159181591915920159211592215923159241592515926159271592815929159301593115932159331593415935159361593715938159391594015941159421594315944159451594615947159481594915950159511595215953159541595515956159571595815959159601596115962159631596415965159661596715968159691597015971159721597315974159751597615977159781597915980159811598215983159841598515986159871598815989159901599115992159931599415995159961599715998159991600016001160021600316004160051600616007160081600916010160111601216013160141601516016160171601816019160201602116022160231602416025160261602716028160291603016031160321603316034160351603616037160381603916040160411604216043160441604516046160471604816049160501605116052160531605416055160561605716058160591606016061160621606316064160651606616067160681606916070160711607216073160741607516076160771607816079160801608116082160831608416085160861608716088160891609016091160921609316094160951609616097160981609916100161011610216103161041610516106161071610816109161101611116112161131611416115161161611716118161191612016121161221612316124161251612616127161281612916130161311613216133161341613516136161371613816139161401614116142161431614416145161461614716148161491615016151161521615316154161551615616157161581615916160161611616216163161641616516166161671616816169161701617116172161731617416175161761617716178161791618016181161821618316184161851618616187161881618916190161911619216193161941619516196161971619816199162001620116202162031620416205162061620716208162091621016211162121621316214162151621616217162181621916220162211622216223162241622516226162271622816229162301623116232162331623416235162361623716238162391624016241162421624316244162451624616247162481624916250162511625216253162541625516256162571625816259162601626116262162631626416265162661626716268162691627016271162721627316274162751627616277162781627916280162811628216283162841628516286162871628816289162901629116292162931629416295162961629716298162991630016301163021630316304163051630616307163081630916310163111631216313163141631516316163171631816319163201632116322163231632416325163261632716328163291633016331163321633316334163351633616337163381633916340163411634216343163441634516346163471634816349163501635116352163531635416355163561635716358163591636016361163621636316364163651636616367163681636916370163711637216373163741637516376163771637816379163801638116382163831638416385163861638716388163891639016391163921639316394163951639616397163981639916400164011640216403164041640516406164071640816409164101641116412164131641416415164161641716418164191642016421164221642316424164251642616427164281642916430164311643216433164341643516436164371643816439164401644116442164431644416445164461644716448164491645016451164521645316454164551645616457164581645916460164611646216463164641646516466164671646816469164701647116472164731647416475164761647716478164791648016481164821648316484164851648616487164881648916490164911649216493164941649516496164971649816499165001650116502165031650416505165061650716508165091651016511165121651316514165151651616517165181651916520165211652216523165241652516526165271652816529165301653116532165331653416535165361653716538165391654016541165421654316544165451654616547165481654916550165511655216553165541655516556165571655816559165601656116562165631656416565165661656716568165691657016571165721657316574165751657616577165781657916580165811658216583165841658516586165871658816589165901659116592165931659416595165961659716598165991660016601166021660316604166051660616607166081660916610166111661216613166141661516616166171661816619166201662116622166231662416625166261662716628166291663016631166321663316634166351663616637166381663916640166411664216643166441664516646166471664816649166501665116652166531665416655166561665716658166591666016661166621666316664166651666616667166681666916670166711667216673166741667516676166771667816679166801668116682166831668416685166861668716688166891669016691166921669316694166951669616697166981669916700167011670216703167041670516706167071670816709167101671116712167131671416715167161671716718167191672016721167221672316724167251672616727167281672916730167311673216733167341673516736167371673816739167401674116742167431674416745167461674716748167491675016751167521675316754167551675616757167581675916760167611676216763167641676516766167671676816769167701677116772167731677416775167761677716778167791678016781167821678316784167851678616787167881678916790167911679216793167941679516796167971679816799168001680116802168031680416805168061680716808168091681016811168121681316814168151681616817168181681916820168211682216823168241682516826168271682816829168301683116832168331683416835168361683716838168391684016841168421684316844168451684616847168481684916850168511685216853168541685516856168571685816859168601686116862168631686416865168661686716868168691687016871168721687316874168751687616877168781687916880168811688216883168841688516886168871688816889168901689116892168931689416895168961689716898168991690016901169021690316904169051690616907169081690916910169111691216913169141691516916169171691816919169201692116922169231692416925169261692716928169291693016931169321693316934169351693616937169381693916940169411694216943169441694516946169471694816949169501695116952169531695416955169561695716958169591696016961169621696316964169651696616967169681696916970169711697216973169741697516976169771697816979169801698116982169831698416985169861698716988169891699016991169921699316994169951699616997169981699917000170011700217003170041700517006170071700817009170101701117012170131701417015170161701717018170191702017021170221702317024170251702617027170281702917030170311703217033170341703517036170371703817039170401704117042170431704417045170461704717048170491705017051170521705317054170551705617057170581705917060170611706217063170641706517066170671706817069170701707117072170731707417075170761707717078170791708017081170821708317084170851708617087170881708917090170911709217093170941709517096170971709817099171001710117102171031710417105171061710717108171091711017111171121711317114171151711617117171181711917120171211712217123171241712517126171271712817129171301713117132171331713417135171361713717138171391714017141171421714317144171451714617147171481714917150171511715217153171541715517156171571715817159171601716117162171631716417165171661716717168171691717017171171721717317174171751717617177171781717917180171811718217183171841718517186171871718817189171901719117192171931719417195171961719717198171991720017201172021720317204172051720617207172081720917210172111721217213172141721517216172171721817219172201722117222172231722417225172261722717228172291723017231172321723317234172351723617237172381723917240172411724217243172441724517246172471724817249172501725117252172531725417255172561725717258172591726017261172621726317264172651726617267172681726917270172711727217273172741727517276172771727817279172801728117282172831728417285172861728717288172891729017291172921729317294172951729617297172981729917300173011730217303173041730517306173071730817309173101731117312173131731417315173161731717318173191732017321173221732317324173251732617327173281732917330173311733217333173341733517336173371733817339173401734117342173431734417345173461734717348173491735017351173521735317354173551735617357173581735917360173611736217363173641736517366173671736817369173701737117372173731737417375173761737717378173791738017381173821738317384173851738617387173881738917390173911739217393173941739517396173971739817399174001740117402174031740417405174061740717408174091741017411174121741317414174151741617417174181741917420174211742217423174241742517426174271742817429174301743117432174331743417435174361743717438174391744017441174421744317444174451744617447174481744917450174511745217453174541745517456174571745817459174601746117462174631746417465174661746717468174691747017471174721747317474174751747617477174781747917480174811748217483174841748517486174871748817489174901749117492174931749417495174961749717498174991750017501175021750317504175051750617507175081750917510175111751217513175141751517516175171751817519175201752117522175231752417525175261752717528175291753017531175321753317534175351753617537175381753917540175411754217543175441754517546175471754817549175501755117552175531755417555175561755717558175591756017561175621756317564175651756617567175681756917570175711757217573175741757517576175771757817579175801758117582175831758417585175861758717588175891759017591175921759317594175951759617597175981759917600176011760217603176041760517606176071760817609176101761117612176131761417615176161761717618176191762017621176221762317624176251762617627176281762917630176311763217633176341763517636176371763817639176401764117642176431764417645176461764717648176491765017651176521765317654176551765617657176581765917660176611766217663176641766517666176671766817669176701767117672176731767417675176761767717678176791768017681176821768317684176851768617687176881768917690176911769217693176941769517696176971769817699177001770117702177031770417705177061770717708177091771017711177121771317714177151771617717177181771917720177211772217723177241772517726177271772817729177301773117732177331773417735177361773717738177391774017741177421774317744177451774617747177481774917750177511775217753177541775517756177571775817759177601776117762177631776417765177661776717768177691777017771177721777317774177751777617777177781777917780177811778217783177841778517786177871778817789177901779117792177931779417795177961779717798177991780017801178021780317804178051780617807178081780917810178111781217813178141781517816178171781817819178201782117822178231782417825178261782717828178291783017831178321783317834178351783617837178381783917840178411784217843178441784517846178471784817849178501785117852178531785417855178561785717858178591786017861178621786317864178651786617867178681786917870178711787217873178741787517876178771787817879178801788117882178831788417885178861788717888178891789017891178921789317894178951789617897178981789917900179011790217903179041790517906179071790817909179101791117912179131791417915179161791717918179191792017921179221792317924179251792617927179281792917930179311793217933179341793517936179371793817939179401794117942179431794417945179461794717948179491795017951179521795317954179551795617957179581795917960179611796217963179641796517966179671796817969179701797117972179731797417975179761797717978179791798017981179821798317984179851798617987179881798917990179911799217993179941799517996179971799817999180001800118002180031800418005180061800718008180091801018011180121801318014180151801618017180181801918020180211802218023180241802518026180271802818029180301803118032180331803418035180361803718038180391804018041180421804318044180451804618047180481804918050180511805218053180541805518056180571805818059180601806118062180631806418065180661806718068180691807018071180721807318074180751807618077180781807918080180811808218083180841808518086180871808818089180901809118092180931809418095180961809718098180991810018101181021810318104181051810618107181081810918110181111811218113181141811518116181171811818119181201812118122181231812418125181261812718128181291813018131181321813318134181351813618137181381813918140181411814218143181441814518146181471814818149181501815118152181531815418155181561815718158181591816018161181621816318164181651816618167181681816918170181711817218173181741817518176181771817818179181801818118182181831818418185181861818718188181891819018191181921819318194181951819618197181981819918200182011820218203182041820518206182071820818209182101821118212182131821418215182161821718218182191822018221182221822318224182251822618227182281822918230182311823218233182341823518236182371823818239182401824118242182431824418245182461824718248182491825018251182521825318254182551825618257182581825918260182611826218263182641826518266182671826818269182701827118272182731827418275182761827718278182791828018281182821828318284182851828618287182881828918290182911829218293182941829518296182971829818299183001830118302183031830418305183061830718308183091831018311183121831318314183151831618317183181831918320183211832218323183241832518326183271832818329183301833118332183331833418335183361833718338183391834018341183421834318344183451834618347183481834918350183511835218353183541835518356183571835818359183601836118362183631836418365183661836718368183691837018371183721837318374183751837618377183781837918380183811838218383183841838518386183871838818389183901839118392183931839418395183961839718398183991840018401184021840318404184051840618407184081840918410184111841218413184141841518416184171841818419184201842118422184231842418425184261842718428184291843018431184321843318434184351843618437184381843918440184411844218443184441844518446184471844818449184501845118452184531845418455184561845718458184591846018461184621846318464184651846618467184681846918470184711847218473184741847518476184771847818479184801848118482184831848418485184861848718488184891849018491184921849318494184951849618497184981849918500185011850218503185041850518506185071850818509185101851118512185131851418515185161851718518185191852018521185221852318524185251852618527185281852918530185311853218533185341853518536185371853818539185401854118542185431854418545185461854718548185491855018551185521855318554185551855618557185581855918560185611856218563185641856518566185671856818569185701857118572185731857418575185761857718578185791858018581185821858318584185851858618587185881858918590185911859218593185941859518596185971859818599186001860118602186031860418605186061860718608186091861018611186121861318614186151861618617186181861918620186211862218623186241862518626186271862818629186301863118632186331863418635186361863718638186391864018641186421864318644186451864618647186481864918650186511865218653186541865518656186571865818659186601866118662186631866418665186661866718668186691867018671186721867318674186751867618677186781867918680186811868218683186841868518686186871868818689186901869118692186931869418695186961869718698186991870018701187021870318704187051870618707187081870918710187111871218713187141871518716187171871818719187201872118722187231872418725187261872718728187291873018731187321873318734187351873618737187381873918740187411874218743187441874518746187471874818749187501875118752187531875418755187561875718758187591876018761187621876318764187651876618767187681876918770187711877218773187741877518776187771877818779187801878118782187831878418785187861878718788187891879018791187921879318794187951879618797187981879918800188011880218803188041880518806188071880818809188101881118812188131881418815188161881718818188191882018821188221882318824188251882618827188281882918830188311883218833188341883518836188371883818839188401884118842188431884418845188461884718848188491885018851188521885318854188551885618857188581885918860188611886218863188641886518866188671886818869188701887118872188731887418875188761887718878188791888018881188821888318884188851888618887188881888918890188911889218893188941889518896188971889818899189001890118902189031890418905189061890718908189091891018911189121891318914189151891618917189181891918920189211892218923189241892518926189271892818929189301893118932189331893418935189361893718938189391894018941189421894318944189451894618947189481894918950189511895218953189541895518956189571895818959189601896118962189631896418965189661896718968189691897018971189721897318974189751897618977189781897918980189811898218983189841898518986189871898818989189901899118992189931899418995189961899718998189991900019001190021900319004190051900619007190081900919010190111901219013190141901519016190171901819019190201902119022190231902419025190261902719028190291903019031190321903319034190351903619037190381903919040190411904219043190441904519046190471904819049190501905119052190531905419055190561905719058190591906019061190621906319064190651906619067190681906919070190711907219073190741907519076190771907819079190801908119082190831908419085190861908719088190891909019091190921909319094190951909619097190981909919100191011910219103191041910519106191071910819109191101911119112191131911419115191161911719118191191912019121191221912319124191251912619127191281912919130191311913219133191341913519136191371913819139191401914119142191431914419145191461914719148191491915019151191521915319154191551915619157191581915919160191611916219163191641916519166191671916819169191701917119172191731917419175191761917719178191791918019181191821918319184191851918619187191881918919190191911919219193191941919519196191971919819199192001920119202192031920419205192061920719208192091921019211192121921319214192151921619217192181921919220192211922219223192241922519226192271922819229192301923119232192331923419235192361923719238192391924019241192421924319244192451924619247192481924919250192511925219253192541925519256192571925819259192601926119262192631926419265192661926719268192691927019271192721927319274192751927619277192781927919280192811928219283192841928519286192871928819289192901929119292192931929419295192961929719298192991930019301193021930319304193051930619307193081930919310193111931219313193141931519316193171931819319193201932119322193231932419325193261932719328193291933019331193321933319334193351933619337193381933919340193411934219343193441934519346193471934819349193501935119352193531935419355193561935719358193591936019361193621936319364193651936619367193681936919370193711937219373193741937519376193771937819379193801938119382193831938419385193861938719388193891939019391193921939319394193951939619397193981939919400194011940219403194041940519406194071940819409194101941119412194131941419415194161941719418194191942019421194221942319424194251942619427194281942919430194311943219433194341943519436194371943819439194401944119442194431944419445194461944719448194491945019451194521945319454194551945619457194581945919460194611946219463194641946519466194671946819469194701947119472194731947419475194761947719478194791948019481194821948319484194851948619487194881948919490194911949219493194941949519496194971949819499195001950119502195031950419505195061950719508195091951019511195121951319514195151951619517195181951919520195211952219523195241952519526195271952819529195301953119532195331953419535195361953719538195391954019541195421954319544195451954619547195481954919550195511955219553195541955519556195571955819559195601956119562195631956419565195661956719568195691957019571195721957319574195751957619577195781957919580195811958219583195841958519586195871958819589195901959119592195931959419595195961959719598195991960019601196021960319604196051960619607196081960919610196111961219613196141961519616196171961819619196201962119622196231962419625196261962719628196291963019631196321963319634196351963619637196381963919640196411964219643196441964519646196471964819649196501965119652196531965419655196561965719658196591966019661196621966319664196651966619667196681966919670196711967219673196741967519676196771967819679196801968119682196831968419685196861968719688196891969019691196921969319694196951969619697196981969919700197011970219703197041970519706197071970819709197101971119712197131971419715197161971719718197191972019721197221972319724197251972619727197281972919730197311973219733197341973519736197371973819739197401974119742197431974419745197461974719748197491975019751197521975319754197551975619757197581975919760197611976219763197641976519766197671976819769197701977119772197731977419775197761977719778197791978019781197821978319784197851978619787197881978919790197911979219793197941979519796197971979819799198001980119802198031980419805198061980719808198091981019811198121981319814198151981619817198181981919820198211982219823198241982519826198271982819829198301983119832198331983419835198361983719838198391984019841198421984319844198451984619847198481984919850198511985219853198541985519856198571985819859198601986119862198631986419865198661986719868198691987019871198721987319874198751987619877198781987919880198811988219883198841988519886198871988819889198901989119892198931989419895198961989719898198991990019901199021990319904199051990619907199081990919910199111991219913199141991519916199171991819919199201992119922199231992419925199261992719928199291993019931199321993319934199351993619937199381993919940199411994219943199441994519946199471994819949199501995119952199531995419955199561995719958199591996019961199621996319964199651996619967199681996919970199711997219973199741997519976199771997819979199801998119982199831998419985199861998719988199891999019991199921999319994199951999619997199981999920000200012000220003200042000520006200072000820009200102001120012200132001420015200162001720018200192002020021200222002320024200252002620027200282002920030200312003220033200342003520036200372003820039200402004120042200432004420045200462004720048200492005020051200522005320054200552005620057200582005920060200612006220063200642006520066200672006820069200702007120072200732007420075200762007720078200792008020081200822008320084200852008620087200882008920090200912009220093200942009520096200972009820099201002010120102201032010420105201062010720108201092011020111201122011320114201152011620117201182011920120201212012220123201242012520126201272012820129201302013120132201332013420135201362013720138201392014020141201422014320144201452014620147201482014920150201512015220153201542015520156201572015820159201602016120162201632016420165201662016720168201692017020171201722017320174201752017620177201782017920180201812018220183201842018520186201872018820189201902019120192201932019420195201962019720198201992020020201202022020320204202052020620207202082020920210202112021220213202142021520216202172021820219202202022120222202232022420225202262022720228202292023020231202322023320234202352023620237202382023920240202412024220243202442024520246202472024820249202502025120252202532025420255202562025720258202592026020261202622026320264202652026620267202682026920270202712027220273202742027520276202772027820279202802028120282202832028420285202862028720288202892029020291202922029320294202952029620297202982029920300203012030220303203042030520306203072030820309203102031120312203132031420315203162031720318203192032020321203222032320324203252032620327203282032920330203312033220333203342033520336203372033820339203402034120342203432034420345203462034720348203492035020351203522035320354203552035620357203582035920360203612036220363203642036520366203672036820369203702037120372203732037420375203762037720378203792038020381203822038320384203852038620387203882038920390203912039220393203942039520396203972039820399204002040120402204032040420405204062040720408204092041020411204122041320414204152041620417204182041920420204212042220423204242042520426204272042820429204302043120432204332043420435204362043720438204392044020441204422044320444204452044620447204482044920450204512045220453204542045520456204572045820459204602046120462204632046420465204662046720468204692047020471204722047320474204752047620477204782047920480204812048220483204842048520486204872048820489204902049120492204932049420495204962049720498204992050020501205022050320504205052050620507205082050920510205112051220513205142051520516205172051820519205202052120522205232052420525205262052720528205292053020531205322053320534205352053620537205382053920540205412054220543205442054520546205472054820549205502055120552205532055420555205562055720558205592056020561205622056320564205652056620567205682056920570205712057220573205742057520576205772057820579205802058120582205832058420585205862058720588205892059020591205922059320594205952059620597205982059920600206012060220603206042060520606206072060820609206102061120612206132061420615206162061720618206192062020621206222062320624206252062620627206282062920630206312063220633206342063520636206372063820639206402064120642206432064420645206462064720648206492065020651206522065320654206552065620657206582065920660206612066220663206642066520666206672066820669206702067120672206732067420675206762067720678206792068020681206822068320684206852068620687206882068920690206912069220693206942069520696206972069820699207002070120702207032070420705207062070720708207092071020711207122071320714207152071620717207182071920720207212072220723207242072520726207272072820729207302073120732207332073420735207362073720738207392074020741207422074320744207452074620747207482074920750207512075220753207542075520756207572075820759207602076120762207632076420765207662076720768207692077020771207722077320774207752077620777207782077920780207812078220783207842078520786207872078820789207902079120792207932079420795207962079720798207992080020801208022080320804208052080620807208082080920810208112081220813208142081520816208172081820819208202082120822208232082420825208262082720828208292083020831208322083320834208352083620837208382083920840208412084220843208442084520846208472084820849208502085120852208532085420855208562085720858208592086020861208622086320864208652086620867208682086920870208712087220873208742087520876208772087820879208802088120882208832088420885208862088720888208892089020891208922089320894208952089620897208982089920900209012090220903209042090520906209072090820909209102091120912209132091420915209162091720918209192092020921209222092320924209252092620927209282092920930209312093220933209342093520936209372093820939209402094120942209432094420945209462094720948209492095020951209522095320954209552095620957209582095920960209612096220963209642096520966209672096820969209702097120972209732097420975209762097720978209792098020981209822098320984209852098620987209882098920990209912099220993209942099520996209972099820999210002100121002210032100421005210062100721008210092101021011210122101321014210152101621017210182101921020210212102221023210242102521026210272102821029210302103121032210332103421035210362103721038210392104021041210422104321044210452104621047210482104921050210512105221053210542105521056210572105821059210602106121062210632106421065210662106721068210692107021071210722107321074210752107621077210782107921080210812108221083210842108521086210872108821089210902109121092210932109421095210962109721098210992110021101211022110321104211052110621107211082110921110211112111221113211142111521116211172111821119211202112121122211232112421125211262112721128211292113021131211322113321134211352113621137211382113921140211412114221143211442114521146211472114821149211502115121152211532115421155211562115721158211592116021161211622116321164211652116621167211682116921170211712117221173211742117521176211772117821179211802118121182211832118421185211862118721188211892119021191211922119321194211952119621197211982119921200212012120221203212042120521206212072120821209212102121121212212132121421215212162121721218212192122021221212222122321224212252122621227212282122921230212312123221233212342123521236212372123821239212402124121242212432124421245212462124721248212492125021251212522125321254212552125621257212582125921260212612126221263212642126521266212672126821269212702127121272212732127421275212762127721278212792128021281212822128321284212852128621287212882128921290212912129221293212942129521296212972129821299213002130121302213032130421305213062130721308213092131021311213122131321314213152131621317213182131921320213212132221323213242132521326213272132821329213302133121332213332133421335213362133721338213392134021341213422134321344213452134621347213482134921350213512135221353213542135521356213572135821359213602136121362213632136421365213662136721368213692137021371213722137321374213752137621377213782137921380213812138221383213842138521386213872138821389213902139121392213932139421395213962139721398213992140021401214022140321404214052140621407214082140921410214112141221413214142141521416214172141821419214202142121422214232142421425214262142721428214292143021431214322143321434214352143621437214382143921440214412144221443214442144521446214472144821449214502145121452214532145421455214562145721458214592146021461214622146321464214652146621467214682146921470214712147221473214742147521476214772147821479214802148121482214832148421485214862148721488214892149021491214922149321494214952149621497214982149921500215012150221503215042150521506215072150821509215102151121512215132151421515215162151721518215192152021521215222152321524215252152621527215282152921530215312153221533215342153521536215372153821539215402154121542215432154421545215462154721548215492155021551215522155321554215552155621557215582155921560215612156221563215642156521566215672156821569215702157121572215732157421575215762157721578215792158021581215822158321584215852158621587215882158921590215912159221593215942159521596215972159821599216002160121602216032160421605216062160721608216092161021611216122161321614216152161621617216182161921620216212162221623216242162521626216272162821629216302163121632216332163421635216362163721638216392164021641216422164321644216452164621647216482164921650216512165221653216542165521656216572165821659216602166121662216632166421665216662166721668216692167021671216722167321674216752167621677216782167921680216812168221683216842168521686216872168821689216902169121692216932169421695216962169721698216992170021701217022170321704217052170621707217082170921710217112171221713217142171521716217172171821719217202172121722217232172421725217262172721728217292173021731217322173321734217352173621737217382173921740217412174221743217442174521746217472174821749217502175121752217532175421755217562175721758217592176021761217622176321764217652176621767217682176921770217712177221773217742177521776217772177821779217802178121782217832178421785217862178721788217892179021791217922179321794217952179621797217982179921800218012180221803218042180521806218072180821809218102181121812218132181421815218162181721818218192182021821218222182321824218252182621827218282182921830218312183221833218342183521836218372183821839218402184121842218432184421845218462184721848218492185021851218522185321854218552185621857218582185921860218612186221863218642186521866218672186821869218702187121872218732187421875218762187721878218792188021881218822188321884218852188621887218882188921890218912189221893218942189521896218972189821899219002190121902219032190421905219062190721908219092191021911219122191321914219152191621917219182191921920219212192221923219242192521926219272192821929219302193121932219332193421935219362193721938219392194021941219422194321944219452194621947219482194921950219512195221953219542195521956219572195821959219602196121962219632196421965219662196721968219692197021971219722197321974219752197621977219782197921980219812198221983219842198521986219872198821989219902199121992219932199421995219962199721998219992200022001220022200322004220052200622007220082200922010220112201222013220142201522016220172201822019220202202122022220232202422025220262202722028220292203022031220322203322034220352203622037220382203922040220412204222043220442204522046220472204822049220502205122052220532205422055220562205722058220592206022061220622206322064220652206622067220682206922070220712207222073220742207522076220772207822079220802208122082220832208422085220862208722088220892209022091220922209322094220952209622097220982209922100221012210222103221042210522106221072210822109221102211122112221132211422115221162211722118221192212022121221222212322124221252212622127221282212922130221312213222133221342213522136221372213822139221402214122142221432214422145221462214722148221492215022151221522215322154221552215622157221582215922160221612216222163221642216522166221672216822169221702217122172221732217422175221762217722178221792218022181221822218322184221852218622187221882218922190221912219222193221942219522196221972219822199222002220122202222032220422205222062220722208222092221022211222122221322214222152221622217222182221922220222212222222223222242222522226222272222822229222302223122232222332223422235222362223722238222392224022241222422224322244222452224622247222482224922250222512225222253222542225522256222572225822259222602226122262222632226422265222662226722268222692227022271222722227322274222752227622277222782227922280222812228222283222842228522286222872228822289222902229122292222932229422295222962229722298222992230022301223022230322304223052230622307223082230922310223112231222313223142231522316223172231822319223202232122322223232232422325223262232722328223292233022331223322233322334223352233622337223382233922340223412234222343223442234522346223472234822349223502235122352223532235422355223562235722358223592236022361223622236322364223652236622367223682236922370223712237222373223742237522376223772237822379223802238122382223832238422385223862238722388223892239022391223922239322394223952239622397223982239922400224012240222403224042240522406224072240822409224102241122412224132241422415224162241722418224192242022421224222242322424224252242622427224282242922430224312243222433224342243522436224372243822439224402244122442224432244422445224462244722448224492245022451224522245322454224552245622457224582245922460224612246222463224642246522466224672246822469224702247122472224732247422475224762247722478224792248022481224822248322484224852248622487224882248922490224912249222493224942249522496224972249822499225002250122502225032250422505225062250722508225092251022511225122251322514225152251622517225182251922520225212252222523225242252522526225272252822529225302253122532225332253422535225362253722538225392254022541225422254322544225452254622547225482254922550225512255222553225542255522556225572255822559225602256122562225632256422565225662256722568225692257022571225722257322574225752257622577225782257922580225812258222583225842258522586225872258822589225902259122592225932259422595225962259722598225992260022601226022260322604226052260622607226082260922610226112261222613226142261522616226172261822619226202262122622226232262422625226262262722628226292263022631226322263322634226352263622637226382263922640226412264222643226442264522646226472264822649226502265122652226532265422655226562265722658226592266022661226622266322664226652266622667226682266922670226712267222673226742267522676226772267822679226802268122682226832268422685226862268722688226892269022691226922269322694226952269622697226982269922700227012270222703227042270522706227072270822709227102271122712227132271422715227162271722718227192272022721227222272322724227252272622727227282272922730227312273222733227342273522736227372273822739227402274122742227432274422745227462274722748227492275022751227522275322754227552275622757227582275922760227612276222763227642276522766227672276822769227702277122772227732277422775227762277722778227792278022781227822278322784227852278622787227882278922790227912279222793227942279522796227972279822799228002280122802228032280422805228062280722808228092281022811228122281322814228152281622817228182281922820228212282222823228242282522826228272282822829228302283122832228332283422835228362283722838228392284022841228422284322844228452284622847228482284922850228512285222853228542285522856228572285822859228602286122862228632286422865228662286722868228692287022871228722287322874228752287622877228782287922880228812288222883228842288522886228872288822889228902289122892228932289422895228962289722898228992290022901229022290322904229052290622907229082290922910229112291222913229142291522916229172291822919229202292122922229232292422925229262292722928229292293022931229322293322934229352293622937229382293922940229412294222943229442294522946229472294822949229502295122952229532295422955229562295722958229592296022961229622296322964229652296622967229682296922970229712297222973229742297522976229772297822979229802298122982229832298422985229862298722988229892299022991229922299322994229952299622997229982299923000230012300223003230042300523006230072300823009230102301123012230132301423015230162301723018230192302023021230222302323024230252302623027230282302923030230312303223033230342303523036230372303823039230402304123042230432304423045230462304723048230492305023051230522305323054230552305623057230582305923060230612306223063230642306523066230672306823069230702307123072230732307423075230762307723078230792308023081230822308323084230852308623087230882308923090230912309223093230942309523096230972309823099231002310123102231032310423105231062310723108231092311023111231122311323114231152311623117231182311923120231212312223123231242312523126231272312823129231302313123132231332313423135231362313723138231392314023141231422314323144231452314623147231482314923150231512315223153231542315523156231572315823159231602316123162231632316423165231662316723168231692317023171231722317323174231752317623177231782317923180231812318223183231842318523186231872318823189231902319123192231932319423195231962319723198231992320023201232022320323204232052320623207232082320923210232112321223213232142321523216232172321823219232202322123222232232322423225232262322723228232292323023231232322323323234232352323623237232382323923240232412324223243232442324523246232472324823249232502325123252232532325423255232562325723258232592326023261232622326323264232652326623267232682326923270232712327223273232742327523276232772327823279232802328123282232832328423285232862328723288232892329023291232922329323294232952329623297232982329923300233012330223303233042330523306233072330823309233102331123312233132331423315233162331723318233192332023321233222332323324233252332623327233282332923330233312333223333233342333523336233372333823339233402334123342233432334423345233462334723348233492335023351233522335323354233552335623357233582335923360233612336223363233642336523366233672336823369233702337123372233732337423375233762337723378233792338023381233822338323384233852338623387233882338923390233912339223393233942339523396233972339823399234002340123402234032340423405234062340723408234092341023411234122341323414234152341623417234182341923420234212342223423234242342523426234272342823429234302343123432234332343423435234362343723438234392344023441234422344323444234452344623447234482344923450234512345223453234542345523456234572345823459234602346123462234632346423465234662346723468234692347023471234722347323474234752347623477234782347923480234812348223483234842348523486234872348823489234902349123492234932349423495234962349723498234992350023501235022350323504235052350623507235082350923510235112351223513235142351523516235172351823519235202352123522235232352423525235262352723528235292353023531235322353323534235352353623537235382353923540235412354223543235442354523546235472354823549235502355123552235532355423555235562355723558235592356023561235622356323564235652356623567235682356923570235712357223573235742357523576235772357823579235802358123582235832358423585235862358723588235892359023591235922359323594235952359623597235982359923600236012360223603236042360523606236072360823609236102361123612236132361423615236162361723618236192362023621236222362323624236252362623627236282362923630236312363223633236342363523636236372363823639236402364123642236432364423645236462364723648236492365023651236522365323654236552365623657236582365923660236612366223663236642366523666236672366823669236702367123672236732367423675236762367723678236792368023681236822368323684236852368623687236882368923690236912369223693236942369523696236972369823699237002370123702237032370423705237062370723708237092371023711237122371323714237152371623717237182371923720237212372223723237242372523726237272372823729237302373123732237332373423735237362373723738237392374023741237422374323744237452374623747237482374923750237512375223753237542375523756237572375823759237602376123762237632376423765237662376723768237692377023771237722377323774237752377623777237782377923780237812378223783237842378523786237872378823789237902379123792237932379423795237962379723798237992380023801238022380323804238052380623807238082380923810238112381223813238142381523816238172381823819238202382123822238232382423825238262382723828238292383023831238322383323834238352383623837238382383923840238412384223843238442384523846238472384823849238502385123852238532385423855238562385723858238592386023861238622386323864238652386623867238682386923870238712387223873238742387523876238772387823879238802388123882238832388423885238862388723888238892389023891238922389323894238952389623897238982389923900239012390223903239042390523906239072390823909239102391123912239132391423915239162391723918239192392023921239222392323924239252392623927239282392923930239312393223933239342393523936239372393823939239402394123942239432394423945239462394723948239492395023951239522395323954239552395623957239582395923960239612396223963239642396523966239672396823969239702397123972239732397423975239762397723978239792398023981239822398323984239852398623987239882398923990239912399223993239942399523996239972399823999240002400124002240032400424005240062400724008240092401024011240122401324014240152401624017240182401924020240212402224023240242402524026240272402824029240302403124032240332403424035240362403724038240392404024041240422404324044240452404624047240482404924050240512405224053240542405524056240572405824059240602406124062240632406424065240662406724068240692407024071240722407324074240752407624077240782407924080240812408224083240842408524086240872408824089240902409124092240932409424095240962409724098240992410024101241022410324104241052410624107241082410924110241112411224113241142411524116241172411824119241202412124122241232412424125241262412724128241292413024131241322413324134241352413624137241382413924140241412414224143241442414524146241472414824149241502415124152241532415424155241562415724158241592416024161241622416324164241652416624167241682416924170241712417224173241742417524176241772417824179241802418124182241832418424185241862418724188241892419024191241922419324194241952419624197241982419924200242012420224203242042420524206242072420824209242102421124212242132421424215242162421724218242192422024221242222422324224242252422624227242282422924230242312423224233242342423524236242372423824239242402424124242242432424424245242462424724248242492425024251242522425324254242552425624257242582425924260242612426224263242642426524266242672426824269242702427124272242732427424275242762427724278242792428024281242822428324284242852428624287242882428924290242912429224293242942429524296242972429824299243002430124302243032430424305243062430724308243092431024311243122431324314243152431624317243182431924320243212432224323243242432524326243272432824329243302433124332243332433424335243362433724338243392434024341243422434324344243452434624347243482434924350243512435224353243542435524356243572435824359243602436124362243632436424365243662436724368243692437024371243722437324374243752437624377243782437924380243812438224383243842438524386243872438824389243902439124392243932439424395243962439724398243992440024401244022440324404244052440624407244082440924410244112441224413244142441524416244172441824419244202442124422244232442424425244262442724428244292443024431244322443324434244352443624437244382443924440244412444224443244442444524446244472444824449244502445124452244532445424455244562445724458244592446024461244622446324464244652446624467244682446924470244712447224473244742447524476244772447824479244802448124482244832448424485244862448724488244892449024491244922449324494244952449624497244982449924500245012450224503245042450524506245072450824509245102451124512245132451424515245162451724518245192452024521245222452324524245252452624527245282452924530245312453224533245342453524536245372453824539245402454124542245432454424545245462454724548245492455024551245522455324554245552455624557245582455924560245612456224563245642456524566245672456824569245702457124572245732457424575245762457724578245792458024581245822458324584245852458624587245882458924590245912459224593245942459524596245972459824599246002460124602246032460424605246062460724608246092461024611246122461324614246152461624617246182461924620246212462224623246242462524626246272462824629246302463124632246332463424635246362463724638246392464024641246422464324644246452464624647246482464924650246512465224653246542465524656246572465824659246602466124662246632466424665246662466724668246692467024671246722467324674246752467624677246782467924680246812468224683246842468524686246872468824689246902469124692246932469424695246962469724698246992470024701247022470324704247052470624707247082470924710247112471224713247142471524716247172471824719247202472124722247232472424725247262472724728247292473024731247322473324734247352473624737247382473924740247412474224743247442474524746247472474824749247502475124752247532475424755247562475724758247592476024761247622476324764247652476624767247682476924770247712477224773247742477524776247772477824779247802478124782247832478424785247862478724788247892479024791247922479324794247952479624797247982479924800248012480224803248042480524806248072480824809248102481124812248132481424815248162481724818248192482024821248222482324824248252482624827248282482924830248312483224833248342483524836248372483824839248402484124842248432484424845248462484724848248492485024851248522485324854248552485624857248582485924860248612486224863248642486524866248672486824869248702487124872248732487424875248762487724878248792488024881248822488324884248852488624887248882488924890248912489224893248942489524896248972489824899249002490124902249032490424905249062490724908249092491024911249122491324914249152491624917249182491924920249212492224923249242492524926249272492824929249302493124932249332493424935249362493724938249392494024941249422494324944249452494624947249482494924950249512495224953249542495524956249572495824959249602496124962249632496424965249662496724968249692497024971249722497324974249752497624977249782497924980249812498224983249842498524986249872498824989249902499124992249932499424995249962499724998249992500025001250022500325004250052500625007250082500925010250112501225013250142501525016250172501825019250202502125022250232502425025250262502725028250292503025031250322503325034250352503625037250382503925040250412504225043250442504525046250472504825049250502505125052250532505425055250562505725058250592506025061250622506325064250652506625067250682506925070250712507225073250742507525076250772507825079250802508125082250832508425085250862508725088250892509025091250922509325094250952509625097250982509925100251012510225103251042510525106251072510825109251102511125112251132511425115251162511725118251192512025121251222512325124251252512625127251282512925130251312513225133251342513525136251372513825139251402514125142251432514425145251462514725148251492515025151251522515325154251552515625157251582515925160251612516225163251642516525166251672516825169251702517125172251732517425175251762517725178251792518025181251822518325184251852518625187251882518925190251912519225193251942519525196251972519825199252002520125202252032520425205252062520725208252092521025211252122521325214252152521625217252182521925220252212522225223252242522525226252272522825229252302523125232252332523425235252362523725238252392524025241252422524325244252452524625247252482524925250252512525225253252542525525256252572525825259252602526125262252632526425265252662526725268252692527025271252722527325274252752527625277252782527925280252812528225283252842528525286252872528825289252902529125292252932529425295252962529725298252992530025301253022530325304253052530625307253082530925310253112531225313253142531525316253172531825319253202532125322253232532425325253262532725328253292533025331253322533325334253352533625337253382533925340253412534225343253442534525346253472534825349253502535125352253532535425355253562535725358253592536025361253622536325364253652536625367253682536925370253712537225373253742537525376253772537825379253802538125382253832538425385253862538725388253892539025391253922539325394253952539625397253982539925400254012540225403254042540525406254072540825409254102541125412254132541425415254162541725418254192542025421254222542325424254252542625427254282542925430254312543225433254342543525436254372543825439254402544125442254432544425445254462544725448254492545025451254522545325454254552545625457254582545925460254612546225463254642546525466254672546825469254702547125472254732547425475254762547725478254792548025481254822548325484254852548625487254882548925490254912549225493254942549525496254972549825499255002550125502255032550425505255062550725508255092551025511255122551325514255152551625517255182551925520255212552225523255242552525526255272552825529255302553125532255332553425535255362553725538255392554025541255422554325544255452554625547255482554925550255512555225553255542555525556255572555825559255602556125562255632556425565255662556725568255692557025571255722557325574255752557625577255782557925580255812558225583255842558525586255872558825589255902559125592255932559425595255962559725598255992560025601256022560325604256052560625607256082560925610256112561225613256142561525616256172561825619256202562125622256232562425625256262562725628256292563025631256322563325634256352563625637256382563925640256412564225643256442564525646256472564825649256502565125652256532565425655256562565725658256592566025661256622566325664256652566625667256682566925670256712567225673256742567525676256772567825679256802568125682256832568425685256862568725688256892569025691256922569325694256952569625697256982569925700257012570225703257042570525706257072570825709257102571125712257132571425715257162571725718257192572025721257222572325724257252572625727257282572925730257312573225733257342573525736257372573825739257402574125742257432574425745257462574725748257492575025751257522575325754257552575625757257582575925760257612576225763257642576525766257672576825769257702577125772257732577425775257762577725778257792578025781257822578325784257852578625787257882578925790257912579225793257942579525796257972579825799258002580125802258032580425805258062580725808258092581025811258122581325814258152581625817258182581925820258212582225823258242582525826258272582825829258302583125832258332583425835258362583725838258392584025841258422584325844258452584625847258482584925850258512585225853258542585525856258572585825859258602586125862258632586425865258662586725868258692587025871258722587325874258752587625877258782587925880258812588225883258842588525886258872588825889258902589125892258932589425895258962589725898258992590025901259022590325904259052590625907259082590925910259112591225913259142591525916259172591825919259202592125922259232592425925259262592725928259292593025931259322593325934259352593625937259382593925940259412594225943259442594525946259472594825949259502595125952259532595425955259562595725958259592596025961259622596325964259652596625967259682596925970259712597225973259742597525976259772597825979259802598125982259832598425985259862598725988259892599025991259922599325994259952599625997259982599926000260012600226003260042600526006260072600826009260102601126012260132601426015260162601726018260192602026021260222602326024260252602626027260282602926030260312603226033260342603526036260372603826039260402604126042260432604426045260462604726048260492605026051260522605326054260552605626057260582605926060260612606226063260642606526066260672606826069260702607126072260732607426075260762607726078260792608026081260822608326084260852608626087260882608926090260912609226093260942609526096260972609826099261002610126102261032610426105261062610726108261092611026111261122611326114261152611626117261182611926120261212612226123261242612526126261272612826129261302613126132261332613426135261362613726138261392614026141261422614326144261452614626147261482614926150261512615226153261542615526156261572615826159261602616126162261632616426165261662616726168261692617026171261722617326174261752617626177261782617926180261812618226183261842618526186261872618826189261902619126192261932619426195261962619726198261992620026201262022620326204262052620626207262082620926210262112621226213262142621526216262172621826219262202622126222262232622426225262262622726228262292623026231262322623326234262352623626237262382623926240262412624226243262442624526246262472624826249262502625126252262532625426255262562625726258262592626026261262622626326264262652626626267262682626926270262712627226273262742627526276262772627826279262802628126282262832628426285262862628726288262892629026291262922629326294262952629626297262982629926300263012630226303263042630526306263072630826309263102631126312263132631426315263162631726318263192632026321263222632326324263252632626327263282632926330263312633226333263342633526336263372633826339263402634126342263432634426345263462634726348263492635026351263522635326354263552635626357263582635926360263612636226363263642636526366263672636826369263702637126372263732637426375263762637726378263792638026381263822638326384263852638626387263882638926390263912639226393263942639526396263972639826399264002640126402264032640426405264062640726408264092641026411264122641326414264152641626417264182641926420264212642226423264242642526426264272642826429264302643126432264332643426435264362643726438264392644026441264422644326444264452644626447264482644926450264512645226453264542645526456264572645826459264602646126462264632646426465264662646726468264692647026471264722647326474264752647626477264782647926480264812648226483264842648526486264872648826489264902649126492264932649426495264962649726498264992650026501265022650326504265052650626507265082650926510265112651226513265142651526516265172651826519265202652126522265232652426525265262652726528265292653026531265322653326534265352653626537265382653926540265412654226543265442654526546265472654826549265502655126552265532655426555265562655726558265592656026561265622656326564265652656626567265682656926570265712657226573265742657526576265772657826579265802658126582265832658426585265862658726588265892659026591265922659326594265952659626597265982659926600266012660226603266042660526606266072660826609266102661126612266132661426615266162661726618266192662026621266222662326624266252662626627266282662926630266312663226633266342663526636266372663826639266402664126642266432664426645266462664726648266492665026651266522665326654266552665626657266582665926660266612666226663266642666526666266672666826669266702667126672266732667426675266762667726678266792668026681266822668326684266852668626687266882668926690266912669226693266942669526696266972669826699267002670126702267032670426705267062670726708267092671026711267122671326714267152671626717267182671926720267212672226723267242672526726267272672826729267302673126732267332673426735267362673726738267392674026741267422674326744267452674626747267482674926750267512675226753267542675526756267572675826759267602676126762267632676426765267662676726768267692677026771267722677326774267752677626777267782677926780267812678226783267842678526786267872678826789267902679126792267932679426795267962679726798267992680026801268022680326804268052680626807268082680926810268112681226813268142681526816268172681826819268202682126822268232682426825268262682726828268292683026831268322683326834268352683626837268382683926840268412684226843268442684526846268472684826849268502685126852268532685426855268562685726858268592686026861268622686326864268652686626867268682686926870268712687226873268742687526876268772687826879268802688126882268832688426885268862688726888268892689026891268922689326894268952689626897268982689926900269012690226903269042690526906269072690826909269102691126912269132691426915269162691726918269192692026921269222692326924269252692626927269282692926930269312693226933269342693526936269372693826939269402694126942269432694426945269462694726948269492695026951269522695326954269552695626957269582695926960269612696226963269642696526966269672696826969269702697126972269732697426975269762697726978269792698026981269822698326984269852698626987269882698926990269912699226993269942699526996269972699826999270002700127002270032700427005270062700727008270092701027011270122701327014270152701627017270182701927020270212702227023270242702527026270272702827029270302703127032270332703427035270362703727038270392704027041270422704327044270452704627047270482704927050270512705227053270542705527056270572705827059270602706127062270632706427065270662706727068270692707027071270722707327074270752707627077270782707927080270812708227083270842708527086270872708827089270902709127092270932709427095270962709727098270992710027101271022710327104271052710627107
  1. /**
  2. * @license
  3. * Video.js 6.0.0-RC.5 <http://videojs.com/>
  4. * Copyright Brightcove, Inc. <https://www.brightcove.com/>
  5. * Available under Apache License Version 2.0
  6. * <https://github.com/videojs/video.js/blob/master/LICENSE>
  7. *
  8. * Includes vtt.js <https://github.com/mozilla/vtt.js>
  9. * Available under Apache License Version 2.0
  10. * <https://github.com/mozilla/vtt.js/blob/master/LICENSE>
  11. */
  12. (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.videojs = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){
  13. 'use strict';
  14. exports.__esModule = true;
  15. var _button = _dereq_(2);
  16. var _button2 = _interopRequireDefault(_button);
  17. var _component = _dereq_(5);
  18. var _component2 = _interopRequireDefault(_component);
  19. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  20. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  21. function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
  22. function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
  23. * @file big-play-button.js
  24. */
  25. /**
  26. * The initial play button that shows before the video has played. The hiding of the
  27. * `BigPlayButton` get done via CSS and `Player` states.
  28. *
  29. * @extends Button
  30. */
  31. var BigPlayButton = function (_Button) {
  32. _inherits(BigPlayButton, _Button);
  33. function BigPlayButton() {
  34. _classCallCheck(this, BigPlayButton);
  35. return _possibleConstructorReturn(this, _Button.apply(this, arguments));
  36. }
  37. /**
  38. * Builds the default DOM `className`.
  39. *
  40. * @return {string}
  41. * The DOM `className` for this object. Always returns 'vjs-big-play-button'.
  42. */
  43. BigPlayButton.prototype.buildCSSClass = function buildCSSClass() {
  44. return 'vjs-big-play-button';
  45. };
  46. /**
  47. * This gets called when a `BigPlayButton` "clicked". See {@link ClickableComponent}
  48. * for more detailed information on what a click can be.
  49. *
  50. * @param {EventTarget~Event} event
  51. * The `keydown`, `tap`, or `click` event that caused this function to be
  52. * called.
  53. *
  54. * @listens tap
  55. * @listens click
  56. */
  57. BigPlayButton.prototype.handleClick = function handleClick(event) {
  58. var playPromise = this.player_.play();
  59. var cb = this.player_.getChild('controlBar');
  60. var playToggle = cb && cb.getChild('playToggle');
  61. if (!playToggle) {
  62. this.player_.focus();
  63. return;
  64. }
  65. if (playPromise) {
  66. playPromise.then(function () {
  67. return playToggle.focus();
  68. });
  69. } else {
  70. this.setTimeout(function () {
  71. playToggle.focus();
  72. }, 1);
  73. }
  74. };
  75. return BigPlayButton;
  76. }(_button2['default']);
  77. /**
  78. * The text that should display over the `BigPlayButton`s controls. Added to for localization.
  79. *
  80. * @type {string}
  81. * @private
  82. */
  83. BigPlayButton.prototype.controlText_ = 'Play Video';
  84. _component2['default'].registerComponent('BigPlayButton', BigPlayButton);
  85. exports['default'] = BigPlayButton;
  86. },{"2":2,"5":5}],2:[function(_dereq_,module,exports){
  87. 'use strict';
  88. exports.__esModule = true;
  89. var _clickableComponent = _dereq_(3);
  90. var _clickableComponent2 = _interopRequireDefault(_clickableComponent);
  91. var _component = _dereq_(5);
  92. var _component2 = _interopRequireDefault(_component);
  93. var _log = _dereq_(91);
  94. var _log2 = _interopRequireDefault(_log);
  95. var _obj = _dereq_(93);
  96. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  97. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  98. function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
  99. function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
  100. * @file button.js
  101. */
  102. /**
  103. * Base class for all buttons.
  104. *
  105. * @extends ClickableComponent
  106. */
  107. var Button = function (_ClickableComponent) {
  108. _inherits(Button, _ClickableComponent);
  109. function Button() {
  110. _classCallCheck(this, Button);
  111. return _possibleConstructorReturn(this, _ClickableComponent.apply(this, arguments));
  112. }
  113. /**
  114. * Create the `Button`s DOM element.
  115. *
  116. * @param {string} [tag="button"]
  117. * The element's node type. This argument is IGNORED: no matter what
  118. * is passed, it will always create a `button` element.
  119. *
  120. * @param {Object} [props={}]
  121. * An object of properties that should be set on the element.
  122. *
  123. * @param {Object} [attributes={}]
  124. * An object of attributes that should be set on the element.
  125. *
  126. * @return {Element}
  127. * The element that gets created.
  128. */
  129. Button.prototype.createEl = function createEl(tag) {
  130. var props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  131. var attributes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
  132. tag = 'button';
  133. props = (0, _obj.assign)({
  134. innerHTML: '<span aria-hidden="true" class="vjs-icon-placeholder"></span>',
  135. className: this.buildCSSClass()
  136. }, props);
  137. // Add attributes for button element
  138. attributes = (0, _obj.assign)({
  139. // Necessary since the default button type is "submit"
  140. 'type': 'button',
  141. // let the screen reader user know that the text of the button may change
  142. 'aria-live': 'polite'
  143. }, attributes);
  144. var el = _component2['default'].prototype.createEl.call(this, tag, props, attributes);
  145. this.createControlTextEl(el);
  146. return el;
  147. };
  148. /**
  149. * Add a child `Component` inside of this `Button`.
  150. *
  151. * @param {string|Component} child
  152. * The name or instance of a child to add.
  153. *
  154. * @param {Object} [options={}]
  155. * The key/value store of options that will get passed to children of
  156. * the child.
  157. *
  158. * @return {Component}
  159. * The `Component` that gets added as a child. When using a string the
  160. * `Component` will get created by this process.
  161. *
  162. * @deprecated since version 5
  163. */
  164. Button.prototype.addChild = function addChild(child) {
  165. var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  166. var className = this.constructor.name;
  167. _log2['default'].warn('Adding an actionable (user controllable) child to a Button (' + className + ') is not supported; use a ClickableComponent instead.');
  168. // Avoid the error message generated by ClickableComponent's addChild method
  169. return _component2['default'].prototype.addChild.call(this, child, options);
  170. };
  171. /**
  172. * Enable the `Button` element so that it can be activated or clicked. Use this with
  173. * {@link Button#disable}.
  174. */
  175. Button.prototype.enable = function enable() {
  176. _ClickableComponent.prototype.enable.call(this);
  177. this.el_.removeAttribute('disabled');
  178. };
  179. /**
  180. * Enable the `Button` element so that it cannot be activated or clicked. Use this with
  181. * {@link Button#enable}.
  182. */
  183. Button.prototype.disable = function disable() {
  184. _ClickableComponent.prototype.disable.call(this);
  185. this.el_.setAttribute('disabled', 'disabled');
  186. };
  187. /**
  188. * This gets called when a `Button` has focus and `keydown` is triggered via a key
  189. * press.
  190. *
  191. * @param {EventTarget~Event} event
  192. * The event that caused this function to get called.
  193. *
  194. * @listens keydown
  195. */
  196. Button.prototype.handleKeyPress = function handleKeyPress(event) {
  197. // Ignore Space (32) or Enter (13) key operation, which is handled by the browser for a button.
  198. if (event.which === 32 || event.which === 13) {
  199. return;
  200. }
  201. // Pass keypress handling up for unsupported keys
  202. _ClickableComponent.prototype.handleKeyPress.call(this, event);
  203. };
  204. return Button;
  205. }(_clickableComponent2['default']);
  206. _component2['default'].registerComponent('Button', Button);
  207. exports['default'] = Button;
  208. },{"3":3,"5":5,"91":91,"93":93}],3:[function(_dereq_,module,exports){
  209. 'use strict';
  210. exports.__esModule = true;
  211. var _component = _dereq_(5);
  212. var _component2 = _interopRequireDefault(_component);
  213. var _dom = _dereq_(85);
  214. var Dom = _interopRequireWildcard(_dom);
  215. var _events = _dereq_(86);
  216. var Events = _interopRequireWildcard(_events);
  217. var _fn = _dereq_(88);
  218. var Fn = _interopRequireWildcard(_fn);
  219. var _log = _dereq_(91);
  220. var _log2 = _interopRequireDefault(_log);
  221. var _document = _dereq_(99);
  222. var _document2 = _interopRequireDefault(_document);
  223. var _obj = _dereq_(93);
  224. function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
  225. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  226. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  227. function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
  228. function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
  229. * @file button.js
  230. */
  231. /**
  232. * Clickable Component which is clickable or keyboard actionable,
  233. * but is not a native HTML button.
  234. *
  235. * @extends Component
  236. */
  237. var ClickableComponent = function (_Component) {
  238. _inherits(ClickableComponent, _Component);
  239. /**
  240. * Creates an instance of this class.
  241. *
  242. * @param {Player} player
  243. * The `Player` that this class should be attached to.
  244. *
  245. * @param {Object} [options]
  246. * The key/value store of player options.
  247. */
  248. function ClickableComponent(player, options) {
  249. _classCallCheck(this, ClickableComponent);
  250. var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
  251. _this.emitTapEvents();
  252. _this.enable();
  253. return _this;
  254. }
  255. /**
  256. * Create the `Component`s DOM element.
  257. *
  258. * @param {string} [tag=div]
  259. * The element's node type.
  260. *
  261. * @param {Object} [props={}]
  262. * An object of properties that should be set on the element.
  263. *
  264. * @param {Object} [attributes={}]
  265. * An object of attributes that should be set on the element.
  266. *
  267. * @return {Element}
  268. * The element that gets created.
  269. */
  270. ClickableComponent.prototype.createEl = function createEl() {
  271. var tag = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'div';
  272. var props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  273. var attributes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
  274. props = (0, _obj.assign)({
  275. innerHTML: '<span aria-hidden="true" class="vjs-icon-placeholder"></span>',
  276. className: this.buildCSSClass(),
  277. tabIndex: 0
  278. }, props);
  279. if (tag === 'button') {
  280. _log2['default'].error('Creating a ClickableComponent with an HTML element of ' + tag + ' is not supported; use a Button instead.');
  281. }
  282. // Add ARIA attributes for clickable element which is not a native HTML button
  283. attributes = (0, _obj.assign)({
  284. 'role': 'button',
  285. // let the screen reader user know that the text of the element may change
  286. 'aria-live': 'polite'
  287. }, attributes);
  288. this.tabIndex_ = props.tabIndex;
  289. var el = _Component.prototype.createEl.call(this, tag, props, attributes);
  290. this.createControlTextEl(el);
  291. return el;
  292. };
  293. /**
  294. * Create a control text element on this `Component`
  295. *
  296. * @param {Element} [el]
  297. * Parent element for the control text.
  298. *
  299. * @return {Element}
  300. * The control text element that gets created.
  301. */
  302. ClickableComponent.prototype.createControlTextEl = function createControlTextEl(el) {
  303. this.controlTextEl_ = Dom.createEl('span', {
  304. className: 'vjs-control-text'
  305. });
  306. if (el) {
  307. el.appendChild(this.controlTextEl_);
  308. }
  309. this.controlText(this.controlText_, el);
  310. return this.controlTextEl_;
  311. };
  312. /**
  313. * Get or set the localize text to use for the controls on the `Component`.
  314. *
  315. * @param {string} [text]
  316. * Control text for element.
  317. *
  318. * @param {Element} [el=this.el()]
  319. * Element to set the title on.
  320. *
  321. * @return {string}
  322. * - The control text when getting
  323. */
  324. ClickableComponent.prototype.controlText = function controlText(text) {
  325. var el = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.el();
  326. if (!text) {
  327. return this.controlText_ || 'Need Text';
  328. }
  329. var localizedText = this.localize(text);
  330. this.controlText_ = text;
  331. this.controlTextEl_.innerHTML = localizedText;
  332. if (!this.nonIconControl) {
  333. // Set title attribute if only an icon is shown
  334. el.setAttribute('title', localizedText);
  335. }
  336. };
  337. /**
  338. * Builds the default DOM `className`.
  339. *
  340. * @return {string}
  341. * The DOM `className` for this object.
  342. */
  343. ClickableComponent.prototype.buildCSSClass = function buildCSSClass() {
  344. return 'vjs-control vjs-button ' + _Component.prototype.buildCSSClass.call(this);
  345. };
  346. /**
  347. * Enable this `Component`s element.
  348. */
  349. ClickableComponent.prototype.enable = function enable() {
  350. this.removeClass('vjs-disabled');
  351. this.el_.setAttribute('aria-disabled', 'false');
  352. if (typeof this.tabIndex_ !== 'undefined') {
  353. this.el_.setAttribute('tabIndex', this.tabIndex_);
  354. }
  355. this.on('tap', this.handleClick);
  356. this.on('click', this.handleClick);
  357. this.on('focus', this.handleFocus);
  358. this.on('blur', this.handleBlur);
  359. };
  360. /**
  361. * Disable this `Component`s element.
  362. */
  363. ClickableComponent.prototype.disable = function disable() {
  364. this.addClass('vjs-disabled');
  365. this.el_.setAttribute('aria-disabled', 'true');
  366. if (typeof this.tabIndex_ !== 'undefined') {
  367. this.el_.removeAttribute('tabIndex');
  368. }
  369. this.off('tap', this.handleClick);
  370. this.off('click', this.handleClick);
  371. this.off('focus', this.handleFocus);
  372. this.off('blur', this.handleBlur);
  373. };
  374. /**
  375. * This gets called when a `ClickableComponent` gets:
  376. * - Clicked (via the `click` event, listening starts in the constructor)
  377. * - Tapped (via the `tap` event, listening starts in the constructor)
  378. * - The following things happen in order:
  379. * 1. {@link ClickableComponent#handleFocus} is called via a `focus` event on the
  380. * `ClickableComponent`.
  381. * 2. {@link ClickableComponent#handleFocus} adds a listener for `keydown` on using
  382. * {@link ClickableComponent#handleKeyPress}.
  383. * 3. `ClickableComponent` has not had a `blur` event (`blur` means that focus was lost). The user presses
  384. * the space or enter key.
  385. * 4. {@link ClickableComponent#handleKeyPress} calls this function with the `keydown`
  386. * event as a parameter.
  387. *
  388. * @param {EventTarget~Event} event
  389. * The `keydown`, `tap`, or `click` event that caused this function to be
  390. * called.
  391. *
  392. * @listens tap
  393. * @listens click
  394. * @abstract
  395. */
  396. ClickableComponent.prototype.handleClick = function handleClick(event) {};
  397. /**
  398. * This gets called when a `ClickableComponent` gains focus via a `focus` event.
  399. * Turns on listening for `keydown` events. When they happen it
  400. * calls `this.handleKeyPress`.
  401. *
  402. * @param {EventTarget~Event} event
  403. * The `focus` event that caused this function to be called.
  404. *
  405. * @listens focus
  406. */
  407. ClickableComponent.prototype.handleFocus = function handleFocus(event) {
  408. Events.on(_document2['default'], 'keydown', Fn.bind(this, this.handleKeyPress));
  409. };
  410. /**
  411. * Called when this ClickableComponent has focus and a key gets pressed down. By
  412. * default it will call `this.handleClick` when the key is space or enter.
  413. *
  414. * @param {EventTarget~Event} event
  415. * The `keydown` event that caused this function to be called.
  416. *
  417. * @listens keydown
  418. */
  419. ClickableComponent.prototype.handleKeyPress = function handleKeyPress(event) {
  420. // Support Space (32) or Enter (13) key operation to fire a click event
  421. if (event.which === 32 || event.which === 13) {
  422. event.preventDefault();
  423. this.trigger('click');
  424. } else if (_Component.prototype.handleKeyPress) {
  425. // Pass keypress handling up for unsupported keys
  426. _Component.prototype.handleKeyPress.call(this, event);
  427. }
  428. };
  429. /**
  430. * Called when a `ClickableComponent` loses focus. Turns off the listener for
  431. * `keydown` events. Which Stops `this.handleKeyPress` from getting called.
  432. *
  433. * @param {EventTarget~Event} event
  434. * The `blur` event that caused this function to be called.
  435. *
  436. * @listens blur
  437. */
  438. ClickableComponent.prototype.handleBlur = function handleBlur(event) {
  439. Events.off(_document2['default'], 'keydown', Fn.bind(this, this.handleKeyPress));
  440. };
  441. return ClickableComponent;
  442. }(_component2['default']);
  443. _component2['default'].registerComponent('ClickableComponent', ClickableComponent);
  444. exports['default'] = ClickableComponent;
  445. },{"5":5,"85":85,"86":86,"88":88,"91":91,"93":93,"99":99}],4:[function(_dereq_,module,exports){
  446. 'use strict';
  447. exports.__esModule = true;
  448. var _button = _dereq_(2);
  449. var _button2 = _interopRequireDefault(_button);
  450. var _component = _dereq_(5);
  451. var _component2 = _interopRequireDefault(_component);
  452. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  453. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  454. function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
  455. function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
  456. * @file close-button.js
  457. */
  458. /**
  459. * The `CloseButton` is a `{@link Button}` that fires a `close` event when
  460. * it gets clicked.
  461. *
  462. * @extends Button
  463. */
  464. var CloseButton = function (_Button) {
  465. _inherits(CloseButton, _Button);
  466. /**
  467. * Creates an instance of the this class.
  468. *
  469. * @param {Player} player
  470. * The `Player` that this class should be attached to.
  471. *
  472. * @param {Object} [options]
  473. * The key/value store of player options.
  474. */
  475. function CloseButton(player, options) {
  476. _classCallCheck(this, CloseButton);
  477. var _this = _possibleConstructorReturn(this, _Button.call(this, player, options));
  478. _this.controlText(options && options.controlText || _this.localize('Close'));
  479. return _this;
  480. }
  481. /**
  482. * Builds the default DOM `className`.
  483. *
  484. * @return {string}
  485. * The DOM `className` for this object.
  486. */
  487. CloseButton.prototype.buildCSSClass = function buildCSSClass() {
  488. return 'vjs-close-button ' + _Button.prototype.buildCSSClass.call(this);
  489. };
  490. /**
  491. * This gets called when a `CloseButton` gets clicked. See
  492. * {@link ClickableComponent#handleClick} for more information on when this will be
  493. * triggered
  494. *
  495. * @param {EventTarget~Event} event
  496. * The `keydown`, `tap`, or `click` event that caused this function to be
  497. * called.
  498. *
  499. * @listens tap
  500. * @listens click
  501. * @fires CloseButton#close
  502. */
  503. CloseButton.prototype.handleClick = function handleClick(event) {
  504. /**
  505. * Triggered when the a `CloseButton` is clicked.
  506. *
  507. * @event CloseButton#close
  508. * @type {EventTarget~Event}
  509. *
  510. * @property {boolean} [bubbles=false]
  511. * set to false so that the close event does not
  512. * bubble up to parents if there is no listener
  513. */
  514. this.trigger({ type: 'close', bubbles: false });
  515. };
  516. return CloseButton;
  517. }(_button2['default']);
  518. _component2['default'].registerComponent('CloseButton', CloseButton);
  519. exports['default'] = CloseButton;
  520. },{"2":2,"5":5}],5:[function(_dereq_,module,exports){
  521. 'use strict';
  522. exports.__esModule = true;
  523. var _window = _dereq_(100);
  524. var _window2 = _interopRequireDefault(_window);
  525. var _evented = _dereq_(53);
  526. var _evented2 = _interopRequireDefault(_evented);
  527. var _stateful = _dereq_(54);
  528. var _stateful2 = _interopRequireDefault(_stateful);
  529. var _dom = _dereq_(85);
  530. var Dom = _interopRequireWildcard(_dom);
  531. var _domData = _dereq_(84);
  532. var DomData = _interopRequireWildcard(_domData);
  533. var _fn = _dereq_(88);
  534. var Fn = _interopRequireWildcard(_fn);
  535. var _guid = _dereq_(90);
  536. var Guid = _interopRequireWildcard(_guid);
  537. var _log = _dereq_(91);
  538. var _log2 = _interopRequireDefault(_log);
  539. var _toTitleCase = _dereq_(96);
  540. var _toTitleCase2 = _interopRequireDefault(_toTitleCase);
  541. var _mergeOptions = _dereq_(92);
  542. var _mergeOptions2 = _interopRequireDefault(_mergeOptions);
  543. function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
  544. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  545. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } /**
  546. * Player Component - Base class for all UI objects
  547. *
  548. * @file component.js
  549. */
  550. /**
  551. * Base class for all UI Components.
  552. * Components are UI objects which represent both a javascript object and an element
  553. * in the DOM. They can be children of other components, and can have
  554. * children themselves.
  555. *
  556. * Components can also use methods from {@link EventTarget}
  557. */
  558. var Component = function () {
  559. /**
  560. * A callback that is called when a component is ready. Does not have any
  561. * paramters and any callback value will be ignored.
  562. *
  563. * @callback Component~ReadyCallback
  564. * @this Component
  565. */
  566. /**
  567. * Creates an instance of this class.
  568. *
  569. * @param {Player} player
  570. * The `Player` that this class should be attached to.
  571. *
  572. * @param {Object} [options]
  573. * The key/value store of player options.
  574. #
  575. * @param {Object[]} [options.children]
  576. * An array of children objects to intialize this component with. Children objects have
  577. * a name property that will be used if more than one component of the same type needs to be
  578. * added.
  579. *
  580. * @param {Component~ReadyCallback} [ready]
  581. * Function that gets called when the `Component` is ready.
  582. */
  583. function Component(player, options, ready) {
  584. _classCallCheck(this, Component);
  585. // The component might be the player itself and we can't pass `this` to super
  586. if (!player && this.play) {
  587. this.player_ = player = this; // eslint-disable-line
  588. } else {
  589. this.player_ = player;
  590. }
  591. // Make a copy of prototype.options_ to protect against overriding defaults
  592. this.options_ = (0, _mergeOptions2['default'])({}, this.options_);
  593. // Updated options with supplied options
  594. options = this.options_ = (0, _mergeOptions2['default'])(this.options_, options);
  595. // Get ID from options or options element if one is supplied
  596. this.id_ = options.id || options.el && options.el.id;
  597. // If there was no ID from the options, generate one
  598. if (!this.id_) {
  599. // Don't require the player ID function in the case of mock players
  600. var id = player && player.id && player.id() || 'no_player';
  601. this.id_ = id + '_component_' + Guid.newGUID();
  602. }
  603. this.name_ = options.name || null;
  604. // Create element if one wasn't provided in options
  605. if (options.el) {
  606. this.el_ = options.el;
  607. } else if (options.createEl !== false) {
  608. this.el_ = this.createEl();
  609. }
  610. // Make this an evented object and use `el_`, if available, as its event bus
  611. (0, _evented2['default'])(this, { eventBusKey: this.el_ ? 'el_' : null });
  612. (0, _stateful2['default'])(this, this.constructor.defaultState);
  613. this.children_ = [];
  614. this.childIndex_ = {};
  615. this.childNameIndex_ = {};
  616. // Add any child components in options
  617. if (options.initChildren !== false) {
  618. this.initChildren();
  619. }
  620. this.ready(ready);
  621. // Don't want to trigger ready here or it will before init is actually
  622. // finished for all children that run this constructor
  623. if (options.reportTouchActivity !== false) {
  624. this.enableTouchActivity();
  625. }
  626. }
  627. /**
  628. * Dispose of the `Component` and all child components.
  629. *
  630. * @fires Component#dispose
  631. */
  632. Component.prototype.dispose = function dispose() {
  633. /**
  634. * Triggered when a `Component` is disposed.
  635. *
  636. * @event Component#dispose
  637. * @type {EventTarget~Event}
  638. *
  639. * @property {boolean} [bubbles=false]
  640. * set to false so that the close event does not
  641. * bubble up
  642. */
  643. this.trigger({ type: 'dispose', bubbles: false });
  644. // Dispose all children.
  645. if (this.children_) {
  646. for (var i = this.children_.length - 1; i >= 0; i--) {
  647. if (this.children_[i].dispose) {
  648. this.children_[i].dispose();
  649. }
  650. }
  651. }
  652. // Delete child references
  653. this.children_ = null;
  654. this.childIndex_ = null;
  655. this.childNameIndex_ = null;
  656. if (this.el_) {
  657. // Remove element from DOM
  658. if (this.el_.parentNode) {
  659. this.el_.parentNode.removeChild(this.el_);
  660. }
  661. DomData.removeData(this.el_);
  662. this.el_ = null;
  663. }
  664. };
  665. /**
  666. * Return the {@link Player} that the `Component` has attached to.
  667. *
  668. * @return {Player}
  669. * The player that this `Component` has attached to.
  670. */
  671. Component.prototype.player = function player() {
  672. return this.player_;
  673. };
  674. /**
  675. * Deep merge of options objects with new options.
  676. * > Note: When both `obj` and `options` contain properties whose values are objects.
  677. * The two properties get merged using {@link module:mergeOptions}
  678. *
  679. * @param {Object} obj
  680. * The object that contains new options.
  681. *
  682. * @return {Object}
  683. * A new object of `this.options_` and `obj` merged together.
  684. *
  685. * @deprecated since version 5
  686. */
  687. Component.prototype.options = function options(obj) {
  688. _log2['default'].warn('this.options() has been deprecated and will be moved to the constructor in 6.0');
  689. if (!obj) {
  690. return this.options_;
  691. }
  692. this.options_ = (0, _mergeOptions2['default'])(this.options_, obj);
  693. return this.options_;
  694. };
  695. /**
  696. * Get the `Component`s DOM element
  697. *
  698. * @return {Element}
  699. * The DOM element for this `Component`.
  700. */
  701. Component.prototype.el = function el() {
  702. return this.el_;
  703. };
  704. /**
  705. * Create the `Component`s DOM element.
  706. *
  707. * @param {string} [tagName]
  708. * Element's DOM node type. e.g. 'div'
  709. *
  710. * @param {Object} [properties]
  711. * An object of properties that should be set.
  712. *
  713. * @param {Object} [attributes]
  714. * An object of attributes that should be set.
  715. *
  716. * @return {Element}
  717. * The element that gets created.
  718. */
  719. Component.prototype.createEl = function createEl(tagName, properties, attributes) {
  720. return Dom.createEl(tagName, properties, attributes);
  721. };
  722. /**
  723. * Localize a string given the string in english.
  724. *
  725. * If tokens are provided, it'll try and run a simple token replacement on the provided string.
  726. * The tokens it loooks for look like `{1}` with the index being 1-indexed into the tokens array.
  727. *
  728. * If a `defaultValue` is provided, it'll use that over `string`,
  729. * if a value isn't found in provided language files.
  730. * This is useful if you want to have a descriptive key for token replacement
  731. * but have a succinct localized string and not require `en.json` to be included.
  732. *
  733. * Currently, it is used for the progress bar timing.
  734. * ```js
  735. * {
  736. * "progress bar timing: currentTime={1} duration={2}": "{1} of {2}"
  737. * }
  738. * ```
  739. * It is then used like so:
  740. * ```js
  741. * this.localize('progress bar timing: currentTime={1} duration{2}',
  742. * [this.player_.currentTime(), this.player_.duration()],
  743. * '{1} of {2}');
  744. * ```
  745. *
  746. * Which outputs something like: `01:23 of 24:56`.
  747. *
  748. *
  749. * @param {string} string
  750. * The string to localize and the key to lookup in the language files.
  751. * @param {string[]} [tokens]
  752. * If the current item has token replacements, provide the tokens here.
  753. * @param {string} [defaultValue]
  754. * Defaults to `string`. Can be a default value to use for token replacement
  755. * if the lookup key is needed to be separate.
  756. *
  757. * @return {string}
  758. * The localized string or if no localization exists the english string.
  759. */
  760. Component.prototype.localize = function localize(string, tokens) {
  761. var defaultValue = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : string;
  762. var code = this.player_.language && this.player_.language();
  763. var languages = this.player_.languages && this.player_.languages();
  764. var language = languages && languages[code];
  765. var primaryCode = code && code.split('-')[0];
  766. var primaryLang = languages && languages[primaryCode];
  767. var localizedString = defaultValue;
  768. if (language && language[string]) {
  769. localizedString = language[string];
  770. } else if (primaryLang && primaryLang[string]) {
  771. localizedString = primaryLang[string];
  772. }
  773. if (tokens) {
  774. localizedString = localizedString.replace(/\{(\d+)\}/g, function (match, index) {
  775. var value = tokens[index - 1];
  776. var ret = value;
  777. if (typeof value === 'undefined') {
  778. ret = match;
  779. }
  780. return ret;
  781. });
  782. }
  783. return localizedString;
  784. };
  785. /**
  786. * Return the `Component`s DOM element. This is where children get inserted.
  787. * This will usually be the the same as the element returned in {@link Component#el}.
  788. *
  789. * @return {Element}
  790. * The content element for this `Component`.
  791. */
  792. Component.prototype.contentEl = function contentEl() {
  793. return this.contentEl_ || this.el_;
  794. };
  795. /**
  796. * Get this `Component`s ID
  797. *
  798. * @return {string}
  799. * The id of this `Component`
  800. */
  801. Component.prototype.id = function id() {
  802. return this.id_;
  803. };
  804. /**
  805. * Get the `Component`s name. The name gets used to reference the `Component`
  806. * and is set during registration.
  807. *
  808. * @return {string}
  809. * The name of this `Component`.
  810. */
  811. Component.prototype.name = function name() {
  812. return this.name_;
  813. };
  814. /**
  815. * Get an array of all child components
  816. *
  817. * @return {Array}
  818. * The children
  819. */
  820. Component.prototype.children = function children() {
  821. return this.children_;
  822. };
  823. /**
  824. * Returns the child `Component` with the given `id`.
  825. *
  826. * @param {string} id
  827. * The id of the child `Component` to get.
  828. *
  829. * @return {Component|undefined}
  830. * The child `Component` with the given `id` or undefined.
  831. */
  832. Component.prototype.getChildById = function getChildById(id) {
  833. return this.childIndex_[id];
  834. };
  835. /**
  836. * Returns the child `Component` with the given `name`.
  837. *
  838. * @param {string} name
  839. * The name of the child `Component` to get.
  840. *
  841. * @return {Component|undefined}
  842. * The child `Component` with the given `name` or undefined.
  843. */
  844. Component.prototype.getChild = function getChild(name) {
  845. if (!name) {
  846. return;
  847. }
  848. name = (0, _toTitleCase2['default'])(name);
  849. return this.childNameIndex_[name];
  850. };
  851. /**
  852. * Add a child `Component` inside the current `Component`.
  853. *
  854. *
  855. * @param {string|Component} child
  856. * The name or instance of a child to add.
  857. *
  858. * @param {Object} [options={}]
  859. * The key/value store of options that will get passed to children of
  860. * the child.
  861. *
  862. * @param {number} [index=this.children_.length]
  863. * The index to attempt to add a child into.
  864. *
  865. * @return {Component}
  866. * The `Component` that gets added as a child. When using a string the
  867. * `Component` will get created by this process.
  868. */
  869. Component.prototype.addChild = function addChild(child) {
  870. var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  871. var index = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.children_.length;
  872. var component = void 0;
  873. var componentName = void 0;
  874. // If child is a string, create component with options
  875. if (typeof child === 'string') {
  876. componentName = (0, _toTitleCase2['default'])(child);
  877. var componentClassName = options.componentClass || componentName;
  878. // Set name through options
  879. options.name = componentName;
  880. // Create a new object & element for this controls set
  881. // If there's no .player_, this is a player
  882. var ComponentClass = Component.getComponent(componentClassName);
  883. if (!ComponentClass) {
  884. throw new Error('Component ' + componentClassName + ' does not exist');
  885. }
  886. // data stored directly on the videojs object may be
  887. // misidentified as a component to retain
  888. // backwards-compatibility with 4.x. check to make sure the
  889. // component class can be instantiated.
  890. if (typeof ComponentClass !== 'function') {
  891. return null;
  892. }
  893. component = new ComponentClass(this.player_ || this, options);
  894. // child is a component instance
  895. } else {
  896. component = child;
  897. }
  898. this.children_.splice(index, 0, component);
  899. if (typeof component.id === 'function') {
  900. this.childIndex_[component.id()] = component;
  901. }
  902. // If a name wasn't used to create the component, check if we can use the
  903. // name function of the component
  904. componentName = componentName || component.name && (0, _toTitleCase2['default'])(component.name());
  905. if (componentName) {
  906. this.childNameIndex_[componentName] = component;
  907. }
  908. // Add the UI object's element to the container div (box)
  909. // Having an element is not required
  910. if (typeof component.el === 'function' && component.el()) {
  911. var childNodes = this.contentEl().children;
  912. var refNode = childNodes[index] || null;
  913. this.contentEl().insertBefore(component.el(), refNode);
  914. }
  915. // Return so it can stored on parent object if desired.
  916. return component;
  917. };
  918. /**
  919. * Remove a child `Component` from this `Component`s list of children. Also removes
  920. * the child `Component`s element from this `Component`s element.
  921. *
  922. * @param {Component} component
  923. * The child `Component` to remove.
  924. */
  925. Component.prototype.removeChild = function removeChild(component) {
  926. if (typeof component === 'string') {
  927. component = this.getChild(component);
  928. }
  929. if (!component || !this.children_) {
  930. return;
  931. }
  932. var childFound = false;
  933. for (var i = this.children_.length - 1; i >= 0; i--) {
  934. if (this.children_[i] === component) {
  935. childFound = true;
  936. this.children_.splice(i, 1);
  937. break;
  938. }
  939. }
  940. if (!childFound) {
  941. return;
  942. }
  943. this.childIndex_[component.id()] = null;
  944. this.childNameIndex_[component.name()] = null;
  945. var compEl = component.el();
  946. if (compEl && compEl.parentNode === this.contentEl()) {
  947. this.contentEl().removeChild(component.el());
  948. }
  949. };
  950. /**
  951. * Add and initialize default child `Component`s based upon options.
  952. */
  953. Component.prototype.initChildren = function initChildren() {
  954. var _this = this;
  955. var children = this.options_.children;
  956. if (children) {
  957. // `this` is `parent`
  958. var parentOptions = this.options_;
  959. var handleAdd = function handleAdd(child) {
  960. var name = child.name;
  961. var opts = child.opts;
  962. // Allow options for children to be set at the parent options
  963. // e.g. videojs(id, { controlBar: false });
  964. // instead of videojs(id, { children: { controlBar: false });
  965. if (parentOptions[name] !== undefined) {
  966. opts = parentOptions[name];
  967. }
  968. // Allow for disabling default components
  969. // e.g. options['children']['posterImage'] = false
  970. if (opts === false) {
  971. return;
  972. }
  973. // Allow options to be passed as a simple boolean if no configuration
  974. // is necessary.
  975. if (opts === true) {
  976. opts = {};
  977. }
  978. // We also want to pass the original player options
  979. // to each component as well so they don't need to
  980. // reach back into the player for options later.
  981. opts.playerOptions = _this.options_.playerOptions;
  982. // Create and add the child component.
  983. // Add a direct reference to the child by name on the parent instance.
  984. // If two of the same component are used, different names should be supplied
  985. // for each
  986. var newChild = _this.addChild(name, opts);
  987. if (newChild) {
  988. _this[name] = newChild;
  989. }
  990. };
  991. // Allow for an array of children details to passed in the options
  992. var workingChildren = void 0;
  993. var Tech = Component.getComponent('Tech');
  994. if (Array.isArray(children)) {
  995. workingChildren = children;
  996. } else {
  997. workingChildren = Object.keys(children);
  998. }
  999. workingChildren
  1000. // children that are in this.options_ but also in workingChildren would
  1001. // give us extra children we do not want. So, we want to filter them out.
  1002. .concat(Object.keys(this.options_).filter(function (child) {
  1003. return !workingChildren.some(function (wchild) {
  1004. if (typeof wchild === 'string') {
  1005. return child === wchild;
  1006. }
  1007. return child === wchild.name;
  1008. });
  1009. })).map(function (child) {
  1010. var name = void 0;
  1011. var opts = void 0;
  1012. if (typeof child === 'string') {
  1013. name = child;
  1014. opts = children[name] || _this.options_[name] || {};
  1015. } else {
  1016. name = child.name;
  1017. opts = child;
  1018. }
  1019. return { name: name, opts: opts };
  1020. }).filter(function (child) {
  1021. // we have to make sure that child.name isn't in the techOrder since
  1022. // techs are registerd as Components but can't aren't compatible
  1023. // See https://github.com/videojs/video.js/issues/2772
  1024. var c = Component.getComponent(child.opts.componentClass || (0, _toTitleCase2['default'])(child.name));
  1025. return c && !Tech.isTech(c);
  1026. }).forEach(handleAdd);
  1027. }
  1028. };
  1029. /**
  1030. * Builds the default DOM class name. Should be overriden by sub-components.
  1031. *
  1032. * @return {string}
  1033. * The DOM class name for this object.
  1034. *
  1035. * @abstract
  1036. */
  1037. Component.prototype.buildCSSClass = function buildCSSClass() {
  1038. // Child classes can include a function that does:
  1039. // return 'CLASS NAME' + this._super();
  1040. return '';
  1041. };
  1042. /**
  1043. * Bind a listener to the component's ready state.
  1044. * Different from event listeners in that if the ready event has already happened
  1045. * it will trigger the function immediately.
  1046. *
  1047. * @return {Component}
  1048. * Returns itself; method can be chained.
  1049. */
  1050. Component.prototype.ready = function ready(fn) {
  1051. var sync = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
  1052. if (fn) {
  1053. if (this.isReady_) {
  1054. if (sync) {
  1055. fn.call(this);
  1056. } else {
  1057. // Call the function asynchronously by default for consistency
  1058. this.setTimeout(fn, 1);
  1059. }
  1060. } else {
  1061. this.readyQueue_ = this.readyQueue_ || [];
  1062. this.readyQueue_.push(fn);
  1063. }
  1064. }
  1065. };
  1066. /**
  1067. * Trigger all the ready listeners for this `Component`.
  1068. *
  1069. * @fires Component#ready
  1070. */
  1071. Component.prototype.triggerReady = function triggerReady() {
  1072. this.isReady_ = true;
  1073. // Ensure ready is triggerd asynchronously
  1074. this.setTimeout(function () {
  1075. var readyQueue = this.readyQueue_;
  1076. // Reset Ready Queue
  1077. this.readyQueue_ = [];
  1078. if (readyQueue && readyQueue.length > 0) {
  1079. readyQueue.forEach(function (fn) {
  1080. fn.call(this);
  1081. }, this);
  1082. }
  1083. // Allow for using event listeners also
  1084. /**
  1085. * Triggered when a `Component` is ready.
  1086. *
  1087. * @event Component#ready
  1088. * @type {EventTarget~Event}
  1089. */
  1090. this.trigger('ready');
  1091. }, 1);
  1092. };
  1093. /**
  1094. * Find a single DOM element matching a `selector`. This can be within the `Component`s
  1095. * `contentEl()` or another custom context.
  1096. *
  1097. * @param {string} selector
  1098. * A valid CSS selector, which will be passed to `querySelector`.
  1099. *
  1100. * @param {Element|string} [context=this.contentEl()]
  1101. * A DOM element within which to query. Can also be a selector string in
  1102. * which case the first matching element will get used as context. If
  1103. * missing `this.contentEl()` gets used. If `this.contentEl()` returns
  1104. * nothing it falls back to `document`.
  1105. *
  1106. * @return {Element|null}
  1107. * the dom element that was found, or null
  1108. *
  1109. * @see [Information on CSS Selectors](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Getting_Started/Selectors)
  1110. */
  1111. Component.prototype.$ = function $(selector, context) {
  1112. return Dom.$(selector, context || this.contentEl());
  1113. };
  1114. /**
  1115. * Finds all DOM element matching a `selector`. This can be within the `Component`s
  1116. * `contentEl()` or another custom context.
  1117. *
  1118. * @param {string} selector
  1119. * A valid CSS selector, which will be passed to `querySelectorAll`.
  1120. *
  1121. * @param {Element|string} [context=this.contentEl()]
  1122. * A DOM element within which to query. Can also be a selector string in
  1123. * which case the first matching element will get used as context. If
  1124. * missing `this.contentEl()` gets used. If `this.contentEl()` returns
  1125. * nothing it falls back to `document`.
  1126. *
  1127. * @return {NodeList}
  1128. * a list of dom elements that were found
  1129. *
  1130. * @see [Information on CSS Selectors](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Getting_Started/Selectors)
  1131. */
  1132. Component.prototype.$$ = function $$(selector, context) {
  1133. return Dom.$$(selector, context || this.contentEl());
  1134. };
  1135. /**
  1136. * Check if a component's element has a CSS class name.
  1137. *
  1138. * @param {string} classToCheck
  1139. * CSS class name to check.
  1140. *
  1141. * @return {boolean}
  1142. * - True if the `Component` has the class.
  1143. * - False if the `Component` does not have the class`
  1144. */
  1145. Component.prototype.hasClass = function hasClass(classToCheck) {
  1146. return Dom.hasClass(this.el_, classToCheck);
  1147. };
  1148. /**
  1149. * Add a CSS class name to the `Component`s element.
  1150. *
  1151. * @param {string} classToAdd
  1152. * CSS class name to add
  1153. */
  1154. Component.prototype.addClass = function addClass(classToAdd) {
  1155. Dom.addClass(this.el_, classToAdd);
  1156. };
  1157. /**
  1158. * Remove a CSS class name from the `Component`s element.
  1159. *
  1160. * @param {string} classToRemove
  1161. * CSS class name to remove
  1162. */
  1163. Component.prototype.removeClass = function removeClass(classToRemove) {
  1164. Dom.removeClass(this.el_, classToRemove);
  1165. };
  1166. /**
  1167. * Add or remove a CSS class name from the component's element.
  1168. * - `classToToggle` gets added when {@link Component#hasClass} would return false.
  1169. * - `classToToggle` gets removed when {@link Component#hasClass} would return true.
  1170. *
  1171. * @param {string} classToToggle
  1172. * The class to add or remove based on (@link Component#hasClass}
  1173. *
  1174. * @param {boolean|Dom~predicate} [predicate]
  1175. * An {@link Dom~predicate} function or a boolean
  1176. */
  1177. Component.prototype.toggleClass = function toggleClass(classToToggle, predicate) {
  1178. Dom.toggleClass(this.el_, classToToggle, predicate);
  1179. };
  1180. /**
  1181. * Show the `Component`s element if it is hidden by removing the
  1182. * 'vjs-hidden' class name from it.
  1183. */
  1184. Component.prototype.show = function show() {
  1185. this.removeClass('vjs-hidden');
  1186. };
  1187. /**
  1188. * Hide the `Component`s element if it is currently showing by adding the
  1189. * 'vjs-hidden` class name to it.
  1190. */
  1191. Component.prototype.hide = function hide() {
  1192. this.addClass('vjs-hidden');
  1193. };
  1194. /**
  1195. * Lock a `Component`s element in its visible state by adding the 'vjs-lock-showing'
  1196. * class name to it. Used during fadeIn/fadeOut.
  1197. *
  1198. * @private
  1199. */
  1200. Component.prototype.lockShowing = function lockShowing() {
  1201. this.addClass('vjs-lock-showing');
  1202. };
  1203. /**
  1204. * Unlock a `Component`s element from its visible state by removing the 'vjs-lock-showing'
  1205. * class name from it. Used during fadeIn/fadeOut.
  1206. *
  1207. * @private
  1208. */
  1209. Component.prototype.unlockShowing = function unlockShowing() {
  1210. this.removeClass('vjs-lock-showing');
  1211. };
  1212. /**
  1213. * Get the value of an attribute on the `Component`s element.
  1214. *
  1215. * @param {string} attribute
  1216. * Name of the attribute to get the value from.
  1217. *
  1218. * @return {string|null}
  1219. * - The value of the attribute that was asked for.
  1220. * - Can be an empty string on some browsers if the attribute does not exist
  1221. * or has no value
  1222. * - Most browsers will return null if the attibute does not exist or has
  1223. * no value.
  1224. *
  1225. * @see [DOM API]{@link https://developer.mozilla.org/en-US/docs/Web/API/Element/getAttribute}
  1226. */
  1227. Component.prototype.getAttribute = function getAttribute(attribute) {
  1228. return Dom.getAttribute(this.el_, attribute);
  1229. };
  1230. /**
  1231. * Set the value of an attribute on the `Component`'s element
  1232. *
  1233. * @param {string} attribute
  1234. * Name of the attribute to set.
  1235. *
  1236. * @param {string} value
  1237. * Value to set the attribute to.
  1238. *
  1239. * @see [DOM API]{@link https://developer.mozilla.org/en-US/docs/Web/API/Element/setAttribute}
  1240. */
  1241. Component.prototype.setAttribute = function setAttribute(attribute, value) {
  1242. Dom.setAttribute(this.el_, attribute, value);
  1243. };
  1244. /**
  1245. * Remove an attribute from the `Component`s element.
  1246. *
  1247. * @param {string} attribute
  1248. * Name of the attribute to remove.
  1249. *
  1250. * @see [DOM API]{@link https://developer.mozilla.org/en-US/docs/Web/API/Element/removeAttribute}
  1251. */
  1252. Component.prototype.removeAttribute = function removeAttribute(attribute) {
  1253. Dom.removeAttribute(this.el_, attribute);
  1254. };
  1255. /**
  1256. * Get or set the width of the component based upon the CSS styles.
  1257. * See {@link Component#dimension} for more detailed information.
  1258. *
  1259. * @param {number|string} [num]
  1260. * The width that you want to set postfixed with '%', 'px' or nothing.
  1261. *
  1262. * @param {boolean} [skipListeners]
  1263. * Skip the componentresize event trigger
  1264. *
  1265. * @return {number|string}
  1266. * The width when getting, zero if there is no width. Can be a string
  1267. * postpixed with '%' or 'px'.
  1268. */
  1269. Component.prototype.width = function width(num, skipListeners) {
  1270. return this.dimension('width', num, skipListeners);
  1271. };
  1272. /**
  1273. * Get or set the height of the component based upon the CSS styles.
  1274. * See {@link Component#dimension} for more detailed information.
  1275. *
  1276. * @param {number|string} [num]
  1277. * The height that you want to set postfixed with '%', 'px' or nothing.
  1278. *
  1279. * @param {boolean} [skipListeners]
  1280. * Skip the componentresize event trigger
  1281. *
  1282. * @return {number|string}
  1283. * The width when getting, zero if there is no width. Can be a string
  1284. * postpixed with '%' or 'px'.
  1285. */
  1286. Component.prototype.height = function height(num, skipListeners) {
  1287. return this.dimension('height', num, skipListeners);
  1288. };
  1289. /**
  1290. * Set both the width and height of the `Component` element at the same time.
  1291. *
  1292. * @param {number|string} width
  1293. * Width to set the `Component`s element to.
  1294. *
  1295. * @param {number|string} height
  1296. * Height to set the `Component`s element to.
  1297. */
  1298. Component.prototype.dimensions = function dimensions(width, height) {
  1299. // Skip componentresize listeners on width for optimization
  1300. this.width(width, true);
  1301. this.height(height);
  1302. };
  1303. /**
  1304. * Get or set width or height of the `Component` element. This is the shared code
  1305. * for the {@link Component#width} and {@link Component#height}.
  1306. *
  1307. * Things to know:
  1308. * - If the width or height in an number this will return the number postfixed with 'px'.
  1309. * - If the width/height is a percent this will return the percent postfixed with '%'
  1310. * - Hidden elements have a width of 0 with `window.getComputedStyle`. This function
  1311. * defaults to the `Component`s `style.width` and falls back to `window.getComputedStyle`.
  1312. * See [this]{@link http://www.foliotek.com/devblog/getting-the-width-of-a-hidden-element-with-jquery-using-width/}
  1313. * for more information
  1314. * - If you want the computed style of the component, use {@link Component#currentWidth}
  1315. * and {@link {Component#currentHeight}
  1316. *
  1317. * @fires Component#componentresize
  1318. *
  1319. * @param {string} widthOrHeight
  1320. 8 'width' or 'height'
  1321. *
  1322. * @param {number|string} [num]
  1323. 8 New dimension
  1324. *
  1325. * @param {boolean} [skipListeners]
  1326. * Skip componentresize event trigger
  1327. *
  1328. * @return {number}
  1329. * The dimension when getting or 0 if unset
  1330. */
  1331. Component.prototype.dimension = function dimension(widthOrHeight, num, skipListeners) {
  1332. if (num !== undefined) {
  1333. // Set to zero if null or literally NaN (NaN !== NaN)
  1334. if (num === null || num !== num) {
  1335. num = 0;
  1336. }
  1337. // Check if using css width/height (% or px) and adjust
  1338. if (('' + num).indexOf('%') !== -1 || ('' + num).indexOf('px') !== -1) {
  1339. this.el_.style[widthOrHeight] = num;
  1340. } else if (num === 'auto') {
  1341. this.el_.style[widthOrHeight] = '';
  1342. } else {
  1343. this.el_.style[widthOrHeight] = num + 'px';
  1344. }
  1345. // skipListeners allows us to avoid triggering the resize event when setting both width and height
  1346. if (!skipListeners) {
  1347. /**
  1348. * Triggered when a component is resized.
  1349. *
  1350. * @event Component#componentresize
  1351. * @type {EventTarget~Event}
  1352. */
  1353. this.trigger('componentresize');
  1354. }
  1355. return;
  1356. }
  1357. // Not setting a value, so getting it
  1358. // Make sure element exists
  1359. if (!this.el_) {
  1360. return 0;
  1361. }
  1362. // Get dimension value from style
  1363. var val = this.el_.style[widthOrHeight];
  1364. var pxIndex = val.indexOf('px');
  1365. if (pxIndex !== -1) {
  1366. // Return the pixel value with no 'px'
  1367. return parseInt(val.slice(0, pxIndex), 10);
  1368. }
  1369. // No px so using % or no style was set, so falling back to offsetWidth/height
  1370. // If component has display:none, offset will return 0
  1371. // TODO: handle display:none and no dimension style using px
  1372. return parseInt(this.el_['offset' + (0, _toTitleCase2['default'])(widthOrHeight)], 10);
  1373. };
  1374. /**
  1375. * Get the width or the height of the `Component` elements computed style. Uses
  1376. * `window.getComputedStyle`.
  1377. *
  1378. * @param {string} widthOrHeight
  1379. * A string containing 'width' or 'height'. Whichever one you want to get.
  1380. *
  1381. * @return {number}
  1382. * The dimension that gets asked for or 0 if nothing was set
  1383. * for that dimension.
  1384. */
  1385. Component.prototype.currentDimension = function currentDimension(widthOrHeight) {
  1386. var computedWidthOrHeight = 0;
  1387. if (widthOrHeight !== 'width' && widthOrHeight !== 'height') {
  1388. throw new Error('currentDimension only accepts width or height value');
  1389. }
  1390. if (typeof _window2['default'].getComputedStyle === 'function') {
  1391. var computedStyle = _window2['default'].getComputedStyle(this.el_);
  1392. computedWidthOrHeight = computedStyle.getPropertyValue(widthOrHeight) || computedStyle[widthOrHeight];
  1393. }
  1394. // remove 'px' from variable and parse as integer
  1395. computedWidthOrHeight = parseFloat(computedWidthOrHeight);
  1396. // if the computed value is still 0, it's possible that the browser is lying
  1397. // and we want to check the offset values.
  1398. // This code also runs on IE8 and wherever getComputedStyle doesn't exist.
  1399. if (computedWidthOrHeight === 0) {
  1400. var rule = 'offset' + (0, _toTitleCase2['default'])(widthOrHeight);
  1401. computedWidthOrHeight = this.el_[rule];
  1402. }
  1403. return computedWidthOrHeight;
  1404. };
  1405. /**
  1406. * An object that contains width and height values of the `Component`s
  1407. * computed style. Uses `window.getComputedStyle`.
  1408. *
  1409. * @typedef {Object} Component~DimensionObject
  1410. *
  1411. * @property {number} width
  1412. * The width of the `Component`s computed style.
  1413. *
  1414. * @property {number} height
  1415. * The height of the `Component`s computed style.
  1416. */
  1417. /**
  1418. * Get an object that contains width and height values of the `Component`s
  1419. * computed style.
  1420. *
  1421. * @return {Component~DimensionObject}
  1422. * The dimensions of the components element
  1423. */
  1424. Component.prototype.currentDimensions = function currentDimensions() {
  1425. return {
  1426. width: this.currentDimension('width'),
  1427. height: this.currentDimension('height')
  1428. };
  1429. };
  1430. /**
  1431. * Get the width of the `Component`s computed style. Uses `window.getComputedStyle`.
  1432. *
  1433. * @return {number} width
  1434. * The width of the `Component`s computed style.
  1435. */
  1436. Component.prototype.currentWidth = function currentWidth() {
  1437. return this.currentDimension('width');
  1438. };
  1439. /**
  1440. * Get the height of the `Component`s computed style. Uses `window.getComputedStyle`.
  1441. *
  1442. * @return {number} height
  1443. * The height of the `Component`s computed style.
  1444. */
  1445. Component.prototype.currentHeight = function currentHeight() {
  1446. return this.currentDimension('height');
  1447. };
  1448. /**
  1449. * Set the focus to this component
  1450. */
  1451. Component.prototype.focus = function focus() {
  1452. this.el_.focus();
  1453. };
  1454. /**
  1455. * Remove the focus from this component
  1456. */
  1457. Component.prototype.blur = function blur() {
  1458. this.el_.blur();
  1459. };
  1460. /**
  1461. * Emit a 'tap' events when touch event support gets detected. This gets used to
  1462. * support toggling the controls through a tap on the video. They get enabled
  1463. * because every sub-component would have extra overhead otherwise.
  1464. *
  1465. * @private
  1466. * @fires Component#tap
  1467. * @listens Component#touchstart
  1468. * @listens Component#touchmove
  1469. * @listens Component#touchleave
  1470. * @listens Component#touchcancel
  1471. * @listens Component#touchend
  1472. */
  1473. Component.prototype.emitTapEvents = function emitTapEvents() {
  1474. // Track the start time so we can determine how long the touch lasted
  1475. var touchStart = 0;
  1476. var firstTouch = null;
  1477. // Maximum movement allowed during a touch event to still be considered a tap
  1478. // Other popular libs use anywhere from 2 (hammer.js) to 15,
  1479. // so 10 seems like a nice, round number.
  1480. var tapMovementThreshold = 10;
  1481. // The maximum length a touch can be while still being considered a tap
  1482. var touchTimeThreshold = 200;
  1483. var couldBeTap = void 0;
  1484. this.on('touchstart', function (event) {
  1485. // If more than one finger, don't consider treating this as a click
  1486. if (event.touches.length === 1) {
  1487. // Copy pageX/pageY from the object
  1488. firstTouch = {
  1489. pageX: event.touches[0].pageX,
  1490. pageY: event.touches[0].pageY
  1491. };
  1492. // Record start time so we can detect a tap vs. "touch and hold"
  1493. touchStart = new Date().getTime();
  1494. // Reset couldBeTap tracking
  1495. couldBeTap = true;
  1496. }
  1497. });
  1498. this.on('touchmove', function (event) {
  1499. // If more than one finger, don't consider treating this as a click
  1500. if (event.touches.length > 1) {
  1501. couldBeTap = false;
  1502. } else if (firstTouch) {
  1503. // Some devices will throw touchmoves for all but the slightest of taps.
  1504. // So, if we moved only a small distance, this could still be a tap
  1505. var xdiff = event.touches[0].pageX - firstTouch.pageX;
  1506. var ydiff = event.touches[0].pageY - firstTouch.pageY;
  1507. var touchDistance = Math.sqrt(xdiff * xdiff + ydiff * ydiff);
  1508. if (touchDistance > tapMovementThreshold) {
  1509. couldBeTap = false;
  1510. }
  1511. }
  1512. });
  1513. var noTap = function noTap() {
  1514. couldBeTap = false;
  1515. };
  1516. // TODO: Listen to the original target. http://youtu.be/DujfpXOKUp8?t=13m8s
  1517. this.on('touchleave', noTap);
  1518. this.on('touchcancel', noTap);
  1519. // When the touch ends, measure how long it took and trigger the appropriate
  1520. // event
  1521. this.on('touchend', function (event) {
  1522. firstTouch = null;
  1523. // Proceed only if the touchmove/leave/cancel event didn't happen
  1524. if (couldBeTap === true) {
  1525. // Measure how long the touch lasted
  1526. var touchTime = new Date().getTime() - touchStart;
  1527. // Make sure the touch was less than the threshold to be considered a tap
  1528. if (touchTime < touchTimeThreshold) {
  1529. // Don't let browser turn this into a click
  1530. event.preventDefault();
  1531. /**
  1532. * Triggered when a `Component` is tapped.
  1533. *
  1534. * @event Component#tap
  1535. * @type {EventTarget~Event}
  1536. */
  1537. this.trigger('tap');
  1538. // It may be good to copy the touchend event object and change the
  1539. // type to tap, if the other event properties aren't exact after
  1540. // Events.fixEvent runs (e.g. event.target)
  1541. }
  1542. }
  1543. });
  1544. };
  1545. /**
  1546. * This function reports user activity whenever touch events happen. This can get
  1547. * turned off by any sub-components that wants touch events to act another way.
  1548. *
  1549. * Report user touch activity when touch events occur. User activity gets used to
  1550. * determine when controls should show/hide. It is simple when it comes to mouse
  1551. * events, because any mouse event should show the controls. So we capture mouse
  1552. * events that bubble up to the player and report activity when that happens.
  1553. * With touch events it isn't as easy as `touchstart` and `touchend` toggle player
  1554. * controls. So touch events can't help us at the player level either.
  1555. *
  1556. * User activity gets checked asynchronously. So what could happen is a tap event
  1557. * on the video turns the controls off. Then the `touchend` event bubbles up to
  1558. * the player. Which, if it reported user activity, would turn the controls right
  1559. * back on. We also don't want to completely block touch events from bubbling up.
  1560. * Furthermore a `touchmove` event and anything other than a tap, should not turn
  1561. * controls back on.
  1562. *
  1563. * @listens Component#touchstart
  1564. * @listens Component#touchmove
  1565. * @listens Component#touchend
  1566. * @listens Component#touchcancel
  1567. */
  1568. Component.prototype.enableTouchActivity = function enableTouchActivity() {
  1569. // Don't continue if the root player doesn't support reporting user activity
  1570. if (!this.player() || !this.player().reportUserActivity) {
  1571. return;
  1572. }
  1573. // listener for reporting that the user is active
  1574. var report = Fn.bind(this.player(), this.player().reportUserActivity);
  1575. var touchHolding = void 0;
  1576. this.on('touchstart', function () {
  1577. report();
  1578. // For as long as the they are touching the device or have their mouse down,
  1579. // we consider them active even if they're not moving their finger or mouse.
  1580. // So we want to continue to update that they are active
  1581. this.clearInterval(touchHolding);
  1582. // report at the same interval as activityCheck
  1583. touchHolding = this.setInterval(report, 250);
  1584. });
  1585. var touchEnd = function touchEnd(event) {
  1586. report();
  1587. // stop the interval that maintains activity if the touch is holding
  1588. this.clearInterval(touchHolding);
  1589. };
  1590. this.on('touchmove', report);
  1591. this.on('touchend', touchEnd);
  1592. this.on('touchcancel', touchEnd);
  1593. };
  1594. /**
  1595. * A callback that has no parameters and is bound into `Component`s context.
  1596. *
  1597. * @callback Component~GenericCallback
  1598. * @this Component
  1599. */
  1600. /**
  1601. * Creates a function that runs after an `x` millisecond timeout. This function is a
  1602. * wrapper around `window.setTimeout`. There are a few reasons to use this one
  1603. * instead though:
  1604. * 1. It gets cleared via {@link Component#clearTimeout} when
  1605. * {@link Component#dispose} gets called.
  1606. * 2. The function callback will gets turned into a {@link Component~GenericCallback}
  1607. *
  1608. * > Note: You can use `window.clearTimeout` on the id returned by this function. This
  1609. * will cause its dispose listener not to get cleaned up! Please use
  1610. * {@link Component#clearTimeout} or {@link Component#dispose}.
  1611. *
  1612. * @param {Component~GenericCallback} fn
  1613. * The function that will be run after `timeout`.
  1614. *
  1615. * @param {number} timeout
  1616. * Timeout in milliseconds to delay before executing the specified function.
  1617. *
  1618. * @return {number}
  1619. * Returns a timeout ID that gets used to identify the timeout. It can also
  1620. * get used in {@link Component#clearTimeout} to clear the timeout that
  1621. * was set.
  1622. *
  1623. * @listens Component#dispose
  1624. * @see [Similar to]{@link https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setTimeout}
  1625. */
  1626. Component.prototype.setTimeout = function setTimeout(fn, timeout) {
  1627. fn = Fn.bind(this, fn);
  1628. var timeoutId = _window2['default'].setTimeout(fn, timeout);
  1629. var disposeFn = function disposeFn() {
  1630. this.clearTimeout(timeoutId);
  1631. };
  1632. disposeFn.guid = 'vjs-timeout-' + timeoutId;
  1633. this.on('dispose', disposeFn);
  1634. return timeoutId;
  1635. };
  1636. /**
  1637. * Clears a timeout that gets created via `window.setTimeout` or
  1638. * {@link Component#setTimeout}. If you set a timeout via {@link Component#setTimeout}
  1639. * use this function instead of `window.clearTimout`. If you don't your dispose
  1640. * listener will not get cleaned up until {@link Component#dispose}!
  1641. *
  1642. * @param {number} timeoutId
  1643. * The id of the timeout to clear. The return value of
  1644. * {@link Component#setTimeout} or `window.setTimeout`.
  1645. *
  1646. * @return {number}
  1647. * Returns the timeout id that was cleared.
  1648. *
  1649. * @see [Similar to]{@link https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/clearTimeout}
  1650. */
  1651. Component.prototype.clearTimeout = function clearTimeout(timeoutId) {
  1652. _window2['default'].clearTimeout(timeoutId);
  1653. var disposeFn = function disposeFn() {};
  1654. disposeFn.guid = 'vjs-timeout-' + timeoutId;
  1655. this.off('dispose', disposeFn);
  1656. return timeoutId;
  1657. };
  1658. /**
  1659. * Creates a function that gets run every `x` milliseconds. This function is a wrapper
  1660. * around `window.setInterval`. There are a few reasons to use this one instead though.
  1661. * 1. It gets cleared via {@link Component#clearInterval} when
  1662. * {@link Component#dispose} gets called.
  1663. * 2. The function callback will be a {@link Component~GenericCallback}
  1664. *
  1665. * @param {Component~GenericCallback} fn
  1666. * The function to run every `x` seconds.
  1667. *
  1668. * @param {number} interval
  1669. * Execute the specified function every `x` milliseconds.
  1670. *
  1671. * @return {number}
  1672. * Returns an id that can be used to identify the interval. It can also be be used in
  1673. * {@link Component#clearInterval} to clear the interval.
  1674. *
  1675. * @listens Component#dispose
  1676. * @see [Similar to]{@link https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setInterval}
  1677. */
  1678. Component.prototype.setInterval = function setInterval(fn, interval) {
  1679. fn = Fn.bind(this, fn);
  1680. var intervalId = _window2['default'].setInterval(fn, interval);
  1681. var disposeFn = function disposeFn() {
  1682. this.clearInterval(intervalId);
  1683. };
  1684. disposeFn.guid = 'vjs-interval-' + intervalId;
  1685. this.on('dispose', disposeFn);
  1686. return intervalId;
  1687. };
  1688. /**
  1689. * Clears an interval that gets created via `window.setInterval` or
  1690. * {@link Component#setInterval}. If you set an inteval via {@link Component#setInterval}
  1691. * use this function instead of `window.clearInterval`. If you don't your dispose
  1692. * listener will not get cleaned up until {@link Component#dispose}!
  1693. *
  1694. * @param {number} intervalId
  1695. * The id of the interval to clear. The return value of
  1696. * {@link Component#setInterval} or `window.setInterval`.
  1697. *
  1698. * @return {number}
  1699. * Returns the interval id that was cleared.
  1700. *
  1701. * @see [Similar to]{@link https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/clearInterval}
  1702. */
  1703. Component.prototype.clearInterval = function clearInterval(intervalId) {
  1704. _window2['default'].clearInterval(intervalId);
  1705. var disposeFn = function disposeFn() {};
  1706. disposeFn.guid = 'vjs-interval-' + intervalId;
  1707. this.off('dispose', disposeFn);
  1708. return intervalId;
  1709. };
  1710. /**
  1711. * Queues up a callback to be passed to requestAnimationFrame (rAF), but
  1712. * with a few extra bonuses:
  1713. *
  1714. * - Supports browsers that do not support rAF by falling back to
  1715. * {@link Component#setTimeout}.
  1716. *
  1717. * - The callback is turned into a {@link Component~GenericCallback} (i.e.
  1718. * bound to the component).
  1719. *
  1720. * - Automatic cancellation of the rAF callback is handled if the component
  1721. * is disposed before it is called.
  1722. *
  1723. * @param {Component~GenericCallback} fn
  1724. * A function that will be bound to this component and executed just
  1725. * before the browser's next repaint.
  1726. *
  1727. * @return {number}
  1728. * Returns an rAF ID that gets used to identify the timeout. It can
  1729. * also be used in {@link Component#cancelAnimationFrame} to cancel
  1730. * the animation frame callback.
  1731. *
  1732. * @listens Component#dispose
  1733. * @see [Similar to]{@link https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame}
  1734. */
  1735. Component.prototype.requestAnimationFrame = function requestAnimationFrame(fn) {
  1736. var _this2 = this;
  1737. if (this.supportsRaf_) {
  1738. fn = Fn.bind(this, fn);
  1739. var id = _window2['default'].requestAnimationFrame(fn);
  1740. var disposeFn = function disposeFn() {
  1741. return _this2.cancelAnimationFrame(id);
  1742. };
  1743. disposeFn.guid = 'vjs-raf-' + id;
  1744. this.on('dispose', disposeFn);
  1745. return id;
  1746. }
  1747. // Fall back to using a timer.
  1748. return this.setTimeout(fn, 1000 / 60);
  1749. };
  1750. /**
  1751. * Cancels a queued callback passed to {@link Component#requestAnimationFrame}
  1752. * (rAF).
  1753. *
  1754. * If you queue an rAF callback via {@link Component#requestAnimationFrame},
  1755. * use this function instead of `window.cancelAnimationFrame`. If you don't,
  1756. * your dispose listener will not get cleaned up until {@link Component#dispose}!
  1757. *
  1758. * @param {number} id
  1759. * The rAF ID to clear. The return value of {@link Component#requestAnimationFrame}.
  1760. *
  1761. * @return {number}
  1762. * Returns the rAF ID that was cleared.
  1763. *
  1764. * @see [Similar to]{@link https://developer.mozilla.org/en-US/docs/Web/API/window/cancelAnimationFrame}
  1765. */
  1766. Component.prototype.cancelAnimationFrame = function cancelAnimationFrame(id) {
  1767. if (this.supportsRaf_) {
  1768. _window2['default'].cancelAnimationFrame(id);
  1769. var disposeFn = function disposeFn() {};
  1770. disposeFn.guid = 'vjs-raf-' + id;
  1771. this.off('dispose', disposeFn);
  1772. return id;
  1773. }
  1774. // Fall back to using a timer.
  1775. return this.clearTimeout(id);
  1776. };
  1777. /**
  1778. * Register a `Component` with `videojs` given the name and the component.
  1779. *
  1780. * > NOTE: {@link Tech}s should not be registered as a `Component`. {@link Tech}s
  1781. * should be registered using {@link Tech.registerTech} or
  1782. * {@link videojs:videojs.registerTech}.
  1783. *
  1784. * > NOTE: This function can also be seen on videojs as
  1785. * {@link videojs:videojs.registerComponent}.
  1786. *
  1787. * @param {string} name
  1788. * The name of the `Component` to register.
  1789. *
  1790. * @param {Component} ComponentToRegister
  1791. * The `Component` class to register.
  1792. *
  1793. * @return {Component}
  1794. * The `Component` that was registered.
  1795. */
  1796. Component.registerComponent = function registerComponent(name, ComponentToRegister) {
  1797. if (typeof name !== 'string' || !name) {
  1798. throw new Error('Illegal component name, "' + name + '"; must be a non-empty string.');
  1799. }
  1800. var Tech = Component.getComponent('Tech');
  1801. // We need to make sure this check is only done if Tech has been registered.
  1802. var isTech = Tech && Tech.isTech(ComponentToRegister);
  1803. var isComp = Component === ComponentToRegister || Component.prototype.isPrototypeOf(ComponentToRegister.prototype);
  1804. if (isTech || !isComp) {
  1805. var reason = void 0;
  1806. if (isTech) {
  1807. reason = 'techs must be registered using Tech.registerTech()';
  1808. } else {
  1809. reason = 'must be a Component subclass';
  1810. }
  1811. throw new Error('Illegal component, "' + name + '"; ' + reason + '.');
  1812. }
  1813. name = (0, _toTitleCase2['default'])(name);
  1814. if (!Component.components_) {
  1815. Component.components_ = {};
  1816. }
  1817. var Player = Component.getComponent('Player');
  1818. if (name === 'Player' && Player && Player.players) {
  1819. var players = Player.players;
  1820. var playerNames = Object.keys(players);
  1821. // If we have players that were disposed, then their name will still be
  1822. // in Players.players. So, we must loop through and verify that the value
  1823. // for each item is not null. This allows registration of the Player component
  1824. // after all players have been disposed or before any were created.
  1825. if (players && playerNames.length > 0 && playerNames.map(function (pname) {
  1826. return players[pname];
  1827. }).every(Boolean)) {
  1828. throw new Error('Can not register Player component after player has been created.');
  1829. }
  1830. }
  1831. Component.components_[name] = ComponentToRegister;
  1832. return ComponentToRegister;
  1833. };
  1834. /**
  1835. * Get a `Component` based on the name it was registered with.
  1836. *
  1837. * @param {string} name
  1838. * The Name of the component to get.
  1839. *
  1840. * @return {Component}
  1841. * The `Component` that got registered under the given name.
  1842. *
  1843. * @deprecated In `videojs` 6 this will not return `Component`s that were not
  1844. * registered using {@link Component.registerComponent}. Currently we
  1845. * check the global `videojs` object for a `Component` name and
  1846. * return that if it exists.
  1847. */
  1848. Component.getComponent = function getComponent(name) {
  1849. if (!name) {
  1850. return;
  1851. }
  1852. name = (0, _toTitleCase2['default'])(name);
  1853. if (Component.components_ && Component.components_[name]) {
  1854. return Component.components_[name];
  1855. }
  1856. };
  1857. return Component;
  1858. }();
  1859. /**
  1860. * Whether or not this component supports `requestAnimationFrame`.
  1861. *
  1862. * This is exposed primarily for testing purposes.
  1863. *
  1864. * @private
  1865. * @type {Boolean}
  1866. */
  1867. Component.prototype.supportsRaf_ = typeof _window2['default'].requestAnimationFrame === 'function' && typeof _window2['default'].cancelAnimationFrame === 'function';
  1868. Component.registerComponent('Component', Component);
  1869. exports['default'] = Component;
  1870. },{"100":100,"53":53,"54":54,"84":84,"85":85,"88":88,"90":90,"91":91,"92":92,"96":96}],6:[function(_dereq_,module,exports){
  1871. 'use strict';
  1872. exports.__esModule = true;
  1873. var _trackButton = _dereq_(38);
  1874. var _trackButton2 = _interopRequireDefault(_trackButton);
  1875. var _component = _dereq_(5);
  1876. var _component2 = _interopRequireDefault(_component);
  1877. var _audioTrackMenuItem = _dereq_(7);
  1878. var _audioTrackMenuItem2 = _interopRequireDefault(_audioTrackMenuItem);
  1879. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  1880. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  1881. function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
  1882. function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
  1883. * @file audio-track-button.js
  1884. */
  1885. /**
  1886. * The base class for buttons that toggle specific {@link AudioTrack} types.
  1887. *
  1888. * @extends TrackButton
  1889. */
  1890. var AudioTrackButton = function (_TrackButton) {
  1891. _inherits(AudioTrackButton, _TrackButton);
  1892. /**
  1893. * Creates an instance of this class.
  1894. *
  1895. * @param {Player} player
  1896. * The `Player` that this class should be attached to.
  1897. *
  1898. * @param {Object} [options={}]
  1899. * The key/value store of player options.
  1900. */
  1901. function AudioTrackButton(player) {
  1902. var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  1903. _classCallCheck(this, AudioTrackButton);
  1904. options.tracks = player.audioTracks();
  1905. return _possibleConstructorReturn(this, _TrackButton.call(this, player, options));
  1906. }
  1907. /**
  1908. * Builds the default DOM `className`.
  1909. *
  1910. * @return {string}
  1911. * The DOM `className` for this object.
  1912. */
  1913. AudioTrackButton.prototype.buildCSSClass = function buildCSSClass() {
  1914. return 'vjs-audio-button ' + _TrackButton.prototype.buildCSSClass.call(this);
  1915. };
  1916. AudioTrackButton.prototype.buildWrapperCSSClass = function buildWrapperCSSClass() {
  1917. return 'vjs-audio-button ' + _TrackButton.prototype.buildWrapperCSSClass.call(this);
  1918. };
  1919. /**
  1920. * Create a menu item for each audio track
  1921. *
  1922. * @param {AudioTrackMenuItem[]} [items=[]]
  1923. * An array of existing menu items to use.
  1924. *
  1925. * @return {AudioTrackMenuItem[]}
  1926. * An array of menu items
  1927. */
  1928. AudioTrackButton.prototype.createItems = function createItems() {
  1929. var items = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
  1930. var tracks = this.player_.audioTracks();
  1931. for (var i = 0; i < tracks.length; i++) {
  1932. var track = tracks[i];
  1933. items.push(new _audioTrackMenuItem2['default'](this.player_, {
  1934. track: track,
  1935. // MenuItem is selectable
  1936. selectable: true
  1937. }));
  1938. }
  1939. return items;
  1940. };
  1941. return AudioTrackButton;
  1942. }(_trackButton2['default']);
  1943. /**
  1944. * The text that should display over the `AudioTrackButton`s controls. Added for localization.
  1945. *
  1946. * @type {string}
  1947. * @private
  1948. */
  1949. AudioTrackButton.prototype.controlText_ = 'Audio Track';
  1950. _component2['default'].registerComponent('AudioTrackButton', AudioTrackButton);
  1951. exports['default'] = AudioTrackButton;
  1952. },{"38":38,"5":5,"7":7}],7:[function(_dereq_,module,exports){
  1953. 'use strict';
  1954. exports.__esModule = true;
  1955. var _menuItem = _dereq_(51);
  1956. var _menuItem2 = _interopRequireDefault(_menuItem);
  1957. var _component = _dereq_(5);
  1958. var _component2 = _interopRequireDefault(_component);
  1959. var _fn = _dereq_(88);
  1960. var Fn = _interopRequireWildcard(_fn);
  1961. function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
  1962. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  1963. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  1964. function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
  1965. function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
  1966. * @file audio-track-menu-item.js
  1967. */
  1968. /**
  1969. * An {@link AudioTrack} {@link MenuItem}
  1970. *
  1971. * @extends MenuItem
  1972. */
  1973. var AudioTrackMenuItem = function (_MenuItem) {
  1974. _inherits(AudioTrackMenuItem, _MenuItem);
  1975. /**
  1976. * Creates an instance of this class.
  1977. *
  1978. * @param {Player} player
  1979. * The `Player` that this class should be attached to.
  1980. *
  1981. * @param {Object} [options]
  1982. * The key/value store of player options.
  1983. */
  1984. function AudioTrackMenuItem(player, options) {
  1985. _classCallCheck(this, AudioTrackMenuItem);
  1986. var track = options.track;
  1987. var tracks = player.audioTracks();
  1988. // Modify options for parent MenuItem class's init.
  1989. options.label = track.label || track.language || 'Unknown';
  1990. options.selected = track.enabled;
  1991. var _this = _possibleConstructorReturn(this, _MenuItem.call(this, player, options));
  1992. _this.track = track;
  1993. var changeHandler = Fn.bind(_this, _this.handleTracksChange);
  1994. tracks.addEventListener('change', changeHandler);
  1995. _this.on('dispose', function () {
  1996. tracks.removeEventListener('change', changeHandler);
  1997. });
  1998. return _this;
  1999. }
  2000. /**
  2001. * This gets called when an `AudioTrackMenuItem is "clicked". See {@link ClickableComponent}
  2002. * for more detailed information on what a click can be.
  2003. *
  2004. * @param {EventTarget~Event} [event]
  2005. * The `keydown`, `tap`, or `click` event that caused this function to be
  2006. * called.
  2007. *
  2008. * @listens tap
  2009. * @listens click
  2010. */
  2011. AudioTrackMenuItem.prototype.handleClick = function handleClick(event) {
  2012. var tracks = this.player_.audioTracks();
  2013. _MenuItem.prototype.handleClick.call(this, event);
  2014. for (var i = 0; i < tracks.length; i++) {
  2015. var track = tracks[i];
  2016. track.enabled = track === this.track;
  2017. }
  2018. };
  2019. /**
  2020. * Handle any {@link AudioTrack} change.
  2021. *
  2022. * @param {EventTarget~Event} [event]
  2023. * The {@link AudioTrackList#change} event that caused this to run.
  2024. *
  2025. * @listens AudioTrackList#change
  2026. */
  2027. AudioTrackMenuItem.prototype.handleTracksChange = function handleTracksChange(event) {
  2028. this.selected(this.track.enabled);
  2029. };
  2030. return AudioTrackMenuItem;
  2031. }(_menuItem2['default']);
  2032. _component2['default'].registerComponent('AudioTrackMenuItem', AudioTrackMenuItem);
  2033. exports['default'] = AudioTrackMenuItem;
  2034. },{"5":5,"51":51,"88":88}],8:[function(_dereq_,module,exports){
  2035. 'use strict';
  2036. exports.__esModule = true;
  2037. var _component = _dereq_(5);
  2038. var _component2 = _interopRequireDefault(_component);
  2039. _dereq_(12);
  2040. _dereq_(34);
  2041. _dereq_(35);
  2042. _dereq_(37);
  2043. _dereq_(36);
  2044. _dereq_(10);
  2045. _dereq_(18);
  2046. _dereq_(9);
  2047. _dereq_(43);
  2048. _dereq_(25);
  2049. _dereq_(27);
  2050. _dereq_(31);
  2051. _dereq_(24);
  2052. _dereq_(29);
  2053. _dereq_(6);
  2054. _dereq_(13);
  2055. _dereq_(21);
  2056. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  2057. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  2058. function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
  2059. function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
  2060. * @file control-bar.js
  2061. */
  2062. // Required children
  2063. /**
  2064. * Container of main controls.
  2065. *
  2066. * @extends Component
  2067. */
  2068. var ControlBar = function (_Component) {
  2069. _inherits(ControlBar, _Component);
  2070. function ControlBar() {
  2071. _classCallCheck(this, ControlBar);
  2072. return _possibleConstructorReturn(this, _Component.apply(this, arguments));
  2073. }
  2074. /**
  2075. * Create the `Component`'s DOM element
  2076. *
  2077. * @return {Element}
  2078. * The element that was created.
  2079. */
  2080. ControlBar.prototype.createEl = function createEl() {
  2081. return _Component.prototype.createEl.call(this, 'div', {
  2082. className: 'vjs-control-bar',
  2083. dir: 'ltr'
  2084. }, {
  2085. // The control bar is a group, but we don't aria-label it to avoid
  2086. // over-announcing by JAWS
  2087. role: 'group'
  2088. });
  2089. };
  2090. return ControlBar;
  2091. }(_component2['default']);
  2092. /**
  2093. * Default options for `ControlBar`
  2094. *
  2095. * @type {Object}
  2096. * @private
  2097. */
  2098. ControlBar.prototype.options_ = {
  2099. children: ['playToggle', 'volumePanel', 'currentTimeDisplay', 'timeDivider', 'durationDisplay', 'progressControl', 'liveDisplay', 'remainingTimeDisplay', 'customControlSpacer', 'playbackRateMenuButton', 'chaptersButton', 'descriptionsButton', 'subsCapsButton', 'audioTrackButton', 'fullscreenToggle']
  2100. };
  2101. _component2['default'].registerComponent('ControlBar', ControlBar);
  2102. exports['default'] = ControlBar;
  2103. },{"10":10,"12":12,"13":13,"18":18,"21":21,"24":24,"25":25,"27":27,"29":29,"31":31,"34":34,"35":35,"36":36,"37":37,"43":43,"5":5,"6":6,"9":9}],9:[function(_dereq_,module,exports){
  2104. 'use strict';
  2105. exports.__esModule = true;
  2106. var _button = _dereq_(2);
  2107. var _button2 = _interopRequireDefault(_button);
  2108. var _component = _dereq_(5);
  2109. var _component2 = _interopRequireDefault(_component);
  2110. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  2111. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  2112. function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
  2113. function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
  2114. * @file fullscreen-toggle.js
  2115. */
  2116. /**
  2117. * Toggle fullscreen video
  2118. *
  2119. * @extends Button
  2120. */
  2121. var FullscreenToggle = function (_Button) {
  2122. _inherits(FullscreenToggle, _Button);
  2123. /**
  2124. * Creates an instance of this class.
  2125. *
  2126. * @param {Player} player
  2127. * The `Player` that this class should be attached to.
  2128. *
  2129. * @param {Object} [options]
  2130. * The key/value store of player options.
  2131. */
  2132. function FullscreenToggle(player, options) {
  2133. _classCallCheck(this, FullscreenToggle);
  2134. var _this = _possibleConstructorReturn(this, _Button.call(this, player, options));
  2135. _this.on(player, 'fullscreenchange', _this.handleFullscreenChange);
  2136. return _this;
  2137. }
  2138. /**
  2139. * Builds the default DOM `className`.
  2140. *
  2141. * @return {string}
  2142. * The DOM `className` for this object.
  2143. */
  2144. FullscreenToggle.prototype.buildCSSClass = function buildCSSClass() {
  2145. return 'vjs-fullscreen-control ' + _Button.prototype.buildCSSClass.call(this);
  2146. };
  2147. /**
  2148. * Handles fullscreenchange on the player and change control text accordingly.
  2149. *
  2150. * @param {EventTarget~Event} [event]
  2151. * The {@link Player#fullscreenchange} event that caused this function to be
  2152. * called.
  2153. *
  2154. * @listens Player#fullscreenchange
  2155. */
  2156. FullscreenToggle.prototype.handleFullscreenChange = function handleFullscreenChange(event) {
  2157. if (this.player_.isFullscreen()) {
  2158. this.controlText('Non-Fullscreen');
  2159. } else {
  2160. this.controlText('Fullscreen');
  2161. }
  2162. };
  2163. /**
  2164. * This gets called when an `FullscreenToggle` is "clicked". See
  2165. * {@link ClickableComponent} for more detailed information on what a click can be.
  2166. *
  2167. * @param {EventTarget~Event} [event]
  2168. * The `keydown`, `tap`, or `click` event that caused this function to be
  2169. * called.
  2170. *
  2171. * @listens tap
  2172. * @listens click
  2173. */
  2174. FullscreenToggle.prototype.handleClick = function handleClick(event) {
  2175. if (!this.player_.isFullscreen()) {
  2176. this.player_.requestFullscreen();
  2177. } else {
  2178. this.player_.exitFullscreen();
  2179. }
  2180. };
  2181. return FullscreenToggle;
  2182. }(_button2['default']);
  2183. /**
  2184. * The text that should display over the `FullscreenToggle`s controls. Added for localization.
  2185. *
  2186. * @type {string}
  2187. * @private
  2188. */
  2189. FullscreenToggle.prototype.controlText_ = 'Fullscreen';
  2190. _component2['default'].registerComponent('FullscreenToggle', FullscreenToggle);
  2191. exports['default'] = FullscreenToggle;
  2192. },{"2":2,"5":5}],10:[function(_dereq_,module,exports){
  2193. 'use strict';
  2194. exports.__esModule = true;
  2195. var _component = _dereq_(5);
  2196. var _component2 = _interopRequireDefault(_component);
  2197. var _dom = _dereq_(85);
  2198. var Dom = _interopRequireWildcard(_dom);
  2199. function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
  2200. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  2201. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  2202. function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
  2203. function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
  2204. * @file live-display.js
  2205. */
  2206. // TODO - Future make it click to snap to live
  2207. /**
  2208. * Displays the live indicator when duration is Infinity.
  2209. *
  2210. * @extends Component
  2211. */
  2212. var LiveDisplay = function (_Component) {
  2213. _inherits(LiveDisplay, _Component);
  2214. /**
  2215. * Creates an instance of this class.
  2216. *
  2217. * @param {Player} player
  2218. * The `Player` that this class should be attached to.
  2219. *
  2220. * @param {Object} [options]
  2221. * The key/value store of player options.
  2222. */
  2223. function LiveDisplay(player, options) {
  2224. _classCallCheck(this, LiveDisplay);
  2225. var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
  2226. _this.updateShowing();
  2227. _this.on(_this.player(), 'durationchange', _this.updateShowing);
  2228. return _this;
  2229. }
  2230. /**
  2231. * Create the `Component`'s DOM element
  2232. *
  2233. * @return {Element}
  2234. * The element that was created.
  2235. */
  2236. LiveDisplay.prototype.createEl = function createEl() {
  2237. var el = _Component.prototype.createEl.call(this, 'div', {
  2238. className: 'vjs-live-control vjs-control'
  2239. });
  2240. this.contentEl_ = Dom.createEl('div', {
  2241. className: 'vjs-live-display',
  2242. innerHTML: '<span class="vjs-control-text">' + this.localize('Stream Type') + '</span>' + this.localize('LIVE')
  2243. }, {
  2244. 'aria-live': 'off'
  2245. });
  2246. el.appendChild(this.contentEl_);
  2247. return el;
  2248. };
  2249. /**
  2250. * Check the duration to see if the LiveDisplay should be showing or not. Then show/hide
  2251. * it accordingly
  2252. *
  2253. * @param {EventTarget~Event} [event]
  2254. * The {@link Player#durationchange} event that caused this function to run.
  2255. *
  2256. * @listens Player#durationchange
  2257. */
  2258. LiveDisplay.prototype.updateShowing = function updateShowing(event) {
  2259. if (this.player().duration() === Infinity) {
  2260. this.show();
  2261. } else {
  2262. this.hide();
  2263. }
  2264. };
  2265. return LiveDisplay;
  2266. }(_component2['default']);
  2267. _component2['default'].registerComponent('LiveDisplay', LiveDisplay);
  2268. exports['default'] = LiveDisplay;
  2269. },{"5":5,"85":85}],11:[function(_dereq_,module,exports){
  2270. 'use strict';
  2271. exports.__esModule = true;
  2272. var _button = _dereq_(2);
  2273. var _button2 = _interopRequireDefault(_button);
  2274. var _component = _dereq_(5);
  2275. var _component2 = _interopRequireDefault(_component);
  2276. var _dom = _dereq_(85);
  2277. var Dom = _interopRequireWildcard(_dom);
  2278. var _checkVolumeSupport = _dereq_(39);
  2279. var _checkVolumeSupport2 = _interopRequireDefault(_checkVolumeSupport);
  2280. function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
  2281. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  2282. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  2283. function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
  2284. function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
  2285. * @file mute-toggle.js
  2286. */
  2287. /**
  2288. * A button component for muting the audio.
  2289. *
  2290. * @extends Button
  2291. */
  2292. var MuteToggle = function (_Button) {
  2293. _inherits(MuteToggle, _Button);
  2294. /**
  2295. * Creates an instance of this class.
  2296. *
  2297. * @param {Player} player
  2298. * The `Player` that this class should be attached to.
  2299. *
  2300. * @param {Object} [options]
  2301. * The key/value store of player options.
  2302. */
  2303. function MuteToggle(player, options) {
  2304. _classCallCheck(this, MuteToggle);
  2305. // hide this control if volume support is missing
  2306. var _this = _possibleConstructorReturn(this, _Button.call(this, player, options));
  2307. (0, _checkVolumeSupport2['default'])(_this, player);
  2308. _this.on(player, ['loadstart', 'volumechange'], _this.update);
  2309. return _this;
  2310. }
  2311. /**
  2312. * Builds the default DOM `className`.
  2313. *
  2314. * @return {string}
  2315. * The DOM `className` for this object.
  2316. */
  2317. MuteToggle.prototype.buildCSSClass = function buildCSSClass() {
  2318. return 'vjs-mute-control ' + _Button.prototype.buildCSSClass.call(this);
  2319. };
  2320. /**
  2321. * This gets called when an `MuteToggle` is "clicked". See
  2322. * {@link ClickableComponent} for more detailed information on what a click can be.
  2323. *
  2324. * @param {EventTarget~Event} [event]
  2325. * The `keydown`, `tap`, or `click` event that caused this function to be
  2326. * called.
  2327. *
  2328. * @listens tap
  2329. * @listens click
  2330. */
  2331. MuteToggle.prototype.handleClick = function handleClick(event) {
  2332. var vol = this.player_.volume();
  2333. var lastVolume = this.player_.lastVolume_();
  2334. if (vol === 0) {
  2335. this.player_.volume(lastVolume);
  2336. this.player_.muted(false);
  2337. } else {
  2338. this.player_.muted(this.player_.muted() ? false : true);
  2339. }
  2340. };
  2341. /**
  2342. * Update the `MuteToggle` button based on the state of `volume` and `muted`
  2343. * on the player.
  2344. *
  2345. * @param {EventTarget~Event} [event]
  2346. * The {@link Player#loadstart} event if this function was called
  2347. * through an event.
  2348. *
  2349. * @listens Player#loadstart
  2350. * @listens Player#volumechange
  2351. */
  2352. MuteToggle.prototype.update = function update(event) {
  2353. this.updateIcon_();
  2354. this.updateControlText_();
  2355. };
  2356. /**
  2357. * Update the appearance of the `MuteToggle` icon.
  2358. *
  2359. * Possible states (given `level` variable below):
  2360. * - 0: crossed out
  2361. * - 1: zero bars of volume
  2362. * - 2: one bar of volume
  2363. * - 3: two bars of volume
  2364. *
  2365. * @private
  2366. */
  2367. MuteToggle.prototype.updateIcon_ = function updateIcon_() {
  2368. var vol = this.player_.volume();
  2369. var level = 3;
  2370. if (vol === 0 || this.player_.muted()) {
  2371. level = 0;
  2372. } else if (vol < 0.33) {
  2373. level = 1;
  2374. } else if (vol < 0.67) {
  2375. level = 2;
  2376. }
  2377. // TODO improve muted icon classes
  2378. for (var i = 0; i < 4; i++) {
  2379. Dom.removeClass(this.el_, 'vjs-vol-' + i);
  2380. }
  2381. Dom.addClass(this.el_, 'vjs-vol-' + level);
  2382. };
  2383. /**
  2384. * If `muted` has changed on the player, update the control text
  2385. * (`title` attribute on `vjs-mute-control` element and content of
  2386. * `vjs-control-text` element).
  2387. *
  2388. * @private
  2389. */
  2390. MuteToggle.prototype.updateControlText_ = function updateControlText_() {
  2391. var soundOff = this.player_.muted() || this.player_.volume() === 0;
  2392. var text = soundOff ? 'Unmute' : 'Mute';
  2393. if (this.controlText() !== text) {
  2394. this.controlText(text);
  2395. }
  2396. };
  2397. return MuteToggle;
  2398. }(_button2['default']);
  2399. /**
  2400. * The text that should display over the `MuteToggle`s controls. Added for localization.
  2401. *
  2402. * @type {string}
  2403. * @private
  2404. */
  2405. MuteToggle.prototype.controlText_ = 'Mute';
  2406. _component2['default'].registerComponent('MuteToggle', MuteToggle);
  2407. exports['default'] = MuteToggle;
  2408. },{"2":2,"39":39,"5":5,"85":85}],12:[function(_dereq_,module,exports){
  2409. 'use strict';
  2410. exports.__esModule = true;
  2411. var _button = _dereq_(2);
  2412. var _button2 = _interopRequireDefault(_button);
  2413. var _component = _dereq_(5);
  2414. var _component2 = _interopRequireDefault(_component);
  2415. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  2416. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  2417. function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
  2418. function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
  2419. * @file play-toggle.js
  2420. */
  2421. /**
  2422. * Button to toggle between play and pause.
  2423. *
  2424. * @extends Button
  2425. */
  2426. var PlayToggle = function (_Button) {
  2427. _inherits(PlayToggle, _Button);
  2428. /**
  2429. * Creates an instance of this class.
  2430. *
  2431. * @param {Player} player
  2432. * The `Player` that this class should be attached to.
  2433. *
  2434. * @param {Object} [options]
  2435. * The key/value store of player options.
  2436. */
  2437. function PlayToggle(player, options) {
  2438. _classCallCheck(this, PlayToggle);
  2439. var _this = _possibleConstructorReturn(this, _Button.call(this, player, options));
  2440. _this.on(player, 'play', _this.handlePlay);
  2441. _this.on(player, 'pause', _this.handlePause);
  2442. _this.on(player, 'ended', _this.handleEnded);
  2443. return _this;
  2444. }
  2445. /**
  2446. * Builds the default DOM `className`.
  2447. *
  2448. * @return {string}
  2449. * The DOM `className` for this object.
  2450. */
  2451. PlayToggle.prototype.buildCSSClass = function buildCSSClass() {
  2452. return 'vjs-play-control ' + _Button.prototype.buildCSSClass.call(this);
  2453. };
  2454. /**
  2455. * This gets called when an `PlayToggle` is "clicked". See
  2456. * {@link ClickableComponent} for more detailed information on what a click can be.
  2457. *
  2458. * @param {EventTarget~Event} [event]
  2459. * The `keydown`, `tap`, or `click` event that caused this function to be
  2460. * called.
  2461. *
  2462. * @listens tap
  2463. * @listens click
  2464. */
  2465. PlayToggle.prototype.handleClick = function handleClick(event) {
  2466. if (this.player_.paused()) {
  2467. this.player_.play();
  2468. } else {
  2469. this.player_.pause();
  2470. }
  2471. };
  2472. /**
  2473. * Add the vjs-playing class to the element so it can change appearance.
  2474. *
  2475. * @param {EventTarget~Event} [event]
  2476. * The event that caused this function to run.
  2477. *
  2478. * @listens Player#play
  2479. */
  2480. PlayToggle.prototype.handlePlay = function handlePlay(event) {
  2481. this.removeClass('vjs-ended');
  2482. this.removeClass('vjs-paused');
  2483. this.addClass('vjs-playing');
  2484. // change the button text to "Pause"
  2485. this.controlText('Pause');
  2486. };
  2487. /**
  2488. * Add the vjs-paused class to the element so it can change appearance.
  2489. *
  2490. * @param {EventTarget~Event} [event]
  2491. * The event that caused this function to run.
  2492. *
  2493. * @listens Player#pause
  2494. */
  2495. PlayToggle.prototype.handlePause = function handlePause(event) {
  2496. this.removeClass('vjs-playing');
  2497. this.addClass('vjs-paused');
  2498. // change the button text to "Play"
  2499. this.controlText('Play');
  2500. };
  2501. /**
  2502. * Add the vjs-ended class to the element so it can change appearance
  2503. *
  2504. */
  2505. PlayToggle.prototype.handleEnded = function handleEnded(event) {
  2506. this.removeClass('vjs-playing');
  2507. this.addClass('vjs-ended');
  2508. // change the button text to "Replay"
  2509. this.controlText('Replay');
  2510. };
  2511. return PlayToggle;
  2512. }(_button2['default']);
  2513. /**
  2514. * The text that should display over the `PlayToggle`s controls. Added for localization.
  2515. *
  2516. * @type {string}
  2517. * @private
  2518. */
  2519. PlayToggle.prototype.controlText_ = 'Play';
  2520. _component2['default'].registerComponent('PlayToggle', PlayToggle);
  2521. exports['default'] = PlayToggle;
  2522. },{"2":2,"5":5}],13:[function(_dereq_,module,exports){
  2523. 'use strict';
  2524. exports.__esModule = true;
  2525. var _menuButton = _dereq_(50);
  2526. var _menuButton2 = _interopRequireDefault(_menuButton);
  2527. var _menu = _dereq_(52);
  2528. var _menu2 = _interopRequireDefault(_menu);
  2529. var _playbackRateMenuItem = _dereq_(14);
  2530. var _playbackRateMenuItem2 = _interopRequireDefault(_playbackRateMenuItem);
  2531. var _component = _dereq_(5);
  2532. var _component2 = _interopRequireDefault(_component);
  2533. var _dom = _dereq_(85);
  2534. var Dom = _interopRequireWildcard(_dom);
  2535. function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
  2536. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  2537. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  2538. function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
  2539. function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
  2540. * @file playback-rate-menu-button.js
  2541. */
  2542. /**
  2543. * The component for controlling the playback rate.
  2544. *
  2545. * @extends MenuButton
  2546. */
  2547. var PlaybackRateMenuButton = function (_MenuButton) {
  2548. _inherits(PlaybackRateMenuButton, _MenuButton);
  2549. /**
  2550. * Creates an instance of this class.
  2551. *
  2552. * @param {Player} player
  2553. * The `Player` that this class should be attached to.
  2554. *
  2555. * @param {Object} [options]
  2556. * The key/value store of player options.
  2557. */
  2558. function PlaybackRateMenuButton(player, options) {
  2559. _classCallCheck(this, PlaybackRateMenuButton);
  2560. var _this = _possibleConstructorReturn(this, _MenuButton.call(this, player, options));
  2561. _this.updateVisibility();
  2562. _this.updateLabel();
  2563. _this.on(player, 'loadstart', _this.updateVisibility);
  2564. _this.on(player, 'ratechange', _this.updateLabel);
  2565. return _this;
  2566. }
  2567. /**
  2568. * Create the `Component`'s DOM element
  2569. *
  2570. * @return {Element}
  2571. * The element that was created.
  2572. */
  2573. PlaybackRateMenuButton.prototype.createEl = function createEl() {
  2574. var el = _MenuButton.prototype.createEl.call(this);
  2575. this.labelEl_ = Dom.createEl('div', {
  2576. className: 'vjs-playback-rate-value',
  2577. innerHTML: 1.0
  2578. });
  2579. el.appendChild(this.labelEl_);
  2580. return el;
  2581. };
  2582. /**
  2583. * Builds the default DOM `className`.
  2584. *
  2585. * @return {string}
  2586. * The DOM `className` for this object.
  2587. */
  2588. PlaybackRateMenuButton.prototype.buildCSSClass = function buildCSSClass() {
  2589. return 'vjs-playback-rate ' + _MenuButton.prototype.buildCSSClass.call(this);
  2590. };
  2591. PlaybackRateMenuButton.prototype.buildWrapperCSSClass = function buildWrapperCSSClass() {
  2592. return 'vjs-playback-rate ' + _MenuButton.prototype.buildWrapperCSSClass.call(this);
  2593. };
  2594. /**
  2595. * Create the playback rate menu
  2596. *
  2597. * @return {Menu}
  2598. * Menu object populated with {@link PlaybackRateMenuItem}s
  2599. */
  2600. PlaybackRateMenuButton.prototype.createMenu = function createMenu() {
  2601. var menu = new _menu2['default'](this.player());
  2602. var rates = this.playbackRates();
  2603. if (rates) {
  2604. for (var i = rates.length - 1; i >= 0; i--) {
  2605. menu.addChild(new _playbackRateMenuItem2['default'](this.player(), { rate: rates[i] + 'x' }));
  2606. }
  2607. }
  2608. return menu;
  2609. };
  2610. /**
  2611. * Updates ARIA accessibility attributes
  2612. */
  2613. PlaybackRateMenuButton.prototype.updateARIAAttributes = function updateARIAAttributes() {
  2614. // Current playback rate
  2615. this.el().setAttribute('aria-valuenow', this.player().playbackRate());
  2616. };
  2617. /**
  2618. * This gets called when an `PlaybackRateMenuButton` is "clicked". See
  2619. * {@link ClickableComponent} for more detailed information on what a click can be.
  2620. *
  2621. * @param {EventTarget~Event} [event]
  2622. * The `keydown`, `tap`, or `click` event that caused this function to be
  2623. * called.
  2624. *
  2625. * @listens tap
  2626. * @listens click
  2627. */
  2628. PlaybackRateMenuButton.prototype.handleClick = function handleClick(event) {
  2629. // select next rate option
  2630. var currentRate = this.player().playbackRate();
  2631. var rates = this.playbackRates();
  2632. // this will select first one if the last one currently selected
  2633. var newRate = rates[0];
  2634. for (var i = 0; i < rates.length; i++) {
  2635. if (rates[i] > currentRate) {
  2636. newRate = rates[i];
  2637. break;
  2638. }
  2639. }
  2640. this.player().playbackRate(newRate);
  2641. };
  2642. /**
  2643. * Get possible playback rates
  2644. *
  2645. * @return {Array}
  2646. * All possible playback rates
  2647. */
  2648. PlaybackRateMenuButton.prototype.playbackRates = function playbackRates() {
  2649. return this.options_.playbackRates || this.options_.playerOptions && this.options_.playerOptions.playbackRates;
  2650. };
  2651. /**
  2652. * Get whether playback rates is supported by the tech
  2653. * and an array of playback rates exists
  2654. *
  2655. * @return {boolean}
  2656. * Whether changing playback rate is supported
  2657. */
  2658. PlaybackRateMenuButton.prototype.playbackRateSupported = function playbackRateSupported() {
  2659. return this.player().tech_ && this.player().tech_.featuresPlaybackRate && this.playbackRates() && this.playbackRates().length > 0;
  2660. };
  2661. /**
  2662. * Hide playback rate controls when they're no playback rate options to select
  2663. *
  2664. * @param {EventTarget~Event} [event]
  2665. * The event that caused this function to run.
  2666. *
  2667. * @listens Player#loadstart
  2668. */
  2669. PlaybackRateMenuButton.prototype.updateVisibility = function updateVisibility(event) {
  2670. if (this.playbackRateSupported()) {
  2671. this.removeClass('vjs-hidden');
  2672. } else {
  2673. this.addClass('vjs-hidden');
  2674. }
  2675. };
  2676. /**
  2677. * Update button label when rate changed
  2678. *
  2679. * @param {EventTarget~Event} [event]
  2680. * The event that caused this function to run.
  2681. *
  2682. * @listens Player#ratechange
  2683. */
  2684. PlaybackRateMenuButton.prototype.updateLabel = function updateLabel(event) {
  2685. if (this.playbackRateSupported()) {
  2686. this.labelEl_.innerHTML = this.player().playbackRate() + 'x';
  2687. }
  2688. };
  2689. return PlaybackRateMenuButton;
  2690. }(_menuButton2['default']);
  2691. /**
  2692. * The text that should display over the `FullscreenToggle`s controls. Added for localization.
  2693. *
  2694. * @type {string}
  2695. * @private
  2696. */
  2697. PlaybackRateMenuButton.prototype.controlText_ = 'Playback Rate';
  2698. _component2['default'].registerComponent('PlaybackRateMenuButton', PlaybackRateMenuButton);
  2699. exports['default'] = PlaybackRateMenuButton;
  2700. },{"14":14,"5":5,"50":50,"52":52,"85":85}],14:[function(_dereq_,module,exports){
  2701. 'use strict';
  2702. exports.__esModule = true;
  2703. var _menuItem = _dereq_(51);
  2704. var _menuItem2 = _interopRequireDefault(_menuItem);
  2705. var _component = _dereq_(5);
  2706. var _component2 = _interopRequireDefault(_component);
  2707. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  2708. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  2709. function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
  2710. function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
  2711. * @file playback-rate-menu-item.js
  2712. */
  2713. /**
  2714. * The specific menu item type for selecting a playback rate.
  2715. *
  2716. * @extends MenuItem
  2717. */
  2718. var PlaybackRateMenuItem = function (_MenuItem) {
  2719. _inherits(PlaybackRateMenuItem, _MenuItem);
  2720. /**
  2721. * Creates an instance of this class.
  2722. *
  2723. * @param {Player} player
  2724. * The `Player` that this class should be attached to.
  2725. *
  2726. * @param {Object} [options]
  2727. * The key/value store of player options.
  2728. */
  2729. function PlaybackRateMenuItem(player, options) {
  2730. _classCallCheck(this, PlaybackRateMenuItem);
  2731. var label = options.rate;
  2732. var rate = parseFloat(label, 10);
  2733. // Modify options for parent MenuItem class's init.
  2734. options.label = label;
  2735. options.selected = rate === 1;
  2736. options.selectable = true;
  2737. var _this = _possibleConstructorReturn(this, _MenuItem.call(this, player, options));
  2738. _this.label = label;
  2739. _this.rate = rate;
  2740. _this.on(player, 'ratechange', _this.update);
  2741. return _this;
  2742. }
  2743. /**
  2744. * This gets called when an `PlaybackRateMenuItem` is "clicked". See
  2745. * {@link ClickableComponent} for more detailed information on what a click can be.
  2746. *
  2747. * @param {EventTarget~Event} [event]
  2748. * The `keydown`, `tap`, or `click` event that caused this function to be
  2749. * called.
  2750. *
  2751. * @listens tap
  2752. * @listens click
  2753. */
  2754. PlaybackRateMenuItem.prototype.handleClick = function handleClick(event) {
  2755. _MenuItem.prototype.handleClick.call(this);
  2756. this.player().playbackRate(this.rate);
  2757. };
  2758. /**
  2759. * Update the PlaybackRateMenuItem when the playbackrate changes.
  2760. *
  2761. * @param {EventTarget~Event} [event]
  2762. * The `ratechange` event that caused this function to run.
  2763. *
  2764. * @listens Player#ratechange
  2765. */
  2766. PlaybackRateMenuItem.prototype.update = function update(event) {
  2767. this.selected(this.player().playbackRate() === this.rate);
  2768. };
  2769. return PlaybackRateMenuItem;
  2770. }(_menuItem2['default']);
  2771. /**
  2772. * The text that should display over the `PlaybackRateMenuItem`s controls. Added for localization.
  2773. *
  2774. * @type {string}
  2775. * @private
  2776. */
  2777. PlaybackRateMenuItem.prototype.contentElType = 'button';
  2778. _component2['default'].registerComponent('PlaybackRateMenuItem', PlaybackRateMenuItem);
  2779. exports['default'] = PlaybackRateMenuItem;
  2780. },{"5":5,"51":51}],15:[function(_dereq_,module,exports){
  2781. 'use strict';
  2782. exports.__esModule = true;
  2783. var _component = _dereq_(5);
  2784. var _component2 = _interopRequireDefault(_component);
  2785. var _dom = _dereq_(85);
  2786. var Dom = _interopRequireWildcard(_dom);
  2787. function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
  2788. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  2789. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  2790. function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
  2791. function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
  2792. * @file load-progress-bar.js
  2793. */
  2794. /**
  2795. * Shows loading progress
  2796. *
  2797. * @extends Component
  2798. */
  2799. var LoadProgressBar = function (_Component) {
  2800. _inherits(LoadProgressBar, _Component);
  2801. /**
  2802. * Creates an instance of this class.
  2803. *
  2804. * @param {Player} player
  2805. * The `Player` that this class should be attached to.
  2806. *
  2807. * @param {Object} [options]
  2808. * The key/value store of player options.
  2809. */
  2810. function LoadProgressBar(player, options) {
  2811. _classCallCheck(this, LoadProgressBar);
  2812. var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
  2813. _this.partEls_ = [];
  2814. _this.on(player, 'progress', _this.update);
  2815. return _this;
  2816. }
  2817. /**
  2818. * Create the `Component`'s DOM element
  2819. *
  2820. * @return {Element}
  2821. * The element that was created.
  2822. */
  2823. LoadProgressBar.prototype.createEl = function createEl() {
  2824. return _Component.prototype.createEl.call(this, 'div', {
  2825. className: 'vjs-load-progress',
  2826. innerHTML: '<span class="vjs-control-text"><span>' + this.localize('Loaded') + '</span>: 0%</span>'
  2827. });
  2828. };
  2829. /**
  2830. * Update progress bar
  2831. *
  2832. * @param {EventTarget~Event} [event]
  2833. * The `progress` event that caused this function to run.
  2834. *
  2835. * @listens Player#progress
  2836. */
  2837. LoadProgressBar.prototype.update = function update(event) {
  2838. var buffered = this.player_.buffered();
  2839. var duration = this.player_.duration();
  2840. var bufferedEnd = this.player_.bufferedEnd();
  2841. var children = this.partEls_;
  2842. // get the percent width of a time compared to the total end
  2843. var percentify = function percentify(time, end) {
  2844. // no NaN
  2845. var percent = time / end || 0;
  2846. return (percent >= 1 ? 1 : percent) * 100 + '%';
  2847. };
  2848. // update the width of the progress bar
  2849. this.el_.style.width = percentify(bufferedEnd, duration);
  2850. // add child elements to represent the individual buffered time ranges
  2851. for (var i = 0; i < buffered.length; i++) {
  2852. var start = buffered.start(i);
  2853. var end = buffered.end(i);
  2854. var part = children[i];
  2855. if (!part) {
  2856. part = this.el_.appendChild(Dom.createEl());
  2857. children[i] = part;
  2858. }
  2859. // set the percent based on the width of the progress bar (bufferedEnd)
  2860. part.style.left = percentify(start, bufferedEnd);
  2861. part.style.width = percentify(end - start, bufferedEnd);
  2862. }
  2863. // remove unused buffered range elements
  2864. for (var _i = children.length; _i > buffered.length; _i--) {
  2865. this.el_.removeChild(children[_i - 1]);
  2866. }
  2867. children.length = buffered.length;
  2868. };
  2869. return LoadProgressBar;
  2870. }(_component2['default']);
  2871. _component2['default'].registerComponent('LoadProgressBar', LoadProgressBar);
  2872. exports['default'] = LoadProgressBar;
  2873. },{"5":5,"85":85}],16:[function(_dereq_,module,exports){
  2874. 'use strict';
  2875. exports.__esModule = true;
  2876. var _component = _dereq_(5);
  2877. var _component2 = _interopRequireDefault(_component);
  2878. var _fn = _dereq_(88);
  2879. var Fn = _interopRequireWildcard(_fn);
  2880. var _formatTime = _dereq_(89);
  2881. var _formatTime2 = _interopRequireDefault(_formatTime);
  2882. _dereq_(20);
  2883. function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
  2884. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  2885. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  2886. function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
  2887. function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
  2888. * @file mouse-time-display.js
  2889. */
  2890. /**
  2891. * The {@link MouseTimeDisplay} component tracks mouse movement over the
  2892. * {@link ProgressControl}. It displays an indicator and a {@link TimeTooltip}
  2893. * indicating the time which is represented by a given point in the
  2894. * {@link ProgressControl}.
  2895. *
  2896. * @extends Component
  2897. */
  2898. var MouseTimeDisplay = function (_Component) {
  2899. _inherits(MouseTimeDisplay, _Component);
  2900. /**
  2901. * Creates an instance of this class.
  2902. *
  2903. * @param {Player} player
  2904. * The {@link Player} that this class should be attached to.
  2905. *
  2906. * @param {Object} [options]
  2907. * The key/value store of player options.
  2908. */
  2909. function MouseTimeDisplay(player, options) {
  2910. _classCallCheck(this, MouseTimeDisplay);
  2911. var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
  2912. _this.update = Fn.throttle(Fn.bind(_this, _this.update), 25);
  2913. return _this;
  2914. }
  2915. /**
  2916. * Create the DOM element for this class.
  2917. *
  2918. * @return {Element}
  2919. * The element that was created.
  2920. */
  2921. MouseTimeDisplay.prototype.createEl = function createEl() {
  2922. return _Component.prototype.createEl.call(this, 'div', {
  2923. className: 'vjs-mouse-display'
  2924. });
  2925. };
  2926. /**
  2927. * Enqueues updates to its own DOM as well as the DOM of its
  2928. * {@link TimeTooltip} child.
  2929. *
  2930. * @param {Object} seekBarRect
  2931. * The `ClientRect` for the {@link SeekBar} element.
  2932. *
  2933. * @param {number} seekBarPoint
  2934. * A number from 0 to 1, representing a horizontal reference point
  2935. * from the left edge of the {@link SeekBar}
  2936. */
  2937. MouseTimeDisplay.prototype.update = function update(seekBarRect, seekBarPoint) {
  2938. var _this2 = this;
  2939. // If there is an existing rAF ID, cancel it so we don't over-queue.
  2940. if (this.rafId_) {
  2941. this.cancelAnimationFrame(this.rafId_);
  2942. }
  2943. this.rafId_ = this.requestAnimationFrame(function () {
  2944. var duration = _this2.player_.duration();
  2945. var content = (0, _formatTime2['default'])(seekBarPoint * duration, duration);
  2946. _this2.el_.style.left = seekBarRect.width * seekBarPoint + 'px';
  2947. _this2.getChild('timeTooltip').update(seekBarRect, seekBarPoint, content);
  2948. });
  2949. };
  2950. return MouseTimeDisplay;
  2951. }(_component2['default']);
  2952. /**
  2953. * Default options for `MouseTimeDisplay`
  2954. *
  2955. * @type {Object}
  2956. * @private
  2957. */
  2958. MouseTimeDisplay.prototype.options_ = {
  2959. children: ['timeTooltip']
  2960. };
  2961. _component2['default'].registerComponent('MouseTimeDisplay', MouseTimeDisplay);
  2962. exports['default'] = MouseTimeDisplay;
  2963. },{"20":20,"5":5,"88":88,"89":89}],17:[function(_dereq_,module,exports){
  2964. 'use strict';
  2965. exports.__esModule = true;
  2966. var _component = _dereq_(5);
  2967. var _component2 = _interopRequireDefault(_component);
  2968. var _browser = _dereq_(81);
  2969. var _formatTime = _dereq_(89);
  2970. var _formatTime2 = _interopRequireDefault(_formatTime);
  2971. _dereq_(20);
  2972. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  2973. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  2974. function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
  2975. function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
  2976. * @file play-progress-bar.js
  2977. */
  2978. /**
  2979. * Used by {@link SeekBar} to display media playback progress as part of the
  2980. * {@link ProgressControl}.
  2981. *
  2982. * @extends Component
  2983. */
  2984. var PlayProgressBar = function (_Component) {
  2985. _inherits(PlayProgressBar, _Component);
  2986. function PlayProgressBar() {
  2987. _classCallCheck(this, PlayProgressBar);
  2988. return _possibleConstructorReturn(this, _Component.apply(this, arguments));
  2989. }
  2990. /**
  2991. * Create the the DOM element for this class.
  2992. *
  2993. * @return {Element}
  2994. * The element that was created.
  2995. */
  2996. PlayProgressBar.prototype.createEl = function createEl() {
  2997. return _Component.prototype.createEl.call(this, 'div', {
  2998. className: 'vjs-play-progress vjs-slider-bar',
  2999. innerHTML: '<span class="vjs-control-text"><span>' + this.localize('Progress') + '</span>: 0%</span>'
  3000. });
  3001. };
  3002. /**
  3003. * Enqueues updates to its own DOM as well as the DOM of its
  3004. * {@link TimeTooltip} child.
  3005. *
  3006. * @param {Object} seekBarRect
  3007. * The `ClientRect` for the {@link SeekBar} element.
  3008. *
  3009. * @param {number} seekBarPoint
  3010. * A number from 0 to 1, representing a horizontal reference point
  3011. * from the left edge of the {@link SeekBar}
  3012. */
  3013. PlayProgressBar.prototype.update = function update(seekBarRect, seekBarPoint) {
  3014. var _this2 = this;
  3015. // If there is an existing rAF ID, cancel it so we don't over-queue.
  3016. if (this.rafId_) {
  3017. this.cancelAnimationFrame(this.rafId_);
  3018. }
  3019. this.rafId_ = this.requestAnimationFrame(function () {
  3020. var time = _this2.player_.scrubbing() ? _this2.player_.getCache().currentTime : _this2.player_.currentTime();
  3021. var content = (0, _formatTime2['default'])(time, _this2.player_.duration());
  3022. var timeTooltip = _this2.getChild('timeTooltip');
  3023. if (timeTooltip) {
  3024. timeTooltip.update(seekBarRect, seekBarPoint, content);
  3025. }
  3026. });
  3027. };
  3028. return PlayProgressBar;
  3029. }(_component2['default']);
  3030. /**
  3031. * Default options for {@link PlayProgressBar}.
  3032. *
  3033. * @type {Object}
  3034. * @private
  3035. */
  3036. PlayProgressBar.prototype.options_ = {
  3037. children: []
  3038. };
  3039. if (!_browser.IE_VERSION || _browser.IE_VERSION > 8) {
  3040. PlayProgressBar.prototype.options_.children.push('timeTooltip');
  3041. }
  3042. _component2['default'].registerComponent('PlayProgressBar', PlayProgressBar);
  3043. exports['default'] = PlayProgressBar;
  3044. },{"20":20,"5":5,"81":81,"89":89}],18:[function(_dereq_,module,exports){
  3045. 'use strict';
  3046. exports.__esModule = true;
  3047. var _component = _dereq_(5);
  3048. var _component2 = _interopRequireDefault(_component);
  3049. var _dom = _dereq_(85);
  3050. var Dom = _interopRequireWildcard(_dom);
  3051. var _fn = _dereq_(88);
  3052. _dereq_(19);
  3053. function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
  3054. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  3055. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  3056. function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
  3057. function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
  3058. * @file progress-control.js
  3059. */
  3060. /**
  3061. * The Progress Control component contains the seek bar, load progress,
  3062. * and play progress.
  3063. *
  3064. * @extends Component
  3065. */
  3066. var ProgressControl = function (_Component) {
  3067. _inherits(ProgressControl, _Component);
  3068. /**
  3069. * Creates an instance of this class.
  3070. *
  3071. * @param {Player} player
  3072. * The `Player` that this class should be attached to.
  3073. *
  3074. * @param {Object} [options]
  3075. * The key/value store of player options.
  3076. */
  3077. function ProgressControl(player, options) {
  3078. _classCallCheck(this, ProgressControl);
  3079. var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
  3080. _this.handleMouseMove = (0, _fn.throttle)((0, _fn.bind)(_this, _this.handleMouseMove), 25);
  3081. _this.on(_this.el_, 'mousemove', _this.handleMouseMove);
  3082. _this.throttledHandleMouseSeek = (0, _fn.throttle)((0, _fn.bind)(_this, _this.handleMouseSeek), 25);
  3083. _this.on(['mousedown', 'touchstart'], _this.handleMouseDown);
  3084. return _this;
  3085. }
  3086. /**
  3087. * Create the `Component`'s DOM element
  3088. *
  3089. * @return {Element}
  3090. * The element that was created.
  3091. */
  3092. ProgressControl.prototype.createEl = function createEl() {
  3093. return _Component.prototype.createEl.call(this, 'div', {
  3094. className: 'vjs-progress-control vjs-control'
  3095. });
  3096. };
  3097. /**
  3098. * When the mouse moves over the `ProgressControl`, the pointer position
  3099. * gets passed down to the `MouseTimeDisplay` component.
  3100. *
  3101. * @param {EventTarget~Event} event
  3102. * The `mousemove` event that caused this function to run.
  3103. *
  3104. * @listen mousemove
  3105. */
  3106. ProgressControl.prototype.handleMouseMove = function handleMouseMove(event) {
  3107. var seekBar = this.getChild('seekBar');
  3108. var mouseTimeDisplay = seekBar.getChild('mouseTimeDisplay');
  3109. var seekBarEl = seekBar.el();
  3110. var seekBarRect = Dom.getBoundingClientRect(seekBarEl);
  3111. var seekBarPoint = Dom.getPointerPosition(seekBarEl, event).x;
  3112. // The default skin has a gap on either side of the `SeekBar`. This means
  3113. // that it's possible to trigger this behavior outside the boundaries of
  3114. // the `SeekBar`. This ensures we stay within it at all times.
  3115. if (seekBarPoint > 1) {
  3116. seekBarPoint = 1;
  3117. } else if (seekBarPoint < 0) {
  3118. seekBarPoint = 0;
  3119. }
  3120. if (mouseTimeDisplay) {
  3121. mouseTimeDisplay.update(seekBarRect, seekBarPoint);
  3122. }
  3123. };
  3124. /**
  3125. * A throttled version of the {@link ProgressControl#handleMouseSeek} listener.
  3126. *
  3127. * @method ProgressControl#throttledHandleMouseSeek
  3128. * @param {EventTarget~Event} event
  3129. * The `mousemove` event that caused this function to run.
  3130. *
  3131. * @listen mousemove
  3132. * @listen touchmove
  3133. */
  3134. /**
  3135. * Handle `mousemove` or `touchmove` events on the `ProgressControl`.
  3136. *
  3137. * @param {EventTarget~Event} event
  3138. * `mousedown` or `touchstart` event that triggered this function
  3139. *
  3140. * @listens mousemove
  3141. * @listens touchmove
  3142. */
  3143. ProgressControl.prototype.handleMouseSeek = function handleMouseSeek(event) {
  3144. var seekBar = this.getChild('seekBar');
  3145. seekBar.handleMouseMove(event);
  3146. };
  3147. /**
  3148. * Handle `mousedown` or `touchstart` events on the `ProgressControl`.
  3149. *
  3150. * @param {EventTarget~Event} event
  3151. * `mousedown` or `touchstart` event that triggered this function
  3152. *
  3153. * @listens mousedown
  3154. * @listens touchstart
  3155. */
  3156. ProgressControl.prototype.handleMouseDown = function handleMouseDown(event) {
  3157. var doc = this.el_.ownerDocument;
  3158. this.on(doc, 'mousemove', this.throttledHandleMouseSeek);
  3159. this.on(doc, 'touchmove', this.throttledHandleMouseSeek);
  3160. this.on(doc, 'mouseup', this.handleMouseUp);
  3161. this.on(doc, 'touchend', this.handleMouseUp);
  3162. };
  3163. /**
  3164. * Handle `mouseup` or `touchend` events on the `ProgressControl`.
  3165. *
  3166. * @param {EventTarget~Event} event
  3167. * `mouseup` or `touchend` event that triggered this function.
  3168. *
  3169. * @listens touchend
  3170. * @listens mouseup
  3171. */
  3172. ProgressControl.prototype.handleMouseUp = function handleMouseUp(event) {
  3173. var doc = this.el_.ownerDocument;
  3174. this.off(doc, 'mousemove', this.throttledHandleMouseSeek);
  3175. this.off(doc, 'touchmove', this.throttledHandleMouseSeek);
  3176. this.off(doc, 'mouseup', this.handleMouseUp);
  3177. this.off(doc, 'touchend', this.handleMouseUp);
  3178. };
  3179. return ProgressControl;
  3180. }(_component2['default']);
  3181. /**
  3182. * Default options for `ProgressControl`
  3183. *
  3184. * @type {Object}
  3185. * @private
  3186. */
  3187. ProgressControl.prototype.options_ = {
  3188. children: ['seekBar']
  3189. };
  3190. _component2['default'].registerComponent('ProgressControl', ProgressControl);
  3191. exports['default'] = ProgressControl;
  3192. },{"19":19,"5":5,"85":85,"88":88}],19:[function(_dereq_,module,exports){
  3193. 'use strict';
  3194. exports.__esModule = true;
  3195. var _slider = _dereq_(60);
  3196. var _slider2 = _interopRequireDefault(_slider);
  3197. var _component = _dereq_(5);
  3198. var _component2 = _interopRequireDefault(_component);
  3199. var _browser = _dereq_(81);
  3200. var _dom = _dereq_(85);
  3201. var Dom = _interopRequireWildcard(_dom);
  3202. var _fn = _dereq_(88);
  3203. var Fn = _interopRequireWildcard(_fn);
  3204. var _formatTime = _dereq_(89);
  3205. var _formatTime2 = _interopRequireDefault(_formatTime);
  3206. _dereq_(15);
  3207. _dereq_(17);
  3208. _dereq_(16);
  3209. function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
  3210. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  3211. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  3212. function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
  3213. function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
  3214. * @file seek-bar.js
  3215. */
  3216. // The number of seconds the `step*` functions move the timeline.
  3217. var STEP_SECONDS = 5;
  3218. /**
  3219. * Seek bar and container for the progress bars. Uses {@link PlayProgressBar}
  3220. * as its `bar`.
  3221. *
  3222. * @extends Slider
  3223. */
  3224. var SeekBar = function (_Slider) {
  3225. _inherits(SeekBar, _Slider);
  3226. /**
  3227. * Creates an instance of this class.
  3228. *
  3229. * @param {Player} player
  3230. * The `Player` that this class should be attached to.
  3231. *
  3232. * @param {Object} [options]
  3233. * The key/value store of player options.
  3234. */
  3235. function SeekBar(player, options) {
  3236. _classCallCheck(this, SeekBar);
  3237. var _this = _possibleConstructorReturn(this, _Slider.call(this, player, options));
  3238. _this.update = Fn.throttle(Fn.bind(_this, _this.update), 50);
  3239. _this.on(player, ['timeupdate', 'ended'], _this.update);
  3240. return _this;
  3241. }
  3242. /**
  3243. * Create the `Component`'s DOM element
  3244. *
  3245. * @return {Element}
  3246. * The element that was created.
  3247. */
  3248. SeekBar.prototype.createEl = function createEl() {
  3249. return _Slider.prototype.createEl.call(this, 'div', {
  3250. className: 'vjs-progress-holder'
  3251. }, {
  3252. 'aria-label': this.localize('Progress Bar')
  3253. });
  3254. };
  3255. /**
  3256. * Update the seek bar's UI.
  3257. *
  3258. * @param {EventTarget~Event} [event]
  3259. * The `timeupdate` or `ended` event that caused this to run.
  3260. *
  3261. * @listens Player#timeupdate
  3262. * @listens Player#ended
  3263. */
  3264. SeekBar.prototype.update = function update() {
  3265. var percent = _Slider.prototype.update.call(this);
  3266. var duration = this.player_.duration();
  3267. // Allows for smooth scrubbing, when player can't keep up.
  3268. var time = this.player_.scrubbing() ? this.player_.getCache().currentTime : this.player_.currentTime();
  3269. // machine readable value of progress bar (percentage complete)
  3270. this.el_.setAttribute('aria-valuenow', (percent * 100).toFixed(2));
  3271. // human readable value of progress bar (time complete)
  3272. this.el_.setAttribute('aria-valuetext', this.localize('progress bar timing: currentTime={1} duration={2}', [(0, _formatTime2['default'])(time, duration), (0, _formatTime2['default'])(duration, duration)], '{1} of {2}'));
  3273. // Update the `PlayProgressBar`.
  3274. this.bar.update(Dom.getBoundingClientRect(this.el_), percent);
  3275. return percent;
  3276. };
  3277. /**
  3278. * Get the percentage of media played so far.
  3279. *
  3280. * @return {number}
  3281. * The percentage of media played so far (0 to 1).
  3282. */
  3283. SeekBar.prototype.getPercent = function getPercent() {
  3284. // Allows for smooth scrubbing, when player can't keep up.
  3285. var time = this.player_.scrubbing() ? this.player_.getCache().currentTime : this.player_.currentTime();
  3286. var percent = time / this.player_.duration();
  3287. return percent >= 1 ? 1 : percent;
  3288. };
  3289. /**
  3290. * Handle mouse down on seek bar
  3291. *
  3292. * @param {EventTarget~Event} event
  3293. * The `mousedown` event that caused this to run.
  3294. *
  3295. * @listens mousedown
  3296. */
  3297. SeekBar.prototype.handleMouseDown = function handleMouseDown(event) {
  3298. this.player_.scrubbing(true);
  3299. this.videoWasPlaying = !this.player_.paused();
  3300. this.player_.pause();
  3301. _Slider.prototype.handleMouseDown.call(this, event);
  3302. };
  3303. /**
  3304. * Handle mouse move on seek bar
  3305. *
  3306. * @param {EventTarget~Event} event
  3307. * The `mousemove` event that caused this to run.
  3308. *
  3309. * @listens mousemove
  3310. */
  3311. SeekBar.prototype.handleMouseMove = function handleMouseMove(event) {
  3312. var newTime = this.calculateDistance(event) * this.player_.duration();
  3313. // Don't let video end while scrubbing.
  3314. if (newTime === this.player_.duration()) {
  3315. newTime = newTime - 0.1;
  3316. }
  3317. // Set new time (tell player to seek to new time)
  3318. this.player_.currentTime(newTime);
  3319. };
  3320. /**
  3321. * Handle mouse up on seek bar
  3322. *
  3323. * @param {EventTarget~Event} event
  3324. * The `mouseup` event that caused this to run.
  3325. *
  3326. * @listens mouseup
  3327. */
  3328. SeekBar.prototype.handleMouseUp = function handleMouseUp(event) {
  3329. _Slider.prototype.handleMouseUp.call(this, event);
  3330. this.player_.scrubbing(false);
  3331. if (this.videoWasPlaying) {
  3332. this.player_.play();
  3333. }
  3334. };
  3335. /**
  3336. * Move more quickly fast forward for keyboard-only users
  3337. */
  3338. SeekBar.prototype.stepForward = function stepForward() {
  3339. this.player_.currentTime(this.player_.currentTime() + STEP_SECONDS);
  3340. };
  3341. /**
  3342. * Move more quickly rewind for keyboard-only users
  3343. */
  3344. SeekBar.prototype.stepBack = function stepBack() {
  3345. this.player_.currentTime(this.player_.currentTime() - STEP_SECONDS);
  3346. };
  3347. /**
  3348. * Toggles the playback state of the player
  3349. * This gets called when enter or space is used on the seekbar
  3350. *
  3351. * @param {EventTarget~Event} event
  3352. * The `keydown` event that caused this function to be called
  3353. *
  3354. */
  3355. SeekBar.prototype.handleAction = function handleAction(event) {
  3356. if (this.player_.paused()) {
  3357. this.player_.play();
  3358. } else {
  3359. this.player_.pause();
  3360. }
  3361. };
  3362. /**
  3363. * Called when this SeekBar has focus and a key gets pressed down. By
  3364. * default it will call `this.handleAction` when the key is space or enter.
  3365. *
  3366. * @param {EventTarget~Event} event
  3367. * The `keydown` event that caused this function to be called.
  3368. *
  3369. * @listens keydown
  3370. */
  3371. SeekBar.prototype.handleKeyPress = function handleKeyPress(event) {
  3372. // Support Space (32) or Enter (13) key operation to fire a click event
  3373. if (event.which === 32 || event.which === 13) {
  3374. event.preventDefault();
  3375. this.handleAction(event);
  3376. } else if (_Slider.prototype.handleKeyPress) {
  3377. // Pass keypress handling up for unsupported keys
  3378. _Slider.prototype.handleKeyPress.call(this, event);
  3379. }
  3380. };
  3381. return SeekBar;
  3382. }(_slider2['default']);
  3383. /**
  3384. * Default options for the `SeekBar`
  3385. *
  3386. * @type {Object}
  3387. * @private
  3388. */
  3389. SeekBar.prototype.options_ = {
  3390. children: ['loadProgressBar', 'playProgressBar'],
  3391. barName: 'playProgressBar'
  3392. };
  3393. if (!_browser.IE_VERSION || _browser.IE_VERSION > 8) {
  3394. SeekBar.prototype.options_.children.splice(1, 0, 'mouseTimeDisplay');
  3395. }
  3396. /**
  3397. * Call the update event for this Slider when this event happens on the player.
  3398. *
  3399. * @type {string}
  3400. */
  3401. SeekBar.prototype.playerEvent = 'timeupdate';
  3402. _component2['default'].registerComponent('SeekBar', SeekBar);
  3403. exports['default'] = SeekBar;
  3404. },{"15":15,"16":16,"17":17,"5":5,"60":60,"81":81,"85":85,"88":88,"89":89}],20:[function(_dereq_,module,exports){
  3405. 'use strict';
  3406. exports.__esModule = true;
  3407. var _component = _dereq_(5);
  3408. var _component2 = _interopRequireDefault(_component);
  3409. var _dom = _dereq_(85);
  3410. var Dom = _interopRequireWildcard(_dom);
  3411. function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
  3412. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  3413. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  3414. function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
  3415. function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
  3416. * @file time-tooltip.js
  3417. */
  3418. /**
  3419. * Time tooltips display a time above the progress bar.
  3420. *
  3421. * @extends Component
  3422. */
  3423. var TimeTooltip = function (_Component) {
  3424. _inherits(TimeTooltip, _Component);
  3425. function TimeTooltip() {
  3426. _classCallCheck(this, TimeTooltip);
  3427. return _possibleConstructorReturn(this, _Component.apply(this, arguments));
  3428. }
  3429. /**
  3430. * Create the time tooltip DOM element
  3431. *
  3432. * @return {Element}
  3433. * The element that was created.
  3434. */
  3435. TimeTooltip.prototype.createEl = function createEl() {
  3436. return _Component.prototype.createEl.call(this, 'div', {
  3437. className: 'vjs-time-tooltip'
  3438. });
  3439. };
  3440. /**
  3441. * Updates the position of the time tooltip relative to the `SeekBar`.
  3442. *
  3443. * @param {Object} seekBarRect
  3444. * The `ClientRect` for the {@link SeekBar} element.
  3445. *
  3446. * @param {number} seekBarPoint
  3447. * A number from 0 to 1, representing a horizontal reference point
  3448. * from the left edge of the {@link SeekBar}
  3449. */
  3450. TimeTooltip.prototype.update = function update(seekBarRect, seekBarPoint, content) {
  3451. var tooltipRect = Dom.getBoundingClientRect(this.el_);
  3452. var playerRect = Dom.getBoundingClientRect(this.player_.el());
  3453. var seekBarPointPx = seekBarRect.width * seekBarPoint;
  3454. // do nothing if either rect isn't available
  3455. // for example, if the player isn't in the DOM for testing
  3456. if (!playerRect || !tooltipRect) {
  3457. return;
  3458. }
  3459. // This is the space left of the `seekBarPoint` available within the bounds
  3460. // of the player. We calculate any gap between the left edge of the player
  3461. // and the left edge of the `SeekBar` and add the number of pixels in the
  3462. // `SeekBar` before hitting the `seekBarPoint`
  3463. var spaceLeftOfPoint = seekBarRect.left - playerRect.left + seekBarPointPx;
  3464. // This is the space right of the `seekBarPoint` available within the bounds
  3465. // of the player. We calculate the number of pixels from the `seekBarPoint`
  3466. // to the right edge of the `SeekBar` and add to that any gap between the
  3467. // right edge of the `SeekBar` and the player.
  3468. var spaceRightOfPoint = seekBarRect.width - seekBarPointPx + (playerRect.right - seekBarRect.right);
  3469. // This is the number of pixels by which the tooltip will need to be pulled
  3470. // further to the right to center it over the `seekBarPoint`.
  3471. var pullTooltipBy = tooltipRect.width / 2;
  3472. // Adjust the `pullTooltipBy` distance to the left or right depending on
  3473. // the results of the space calculations above.
  3474. if (spaceLeftOfPoint < pullTooltipBy) {
  3475. pullTooltipBy += pullTooltipBy - spaceLeftOfPoint;
  3476. } else if (spaceRightOfPoint < pullTooltipBy) {
  3477. pullTooltipBy = spaceRightOfPoint;
  3478. }
  3479. // Due to the imprecision of decimal/ratio based calculations and varying
  3480. // rounding behaviors, there are cases where the spacing adjustment is off
  3481. // by a pixel or two. This adds insurance to these calculations.
  3482. if (pullTooltipBy < 0) {
  3483. pullTooltipBy = 0;
  3484. } else if (pullTooltipBy > tooltipRect.width) {
  3485. pullTooltipBy = tooltipRect.width;
  3486. }
  3487. this.el_.style.right = '-' + pullTooltipBy + 'px';
  3488. Dom.textContent(this.el_, content);
  3489. };
  3490. return TimeTooltip;
  3491. }(_component2['default']);
  3492. _component2['default'].registerComponent('TimeTooltip', TimeTooltip);
  3493. exports['default'] = TimeTooltip;
  3494. },{"5":5,"85":85}],21:[function(_dereq_,module,exports){
  3495. 'use strict';
  3496. exports.__esModule = true;
  3497. var _spacer = _dereq_(22);
  3498. var _spacer2 = _interopRequireDefault(_spacer);
  3499. var _component = _dereq_(5);
  3500. var _component2 = _interopRequireDefault(_component);
  3501. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  3502. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  3503. function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
  3504. function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
  3505. * @file custom-control-spacer.js
  3506. */
  3507. /**
  3508. * Spacer specifically meant to be used as an insertion point for new plugins, etc.
  3509. *
  3510. * @extends Spacer
  3511. */
  3512. var CustomControlSpacer = function (_Spacer) {
  3513. _inherits(CustomControlSpacer, _Spacer);
  3514. function CustomControlSpacer() {
  3515. _classCallCheck(this, CustomControlSpacer);
  3516. return _possibleConstructorReturn(this, _Spacer.apply(this, arguments));
  3517. }
  3518. /**
  3519. * Builds the default DOM `className`.
  3520. *
  3521. * @return {string}
  3522. * The DOM `className` for this object.
  3523. */
  3524. CustomControlSpacer.prototype.buildCSSClass = function buildCSSClass() {
  3525. return 'vjs-custom-control-spacer ' + _Spacer.prototype.buildCSSClass.call(this);
  3526. };
  3527. /**
  3528. * Create the `Component`'s DOM element
  3529. *
  3530. * @return {Element}
  3531. * The element that was created.
  3532. */
  3533. CustomControlSpacer.prototype.createEl = function createEl() {
  3534. var el = _Spacer.prototype.createEl.call(this, {
  3535. className: this.buildCSSClass()
  3536. });
  3537. // No-flex/table-cell mode requires there be some content
  3538. // in the cell to fill the remaining space of the table.
  3539. el.innerHTML = '&nbsp;';
  3540. return el;
  3541. };
  3542. return CustomControlSpacer;
  3543. }(_spacer2['default']);
  3544. _component2['default'].registerComponent('CustomControlSpacer', CustomControlSpacer);
  3545. exports['default'] = CustomControlSpacer;
  3546. },{"22":22,"5":5}],22:[function(_dereq_,module,exports){
  3547. 'use strict';
  3548. exports.__esModule = true;
  3549. var _component = _dereq_(5);
  3550. var _component2 = _interopRequireDefault(_component);
  3551. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  3552. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  3553. function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
  3554. function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
  3555. * @file spacer.js
  3556. */
  3557. /**
  3558. * Just an empty spacer element that can be used as an append point for plugins, etc.
  3559. * Also can be used to create space between elements when necessary.
  3560. *
  3561. * @extends Component
  3562. */
  3563. var Spacer = function (_Component) {
  3564. _inherits(Spacer, _Component);
  3565. function Spacer() {
  3566. _classCallCheck(this, Spacer);
  3567. return _possibleConstructorReturn(this, _Component.apply(this, arguments));
  3568. }
  3569. /**
  3570. * Builds the default DOM `className`.
  3571. *
  3572. * @return {string}
  3573. * The DOM `className` for this object.
  3574. */
  3575. Spacer.prototype.buildCSSClass = function buildCSSClass() {
  3576. return 'vjs-spacer ' + _Component.prototype.buildCSSClass.call(this);
  3577. };
  3578. /**
  3579. * Create the `Component`'s DOM element
  3580. *
  3581. * @return {Element}
  3582. * The element that was created.
  3583. */
  3584. Spacer.prototype.createEl = function createEl() {
  3585. return _Component.prototype.createEl.call(this, 'div', {
  3586. className: this.buildCSSClass()
  3587. });
  3588. };
  3589. return Spacer;
  3590. }(_component2['default']);
  3591. _component2['default'].registerComponent('Spacer', Spacer);
  3592. exports['default'] = Spacer;
  3593. },{"5":5}],23:[function(_dereq_,module,exports){
  3594. 'use strict';
  3595. exports.__esModule = true;
  3596. var _textTrackMenuItem = _dereq_(33);
  3597. var _textTrackMenuItem2 = _interopRequireDefault(_textTrackMenuItem);
  3598. var _component = _dereq_(5);
  3599. var _component2 = _interopRequireDefault(_component);
  3600. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  3601. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  3602. function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
  3603. function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
  3604. * @file caption-settings-menu-item.js
  3605. */
  3606. /**
  3607. * The menu item for caption track settings menu
  3608. *
  3609. * @extends TextTrackMenuItem
  3610. */
  3611. var CaptionSettingsMenuItem = function (_TextTrackMenuItem) {
  3612. _inherits(CaptionSettingsMenuItem, _TextTrackMenuItem);
  3613. /**
  3614. * Creates an instance of this class.
  3615. *
  3616. * @param {Player} player
  3617. * The `Player` that this class should be attached to.
  3618. *
  3619. * @param {Object} [options]
  3620. * The key/value store of player options.
  3621. */
  3622. function CaptionSettingsMenuItem(player, options) {
  3623. _classCallCheck(this, CaptionSettingsMenuItem);
  3624. options.track = {
  3625. player: player,
  3626. kind: options.kind,
  3627. label: options.kind + ' settings',
  3628. selectable: false,
  3629. 'default': false,
  3630. mode: 'disabled'
  3631. };
  3632. // CaptionSettingsMenuItem has no concept of 'selected'
  3633. options.selectable = false;
  3634. options.name = 'CaptionSettingsMenuItem';
  3635. var _this = _possibleConstructorReturn(this, _TextTrackMenuItem.call(this, player, options));
  3636. _this.addClass('vjs-texttrack-settings');
  3637. _this.controlText(', opens ' + options.kind + ' settings dialog');
  3638. return _this;
  3639. }
  3640. /**
  3641. * This gets called when an `CaptionSettingsMenuItem` is "clicked". See
  3642. * {@link ClickableComponent} for more detailed information on what a click can be.
  3643. *
  3644. * @param {EventTarget~Event} [event]
  3645. * The `keydown`, `tap`, or `click` event that caused this function to be
  3646. * called.
  3647. *
  3648. * @listens tap
  3649. * @listens click
  3650. */
  3651. CaptionSettingsMenuItem.prototype.handleClick = function handleClick(event) {
  3652. this.player().getChild('textTrackSettings').open();
  3653. };
  3654. return CaptionSettingsMenuItem;
  3655. }(_textTrackMenuItem2['default']);
  3656. _component2['default'].registerComponent('CaptionSettingsMenuItem', CaptionSettingsMenuItem);
  3657. exports['default'] = CaptionSettingsMenuItem;
  3658. },{"33":33,"5":5}],24:[function(_dereq_,module,exports){
  3659. 'use strict';
  3660. exports.__esModule = true;
  3661. var _textTrackButton = _dereq_(32);
  3662. var _textTrackButton2 = _interopRequireDefault(_textTrackButton);
  3663. var _component = _dereq_(5);
  3664. var _component2 = _interopRequireDefault(_component);
  3665. var _captionSettingsMenuItem = _dereq_(23);
  3666. var _captionSettingsMenuItem2 = _interopRequireDefault(_captionSettingsMenuItem);
  3667. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  3668. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  3669. function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
  3670. function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
  3671. * @file captions-button.js
  3672. */
  3673. /**
  3674. * The button component for toggling and selecting captions
  3675. *
  3676. * @extends TextTrackButton
  3677. */
  3678. var CaptionsButton = function (_TextTrackButton) {
  3679. _inherits(CaptionsButton, _TextTrackButton);
  3680. /**
  3681. * Creates an instance of this class.
  3682. *
  3683. * @param {Player} player
  3684. * The `Player` that this class should be attached to.
  3685. *
  3686. * @param {Object} [options]
  3687. * The key/value store of player options.
  3688. *
  3689. * @param {Component~ReadyCallback} [ready]
  3690. * The function to call when this component is ready.
  3691. */
  3692. function CaptionsButton(player, options, ready) {
  3693. _classCallCheck(this, CaptionsButton);
  3694. return _possibleConstructorReturn(this, _TextTrackButton.call(this, player, options, ready));
  3695. }
  3696. /**
  3697. * Builds the default DOM `className`.
  3698. *
  3699. * @return {string}
  3700. * The DOM `className` for this object.
  3701. */
  3702. CaptionsButton.prototype.buildCSSClass = function buildCSSClass() {
  3703. return 'vjs-captions-button ' + _TextTrackButton.prototype.buildCSSClass.call(this);
  3704. };
  3705. CaptionsButton.prototype.buildWrapperCSSClass = function buildWrapperCSSClass() {
  3706. return 'vjs-captions-button ' + _TextTrackButton.prototype.buildWrapperCSSClass.call(this);
  3707. };
  3708. /**
  3709. * Create caption menu items
  3710. *
  3711. * @return {CaptionSettingsMenuItem[]}
  3712. * The array of current menu items.
  3713. */
  3714. CaptionsButton.prototype.createItems = function createItems() {
  3715. var items = [];
  3716. if (!(this.player().tech_ && this.player().tech_.featuresNativeTextTracks)) {
  3717. items.push(new _captionSettingsMenuItem2['default'](this.player_, { kind: this.kind_ }));
  3718. this.hideThreshold_ += 1;
  3719. }
  3720. return _TextTrackButton.prototype.createItems.call(this, items);
  3721. };
  3722. return CaptionsButton;
  3723. }(_textTrackButton2['default']);
  3724. /**
  3725. * `kind` of TextTrack to look for to associate it with this menu.
  3726. *
  3727. * @type {string}
  3728. * @private
  3729. */
  3730. CaptionsButton.prototype.kind_ = 'captions';
  3731. /**
  3732. * The text that should display over the `CaptionsButton`s controls. Added for localization.
  3733. *
  3734. * @type {string}
  3735. * @private
  3736. */
  3737. CaptionsButton.prototype.controlText_ = 'Captions';
  3738. _component2['default'].registerComponent('CaptionsButton', CaptionsButton);
  3739. exports['default'] = CaptionsButton;
  3740. },{"23":23,"32":32,"5":5}],25:[function(_dereq_,module,exports){
  3741. 'use strict';
  3742. exports.__esModule = true;
  3743. var _textTrackButton = _dereq_(32);
  3744. var _textTrackButton2 = _interopRequireDefault(_textTrackButton);
  3745. var _component = _dereq_(5);
  3746. var _component2 = _interopRequireDefault(_component);
  3747. var _chaptersTrackMenuItem = _dereq_(26);
  3748. var _chaptersTrackMenuItem2 = _interopRequireDefault(_chaptersTrackMenuItem);
  3749. var _toTitleCase = _dereq_(96);
  3750. var _toTitleCase2 = _interopRequireDefault(_toTitleCase);
  3751. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  3752. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  3753. function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
  3754. function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
  3755. * @file chapters-button.js
  3756. */
  3757. /**
  3758. * The button component for toggling and selecting chapters
  3759. * Chapters act much differently than other text tracks
  3760. * Cues are navigation vs. other tracks of alternative languages
  3761. *
  3762. * @extends TextTrackButton
  3763. */
  3764. var ChaptersButton = function (_TextTrackButton) {
  3765. _inherits(ChaptersButton, _TextTrackButton);
  3766. /**
  3767. * Creates an instance of this class.
  3768. *
  3769. * @param {Player} player
  3770. * The `Player` that this class should be attached to.
  3771. *
  3772. * @param {Object} [options]
  3773. * The key/value store of player options.
  3774. *
  3775. * @param {Component~ReadyCallback} [ready]
  3776. * The function to call when this function is ready.
  3777. */
  3778. function ChaptersButton(player, options, ready) {
  3779. _classCallCheck(this, ChaptersButton);
  3780. return _possibleConstructorReturn(this, _TextTrackButton.call(this, player, options, ready));
  3781. }
  3782. /**
  3783. * Builds the default DOM `className`.
  3784. *
  3785. * @return {string}
  3786. * The DOM `className` for this object.
  3787. */
  3788. ChaptersButton.prototype.buildCSSClass = function buildCSSClass() {
  3789. return 'vjs-chapters-button ' + _TextTrackButton.prototype.buildCSSClass.call(this);
  3790. };
  3791. ChaptersButton.prototype.buildWrapperCSSClass = function buildWrapperCSSClass() {
  3792. return 'vjs-chapters-button ' + _TextTrackButton.prototype.buildWrapperCSSClass.call(this);
  3793. };
  3794. /**
  3795. * Update the menu based on the current state of its items.
  3796. *
  3797. * @param {EventTarget~Event} [event]
  3798. * An event that triggered this function to run.
  3799. *
  3800. * @listens TextTrackList#addtrack
  3801. * @listens TextTrackList#removetrack
  3802. * @listens TextTrackList#change
  3803. */
  3804. ChaptersButton.prototype.update = function update(event) {
  3805. if (!this.track_ || event && (event.type === 'addtrack' || event.type === 'removetrack')) {
  3806. this.setTrack(this.findChaptersTrack());
  3807. }
  3808. _TextTrackButton.prototype.update.call(this);
  3809. };
  3810. /**
  3811. * Set the currently selected track for the chapters button.
  3812. *
  3813. * @param {TextTrack} track
  3814. * The new track to select. Nothing will change if this is the currently selected
  3815. * track.
  3816. */
  3817. ChaptersButton.prototype.setTrack = function setTrack(track) {
  3818. if (this.track_ === track) {
  3819. return;
  3820. }
  3821. if (!this.updateHandler_) {
  3822. this.updateHandler_ = this.update.bind(this);
  3823. }
  3824. // here this.track_ refers to the old track instance
  3825. if (this.track_) {
  3826. var remoteTextTrackEl = this.player_.remoteTextTrackEls().getTrackElementByTrack_(this.track_);
  3827. if (remoteTextTrackEl) {
  3828. remoteTextTrackEl.removeEventListener('load', this.updateHandler_);
  3829. }
  3830. this.track_ = null;
  3831. }
  3832. this.track_ = track;
  3833. // here this.track_ refers to the new track instance
  3834. if (this.track_) {
  3835. this.track_.mode = 'hidden';
  3836. var _remoteTextTrackEl = this.player_.remoteTextTrackEls().getTrackElementByTrack_(this.track_);
  3837. if (_remoteTextTrackEl) {
  3838. _remoteTextTrackEl.addEventListener('load', this.updateHandler_);
  3839. }
  3840. }
  3841. };
  3842. /**
  3843. * Find the track object that is currently in use by this ChaptersButton
  3844. *
  3845. * @return {TextTrack|undefined}
  3846. * The current track or undefined if none was found.
  3847. */
  3848. ChaptersButton.prototype.findChaptersTrack = function findChaptersTrack() {
  3849. var tracks = this.player_.textTracks() || [];
  3850. for (var i = tracks.length - 1; i >= 0; i--) {
  3851. // We will always choose the last track as our chaptersTrack
  3852. var track = tracks[i];
  3853. if (track.kind === this.kind_) {
  3854. return track;
  3855. }
  3856. }
  3857. };
  3858. /**
  3859. * Get the caption for the ChaptersButton based on the track label. This will also
  3860. * use the current tracks localized kind as a fallback if a label does not exist.
  3861. *
  3862. * @return {string}
  3863. * The tracks current label or the localized track kind.
  3864. */
  3865. ChaptersButton.prototype.getMenuCaption = function getMenuCaption() {
  3866. if (this.track_ && this.track_.label) {
  3867. return this.track_.label;
  3868. }
  3869. return this.localize((0, _toTitleCase2['default'])(this.kind_));
  3870. };
  3871. /**
  3872. * Create menu from chapter track
  3873. *
  3874. * @return {Menu}
  3875. * New menu for the chapter buttons
  3876. */
  3877. ChaptersButton.prototype.createMenu = function createMenu() {
  3878. this.options_.title = this.getMenuCaption();
  3879. return _TextTrackButton.prototype.createMenu.call(this);
  3880. };
  3881. /**
  3882. * Create a menu item for each text track
  3883. *
  3884. * @return {TextTrackMenuItem[]}
  3885. * Array of menu items
  3886. */
  3887. ChaptersButton.prototype.createItems = function createItems() {
  3888. var items = [];
  3889. if (!this.track_) {
  3890. return items;
  3891. }
  3892. var cues = this.track_.cues;
  3893. if (!cues) {
  3894. return items;
  3895. }
  3896. for (var i = 0, l = cues.length; i < l; i++) {
  3897. var cue = cues[i];
  3898. var mi = new _chaptersTrackMenuItem2['default'](this.player_, { track: this.track_, cue: cue });
  3899. items.push(mi);
  3900. }
  3901. return items;
  3902. };
  3903. return ChaptersButton;
  3904. }(_textTrackButton2['default']);
  3905. /**
  3906. * `kind` of TextTrack to look for to associate it with this menu.
  3907. *
  3908. * @type {string}
  3909. * @private
  3910. */
  3911. ChaptersButton.prototype.kind_ = 'chapters';
  3912. /**
  3913. * The text that should display over the `ChaptersButton`s controls. Added for localization.
  3914. *
  3915. * @type {string}
  3916. * @private
  3917. */
  3918. ChaptersButton.prototype.controlText_ = 'Chapters';
  3919. _component2['default'].registerComponent('ChaptersButton', ChaptersButton);
  3920. exports['default'] = ChaptersButton;
  3921. },{"26":26,"32":32,"5":5,"96":96}],26:[function(_dereq_,module,exports){
  3922. 'use strict';
  3923. exports.__esModule = true;
  3924. var _menuItem = _dereq_(51);
  3925. var _menuItem2 = _interopRequireDefault(_menuItem);
  3926. var _component = _dereq_(5);
  3927. var _component2 = _interopRequireDefault(_component);
  3928. var _fn = _dereq_(88);
  3929. var Fn = _interopRequireWildcard(_fn);
  3930. function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
  3931. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  3932. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  3933. function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
  3934. function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
  3935. * @file chapters-track-menu-item.js
  3936. */
  3937. /**
  3938. * The chapter track menu item
  3939. *
  3940. * @extends MenuItem
  3941. */
  3942. var ChaptersTrackMenuItem = function (_MenuItem) {
  3943. _inherits(ChaptersTrackMenuItem, _MenuItem);
  3944. /**
  3945. * Creates an instance of this class.
  3946. *
  3947. * @param {Player} player
  3948. * The `Player` that this class should be attached to.
  3949. *
  3950. * @param {Object} [options]
  3951. * The key/value store of player options.
  3952. */
  3953. function ChaptersTrackMenuItem(player, options) {
  3954. _classCallCheck(this, ChaptersTrackMenuItem);
  3955. var track = options.track;
  3956. var cue = options.cue;
  3957. var currentTime = player.currentTime();
  3958. // Modify options for parent MenuItem class's init.
  3959. options.selectable = true;
  3960. options.label = cue.text;
  3961. options.selected = cue.startTime <= currentTime && currentTime < cue.endTime;
  3962. var _this = _possibleConstructorReturn(this, _MenuItem.call(this, player, options));
  3963. _this.track = track;
  3964. _this.cue = cue;
  3965. track.addEventListener('cuechange', Fn.bind(_this, _this.update));
  3966. return _this;
  3967. }
  3968. /**
  3969. * This gets called when an `ChaptersTrackMenuItem` is "clicked". See
  3970. * {@link ClickableComponent} for more detailed information on what a click can be.
  3971. *
  3972. * @param {EventTarget~Event} [event]
  3973. * The `keydown`, `tap`, or `click` event that caused this function to be
  3974. * called.
  3975. *
  3976. * @listens tap
  3977. * @listens click
  3978. */
  3979. ChaptersTrackMenuItem.prototype.handleClick = function handleClick(event) {
  3980. _MenuItem.prototype.handleClick.call(this);
  3981. this.player_.currentTime(this.cue.startTime);
  3982. this.update(this.cue.startTime);
  3983. };
  3984. /**
  3985. * Update chapter menu item
  3986. *
  3987. * @param {EventTarget~Event} [event]
  3988. * The `cuechange` event that caused this function to run.
  3989. *
  3990. * @listens TextTrack#cuechange
  3991. */
  3992. ChaptersTrackMenuItem.prototype.update = function update(event) {
  3993. var cue = this.cue;
  3994. var currentTime = this.player_.currentTime();
  3995. // vjs.log(currentTime, cue.startTime);
  3996. this.selected(cue.startTime <= currentTime && currentTime < cue.endTime);
  3997. };
  3998. return ChaptersTrackMenuItem;
  3999. }(_menuItem2['default']);
  4000. _component2['default'].registerComponent('ChaptersTrackMenuItem', ChaptersTrackMenuItem);
  4001. exports['default'] = ChaptersTrackMenuItem;
  4002. },{"5":5,"51":51,"88":88}],27:[function(_dereq_,module,exports){
  4003. 'use strict';
  4004. exports.__esModule = true;
  4005. var _textTrackButton = _dereq_(32);
  4006. var _textTrackButton2 = _interopRequireDefault(_textTrackButton);
  4007. var _component = _dereq_(5);
  4008. var _component2 = _interopRequireDefault(_component);
  4009. var _fn = _dereq_(88);
  4010. var Fn = _interopRequireWildcard(_fn);
  4011. function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
  4012. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  4013. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  4014. function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
  4015. function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
  4016. * @file descriptions-button.js
  4017. */
  4018. /**
  4019. * The button component for toggling and selecting descriptions
  4020. *
  4021. * @extends TextTrackButton
  4022. */
  4023. var DescriptionsButton = function (_TextTrackButton) {
  4024. _inherits(DescriptionsButton, _TextTrackButton);
  4025. /**
  4026. * Creates an instance of this class.
  4027. *
  4028. * @param {Player} player
  4029. * The `Player` that this class should be attached to.
  4030. *
  4031. * @param {Object} [options]
  4032. * The key/value store of player options.
  4033. *
  4034. * @param {Component~ReadyCallback} [ready]
  4035. * The function to call when this component is ready.
  4036. */
  4037. function DescriptionsButton(player, options, ready) {
  4038. _classCallCheck(this, DescriptionsButton);
  4039. var _this = _possibleConstructorReturn(this, _TextTrackButton.call(this, player, options, ready));
  4040. var tracks = player.textTracks();
  4041. var changeHandler = Fn.bind(_this, _this.handleTracksChange);
  4042. tracks.addEventListener('change', changeHandler);
  4043. _this.on('dispose', function () {
  4044. tracks.removeEventListener('change', changeHandler);
  4045. });
  4046. return _this;
  4047. }
  4048. /**
  4049. * Handle text track change
  4050. *
  4051. * @param {EventTarget~Event} event
  4052. * The event that caused this function to run
  4053. *
  4054. * @listens TextTrackList#change
  4055. */
  4056. DescriptionsButton.prototype.handleTracksChange = function handleTracksChange(event) {
  4057. var tracks = this.player().textTracks();
  4058. var disabled = false;
  4059. // Check whether a track of a different kind is showing
  4060. for (var i = 0, l = tracks.length; i < l; i++) {
  4061. var track = tracks[i];
  4062. if (track.kind !== this.kind_ && track.mode === 'showing') {
  4063. disabled = true;
  4064. break;
  4065. }
  4066. }
  4067. // If another track is showing, disable this menu button
  4068. if (disabled) {
  4069. this.disable();
  4070. } else {
  4071. this.enable();
  4072. }
  4073. };
  4074. /**
  4075. * Builds the default DOM `className`.
  4076. *
  4077. * @return {string}
  4078. * The DOM `className` for this object.
  4079. */
  4080. DescriptionsButton.prototype.buildCSSClass = function buildCSSClass() {
  4081. return 'vjs-descriptions-button ' + _TextTrackButton.prototype.buildCSSClass.call(this);
  4082. };
  4083. DescriptionsButton.prototype.buildWrapperCSSClass = function buildWrapperCSSClass() {
  4084. return 'vjs-descriptions-button ' + _TextTrackButton.prototype.buildWrapperCSSClass.call(this);
  4085. };
  4086. return DescriptionsButton;
  4087. }(_textTrackButton2['default']);
  4088. /**
  4089. * `kind` of TextTrack to look for to associate it with this menu.
  4090. *
  4091. * @type {string}
  4092. * @private
  4093. */
  4094. DescriptionsButton.prototype.kind_ = 'descriptions';
  4095. /**
  4096. * The text that should display over the `DescriptionsButton`s controls. Added for localization.
  4097. *
  4098. * @type {string}
  4099. * @private
  4100. */
  4101. DescriptionsButton.prototype.controlText_ = 'Descriptions';
  4102. _component2['default'].registerComponent('DescriptionsButton', DescriptionsButton);
  4103. exports['default'] = DescriptionsButton;
  4104. },{"32":32,"5":5,"88":88}],28:[function(_dereq_,module,exports){
  4105. 'use strict';
  4106. exports.__esModule = true;
  4107. var _textTrackMenuItem = _dereq_(33);
  4108. var _textTrackMenuItem2 = _interopRequireDefault(_textTrackMenuItem);
  4109. var _component = _dereq_(5);
  4110. var _component2 = _interopRequireDefault(_component);
  4111. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  4112. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  4113. function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
  4114. function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
  4115. * @file off-text-track-menu-item.js
  4116. */
  4117. /**
  4118. * A special menu item for turning of a specific type of text track
  4119. *
  4120. * @extends TextTrackMenuItem
  4121. */
  4122. var OffTextTrackMenuItem = function (_TextTrackMenuItem) {
  4123. _inherits(OffTextTrackMenuItem, _TextTrackMenuItem);
  4124. /**
  4125. * Creates an instance of this class.
  4126. *
  4127. * @param {Player} player
  4128. * The `Player` that this class should be attached to.
  4129. *
  4130. * @param {Object} [options]
  4131. * The key/value store of player options.
  4132. */
  4133. function OffTextTrackMenuItem(player, options) {
  4134. _classCallCheck(this, OffTextTrackMenuItem);
  4135. // Create pseudo track info
  4136. // Requires options['kind']
  4137. options.track = {
  4138. player: player,
  4139. kind: options.kind,
  4140. kinds: options.kinds,
  4141. 'default': false,
  4142. mode: 'disabled'
  4143. };
  4144. if (!options.kinds) {
  4145. options.kinds = [options.kind];
  4146. }
  4147. if (options.label) {
  4148. options.track.label = options.label;
  4149. } else {
  4150. options.track.label = options.kinds.join(' and ') + ' off';
  4151. }
  4152. // MenuItem is selectable
  4153. options.selectable = true;
  4154. var _this = _possibleConstructorReturn(this, _TextTrackMenuItem.call(this, player, options));
  4155. _this.selected(true);
  4156. return _this;
  4157. }
  4158. /**
  4159. * Handle text track change
  4160. *
  4161. * @param {EventTarget~Event} event
  4162. * The event that caused this function to run
  4163. */
  4164. OffTextTrackMenuItem.prototype.handleTracksChange = function handleTracksChange(event) {
  4165. var tracks = this.player().textTracks();
  4166. var selected = true;
  4167. for (var i = 0, l = tracks.length; i < l; i++) {
  4168. var track = tracks[i];
  4169. if (this.options_.kinds.indexOf(track.kind) > -1 && track.mode === 'showing') {
  4170. selected = false;
  4171. break;
  4172. }
  4173. }
  4174. this.selected(selected);
  4175. };
  4176. return OffTextTrackMenuItem;
  4177. }(_textTrackMenuItem2['default']);
  4178. _component2['default'].registerComponent('OffTextTrackMenuItem', OffTextTrackMenuItem);
  4179. exports['default'] = OffTextTrackMenuItem;
  4180. },{"33":33,"5":5}],29:[function(_dereq_,module,exports){
  4181. 'use strict';
  4182. exports.__esModule = true;
  4183. var _textTrackButton = _dereq_(32);
  4184. var _textTrackButton2 = _interopRequireDefault(_textTrackButton);
  4185. var _component = _dereq_(5);
  4186. var _component2 = _interopRequireDefault(_component);
  4187. var _captionSettingsMenuItem = _dereq_(23);
  4188. var _captionSettingsMenuItem2 = _interopRequireDefault(_captionSettingsMenuItem);
  4189. var _subsCapsMenuItem = _dereq_(30);
  4190. var _subsCapsMenuItem2 = _interopRequireDefault(_subsCapsMenuItem);
  4191. var _toTitleCase = _dereq_(96);
  4192. var _toTitleCase2 = _interopRequireDefault(_toTitleCase);
  4193. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  4194. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  4195. function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
  4196. function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
  4197. * @file sub-caps-button.js
  4198. */
  4199. /**
  4200. * The button component for toggling and selecting captions and/or subtitles
  4201. *
  4202. * @extends TextTrackButton
  4203. */
  4204. var SubsCapsButton = function (_TextTrackButton) {
  4205. _inherits(SubsCapsButton, _TextTrackButton);
  4206. function SubsCapsButton(player) {
  4207. var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  4208. _classCallCheck(this, SubsCapsButton);
  4209. // Although North America uses "captions" in most cases for
  4210. // "captions and subtitles" other locales use "subtitles"
  4211. var _this = _possibleConstructorReturn(this, _TextTrackButton.call(this, player, options));
  4212. _this.label_ = 'subtitles';
  4213. if (['en', 'en-us', 'en-ca', 'fr-ca'].indexOf(_this.player_.language_) > -1) {
  4214. _this.label_ = 'captions';
  4215. }
  4216. _this.menuButton_.controlText((0, _toTitleCase2['default'])(_this.label_));
  4217. return _this;
  4218. }
  4219. /**
  4220. * Builds the default DOM `className`.
  4221. *
  4222. * @return {string}
  4223. * The DOM `className` for this object.
  4224. */
  4225. SubsCapsButton.prototype.buildCSSClass = function buildCSSClass() {
  4226. return 'vjs-subs-caps-button ' + _TextTrackButton.prototype.buildCSSClass.call(this);
  4227. };
  4228. SubsCapsButton.prototype.buildWrapperCSSClass = function buildWrapperCSSClass() {
  4229. return 'vjs-subs-caps-button ' + _TextTrackButton.prototype.buildWrapperCSSClass.call(this);
  4230. };
  4231. /**
  4232. * Create caption/subtitles menu items
  4233. *
  4234. * @return {CaptionSettingsMenuItem[]}
  4235. * The array of current menu items.
  4236. */
  4237. SubsCapsButton.prototype.createItems = function createItems() {
  4238. var items = [];
  4239. if (!(this.player().tech_ && this.player().tech_.featuresNativeTextTracks)) {
  4240. items.push(new _captionSettingsMenuItem2['default'](this.player_, { kind: this.label_ }));
  4241. this.hideThreshold_ += 1;
  4242. }
  4243. items = _TextTrackButton.prototype.createItems.call(this, items, _subsCapsMenuItem2['default']);
  4244. return items;
  4245. };
  4246. return SubsCapsButton;
  4247. }(_textTrackButton2['default']);
  4248. /**
  4249. * `kind`s of TextTrack to look for to associate it with this menu.
  4250. *
  4251. * @type {array}
  4252. * @private
  4253. */
  4254. SubsCapsButton.prototype.kinds_ = ['captions', 'subtitles'];
  4255. /**
  4256. * The text that should display over the `SubsCapsButton`s controls.
  4257. *
  4258. *
  4259. * @type {string}
  4260. * @private
  4261. */
  4262. SubsCapsButton.prototype.controlText_ = 'Subtitles';
  4263. _component2['default'].registerComponent('SubsCapsButton', SubsCapsButton);
  4264. exports['default'] = SubsCapsButton;
  4265. },{"23":23,"30":30,"32":32,"5":5,"96":96}],30:[function(_dereq_,module,exports){
  4266. 'use strict';
  4267. exports.__esModule = true;
  4268. var _textTrackMenuItem = _dereq_(33);
  4269. var _textTrackMenuItem2 = _interopRequireDefault(_textTrackMenuItem);
  4270. var _component = _dereq_(5);
  4271. var _component2 = _interopRequireDefault(_component);
  4272. var _obj = _dereq_(93);
  4273. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  4274. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  4275. function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
  4276. function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
  4277. * @file subs-caps-menu-item.js
  4278. */
  4279. /**
  4280. * SubsCapsMenuItem has an [cc] icon to distinguish captions from subtitles
  4281. * in the SubsCapsMenu.
  4282. *
  4283. * @extends TextTrackMenuItem
  4284. */
  4285. var SubsCapsMenuItem = function (_TextTrackMenuItem) {
  4286. _inherits(SubsCapsMenuItem, _TextTrackMenuItem);
  4287. function SubsCapsMenuItem() {
  4288. _classCallCheck(this, SubsCapsMenuItem);
  4289. return _possibleConstructorReturn(this, _TextTrackMenuItem.apply(this, arguments));
  4290. }
  4291. SubsCapsMenuItem.prototype.createEl = function createEl(type, props, attrs) {
  4292. var innerHTML = '<span class="vjs-menu-item-text">' + this.localize(this.options_.label);
  4293. if (this.options_.track.kind === 'captions') {
  4294. innerHTML += '\n <span aria-hidden="true" class="vjs-icon-placeholder"></span>\n <span class="vjs-control-text"> ' + this.localize('Captions') + '</span>\n ';
  4295. }
  4296. innerHTML += '</span>';
  4297. var el = _TextTrackMenuItem.prototype.createEl.call(this, type, (0, _obj.assign)({
  4298. innerHTML: innerHTML
  4299. }, props), attrs);
  4300. return el;
  4301. };
  4302. return SubsCapsMenuItem;
  4303. }(_textTrackMenuItem2['default']);
  4304. _component2['default'].registerComponent('SubsCapsMenuItem', SubsCapsMenuItem);
  4305. exports['default'] = SubsCapsMenuItem;
  4306. },{"33":33,"5":5,"93":93}],31:[function(_dereq_,module,exports){
  4307. 'use strict';
  4308. exports.__esModule = true;
  4309. var _textTrackButton = _dereq_(32);
  4310. var _textTrackButton2 = _interopRequireDefault(_textTrackButton);
  4311. var _component = _dereq_(5);
  4312. var _component2 = _interopRequireDefault(_component);
  4313. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  4314. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  4315. function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
  4316. function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
  4317. * @file subtitles-button.js
  4318. */
  4319. /**
  4320. * The button component for toggling and selecting subtitles
  4321. *
  4322. * @extends TextTrackButton
  4323. */
  4324. var SubtitlesButton = function (_TextTrackButton) {
  4325. _inherits(SubtitlesButton, _TextTrackButton);
  4326. /**
  4327. * Creates an instance of this class.
  4328. *
  4329. * @param {Player} player
  4330. * The `Player` that this class should be attached to.
  4331. *
  4332. * @param {Object} [options]
  4333. * The key/value store of player options.
  4334. *
  4335. * @param {Component~ReadyCallback} [ready]
  4336. * The function to call when this component is ready.
  4337. */
  4338. function SubtitlesButton(player, options, ready) {
  4339. _classCallCheck(this, SubtitlesButton);
  4340. return _possibleConstructorReturn(this, _TextTrackButton.call(this, player, options, ready));
  4341. }
  4342. /**
  4343. * Builds the default DOM `className`.
  4344. *
  4345. * @return {string}
  4346. * The DOM `className` for this object.
  4347. */
  4348. SubtitlesButton.prototype.buildCSSClass = function buildCSSClass() {
  4349. return 'vjs-subtitles-button ' + _TextTrackButton.prototype.buildCSSClass.call(this);
  4350. };
  4351. SubtitlesButton.prototype.buildWrapperCSSClass = function buildWrapperCSSClass() {
  4352. return 'vjs-subtitles-button ' + _TextTrackButton.prototype.buildWrapperCSSClass.call(this);
  4353. };
  4354. return SubtitlesButton;
  4355. }(_textTrackButton2['default']);
  4356. /**
  4357. * `kind` of TextTrack to look for to associate it with this menu.
  4358. *
  4359. * @type {string}
  4360. * @private
  4361. */
  4362. SubtitlesButton.prototype.kind_ = 'subtitles';
  4363. /**
  4364. * The text that should display over the `SubtitlesButton`s controls. Added for localization.
  4365. *
  4366. * @type {string}
  4367. * @private
  4368. */
  4369. SubtitlesButton.prototype.controlText_ = 'Subtitles';
  4370. _component2['default'].registerComponent('SubtitlesButton', SubtitlesButton);
  4371. exports['default'] = SubtitlesButton;
  4372. },{"32":32,"5":5}],32:[function(_dereq_,module,exports){
  4373. 'use strict';
  4374. exports.__esModule = true;
  4375. var _trackButton = _dereq_(38);
  4376. var _trackButton2 = _interopRequireDefault(_trackButton);
  4377. var _component = _dereq_(5);
  4378. var _component2 = _interopRequireDefault(_component);
  4379. var _textTrackMenuItem = _dereq_(33);
  4380. var _textTrackMenuItem2 = _interopRequireDefault(_textTrackMenuItem);
  4381. var _offTextTrackMenuItem = _dereq_(28);
  4382. var _offTextTrackMenuItem2 = _interopRequireDefault(_offTextTrackMenuItem);
  4383. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  4384. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  4385. function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
  4386. function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
  4387. * @file text-track-button.js
  4388. */
  4389. /**
  4390. * The base class for buttons that toggle specific text track types (e.g. subtitles)
  4391. *
  4392. * @extends MenuButton
  4393. */
  4394. var TextTrackButton = function (_TrackButton) {
  4395. _inherits(TextTrackButton, _TrackButton);
  4396. /**
  4397. * Creates an instance of this class.
  4398. *
  4399. * @param {Player} player
  4400. * The `Player` that this class should be attached to.
  4401. *
  4402. * @param {Object} [options={}]
  4403. * The key/value store of player options.
  4404. */
  4405. function TextTrackButton(player) {
  4406. var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  4407. _classCallCheck(this, TextTrackButton);
  4408. options.tracks = player.textTracks();
  4409. var _this = _possibleConstructorReturn(this, _TrackButton.call(this, player, options));
  4410. if (!Array.isArray(_this.kinds_)) {
  4411. _this.kinds_ = [_this.kind_];
  4412. }
  4413. return _this;
  4414. }
  4415. /**
  4416. * Create a menu item for each text track
  4417. *
  4418. * @param {TextTrackMenuItem[]} [items=[]]
  4419. * Existing array of items to use during creation
  4420. *
  4421. * @return {TextTrackMenuItem[]}
  4422. * Array of menu items that were created
  4423. */
  4424. TextTrackButton.prototype.createItems = function createItems() {
  4425. var items = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
  4426. var TrackMenuItem = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _textTrackMenuItem2['default'];
  4427. // Label is an overide for the [track] off label
  4428. // USed to localise captions/subtitles
  4429. var label = void 0;
  4430. if (this.label_) {
  4431. label = this.label_ + ' off';
  4432. }
  4433. // Add an OFF menu item to turn all tracks off
  4434. items.push(new _offTextTrackMenuItem2['default'](this.player_, {
  4435. kinds: this.kinds_,
  4436. kind: this.kind_,
  4437. label: label
  4438. }));
  4439. this.hideThreshold_ += 1;
  4440. var tracks = this.player_.textTracks();
  4441. for (var i = 0; i < tracks.length; i++) {
  4442. var track = tracks[i];
  4443. // only add tracks that are of an appropriate kind and have a label
  4444. if (this.kinds_.indexOf(track.kind) > -1) {
  4445. var item = new TrackMenuItem(this.player_, {
  4446. track: track,
  4447. // MenuItem is selectable
  4448. selectable: true
  4449. });
  4450. item.addClass('vjs-' + track.kind + '-menu-item');
  4451. items.push(item);
  4452. }
  4453. }
  4454. return items;
  4455. };
  4456. return TextTrackButton;
  4457. }(_trackButton2['default']);
  4458. _component2['default'].registerComponent('TextTrackButton', TextTrackButton);
  4459. exports['default'] = TextTrackButton;
  4460. },{"28":28,"33":33,"38":38,"5":5}],33:[function(_dereq_,module,exports){
  4461. 'use strict';
  4462. exports.__esModule = true;
  4463. var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
  4464. var _menuItem = _dereq_(51);
  4465. var _menuItem2 = _interopRequireDefault(_menuItem);
  4466. var _component = _dereq_(5);
  4467. var _component2 = _interopRequireDefault(_component);
  4468. var _fn = _dereq_(88);
  4469. var Fn = _interopRequireWildcard(_fn);
  4470. var _window = _dereq_(100);
  4471. var _window2 = _interopRequireDefault(_window);
  4472. var _document = _dereq_(99);
  4473. var _document2 = _interopRequireDefault(_document);
  4474. function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
  4475. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  4476. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  4477. function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
  4478. function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
  4479. * @file text-track-menu-item.js
  4480. */
  4481. /**
  4482. * The specific menu item type for selecting a language within a text track kind
  4483. *
  4484. * @extends MenuItem
  4485. */
  4486. var TextTrackMenuItem = function (_MenuItem) {
  4487. _inherits(TextTrackMenuItem, _MenuItem);
  4488. /**
  4489. * Creates an instance of this class.
  4490. *
  4491. * @param {Player} player
  4492. * The `Player` that this class should be attached to.
  4493. *
  4494. * @param {Object} [options]
  4495. * The key/value store of player options.
  4496. */
  4497. function TextTrackMenuItem(player, options) {
  4498. _classCallCheck(this, TextTrackMenuItem);
  4499. var track = options.track;
  4500. var tracks = player.textTracks();
  4501. // Modify options for parent MenuItem class's init.
  4502. options.label = track.label || track.language || 'Unknown';
  4503. options.selected = track['default'] || track.mode === 'showing';
  4504. var _this = _possibleConstructorReturn(this, _MenuItem.call(this, player, options));
  4505. _this.track = track;
  4506. var changeHandler = Fn.bind(_this, _this.handleTracksChange);
  4507. tracks.addEventListener('change', changeHandler);
  4508. _this.on('dispose', function () {
  4509. tracks.removeEventListener('change', changeHandler);
  4510. });
  4511. // iOS7 doesn't dispatch change events to TextTrackLists when an
  4512. // associated track's mode changes. Without something like
  4513. // Object.observe() (also not present on iOS7), it's not
  4514. // possible to detect changes to the mode attribute and polyfill
  4515. // the change event. As a poor substitute, we manually dispatch
  4516. // change events whenever the controls modify the mode.
  4517. if (tracks.onchange === undefined) {
  4518. var event = void 0;
  4519. _this.on(['tap', 'click'], function () {
  4520. if (_typeof(_window2['default'].Event) !== 'object') {
  4521. // Android 2.3 throws an Illegal Constructor error for window.Event
  4522. try {
  4523. event = new _window2['default'].Event('change');
  4524. } catch (err) {
  4525. // continue regardless of error
  4526. }
  4527. }
  4528. if (!event) {
  4529. event = _document2['default'].createEvent('Event');
  4530. event.initEvent('change', true, true);
  4531. }
  4532. tracks.dispatchEvent(event);
  4533. });
  4534. }
  4535. return _this;
  4536. }
  4537. /**
  4538. * This gets called when an `TextTrackMenuItem` is "clicked". See
  4539. * {@link ClickableComponent} for more detailed information on what a click can be.
  4540. *
  4541. * @param {EventTarget~Event} event
  4542. * The `keydown`, `tap`, or `click` event that caused this function to be
  4543. * called.
  4544. *
  4545. * @listens tap
  4546. * @listens click
  4547. */
  4548. TextTrackMenuItem.prototype.handleClick = function handleClick(event) {
  4549. var kind = this.track.kind;
  4550. var kinds = this.track.kinds;
  4551. var tracks = this.player_.textTracks();
  4552. if (!kinds) {
  4553. kinds = [kind];
  4554. }
  4555. _MenuItem.prototype.handleClick.call(this, event);
  4556. if (!tracks) {
  4557. return;
  4558. }
  4559. for (var i = 0; i < tracks.length; i++) {
  4560. var track = tracks[i];
  4561. if (track === this.track && kinds.indexOf(track.kind) > -1) {
  4562. track.mode = 'showing';
  4563. } else {
  4564. track.mode = 'disabled';
  4565. }
  4566. }
  4567. };
  4568. /**
  4569. * Handle text track list change
  4570. *
  4571. * @param {EventTarget~Event} event
  4572. * The `change` event that caused this function to be called.
  4573. *
  4574. * @listens TextTrackList#change
  4575. */
  4576. TextTrackMenuItem.prototype.handleTracksChange = function handleTracksChange(event) {
  4577. this.selected(this.track.mode === 'showing');
  4578. };
  4579. return TextTrackMenuItem;
  4580. }(_menuItem2['default']);
  4581. _component2['default'].registerComponent('TextTrackMenuItem', TextTrackMenuItem);
  4582. exports['default'] = TextTrackMenuItem;
  4583. },{"100":100,"5":5,"51":51,"88":88,"99":99}],34:[function(_dereq_,module,exports){
  4584. 'use strict';
  4585. exports.__esModule = true;
  4586. var _component = _dereq_(5);
  4587. var _component2 = _interopRequireDefault(_component);
  4588. var _dom = _dereq_(85);
  4589. var Dom = _interopRequireWildcard(_dom);
  4590. var _formatTime = _dereq_(89);
  4591. var _formatTime2 = _interopRequireDefault(_formatTime);
  4592. function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
  4593. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  4594. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  4595. function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
  4596. function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
  4597. * @file current-time-display.js
  4598. */
  4599. /**
  4600. * Displays the current time
  4601. *
  4602. * @extends Component
  4603. */
  4604. var CurrentTimeDisplay = function (_Component) {
  4605. _inherits(CurrentTimeDisplay, _Component);
  4606. /**
  4607. * Creates an instance of this class.
  4608. *
  4609. * @param {Player} player
  4610. * The `Player` that this class should be attached to.
  4611. *
  4612. * @param {Object} [options]
  4613. * The key/value store of player options.
  4614. */
  4615. function CurrentTimeDisplay(player, options) {
  4616. _classCallCheck(this, CurrentTimeDisplay);
  4617. var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
  4618. _this.on(player, 'timeupdate', _this.updateContent);
  4619. return _this;
  4620. }
  4621. /**
  4622. * Create the `Component`'s DOM element
  4623. *
  4624. * @return {Element}
  4625. * The element that was created.
  4626. */
  4627. CurrentTimeDisplay.prototype.createEl = function createEl() {
  4628. var el = _Component.prototype.createEl.call(this, 'div', {
  4629. className: 'vjs-current-time vjs-time-control vjs-control'
  4630. });
  4631. this.contentEl_ = Dom.createEl('div', {
  4632. className: 'vjs-current-time-display',
  4633. // label the current time for screen reader users
  4634. innerHTML: '<span class="vjs-control-text">Current Time </span>' + '0:00'
  4635. }, {
  4636. // tell screen readers not to automatically read the time as it changes
  4637. 'aria-live': 'off'
  4638. });
  4639. el.appendChild(this.contentEl_);
  4640. return el;
  4641. };
  4642. /**
  4643. * Update current time display
  4644. *
  4645. * @param {EventTarget~Event} [event]
  4646. * The `timeupdate` event that caused this function to run.
  4647. *
  4648. * @listens Player#timeupdate
  4649. */
  4650. CurrentTimeDisplay.prototype.updateContent = function updateContent(event) {
  4651. // Allows for smooth scrubbing, when player can't keep up.
  4652. var time = this.player_.scrubbing() ? this.player_.getCache().currentTime : this.player_.currentTime();
  4653. var localizedText = this.localize('Current Time');
  4654. var formattedTime = (0, _formatTime2['default'])(time, this.player_.duration());
  4655. if (formattedTime !== this.formattedTime_) {
  4656. this.formattedTime_ = formattedTime;
  4657. this.contentEl_.innerHTML = '<span class="vjs-control-text">' + localizedText + '</span> ' + formattedTime;
  4658. }
  4659. };
  4660. return CurrentTimeDisplay;
  4661. }(_component2['default']);
  4662. _component2['default'].registerComponent('CurrentTimeDisplay', CurrentTimeDisplay);
  4663. exports['default'] = CurrentTimeDisplay;
  4664. },{"5":5,"85":85,"89":89}],35:[function(_dereq_,module,exports){
  4665. 'use strict';
  4666. exports.__esModule = true;
  4667. var _component = _dereq_(5);
  4668. var _component2 = _interopRequireDefault(_component);
  4669. var _dom = _dereq_(85);
  4670. var Dom = _interopRequireWildcard(_dom);
  4671. var _formatTime = _dereq_(89);
  4672. var _formatTime2 = _interopRequireDefault(_formatTime);
  4673. function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
  4674. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  4675. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  4676. function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
  4677. function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
  4678. * @file duration-display.js
  4679. */
  4680. /**
  4681. * Displays the duration
  4682. *
  4683. * @extends Component
  4684. */
  4685. var DurationDisplay = function (_Component) {
  4686. _inherits(DurationDisplay, _Component);
  4687. /**
  4688. * Creates an instance of this class.
  4689. *
  4690. * @param {Player} player
  4691. * The `Player` that this class should be attached to.
  4692. *
  4693. * @param {Object} [options]
  4694. * The key/value store of player options.
  4695. */
  4696. function DurationDisplay(player, options) {
  4697. _classCallCheck(this, DurationDisplay);
  4698. var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
  4699. _this.on(player, 'durationchange', _this.updateContent);
  4700. // Also listen for timeupdate and loadedmetadata because removing those
  4701. // listeners could have broken dependent applications/libraries. These
  4702. // can likely be removed for 6.0.
  4703. _this.on(player, 'timeupdate', _this.updateContent);
  4704. _this.on(player, 'loadedmetadata', _this.updateContent);
  4705. return _this;
  4706. }
  4707. /**
  4708. * Create the `Component`'s DOM element
  4709. *
  4710. * @return {Element}
  4711. * The element that was created.
  4712. */
  4713. DurationDisplay.prototype.createEl = function createEl() {
  4714. var el = _Component.prototype.createEl.call(this, 'div', {
  4715. className: 'vjs-duration vjs-time-control vjs-control'
  4716. });
  4717. this.contentEl_ = Dom.createEl('div', {
  4718. className: 'vjs-duration-display',
  4719. // label the duration time for screen reader users
  4720. innerHTML: '<span class="vjs-control-text">' + this.localize('Duration Time') + '</span> 0:00'
  4721. }, {
  4722. // tell screen readers not to automatically read the time as it changes
  4723. 'aria-live': 'off'
  4724. });
  4725. el.appendChild(this.contentEl_);
  4726. return el;
  4727. };
  4728. /**
  4729. * Update duration time display.
  4730. *
  4731. * @param {EventTarget~Event} [event]
  4732. * The `durationchange`, `timeupdate`, or `loadedmetadata` event that caused
  4733. * this function to be called.
  4734. *
  4735. * @listens Player#durationchange
  4736. * @listens Player#timeupdate
  4737. * @listens Player#loadedmetadata
  4738. */
  4739. DurationDisplay.prototype.updateContent = function updateContent(event) {
  4740. var duration = this.player_.duration();
  4741. if (duration && this.duration_ !== duration) {
  4742. this.duration_ = duration;
  4743. var localizedText = this.localize('Duration Time');
  4744. var formattedTime = (0, _formatTime2['default'])(duration);
  4745. // label the duration time for screen reader users
  4746. this.contentEl_.innerHTML = '<span class="vjs-control-text">' + localizedText + '</span> ' + formattedTime;
  4747. }
  4748. };
  4749. return DurationDisplay;
  4750. }(_component2['default']);
  4751. _component2['default'].registerComponent('DurationDisplay', DurationDisplay);
  4752. exports['default'] = DurationDisplay;
  4753. },{"5":5,"85":85,"89":89}],36:[function(_dereq_,module,exports){
  4754. 'use strict';
  4755. exports.__esModule = true;
  4756. var _component = _dereq_(5);
  4757. var _component2 = _interopRequireDefault(_component);
  4758. var _dom = _dereq_(85);
  4759. var Dom = _interopRequireWildcard(_dom);
  4760. var _formatTime = _dereq_(89);
  4761. var _formatTime2 = _interopRequireDefault(_formatTime);
  4762. function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
  4763. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  4764. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  4765. function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
  4766. function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
  4767. * @file remaining-time-display.js
  4768. */
  4769. /**
  4770. * Displays the time left in the video
  4771. *
  4772. * @extends Component
  4773. */
  4774. var RemainingTimeDisplay = function (_Component) {
  4775. _inherits(RemainingTimeDisplay, _Component);
  4776. /**
  4777. * Creates an instance of this class.
  4778. *
  4779. * @param {Player} player
  4780. * The `Player` that this class should be attached to.
  4781. *
  4782. * @param {Object} [options]
  4783. * The key/value store of player options.
  4784. */
  4785. function RemainingTimeDisplay(player, options) {
  4786. _classCallCheck(this, RemainingTimeDisplay);
  4787. var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
  4788. _this.on(player, 'timeupdate', _this.updateContent);
  4789. _this.on(player, 'durationchange', _this.updateContent);
  4790. return _this;
  4791. }
  4792. /**
  4793. * Create the `Component`'s DOM element
  4794. *
  4795. * @return {Element}
  4796. * The element that was created.
  4797. */
  4798. RemainingTimeDisplay.prototype.createEl = function createEl() {
  4799. var el = _Component.prototype.createEl.call(this, 'div', {
  4800. className: 'vjs-remaining-time vjs-time-control vjs-control'
  4801. });
  4802. this.contentEl_ = Dom.createEl('div', {
  4803. className: 'vjs-remaining-time-display',
  4804. // label the remaining time for screen reader users
  4805. innerHTML: '<span class="vjs-control-text">' + this.localize('Remaining Time') + '</span> -0:00'
  4806. }, {
  4807. // tell screen readers not to automatically read the time as it changes
  4808. 'aria-live': 'off'
  4809. });
  4810. el.appendChild(this.contentEl_);
  4811. return el;
  4812. };
  4813. /**
  4814. * Update remaining time display.
  4815. *
  4816. * @param {EventTarget~Event} [event]
  4817. * The `timeupdate` or `durationchange` event that caused this to run.
  4818. *
  4819. * @listens Player#timeupdate
  4820. * @listens Player#durationchange
  4821. */
  4822. RemainingTimeDisplay.prototype.updateContent = function updateContent(event) {
  4823. if (this.player_.duration()) {
  4824. var localizedText = this.localize('Remaining Time');
  4825. var formattedTime = (0, _formatTime2['default'])(this.player_.remainingTime());
  4826. if (formattedTime !== this.formattedTime_) {
  4827. this.formattedTime_ = formattedTime;
  4828. this.contentEl_.innerHTML = '<span class="vjs-control-text">' + localizedText + '</span> -' + formattedTime;
  4829. }
  4830. }
  4831. // Allows for smooth scrubbing, when player can't keep up.
  4832. // var time = (this.player_.scrubbing()) ? this.player_.getCache().currentTime : this.player_.currentTime();
  4833. // this.contentEl_.innerHTML = vjs.formatTime(time, this.player_.duration());
  4834. };
  4835. return RemainingTimeDisplay;
  4836. }(_component2['default']);
  4837. _component2['default'].registerComponent('RemainingTimeDisplay', RemainingTimeDisplay);
  4838. exports['default'] = RemainingTimeDisplay;
  4839. },{"5":5,"85":85,"89":89}],37:[function(_dereq_,module,exports){
  4840. 'use strict';
  4841. exports.__esModule = true;
  4842. var _component = _dereq_(5);
  4843. var _component2 = _interopRequireDefault(_component);
  4844. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  4845. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  4846. function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
  4847. function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
  4848. * @file time-divider.js
  4849. */
  4850. /**
  4851. * The separator between the current time and duration.
  4852. * Can be hidden if it's not needed in the design.
  4853. *
  4854. * @extends Component
  4855. */
  4856. var TimeDivider = function (_Component) {
  4857. _inherits(TimeDivider, _Component);
  4858. function TimeDivider() {
  4859. _classCallCheck(this, TimeDivider);
  4860. return _possibleConstructorReturn(this, _Component.apply(this, arguments));
  4861. }
  4862. /**
  4863. * Create the component's DOM element
  4864. *
  4865. * @return {Element}
  4866. * The element that was created.
  4867. */
  4868. TimeDivider.prototype.createEl = function createEl() {
  4869. return _Component.prototype.createEl.call(this, 'div', {
  4870. className: 'vjs-time-control vjs-time-divider',
  4871. innerHTML: '<div><span>/</span></div>'
  4872. });
  4873. };
  4874. return TimeDivider;
  4875. }(_component2['default']);
  4876. _component2['default'].registerComponent('TimeDivider', TimeDivider);
  4877. exports['default'] = TimeDivider;
  4878. },{"5":5}],38:[function(_dereq_,module,exports){
  4879. 'use strict';
  4880. exports.__esModule = true;
  4881. var _menuButton = _dereq_(50);
  4882. var _menuButton2 = _interopRequireDefault(_menuButton);
  4883. var _component = _dereq_(5);
  4884. var _component2 = _interopRequireDefault(_component);
  4885. var _fn = _dereq_(88);
  4886. var Fn = _interopRequireWildcard(_fn);
  4887. function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
  4888. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  4889. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  4890. function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
  4891. function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
  4892. * @file track-button.js
  4893. */
  4894. /**
  4895. * The base class for buttons that toggle specific track types (e.g. subtitles).
  4896. *
  4897. * @extends MenuButton
  4898. */
  4899. var TrackButton = function (_MenuButton) {
  4900. _inherits(TrackButton, _MenuButton);
  4901. /**
  4902. * Creates an instance of this class.
  4903. *
  4904. * @param {Player} player
  4905. * The `Player` that this class should be attached to.
  4906. *
  4907. * @param {Object} [options]
  4908. * The key/value store of player options.
  4909. */
  4910. function TrackButton(player, options) {
  4911. _classCallCheck(this, TrackButton);
  4912. var tracks = options.tracks;
  4913. var _this = _possibleConstructorReturn(this, _MenuButton.call(this, player, options));
  4914. if (_this.items.length <= 1) {
  4915. _this.hide();
  4916. }
  4917. if (!tracks) {
  4918. return _possibleConstructorReturn(_this);
  4919. }
  4920. var updateHandler = Fn.bind(_this, _this.update);
  4921. tracks.addEventListener('removetrack', updateHandler);
  4922. tracks.addEventListener('addtrack', updateHandler);
  4923. _this.player_.on('ready', updateHandler);
  4924. _this.player_.on('dispose', function () {
  4925. tracks.removeEventListener('removetrack', updateHandler);
  4926. tracks.removeEventListener('addtrack', updateHandler);
  4927. });
  4928. return _this;
  4929. }
  4930. return TrackButton;
  4931. }(_menuButton2['default']);
  4932. _component2['default'].registerComponent('TrackButton', TrackButton);
  4933. exports['default'] = TrackButton;
  4934. },{"5":5,"50":50,"88":88}],39:[function(_dereq_,module,exports){
  4935. 'use strict';
  4936. exports.__esModule = true;
  4937. /**
  4938. * Check if volume control is supported and if it isn't hide the
  4939. * `Component` that was passed using the `vjs-hidden` class.
  4940. *
  4941. * @param {Component} self
  4942. * The component that should be hidden if volume is unsupported
  4943. *
  4944. * @param {Player} player
  4945. * A reference to the player
  4946. *
  4947. * @private
  4948. */
  4949. var checkVolumeSupport = function checkVolumeSupport(self, player) {
  4950. // hide volume controls when they're not supported by the current tech
  4951. if (player.tech_ && !player.tech_.featuresVolumeControl) {
  4952. self.addClass('vjs-hidden');
  4953. }
  4954. self.on(player, 'loadstart', function () {
  4955. if (!player.tech_.featuresVolumeControl) {
  4956. self.addClass('vjs-hidden');
  4957. } else {
  4958. self.removeClass('vjs-hidden');
  4959. }
  4960. });
  4961. };
  4962. exports['default'] = checkVolumeSupport;
  4963. },{}],40:[function(_dereq_,module,exports){
  4964. 'use strict';
  4965. exports.__esModule = true;
  4966. var _slider = _dereq_(60);
  4967. var _slider2 = _interopRequireDefault(_slider);
  4968. var _component = _dereq_(5);
  4969. var _component2 = _interopRequireDefault(_component);
  4970. _dereq_(42);
  4971. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  4972. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  4973. function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
  4974. function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
  4975. * @file volume-bar.js
  4976. */
  4977. // Required children
  4978. /**
  4979. * The bar that contains the volume level and can be clicked on to adjust the level
  4980. *
  4981. * @extends Slider
  4982. */
  4983. var VolumeBar = function (_Slider) {
  4984. _inherits(VolumeBar, _Slider);
  4985. /**
  4986. * Creates an instance of this class.
  4987. *
  4988. * @param {Player} player
  4989. * The `Player` that this class should be attached to.
  4990. *
  4991. * @param {Object} [options]
  4992. * The key/value store of player options.
  4993. */
  4994. function VolumeBar(player, options) {
  4995. _classCallCheck(this, VolumeBar);
  4996. var _this = _possibleConstructorReturn(this, _Slider.call(this, player, options));
  4997. _this.on('slideractive', _this.updateLastVolume_);
  4998. _this.on(player, 'volumechange', _this.updateARIAAttributes);
  4999. player.ready(function () {
  5000. return _this.updateARIAAttributes();
  5001. });
  5002. return _this;
  5003. }
  5004. /**
  5005. * Create the `Component`'s DOM element
  5006. *
  5007. * @return {Element}
  5008. * The element that was created.
  5009. */
  5010. VolumeBar.prototype.createEl = function createEl() {
  5011. return _Slider.prototype.createEl.call(this, 'div', {
  5012. className: 'vjs-volume-bar vjs-slider-bar'
  5013. }, {
  5014. 'aria-label': this.localize('Volume Level'),
  5015. 'aria-live': 'polite'
  5016. });
  5017. };
  5018. /**
  5019. * Handle movement events on the {@link VolumeMenuButton}.
  5020. *
  5021. * @param {EventTarget~Event} event
  5022. * The event that caused this function to run.
  5023. *
  5024. * @listens mousemove
  5025. */
  5026. VolumeBar.prototype.handleMouseMove = function handleMouseMove(event) {
  5027. this.checkMuted();
  5028. this.player_.volume(this.calculateDistance(event));
  5029. };
  5030. /**
  5031. * If the player is muted unmute it.
  5032. */
  5033. VolumeBar.prototype.checkMuted = function checkMuted() {
  5034. if (this.player_.muted()) {
  5035. this.player_.muted(false);
  5036. }
  5037. };
  5038. /**
  5039. * Get percent of volume level
  5040. *
  5041. * @return {number}
  5042. * Volume level percent as a decimal number.
  5043. */
  5044. VolumeBar.prototype.getPercent = function getPercent() {
  5045. if (this.player_.muted()) {
  5046. return 0;
  5047. }
  5048. return this.player_.volume();
  5049. };
  5050. /**
  5051. * Increase volume level for keyboard users
  5052. */
  5053. VolumeBar.prototype.stepForward = function stepForward() {
  5054. this.checkMuted();
  5055. this.player_.volume(this.player_.volume() + 0.1);
  5056. };
  5057. /**
  5058. * Decrease volume level for keyboard users
  5059. */
  5060. VolumeBar.prototype.stepBack = function stepBack() {
  5061. this.checkMuted();
  5062. this.player_.volume(this.player_.volume() - 0.1);
  5063. };
  5064. /**
  5065. * Update ARIA accessibility attributes
  5066. *
  5067. * @param {EventTarget~Event} [event]
  5068. * The `volumechange` event that caused this function to run.
  5069. *
  5070. * @listens Player#volumechange
  5071. */
  5072. VolumeBar.prototype.updateARIAAttributes = function updateARIAAttributes(event) {
  5073. var ariaValue = this.player_.muted() ? 0 : this.volumeAsPercentage_();
  5074. this.el_.setAttribute('aria-valuenow', ariaValue);
  5075. this.el_.setAttribute('aria-valuetext', ariaValue + '%');
  5076. };
  5077. /**
  5078. * Returns the current value of the player volume as a percentage
  5079. *
  5080. * @private
  5081. */
  5082. VolumeBar.prototype.volumeAsPercentage_ = function volumeAsPercentage_() {
  5083. return Math.round(this.player_.volume() * 100);
  5084. };
  5085. /**
  5086. * When user starts dragging the VolumeBar, store the volume and listen for
  5087. * the end of the drag. When the drag ends, if the volume was set to zero,
  5088. * set lastVolume to the stored volume.
  5089. *
  5090. * @listens slideractive
  5091. * @private
  5092. */
  5093. VolumeBar.prototype.updateLastVolume_ = function updateLastVolume_() {
  5094. var _this2 = this;
  5095. var volumeBeforeDrag = this.player_.volume();
  5096. this.one('sliderinactive', function () {
  5097. if (_this2.player_.volume() === 0) {
  5098. _this2.player_.lastVolume_(volumeBeforeDrag);
  5099. }
  5100. });
  5101. };
  5102. return VolumeBar;
  5103. }(_slider2['default']);
  5104. /**
  5105. * Default options for the `VolumeBar`
  5106. *
  5107. * @type {Object}
  5108. * @private
  5109. */
  5110. VolumeBar.prototype.options_ = {
  5111. children: ['volumeLevel'],
  5112. barName: 'volumeLevel'
  5113. };
  5114. /**
  5115. * Call the update event for this Slider when this event happens on the player.
  5116. *
  5117. * @type {string}
  5118. */
  5119. VolumeBar.prototype.playerEvent = 'volumechange';
  5120. _component2['default'].registerComponent('VolumeBar', VolumeBar);
  5121. exports['default'] = VolumeBar;
  5122. },{"42":42,"5":5,"60":60}],41:[function(_dereq_,module,exports){
  5123. 'use strict';
  5124. exports.__esModule = true;
  5125. var _component = _dereq_(5);
  5126. var _component2 = _interopRequireDefault(_component);
  5127. var _checkVolumeSupport = _dereq_(39);
  5128. var _checkVolumeSupport2 = _interopRequireDefault(_checkVolumeSupport);
  5129. var _obj = _dereq_(93);
  5130. var _fn = _dereq_(88);
  5131. _dereq_(40);
  5132. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  5133. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  5134. function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
  5135. function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
  5136. * @file volume-control.js
  5137. */
  5138. // Required children
  5139. /**
  5140. * The component for controlling the volume level
  5141. *
  5142. * @extends Component
  5143. */
  5144. var VolumeControl = function (_Component) {
  5145. _inherits(VolumeControl, _Component);
  5146. /**
  5147. * Creates an instance of this class.
  5148. *
  5149. * @param {Player} player
  5150. * The `Player` that this class should be attached to.
  5151. *
  5152. * @param {Object} [options={}]
  5153. * The key/value store of player options.
  5154. */
  5155. function VolumeControl(player) {
  5156. var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  5157. _classCallCheck(this, VolumeControl);
  5158. options.vertical = options.vertical || false;
  5159. // Pass the vertical option down to the VolumeBar if
  5160. // the VolumeBar is turned on.
  5161. if (typeof options.volumeBar === 'undefined' || (0, _obj.isPlain)(options.volumeBar)) {
  5162. options.volumeBar = options.volumeBar || {};
  5163. options.volumeBar.vertical = options.vertical;
  5164. }
  5165. // hide this control if volume support is missing
  5166. var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
  5167. (0, _checkVolumeSupport2['default'])(_this, player);
  5168. _this.throttledHandleMouseMove = (0, _fn.throttle)((0, _fn.bind)(_this, _this.handleMouseMove), 25);
  5169. _this.on('mousedown', _this.handleMouseDown);
  5170. _this.on('touchstart', _this.handleMouseDown);
  5171. // while the slider is active (the mouse has been pressed down and
  5172. // is dragging) or in focus we do not want to hide the VolumeBar
  5173. _this.on(_this.volumeBar, ['focus', 'slideractive'], function () {
  5174. _this.volumeBar.addClass('vjs-slider-active');
  5175. _this.addClass('vjs-slider-active');
  5176. _this.trigger('slideractive');
  5177. });
  5178. _this.on(_this.volumeBar, ['blur', 'sliderinactive'], function () {
  5179. _this.volumeBar.removeClass('vjs-slider-active');
  5180. _this.removeClass('vjs-slider-active');
  5181. _this.trigger('sliderinactive');
  5182. });
  5183. return _this;
  5184. }
  5185. /**
  5186. * Create the `Component`'s DOM element
  5187. *
  5188. * @return {Element}
  5189. * The element that was created.
  5190. */
  5191. VolumeControl.prototype.createEl = function createEl() {
  5192. var orientationClass = 'vjs-volume-horizontal';
  5193. if (this.options_.vertical) {
  5194. orientationClass = 'vjs-volume-vertical';
  5195. }
  5196. return _Component.prototype.createEl.call(this, 'div', {
  5197. className: 'vjs-volume-control vjs-control ' + orientationClass
  5198. });
  5199. };
  5200. /**
  5201. * Handle `mousedown` or `touchstart` events on the `VolumeControl`.
  5202. *
  5203. * @param {EventTarget~Event} event
  5204. * `mousedown` or `touchstart` event that triggered this function
  5205. *
  5206. * @listens mousedown
  5207. * @listens touchstart
  5208. */
  5209. VolumeControl.prototype.handleMouseDown = function handleMouseDown(event) {
  5210. var doc = this.el_.ownerDocument;
  5211. this.on(doc, 'mousemove', this.throttledHandleMouseMove);
  5212. this.on(doc, 'touchmove', this.throttledHandleMouseMove);
  5213. this.on(doc, 'mouseup', this.handleMouseUp);
  5214. this.on(doc, 'touchend', this.handleMouseUp);
  5215. };
  5216. /**
  5217. * Handle `mouseup` or `touchend` events on the `VolumeControl`.
  5218. *
  5219. * @param {EventTarget~Event} event
  5220. * `mouseup` or `touchend` event that triggered this function.
  5221. *
  5222. * @listens touchend
  5223. * @listens mouseup
  5224. */
  5225. VolumeControl.prototype.handleMouseUp = function handleMouseUp(event) {
  5226. var doc = this.el_.ownerDocument;
  5227. this.off(doc, 'mousemove', this.throttledHandleMouseMove);
  5228. this.off(doc, 'touchmove', this.throttledHandleMouseMove);
  5229. this.off(doc, 'mouseup', this.handleMouseUp);
  5230. this.off(doc, 'touchend', this.handleMouseUp);
  5231. };
  5232. /**
  5233. * Handle `mousedown` or `touchstart` events on the `VolumeControl`.
  5234. *
  5235. * @param {EventTarget~Event} event
  5236. * `mousedown` or `touchstart` event that triggered this function
  5237. *
  5238. * @listens mousedown
  5239. * @listens touchstart
  5240. */
  5241. VolumeControl.prototype.handleMouseMove = function handleMouseMove(event) {
  5242. this.volumeBar.handleMouseMove(event);
  5243. };
  5244. return VolumeControl;
  5245. }(_component2['default']);
  5246. /**
  5247. * Default options for the `VolumeControl`
  5248. *
  5249. * @type {Object}
  5250. * @private
  5251. */
  5252. VolumeControl.prototype.options_ = {
  5253. children: ['volumeBar']
  5254. };
  5255. _component2['default'].registerComponent('VolumeControl', VolumeControl);
  5256. exports['default'] = VolumeControl;
  5257. },{"39":39,"40":40,"5":5,"88":88,"93":93}],42:[function(_dereq_,module,exports){
  5258. 'use strict';
  5259. exports.__esModule = true;
  5260. var _component = _dereq_(5);
  5261. var _component2 = _interopRequireDefault(_component);
  5262. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  5263. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  5264. function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
  5265. function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
  5266. * @file volume-level.js
  5267. */
  5268. /**
  5269. * Shows volume level
  5270. *
  5271. * @extends Component
  5272. */
  5273. var VolumeLevel = function (_Component) {
  5274. _inherits(VolumeLevel, _Component);
  5275. function VolumeLevel() {
  5276. _classCallCheck(this, VolumeLevel);
  5277. return _possibleConstructorReturn(this, _Component.apply(this, arguments));
  5278. }
  5279. /**
  5280. * Create the `Component`'s DOM element
  5281. *
  5282. * @return {Element}
  5283. * The element that was created.
  5284. */
  5285. VolumeLevel.prototype.createEl = function createEl() {
  5286. return _Component.prototype.createEl.call(this, 'div', {
  5287. className: 'vjs-volume-level',
  5288. innerHTML: '<span class="vjs-control-text"></span>'
  5289. });
  5290. };
  5291. return VolumeLevel;
  5292. }(_component2['default']);
  5293. _component2['default'].registerComponent('VolumeLevel', VolumeLevel);
  5294. exports['default'] = VolumeLevel;
  5295. },{"5":5}],43:[function(_dereq_,module,exports){
  5296. 'use strict';
  5297. exports.__esModule = true;
  5298. var _component = _dereq_(5);
  5299. var _component2 = _interopRequireDefault(_component);
  5300. var _checkVolumeSupport = _dereq_(39);
  5301. var _checkVolumeSupport2 = _interopRequireDefault(_checkVolumeSupport);
  5302. var _obj = _dereq_(93);
  5303. _dereq_(41);
  5304. _dereq_(11);
  5305. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  5306. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  5307. function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
  5308. function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
  5309. * @file volume-control.js
  5310. */
  5311. // Required children
  5312. /**
  5313. * A Component to contain the MuteToggle and VolumeControl so that
  5314. * they can work together.
  5315. *
  5316. * @extends Component
  5317. */
  5318. var VolumePanel = function (_Component) {
  5319. _inherits(VolumePanel, _Component);
  5320. /**
  5321. * Creates an instance of this class.
  5322. *
  5323. * @param {Player} player
  5324. * The `Player` that this class should be attached to.
  5325. *
  5326. * @param {Object} [options={}]
  5327. * The key/value store of player options.
  5328. */
  5329. function VolumePanel(player) {
  5330. var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  5331. _classCallCheck(this, VolumePanel);
  5332. if (typeof options.inline !== 'undefined') {
  5333. options.inline = options.inline;
  5334. } else {
  5335. options.inline = true;
  5336. }
  5337. // pass the inline option down to the VolumeControl as vertical if
  5338. // the VolumeControl is on.
  5339. if (typeof options.volumeControl === 'undefined' || (0, _obj.isPlain)(options.volumeControl)) {
  5340. options.volumeControl = options.volumeControl || {};
  5341. options.volumeControl.vertical = !options.inline;
  5342. }
  5343. // hide this control if volume support is missing
  5344. var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
  5345. (0, _checkVolumeSupport2['default'])(_this, player);
  5346. // while the slider is active (the mouse has been pressed down and
  5347. // is dragging) or in focus we do not want to hide the VolumeBar
  5348. _this.on(_this.volumeControl, ['slideractive'], _this.sliderActive_);
  5349. _this.on(_this.muteToggle, 'focus', _this.sliderActive_);
  5350. _this.on(_this.volumeControl, ['sliderinactive'], _this.sliderInactive_);
  5351. _this.on(_this.muteToggle, 'blur', _this.sliderInactive_);
  5352. return _this;
  5353. }
  5354. /**
  5355. * Add vjs-slider-active class to the VolumePanel
  5356. *
  5357. * @listens VolumeControl#slideractive
  5358. * @private
  5359. */
  5360. VolumePanel.prototype.sliderActive_ = function sliderActive_() {
  5361. this.addClass('vjs-slider-active');
  5362. };
  5363. /**
  5364. * Removes vjs-slider-active class to the VolumePanel
  5365. *
  5366. * @listens VolumeControl#sliderinactive
  5367. * @private
  5368. */
  5369. VolumePanel.prototype.sliderInactive_ = function sliderInactive_() {
  5370. this.removeClass('vjs-slider-active');
  5371. };
  5372. /**
  5373. * Create the `Component`'s DOM element
  5374. *
  5375. * @return {Element}
  5376. * The element that was created.
  5377. */
  5378. VolumePanel.prototype.createEl = function createEl() {
  5379. var orientationClass = 'vjs-volume-panel-horizontal';
  5380. if (!this.options_.inline) {
  5381. orientationClass = 'vjs-volume-panel-vertical';
  5382. }
  5383. return _Component.prototype.createEl.call(this, 'div', {
  5384. className: 'vjs-volume-panel vjs-control ' + orientationClass
  5385. });
  5386. };
  5387. return VolumePanel;
  5388. }(_component2['default']);
  5389. /**
  5390. * Default options for the `VolumeControl`
  5391. *
  5392. * @type {Object}
  5393. * @private
  5394. */
  5395. VolumePanel.prototype.options_ = {
  5396. children: ['muteToggle', 'volumeControl']
  5397. };
  5398. _component2['default'].registerComponent('VolumePanel', VolumePanel);
  5399. exports['default'] = VolumePanel;
  5400. },{"11":11,"39":39,"41":41,"5":5,"93":93}],44:[function(_dereq_,module,exports){
  5401. 'use strict';
  5402. exports.__esModule = true;
  5403. var _component = _dereq_(5);
  5404. var _component2 = _interopRequireDefault(_component);
  5405. var _modalDialog = _dereq_(55);
  5406. var _modalDialog2 = _interopRequireDefault(_modalDialog);
  5407. var _mergeOptions = _dereq_(92);
  5408. var _mergeOptions2 = _interopRequireDefault(_mergeOptions);
  5409. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  5410. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  5411. function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
  5412. function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
  5413. * @file error-display.js
  5414. */
  5415. /**
  5416. * A display that indicates an error has occurred. This means that the video
  5417. * is unplayable.
  5418. *
  5419. * @extends ModalDialog
  5420. */
  5421. var ErrorDisplay = function (_ModalDialog) {
  5422. _inherits(ErrorDisplay, _ModalDialog);
  5423. /**
  5424. * Creates an instance of this class.
  5425. *
  5426. * @param {Player} player
  5427. * The `Player` that this class should be attached to.
  5428. *
  5429. * @param {Object} [options]
  5430. * The key/value store of player options.
  5431. */
  5432. function ErrorDisplay(player, options) {
  5433. _classCallCheck(this, ErrorDisplay);
  5434. var _this = _possibleConstructorReturn(this, _ModalDialog.call(this, player, options));
  5435. _this.on(player, 'error', _this.open);
  5436. return _this;
  5437. }
  5438. /**
  5439. * Builds the default DOM `className`.
  5440. *
  5441. * @return {string}
  5442. * The DOM `className` for this object.
  5443. *
  5444. * @deprecated Since version 5.
  5445. */
  5446. ErrorDisplay.prototype.buildCSSClass = function buildCSSClass() {
  5447. return 'vjs-error-display ' + _ModalDialog.prototype.buildCSSClass.call(this);
  5448. };
  5449. /**
  5450. * Gets the localized error message based on the `Player`s error.
  5451. *
  5452. * @return {string}
  5453. * The `Player`s error message localized or an empty string.
  5454. */
  5455. ErrorDisplay.prototype.content = function content() {
  5456. var error = this.player().error();
  5457. return error ? this.localize(error.message) : '';
  5458. };
  5459. return ErrorDisplay;
  5460. }(_modalDialog2['default']);
  5461. /**
  5462. * The default options for an `ErrorDisplay`.
  5463. *
  5464. * @private
  5465. */
  5466. ErrorDisplay.prototype.options_ = (0, _mergeOptions2['default'])(_modalDialog2['default'].prototype.options_, {
  5467. fillAlways: true,
  5468. temporary: false,
  5469. uncloseable: true
  5470. });
  5471. _component2['default'].registerComponent('ErrorDisplay', ErrorDisplay);
  5472. exports['default'] = ErrorDisplay;
  5473. },{"5":5,"55":55,"92":92}],45:[function(_dereq_,module,exports){
  5474. 'use strict';
  5475. exports.__esModule = true;
  5476. var _events = _dereq_(86);
  5477. var Events = _interopRequireWildcard(_events);
  5478. function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
  5479. /**
  5480. * `EventTarget` is a class that can have the same API as the DOM `EventTarget`. It
  5481. * adds shorthand functions that wrap around lengthy functions. For example:
  5482. * the `on` function is a wrapper around `addEventListener`.
  5483. *
  5484. * @see [EventTarget Spec]{@link https://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-EventTarget}
  5485. * @class EventTarget
  5486. */
  5487. var EventTarget = function EventTarget() {};
  5488. /**
  5489. * A Custom DOM event.
  5490. *
  5491. * @typedef {Object} EventTarget~Event
  5492. * @see [Properties]{@link https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent}
  5493. */
  5494. /**
  5495. * All event listeners should follow the following format.
  5496. *
  5497. * @callback EventTarget~EventListener
  5498. * @this {EventTarget}
  5499. *
  5500. * @param {EventTarget~Event} event
  5501. * the event that triggered this function
  5502. *
  5503. * @param {Object} [hash]
  5504. * hash of data sent during the event
  5505. */
  5506. /**
  5507. * An object containing event names as keys and booleans as values.
  5508. *
  5509. * > NOTE: If an event name is set to a true value here {@link EventTarget#trigger}
  5510. * will have extra functionality. See that function for more information.
  5511. *
  5512. * @property EventTarget.prototype.allowedEvents_
  5513. * @private
  5514. */
  5515. /**
  5516. * @file src/js/event-target.js
  5517. */
  5518. EventTarget.prototype.allowedEvents_ = {};
  5519. /**
  5520. * Adds an `event listener` to an instance of an `EventTarget`. An `event listener` is a
  5521. * function that will get called when an event with a certain name gets triggered.
  5522. *
  5523. * @param {string|string[]} type
  5524. * An event name or an array of event names.
  5525. *
  5526. * @param {EventTarget~EventListener} fn
  5527. * The function to call with `EventTarget`s
  5528. */
  5529. EventTarget.prototype.on = function (type, fn) {
  5530. // Remove the addEventListener alias before calling Events.on
  5531. // so we don't get into an infinite type loop
  5532. var ael = this.addEventListener;
  5533. this.addEventListener = function () {};
  5534. Events.on(this, type, fn);
  5535. this.addEventListener = ael;
  5536. };
  5537. /**
  5538. * An alias of {@link EventTarget#on}. Allows `EventTarget` to mimic
  5539. * the standard DOM API.
  5540. *
  5541. * @function
  5542. * @see {@link EventTarget#on}
  5543. */
  5544. EventTarget.prototype.addEventListener = EventTarget.prototype.on;
  5545. /**
  5546. * Removes an `event listener` for a specific event from an instance of `EventTarget`.
  5547. * This makes it so that the `event listener` will no longer get called when the
  5548. * named event happens.
  5549. *
  5550. * @param {string|string[]} type
  5551. * An event name or an array of event names.
  5552. *
  5553. * @param {EventTarget~EventListener} fn
  5554. * The function to remove.
  5555. */
  5556. EventTarget.prototype.off = function (type, fn) {
  5557. Events.off(this, type, fn);
  5558. };
  5559. /**
  5560. * An alias of {@link EventTarget#off}. Allows `EventTarget` to mimic
  5561. * the standard DOM API.
  5562. *
  5563. * @function
  5564. * @see {@link EventTarget#off}
  5565. */
  5566. EventTarget.prototype.removeEventListener = EventTarget.prototype.off;
  5567. /**
  5568. * This function will add an `event listener` that gets triggered only once. After the
  5569. * first trigger it will get removed. This is like adding an `event listener`
  5570. * with {@link EventTarget#on} that calls {@link EventTarget#off} on itself.
  5571. *
  5572. * @param {string|string[]} type
  5573. * An event name or an array of event names.
  5574. *
  5575. * @param {EventTarget~EventListener} fn
  5576. * The function to be called once for each event name.
  5577. */
  5578. EventTarget.prototype.one = function (type, fn) {
  5579. // Remove the addEventListener alialing Events.on
  5580. // so we don't get into an infinite type loop
  5581. var ael = this.addEventListener;
  5582. this.addEventListener = function () {};
  5583. Events.one(this, type, fn);
  5584. this.addEventListener = ael;
  5585. };
  5586. /**
  5587. * This function causes an event to happen. This will then cause any `event listeners`
  5588. * that are waiting for that event, to get called. If there are no `event listeners`
  5589. * for an event then nothing will happen.
  5590. *
  5591. * If the name of the `Event` that is being triggered is in `EventTarget.allowedEvents_`.
  5592. * Trigger will also call the `on` + `uppercaseEventName` function.
  5593. *
  5594. * Example:
  5595. * 'click' is in `EventTarget.allowedEvents_`, so, trigger will attempt to call
  5596. * `onClick` if it exists.
  5597. *
  5598. * @param {string|EventTarget~Event|Object} event
  5599. * The name of the event, an `Event`, or an object with a key of type set to
  5600. * an event name.
  5601. */
  5602. EventTarget.prototype.trigger = function (event) {
  5603. var type = event.type || event;
  5604. if (typeof event === 'string') {
  5605. event = { type: type };
  5606. }
  5607. event = Events.fixEvent(event);
  5608. if (this.allowedEvents_[type] && this['on' + type]) {
  5609. this['on' + type](event);
  5610. }
  5611. Events.trigger(this, event);
  5612. };
  5613. /**
  5614. * An alias of {@link EventTarget#trigger}. Allows `EventTarget` to mimic
  5615. * the standard DOM API.
  5616. *
  5617. * @function
  5618. * @see {@link EventTarget#trigger}
  5619. */
  5620. EventTarget.prototype.dispatchEvent = EventTarget.prototype.trigger;
  5621. exports['default'] = EventTarget;
  5622. },{"86":86}],46:[function(_dereq_,module,exports){
  5623. 'use strict';
  5624. exports.__esModule = true;
  5625. var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
  5626. /**
  5627. * @file extend.js
  5628. * @module extend
  5629. */
  5630. /**
  5631. * A combination of node inherits and babel's inherits (after transpile).
  5632. * Both work the same but node adds `super_` to the subClass
  5633. * and Bable adds the superClass as __proto__. Both seem useful.
  5634. *
  5635. * @param {Object} subClass
  5636. * The class to inherit to
  5637. *
  5638. * @param {Object} superClass
  5639. * The class to inherit from
  5640. *
  5641. * @private
  5642. */
  5643. var _inherits = function _inherits(subClass, superClass) {
  5644. if (typeof superClass !== 'function' && superClass !== null) {
  5645. throw new TypeError('Super expression must either be null or a function, not ' + (typeof superClass === 'undefined' ? 'undefined' : _typeof(superClass)));
  5646. }
  5647. subClass.prototype = Object.create(superClass && superClass.prototype, {
  5648. constructor: {
  5649. value: subClass,
  5650. enumerable: false,
  5651. writable: true,
  5652. configurable: true
  5653. }
  5654. });
  5655. if (superClass) {
  5656. // node
  5657. subClass.super_ = superClass;
  5658. }
  5659. };
  5660. /**
  5661. * Function for subclassing using the same inheritance that
  5662. * videojs uses internally
  5663. *
  5664. * @static
  5665. * @const
  5666. *
  5667. * @param {Object} superClass
  5668. * The class to inherit from
  5669. *
  5670. * @param {Object} [subClassMethods={}]
  5671. * The class to inherit to
  5672. *
  5673. * @return {Object}
  5674. * The new object with subClassMethods that inherited superClass.
  5675. */
  5676. var extendFn = function extendFn(superClass) {
  5677. var subClassMethods = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  5678. var subClass = function subClass() {
  5679. superClass.apply(this, arguments);
  5680. };
  5681. var methods = {};
  5682. if ((typeof subClassMethods === 'undefined' ? 'undefined' : _typeof(subClassMethods)) === 'object') {
  5683. if (subClassMethods.constructor !== Object.prototype.constructor) {
  5684. subClass = subClassMethods.constructor;
  5685. }
  5686. methods = subClassMethods;
  5687. } else if (typeof subClassMethods === 'function') {
  5688. subClass = subClassMethods;
  5689. }
  5690. _inherits(subClass, superClass);
  5691. // Extend subObj's prototype with functions and other properties from props
  5692. for (var name in methods) {
  5693. if (methods.hasOwnProperty(name)) {
  5694. subClass.prototype[name] = methods[name];
  5695. }
  5696. }
  5697. return subClass;
  5698. };
  5699. exports['default'] = extendFn;
  5700. },{}],47:[function(_dereq_,module,exports){
  5701. 'use strict';
  5702. exports.__esModule = true;
  5703. var _document = _dereq_(99);
  5704. var _document2 = _interopRequireDefault(_document);
  5705. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  5706. /**
  5707. * Store the browser-specific methods for the fullscreen API.
  5708. *
  5709. * @type {Object}
  5710. * @see [Specification]{@link https://fullscreen.spec.whatwg.org}
  5711. * @see [Map Approach From Screenfull.js]{@link https://github.com/sindresorhus/screenfull.js}
  5712. */
  5713. var FullscreenApi = {};
  5714. // browser API methods
  5715. /**
  5716. * @file fullscreen-api.js
  5717. * @module fullscreen-api
  5718. * @private
  5719. */
  5720. var apiMap = [['requestFullscreen', 'exitFullscreen', 'fullscreenElement', 'fullscreenEnabled', 'fullscreenchange', 'fullscreenerror'],
  5721. // WebKit
  5722. ['webkitRequestFullscreen', 'webkitExitFullscreen', 'webkitFullscreenElement', 'webkitFullscreenEnabled', 'webkitfullscreenchange', 'webkitfullscreenerror'],
  5723. // Old WebKit (Safari 5.1)
  5724. ['webkitRequestFullScreen', 'webkitCancelFullScreen', 'webkitCurrentFullScreenElement', 'webkitCancelFullScreen', 'webkitfullscreenchange', 'webkitfullscreenerror'],
  5725. // Mozilla
  5726. ['mozRequestFullScreen', 'mozCancelFullScreen', 'mozFullScreenElement', 'mozFullScreenEnabled', 'mozfullscreenchange', 'mozfullscreenerror'],
  5727. // Microsoft
  5728. ['msRequestFullscreen', 'msExitFullscreen', 'msFullscreenElement', 'msFullscreenEnabled', 'MSFullscreenChange', 'MSFullscreenError']];
  5729. var specApi = apiMap[0];
  5730. var browserApi = void 0;
  5731. // determine the supported set of functions
  5732. for (var i = 0; i < apiMap.length; i++) {
  5733. // check for exitFullscreen function
  5734. if (apiMap[i][1] in _document2['default']) {
  5735. browserApi = apiMap[i];
  5736. break;
  5737. }
  5738. }
  5739. // map the browser API names to the spec API names
  5740. if (browserApi) {
  5741. for (var _i = 0; _i < browserApi.length; _i++) {
  5742. FullscreenApi[specApi[_i]] = browserApi[_i];
  5743. }
  5744. }
  5745. exports['default'] = FullscreenApi;
  5746. },{"99":99}],48:[function(_dereq_,module,exports){
  5747. 'use strict';
  5748. exports.__esModule = true;
  5749. var _component = _dereq_(5);
  5750. var _component2 = _interopRequireDefault(_component);
  5751. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  5752. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  5753. function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
  5754. function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
  5755. * @file loading-spinner.js
  5756. */
  5757. /**
  5758. * A loading spinner for use during waiting/loading events.
  5759. *
  5760. * @extends Component
  5761. */
  5762. var LoadingSpinner = function (_Component) {
  5763. _inherits(LoadingSpinner, _Component);
  5764. function LoadingSpinner() {
  5765. _classCallCheck(this, LoadingSpinner);
  5766. return _possibleConstructorReturn(this, _Component.apply(this, arguments));
  5767. }
  5768. /**
  5769. * Create the `LoadingSpinner`s DOM element.
  5770. *
  5771. * @return {Element}
  5772. * The dom element that gets created.
  5773. */
  5774. LoadingSpinner.prototype.createEl = function createEl() {
  5775. return _Component.prototype.createEl.call(this, 'div', {
  5776. className: 'vjs-loading-spinner',
  5777. dir: 'ltr'
  5778. });
  5779. };
  5780. return LoadingSpinner;
  5781. }(_component2['default']);
  5782. _component2['default'].registerComponent('LoadingSpinner', LoadingSpinner);
  5783. exports['default'] = LoadingSpinner;
  5784. },{"5":5}],49:[function(_dereq_,module,exports){
  5785. 'use strict';
  5786. exports.__esModule = true;
  5787. var _obj = _dereq_(93);
  5788. /**
  5789. * A Custom `MediaError` class which mimics the standard HTML5 `MediaError` class.
  5790. *
  5791. * @param {number|string|Object|MediaError} value
  5792. * This can be of multiple types:
  5793. * - number: should be a standard error code
  5794. * - string: an error message (the code will be 0)
  5795. * - Object: arbitrary properties
  5796. * - `MediaError` (native): used to populate a video.js `MediaError` object
  5797. * - `MediaError` (video.js): will return itself if it's already a
  5798. * video.js `MediaError` object.
  5799. *
  5800. * @see [MediaError Spec]{@link https://dev.w3.org/html5/spec-author-view/video.html#mediaerror}
  5801. * @see [Encrypted MediaError Spec]{@link https://www.w3.org/TR/2013/WD-encrypted-media-20130510/#error-codes}
  5802. *
  5803. * @class MediaError
  5804. */
  5805. function MediaError(value) {
  5806. // Allow redundant calls to this constructor to avoid having `instanceof`
  5807. // checks peppered around the code.
  5808. if (value instanceof MediaError) {
  5809. return value;
  5810. }
  5811. if (typeof value === 'number') {
  5812. this.code = value;
  5813. } else if (typeof value === 'string') {
  5814. // default code is zero, so this is a custom error
  5815. this.message = value;
  5816. } else if ((0, _obj.isObject)(value)) {
  5817. // We assign the `code` property manually because native `MediaError` objects
  5818. // do not expose it as an own/enumerable property of the object.
  5819. if (typeof value.code === 'number') {
  5820. this.code = value.code;
  5821. }
  5822. (0, _obj.assign)(this, value);
  5823. }
  5824. if (!this.message) {
  5825. this.message = MediaError.defaultMessages[this.code] || '';
  5826. }
  5827. }
  5828. /**
  5829. * The error code that refers two one of the defined `MediaError` types
  5830. *
  5831. * @type {Number}
  5832. */
  5833. /**
  5834. * @file media-error.js
  5835. */
  5836. MediaError.prototype.code = 0;
  5837. /**
  5838. * An optional message that to show with the error. Message is not part of the HTML5
  5839. * video spec but allows for more informative custom errors.
  5840. *
  5841. * @type {String}
  5842. */
  5843. MediaError.prototype.message = '';
  5844. /**
  5845. * An optional status code that can be set by plugins to allow even more detail about
  5846. * the error. For example a plugin might provide a specific HTTP status code and an
  5847. * error message for that code. Then when the plugin gets that error this class will
  5848. * know how to display an error message for it. This allows a custom message to show
  5849. * up on the `Player` error overlay.
  5850. *
  5851. * @type {Array}
  5852. */
  5853. MediaError.prototype.status = null;
  5854. /**
  5855. * Errors indexed by the W3C standard. The order **CANNOT CHANGE**! See the
  5856. * specification listed under {@link MediaError} for more information.
  5857. *
  5858. * @enum {array}
  5859. * @readonly
  5860. * @property {string} 0 - MEDIA_ERR_CUSTOM
  5861. * @property {string} 1 - MEDIA_ERR_CUSTOM
  5862. * @property {string} 2 - MEDIA_ERR_ABORTED
  5863. * @property {string} 3 - MEDIA_ERR_NETWORK
  5864. * @property {string} 4 - MEDIA_ERR_SRC_NOT_SUPPORTED
  5865. * @property {string} 5 - MEDIA_ERR_ENCRYPTED
  5866. */
  5867. MediaError.errorTypes = ['MEDIA_ERR_CUSTOM', 'MEDIA_ERR_ABORTED', 'MEDIA_ERR_NETWORK', 'MEDIA_ERR_DECODE', 'MEDIA_ERR_SRC_NOT_SUPPORTED', 'MEDIA_ERR_ENCRYPTED'];
  5868. /**
  5869. * The default `MediaError` messages based on the {@link MediaError.errorTypes}.
  5870. *
  5871. * @type {Array}
  5872. * @constant
  5873. */
  5874. MediaError.defaultMessages = {
  5875. 1: 'You aborted the media playback',
  5876. 2: 'A network error caused the media download to fail part-way.',
  5877. 3: 'The media playback was aborted due to a corruption problem or because the media used features your browser did not support.',
  5878. 4: 'The media could not be loaded, either because the server or network failed or because the format is not supported.',
  5879. 5: 'The media is encrypted and we do not have the keys to decrypt it.'
  5880. };
  5881. // Add types as properties on MediaError
  5882. // e.g. MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED = 4;
  5883. for (var errNum = 0; errNum < MediaError.errorTypes.length; errNum++) {
  5884. MediaError[MediaError.errorTypes[errNum]] = errNum;
  5885. // values should be accessible on both the class and instance
  5886. MediaError.prototype[MediaError.errorTypes[errNum]] = errNum;
  5887. }
  5888. // jsdocs for instance/static members added above
  5889. // instance methods use `#` and static methods use `.`
  5890. /**
  5891. * W3C error code for any custom error.
  5892. *
  5893. * @member MediaError#MEDIA_ERR_CUSTOM
  5894. * @constant {number}
  5895. * @default 0
  5896. */
  5897. /**
  5898. * W3C error code for any custom error.
  5899. *
  5900. * @member MediaError.MEDIA_ERR_CUSTOM
  5901. * @constant {number}
  5902. * @default 0
  5903. */
  5904. /**
  5905. * W3C error code for media error aborted.
  5906. *
  5907. * @member MediaError#MEDIA_ERR_ABORTED
  5908. * @constant {number}
  5909. * @default 1
  5910. */
  5911. /**
  5912. * W3C error code for media error aborted.
  5913. *
  5914. * @member MediaError.MEDIA_ERR_ABORTED
  5915. * @constant {number}
  5916. * @default 1
  5917. */
  5918. /**
  5919. * W3C error code for any network error.
  5920. *
  5921. * @member MediaError#MEDIA_ERR_NETWORK
  5922. * @constant {number}
  5923. * @default 2
  5924. */
  5925. /**
  5926. * W3C error code for any network error.
  5927. *
  5928. * @member MediaError.MEDIA_ERR_NETWORK
  5929. * @constant {number}
  5930. * @default 2
  5931. */
  5932. /**
  5933. * W3C error code for any decoding error.
  5934. *
  5935. * @member MediaError#MEDIA_ERR_DECODE
  5936. * @constant {number}
  5937. * @default 3
  5938. */
  5939. /**
  5940. * W3C error code for any decoding error.
  5941. *
  5942. * @member MediaError.MEDIA_ERR_DECODE
  5943. * @constant {number}
  5944. * @default 3
  5945. */
  5946. /**
  5947. * W3C error code for any time that a source is not supported.
  5948. *
  5949. * @member MediaError#MEDIA_ERR_SRC_NOT_SUPPORTED
  5950. * @constant {number}
  5951. * @default 4
  5952. */
  5953. /**
  5954. * W3C error code for any time that a source is not supported.
  5955. *
  5956. * @member MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED
  5957. * @constant {number}
  5958. * @default 4
  5959. */
  5960. /**
  5961. * W3C error code for any time that a source is encrypted.
  5962. *
  5963. * @member MediaError#MEDIA_ERR_ENCRYPTED
  5964. * @constant {number}
  5965. * @default 5
  5966. */
  5967. /**
  5968. * W3C error code for any time that a source is encrypted.
  5969. *
  5970. * @member MediaError.MEDIA_ERR_ENCRYPTED
  5971. * @constant {number}
  5972. * @default 5
  5973. */
  5974. exports['default'] = MediaError;
  5975. },{"93":93}],50:[function(_dereq_,module,exports){
  5976. 'use strict';
  5977. exports.__esModule = true;
  5978. var _button = _dereq_(2);
  5979. var _button2 = _interopRequireDefault(_button);
  5980. var _component = _dereq_(5);
  5981. var _component2 = _interopRequireDefault(_component);
  5982. var _menu = _dereq_(52);
  5983. var _menu2 = _interopRequireDefault(_menu);
  5984. var _dom = _dereq_(85);
  5985. var Dom = _interopRequireWildcard(_dom);
  5986. var _fn = _dereq_(88);
  5987. var Fn = _interopRequireWildcard(_fn);
  5988. var _events = _dereq_(86);
  5989. var Events = _interopRequireWildcard(_events);
  5990. var _toTitleCase = _dereq_(96);
  5991. var _toTitleCase2 = _interopRequireDefault(_toTitleCase);
  5992. var _document = _dereq_(99);
  5993. var _document2 = _interopRequireDefault(_document);
  5994. function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
  5995. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  5996. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  5997. function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
  5998. function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
  5999. * @file menu-button.js
  6000. */
  6001. /**
  6002. * A `MenuButton` class for any popup {@link Menu}.
  6003. *
  6004. * @extends Component
  6005. */
  6006. var MenuButton = function (_Component) {
  6007. _inherits(MenuButton, _Component);
  6008. /**
  6009. * Creates an instance of this class.
  6010. *
  6011. * @param {Player} player
  6012. * The `Player` that this class should be attached to.
  6013. *
  6014. * @param {Object} [options={}]
  6015. * The key/value store of player options.
  6016. */
  6017. function MenuButton(player) {
  6018. var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  6019. _classCallCheck(this, MenuButton);
  6020. var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
  6021. _this.menuButton_ = new _button2['default'](player, options);
  6022. _this.menuButton_.controlText(_this.controlText_);
  6023. _this.menuButton_.el_.setAttribute('aria-haspopup', 'true');
  6024. // Add buildCSSClass values to the button, not the wrapper
  6025. var buttonClass = _button2['default'].prototype.buildCSSClass();
  6026. _this.menuButton_.el_.className = _this.buildCSSClass() + ' ' + buttonClass;
  6027. _this.menuButton_.removeClass('vjs-control');
  6028. _this.addChild(_this.menuButton_);
  6029. _this.update();
  6030. _this.enabled_ = true;
  6031. _this.on(_this.menuButton_, 'tap', _this.handleClick);
  6032. _this.on(_this.menuButton_, 'click', _this.handleClick);
  6033. _this.on(_this.menuButton_, 'focus', _this.handleFocus);
  6034. _this.on(_this.menuButton_, 'blur', _this.handleBlur);
  6035. _this.on('keydown', _this.handleSubmenuKeyPress);
  6036. return _this;
  6037. }
  6038. /**
  6039. * Update the menu based on the current state of its items.
  6040. */
  6041. MenuButton.prototype.update = function update() {
  6042. var menu = this.createMenu();
  6043. if (this.menu) {
  6044. this.removeChild(this.menu);
  6045. }
  6046. this.menu = menu;
  6047. this.addChild(menu);
  6048. /**
  6049. * Track the state of the menu button
  6050. *
  6051. * @type {Boolean}
  6052. * @private
  6053. */
  6054. this.buttonPressed_ = false;
  6055. this.menuButton_.el_.setAttribute('aria-expanded', 'false');
  6056. if (this.items && this.items.length <= this.hideThreshold_) {
  6057. this.hide();
  6058. } else {
  6059. this.show();
  6060. }
  6061. };
  6062. /**
  6063. * Create the menu and add all items to it.
  6064. *
  6065. * @return {Menu}
  6066. * The constructed menu
  6067. */
  6068. MenuButton.prototype.createMenu = function createMenu() {
  6069. var menu = new _menu2['default'](this.player_, { menuButton: this });
  6070. /**
  6071. * Hide the menu if the number of items is less than or equal to this threshold. This defaults
  6072. * to 0 and whenever we add items which can be hidden to the menu we'll increment it. We list
  6073. * it here because every time we run `createMenu` we need to reset the value.
  6074. *
  6075. * @protected
  6076. * @type {Number}
  6077. */
  6078. this.hideThreshold_ = 0;
  6079. // Add a title list item to the top
  6080. if (this.options_.title) {
  6081. var title = Dom.createEl('li', {
  6082. className: 'vjs-menu-title',
  6083. innerHTML: (0, _toTitleCase2['default'])(this.options_.title),
  6084. tabIndex: -1
  6085. });
  6086. this.hideThreshold_ += 1;
  6087. menu.children_.unshift(title);
  6088. Dom.prependTo(title, menu.contentEl());
  6089. }
  6090. this.items = this.createItems();
  6091. if (this.items) {
  6092. // Add menu items to the menu
  6093. for (var i = 0; i < this.items.length; i++) {
  6094. menu.addItem(this.items[i]);
  6095. }
  6096. }
  6097. return menu;
  6098. };
  6099. /**
  6100. * Create the list of menu items. Specific to each subclass.
  6101. *
  6102. * @abstract
  6103. */
  6104. MenuButton.prototype.createItems = function createItems() {};
  6105. /**
  6106. * Create the `MenuButtons`s DOM element.
  6107. *
  6108. * @return {Element}
  6109. * The element that gets created.
  6110. */
  6111. MenuButton.prototype.createEl = function createEl() {
  6112. return _Component.prototype.createEl.call(this, 'div', {
  6113. className: this.buildWrapperCSSClass()
  6114. }, {});
  6115. };
  6116. /**
  6117. * Allow sub components to stack CSS class names for the wrapper element
  6118. *
  6119. * @return {string}
  6120. * The constructed wrapper DOM `className`
  6121. */
  6122. MenuButton.prototype.buildWrapperCSSClass = function buildWrapperCSSClass() {
  6123. var menuButtonClass = 'vjs-menu-button';
  6124. // If the inline option is passed, we want to use different styles altogether.
  6125. if (this.options_.inline === true) {
  6126. menuButtonClass += '-inline';
  6127. } else {
  6128. menuButtonClass += '-popup';
  6129. }
  6130. // TODO: Fix the CSS so that this isn't necessary
  6131. var buttonClass = _button2['default'].prototype.buildCSSClass();
  6132. return 'vjs-menu-button ' + menuButtonClass + ' ' + buttonClass + ' ' + _Component.prototype.buildCSSClass.call(this);
  6133. };
  6134. /**
  6135. * Builds the default DOM `className`.
  6136. *
  6137. * @return {string}
  6138. * The DOM `className` for this object.
  6139. */
  6140. MenuButton.prototype.buildCSSClass = function buildCSSClass() {
  6141. var menuButtonClass = 'vjs-menu-button';
  6142. // If the inline option is passed, we want to use different styles altogether.
  6143. if (this.options_.inline === true) {
  6144. menuButtonClass += '-inline';
  6145. } else {
  6146. menuButtonClass += '-popup';
  6147. }
  6148. return 'vjs-menu-button ' + menuButtonClass + ' ' + _Component.prototype.buildCSSClass.call(this);
  6149. };
  6150. /**
  6151. * Get or set the localized control text that will be used for accessibility.
  6152. *
  6153. * > NOTE: This will come from the internal `menuButton_` element.
  6154. *
  6155. * @param {string} [text]
  6156. * Control text for element.
  6157. *
  6158. * @param {Element} [el=this.menuButton_.el()]
  6159. * Element to set the title on.
  6160. *
  6161. * @return {string}
  6162. * - The control text when getting
  6163. */
  6164. MenuButton.prototype.controlText = function controlText(text) {
  6165. var el = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.menuButton_.el();
  6166. return this.menuButton_.controlText(text, el);
  6167. };
  6168. /**
  6169. * Handle a click on a `MenuButton`.
  6170. * See {@link ClickableComponent#handleClick} for instances where this is called.
  6171. *
  6172. * @param {EventTarget~Event} event
  6173. * The `keydown`, `tap`, or `click` event that caused this function to be
  6174. * called.
  6175. *
  6176. * @listens tap
  6177. * @listens click
  6178. */
  6179. MenuButton.prototype.handleClick = function handleClick(event) {
  6180. // When you click the button it adds focus, which will show the menu.
  6181. // So we'll remove focus when the mouse leaves the button. Focus is needed
  6182. // for tab navigation.
  6183. this.one(this.menu.contentEl(), 'mouseleave', Fn.bind(this, function (e) {
  6184. this.unpressButton();
  6185. this.el_.blur();
  6186. }));
  6187. if (this.buttonPressed_) {
  6188. this.unpressButton();
  6189. } else {
  6190. this.pressButton();
  6191. }
  6192. };
  6193. /**
  6194. * Set the focus to the actual button, not to this element
  6195. */
  6196. MenuButton.prototype.focus = function focus() {
  6197. this.menuButton_.focus();
  6198. };
  6199. /**
  6200. * Remove the focus from the actual button, not this element
  6201. */
  6202. MenuButton.prototype.blur = function blur() {
  6203. this.menuButton_.blur();
  6204. };
  6205. /**
  6206. * This gets called when a `MenuButton` gains focus via a `focus` event.
  6207. * Turns on listening for `keydown` events. When they happen it
  6208. * calls `this.handleKeyPress`.
  6209. *
  6210. * @param {EventTarget~Event} event
  6211. * The `focus` event that caused this function to be called.
  6212. *
  6213. * @listens focus
  6214. */
  6215. MenuButton.prototype.handleFocus = function handleFocus() {
  6216. Events.on(_document2['default'], 'keydown', Fn.bind(this, this.handleKeyPress));
  6217. };
  6218. /**
  6219. * Called when a `MenuButton` loses focus. Turns off the listener for
  6220. * `keydown` events. Which Stops `this.handleKeyPress` from getting called.
  6221. *
  6222. * @param {EventTarget~Event} event
  6223. * The `blur` event that caused this function to be called.
  6224. *
  6225. * @listens blur
  6226. */
  6227. MenuButton.prototype.handleBlur = function handleBlur() {
  6228. Events.off(_document2['default'], 'keydown', Fn.bind(this, this.handleKeyPress));
  6229. };
  6230. /**
  6231. * Handle tab, escape, down arrow, and up arrow keys for `MenuButton`. See
  6232. * {@link ClickableComponent#handleKeyPress} for instances where this is called.
  6233. *
  6234. * @param {EventTarget~Event} event
  6235. * The `keydown` event that caused this function to be called.
  6236. *
  6237. * @listens keydown
  6238. */
  6239. MenuButton.prototype.handleKeyPress = function handleKeyPress(event) {
  6240. // Escape (27) key or Tab (9) key unpress the 'button'
  6241. if (event.which === 27 || event.which === 9) {
  6242. if (this.buttonPressed_) {
  6243. this.unpressButton();
  6244. }
  6245. // Don't preventDefault for Tab key - we still want to lose focus
  6246. if (event.which !== 9) {
  6247. event.preventDefault();
  6248. // Set focus back to the menu button's button
  6249. this.menuButton_.el_.focus();
  6250. }
  6251. // Up (38) key or Down (40) key press the 'button'
  6252. } else if (event.which === 38 || event.which === 40) {
  6253. if (!this.buttonPressed_) {
  6254. this.pressButton();
  6255. event.preventDefault();
  6256. }
  6257. }
  6258. };
  6259. /**
  6260. * Handle a `keydown` event on a sub-menu. The listener for this is added in
  6261. * the constructor.
  6262. *
  6263. * @param {EventTarget~Event} event
  6264. * Key press event
  6265. *
  6266. * @listens keydown
  6267. */
  6268. MenuButton.prototype.handleSubmenuKeyPress = function handleSubmenuKeyPress(event) {
  6269. // Escape (27) key or Tab (9) key unpress the 'button'
  6270. if (event.which === 27 || event.which === 9) {
  6271. if (this.buttonPressed_) {
  6272. this.unpressButton();
  6273. }
  6274. // Don't preventDefault for Tab key - we still want to lose focus
  6275. if (event.which !== 9) {
  6276. event.preventDefault();
  6277. // Set focus back to the menu button's button
  6278. this.menuButton_.el_.focus();
  6279. }
  6280. }
  6281. };
  6282. /**
  6283. * Put the current `MenuButton` into a pressed state.
  6284. */
  6285. MenuButton.prototype.pressButton = function pressButton() {
  6286. if (this.enabled_) {
  6287. this.buttonPressed_ = true;
  6288. this.menu.lockShowing();
  6289. this.menuButton_.el_.setAttribute('aria-expanded', 'true');
  6290. // set the focus into the submenu
  6291. this.menu.focus();
  6292. }
  6293. };
  6294. /**
  6295. * Take the current `MenuButton` out of a pressed state.
  6296. */
  6297. MenuButton.prototype.unpressButton = function unpressButton() {
  6298. if (this.enabled_) {
  6299. this.buttonPressed_ = false;
  6300. this.menu.unlockShowing();
  6301. this.menuButton_.el_.setAttribute('aria-expanded', 'false');
  6302. }
  6303. };
  6304. /**
  6305. * Disable the `MenuButton`. Don't allow it to be clicked.
  6306. */
  6307. MenuButton.prototype.disable = function disable() {
  6308. this.unpressButton();
  6309. this.enabled_ = false;
  6310. this.addClass('vjs-disabled');
  6311. this.menuButton_.disable();
  6312. };
  6313. /**
  6314. * Enable the `MenuButton`. Allow it to be clicked.
  6315. */
  6316. MenuButton.prototype.enable = function enable() {
  6317. this.enabled_ = true;
  6318. this.removeClass('vjs-disabled');
  6319. this.menuButton_.enable();
  6320. };
  6321. return MenuButton;
  6322. }(_component2['default']);
  6323. _component2['default'].registerComponent('MenuButton', MenuButton);
  6324. exports['default'] = MenuButton;
  6325. },{"2":2,"5":5,"52":52,"85":85,"86":86,"88":88,"96":96,"99":99}],51:[function(_dereq_,module,exports){
  6326. 'use strict';
  6327. exports.__esModule = true;
  6328. var _clickableComponent = _dereq_(3);
  6329. var _clickableComponent2 = _interopRequireDefault(_clickableComponent);
  6330. var _component = _dereq_(5);
  6331. var _component2 = _interopRequireDefault(_component);
  6332. var _obj = _dereq_(93);
  6333. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  6334. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  6335. function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
  6336. function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
  6337. * @file menu-item.js
  6338. */
  6339. /**
  6340. * The component for a menu item. `<li>`
  6341. *
  6342. * @extends ClickableComponent
  6343. */
  6344. var MenuItem = function (_ClickableComponent) {
  6345. _inherits(MenuItem, _ClickableComponent);
  6346. /**
  6347. * Creates an instance of the this class.
  6348. *
  6349. * @param {Player} player
  6350. * The `Player` that this class should be attached to.
  6351. *
  6352. * @param {Object} [options={}]
  6353. * The key/value store of player options.
  6354. *
  6355. */
  6356. function MenuItem(player, options) {
  6357. _classCallCheck(this, MenuItem);
  6358. var _this = _possibleConstructorReturn(this, _ClickableComponent.call(this, player, options));
  6359. _this.selectable = options.selectable;
  6360. _this.selected(options.selected);
  6361. if (_this.selectable) {
  6362. // TODO: May need to be either menuitemcheckbox or menuitemradio,
  6363. // and may need logical grouping of menu items.
  6364. _this.el_.setAttribute('role', 'menuitemcheckbox');
  6365. } else {
  6366. _this.el_.setAttribute('role', 'menuitem');
  6367. }
  6368. return _this;
  6369. }
  6370. /**
  6371. * Create the `MenuItem's DOM element
  6372. *
  6373. * @param {string} [type=li]
  6374. * Element's node type, not actually used, always set to `li`.
  6375. *
  6376. * @param {Object} [props={}]
  6377. * An object of properties that should be set on the element
  6378. *
  6379. * @param {Object} [attrs={}]
  6380. * An object of attributes that should be set on the element
  6381. *
  6382. * @return {Element}
  6383. * The element that gets created.
  6384. */
  6385. MenuItem.prototype.createEl = function createEl(type, props, attrs) {
  6386. // The control is textual, not just an icon
  6387. this.nonIconControl = true;
  6388. return _ClickableComponent.prototype.createEl.call(this, 'li', (0, _obj.assign)({
  6389. className: 'vjs-menu-item',
  6390. innerHTML: '<span class="vjs-menu-item-text">' + this.localize(this.options_.label) + '</span>',
  6391. tabIndex: -1
  6392. }, props), attrs);
  6393. };
  6394. /**
  6395. * Any click on a `MenuItem` puts int into the selected state.
  6396. * See {@link ClickableComponent#handleClick} for instances where this is called.
  6397. *
  6398. * @param {EventTarget~Event} event
  6399. * The `keydown`, `tap`, or `click` event that caused this function to be
  6400. * called.
  6401. *
  6402. * @listens tap
  6403. * @listens click
  6404. */
  6405. MenuItem.prototype.handleClick = function handleClick(event) {
  6406. this.selected(true);
  6407. };
  6408. /**
  6409. * Set the state for this menu item as selected or not.
  6410. *
  6411. * @param {boolean} selected
  6412. * if the menu item is selected or not
  6413. */
  6414. MenuItem.prototype.selected = function selected(_selected) {
  6415. if (this.selectable) {
  6416. if (_selected) {
  6417. this.addClass('vjs-selected');
  6418. this.el_.setAttribute('aria-checked', 'true');
  6419. // aria-checked isn't fully supported by browsers/screen readers,
  6420. // so indicate selected state to screen reader in the control text.
  6421. this.controlText(', selected');
  6422. } else {
  6423. this.removeClass('vjs-selected');
  6424. this.el_.setAttribute('aria-checked', 'false');
  6425. // Indicate un-selected state to screen reader
  6426. // Note that a space clears out the selected state text
  6427. this.controlText(' ');
  6428. }
  6429. }
  6430. };
  6431. return MenuItem;
  6432. }(_clickableComponent2['default']);
  6433. _component2['default'].registerComponent('MenuItem', MenuItem);
  6434. exports['default'] = MenuItem;
  6435. },{"3":3,"5":5,"93":93}],52:[function(_dereq_,module,exports){
  6436. 'use strict';
  6437. exports.__esModule = true;
  6438. var _component = _dereq_(5);
  6439. var _component2 = _interopRequireDefault(_component);
  6440. var _dom = _dereq_(85);
  6441. var Dom = _interopRequireWildcard(_dom);
  6442. var _fn = _dereq_(88);
  6443. var Fn = _interopRequireWildcard(_fn);
  6444. var _events = _dereq_(86);
  6445. var Events = _interopRequireWildcard(_events);
  6446. function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
  6447. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  6448. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  6449. function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
  6450. function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
  6451. * @file menu.js
  6452. */
  6453. /**
  6454. * The Menu component is used to build popup menus, including subtitle and
  6455. * captions selection menus.
  6456. *
  6457. * @extends Component
  6458. */
  6459. var Menu = function (_Component) {
  6460. _inherits(Menu, _Component);
  6461. /**
  6462. * Create an instance of this class.
  6463. *
  6464. * @param {Player} player
  6465. * the player that this component should attach to
  6466. *
  6467. * @param {Object} [options]
  6468. * Object of option names and values
  6469. *
  6470. */
  6471. function Menu(player, options) {
  6472. _classCallCheck(this, Menu);
  6473. var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
  6474. if (options) {
  6475. _this.menuButton_ = options.menuButton;
  6476. }
  6477. _this.focusedChild_ = -1;
  6478. _this.on('keydown', _this.handleKeyPress);
  6479. return _this;
  6480. }
  6481. /**
  6482. * Add a {@link MenuItem} to the menu.
  6483. *
  6484. * @param {Object|string} component
  6485. * The name or instance of the `MenuItem` to add.
  6486. *
  6487. */
  6488. Menu.prototype.addItem = function addItem(component) {
  6489. this.addChild(component);
  6490. component.on('click', Fn.bind(this, function (event) {
  6491. // Unpress the associated MenuButton, and move focus back to it
  6492. if (this.menuButton_) {
  6493. this.menuButton_.unpressButton();
  6494. // don't focus menu button if item is a caption settings item
  6495. // because focus will move elsewhere and it logs an error on IE8
  6496. if (component.name() !== 'CaptionSettingsMenuItem') {
  6497. this.menuButton_.focus();
  6498. }
  6499. }
  6500. }));
  6501. };
  6502. /**
  6503. * Create the `Menu`s DOM element.
  6504. *
  6505. * @return {Element}
  6506. * the element that was created
  6507. */
  6508. Menu.prototype.createEl = function createEl() {
  6509. var contentElType = this.options_.contentElType || 'ul';
  6510. this.contentEl_ = Dom.createEl(contentElType, {
  6511. className: 'vjs-menu-content'
  6512. });
  6513. this.contentEl_.setAttribute('role', 'menu');
  6514. var el = _Component.prototype.createEl.call(this, 'div', {
  6515. append: this.contentEl_,
  6516. className: 'vjs-menu'
  6517. });
  6518. el.appendChild(this.contentEl_);
  6519. // Prevent clicks from bubbling up. Needed for Menu Buttons,
  6520. // where a click on the parent is significant
  6521. Events.on(el, 'click', function (event) {
  6522. event.preventDefault();
  6523. event.stopImmediatePropagation();
  6524. });
  6525. return el;
  6526. };
  6527. /**
  6528. * Handle a `keydown` event on this menu. This listener is added in the constructor.
  6529. *
  6530. * @param {EventTarget~Event} event
  6531. * A `keydown` event that happened on the menu.
  6532. *
  6533. * @listens keydown
  6534. */
  6535. Menu.prototype.handleKeyPress = function handleKeyPress(event) {
  6536. // Left and Down Arrows
  6537. if (event.which === 37 || event.which === 40) {
  6538. event.preventDefault();
  6539. this.stepForward();
  6540. // Up and Right Arrows
  6541. } else if (event.which === 38 || event.which === 39) {
  6542. event.preventDefault();
  6543. this.stepBack();
  6544. }
  6545. };
  6546. /**
  6547. * Move to next (lower) menu item for keyboard users.
  6548. */
  6549. Menu.prototype.stepForward = function stepForward() {
  6550. var stepChild = 0;
  6551. if (this.focusedChild_ !== undefined) {
  6552. stepChild = this.focusedChild_ + 1;
  6553. }
  6554. this.focus(stepChild);
  6555. };
  6556. /**
  6557. * Move to previous (higher) menu item for keyboard users.
  6558. */
  6559. Menu.prototype.stepBack = function stepBack() {
  6560. var stepChild = 0;
  6561. if (this.focusedChild_ !== undefined) {
  6562. stepChild = this.focusedChild_ - 1;
  6563. }
  6564. this.focus(stepChild);
  6565. };
  6566. /**
  6567. * Set focus on a {@link MenuItem} in the `Menu`.
  6568. *
  6569. * @param {Object|string} [item=0]
  6570. * Index of child item set focus on.
  6571. */
  6572. Menu.prototype.focus = function focus() {
  6573. var item = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
  6574. var children = this.children().slice();
  6575. var haveTitle = children.length && children[0].className && /vjs-menu-title/.test(children[0].className);
  6576. if (haveTitle) {
  6577. children.shift();
  6578. }
  6579. if (children.length > 0) {
  6580. if (item < 0) {
  6581. item = 0;
  6582. } else if (item >= children.length) {
  6583. item = children.length - 1;
  6584. }
  6585. this.focusedChild_ = item;
  6586. children[item].el_.focus();
  6587. }
  6588. };
  6589. return Menu;
  6590. }(_component2['default']);
  6591. _component2['default'].registerComponent('Menu', Menu);
  6592. exports['default'] = Menu;
  6593. },{"5":5,"85":85,"86":86,"88":88}],53:[function(_dereq_,module,exports){
  6594. 'use strict';
  6595. exports.__esModule = true;
  6596. exports.isEvented = undefined;
  6597. var _dom = _dereq_(85);
  6598. var Dom = _interopRequireWildcard(_dom);
  6599. var _events = _dereq_(86);
  6600. var Events = _interopRequireWildcard(_events);
  6601. var _fn = _dereq_(88);
  6602. var Fn = _interopRequireWildcard(_fn);
  6603. var _obj = _dereq_(93);
  6604. var Obj = _interopRequireWildcard(_obj);
  6605. var _eventTarget = _dereq_(45);
  6606. var _eventTarget2 = _interopRequireDefault(_eventTarget);
  6607. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  6608. function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
  6609. /**
  6610. * Returns whether or not an object has had the evented mixin applied.
  6611. *
  6612. * @param {Object} object
  6613. * An object to test.
  6614. *
  6615. * @return {boolean}
  6616. * Whether or not the object appears to be evented.
  6617. */
  6618. var isEvented = function isEvented(object) {
  6619. return object instanceof _eventTarget2['default'] || !!object.eventBusEl_ && ['on', 'one', 'off', 'trigger'].every(function (k) {
  6620. return typeof object[k] === 'function';
  6621. });
  6622. };
  6623. /**
  6624. * Whether a value is a valid event type - non-empty string or array.
  6625. *
  6626. * @private
  6627. * @param {string|Array} type
  6628. * The type value to test.
  6629. *
  6630. * @return {boolean}
  6631. * Whether or not the type is a valid event type.
  6632. */
  6633. /**
  6634. * @file mixins/evented.js
  6635. * @module evented
  6636. */
  6637. var isValidEventType = function isValidEventType(type) {
  6638. return (
  6639. // The regex here verifies that the `type` contains at least one non-
  6640. // whitespace character.
  6641. typeof type === 'string' && /\S/.test(type) || Array.isArray(type) && !!type.length
  6642. );
  6643. };
  6644. /**
  6645. * Validates a value to determine if it is a valid event target. Throws if not.
  6646. *
  6647. * @private
  6648. * @throws {Error}
  6649. * If the target does not appear to be a valid event target.
  6650. *
  6651. * @param {Object} target
  6652. * The object to test.
  6653. */
  6654. var validateTarget = function validateTarget(target) {
  6655. if (!target.nodeName && !isEvented(target)) {
  6656. throw new Error('Invalid target; must be a DOM node or evented object.');
  6657. }
  6658. };
  6659. /**
  6660. * Validates a value to determine if it is a valid event target. Throws if not.
  6661. *
  6662. * @private
  6663. * @throws {Error}
  6664. * If the type does not appear to be a valid event type.
  6665. *
  6666. * @param {string|Array} type
  6667. * The type to test.
  6668. */
  6669. var validateEventType = function validateEventType(type) {
  6670. if (!isValidEventType(type)) {
  6671. throw new Error('Invalid event type; must be a non-empty string or array.');
  6672. }
  6673. };
  6674. /**
  6675. * Validates a value to determine if it is a valid listener. Throws if not.
  6676. *
  6677. * @private
  6678. * @throws {Error}
  6679. * If the listener is not a function.
  6680. *
  6681. * @param {Function} listener
  6682. * The listener to test.
  6683. */
  6684. var validateListener = function validateListener(listener) {
  6685. if (typeof listener !== 'function') {
  6686. throw new Error('Invalid listener; must be a function.');
  6687. }
  6688. };
  6689. /**
  6690. * Takes an array of arguments given to `on()` or `one()`, validates them, and
  6691. * normalizes them into an object.
  6692. *
  6693. * @private
  6694. * @param {Object} self
  6695. * The evented object on which `on()` or `one()` was called. This
  6696. * object will be bound as the `this` value for the listener.
  6697. *
  6698. * @param {Array} args
  6699. * An array of arguments passed to `on()` or `one()`.
  6700. *
  6701. * @return {Object}
  6702. * An object containing useful values for `on()` or `one()` calls.
  6703. */
  6704. var normalizeListenArgs = function normalizeListenArgs(self, args) {
  6705. // If the number of arguments is less than 3, the target is always the
  6706. // evented object itself.
  6707. var isTargetingSelf = args.length < 3 || args[0] === self || args[0] === self.eventBusEl_;
  6708. var target = void 0;
  6709. var type = void 0;
  6710. var listener = void 0;
  6711. if (isTargetingSelf) {
  6712. target = self.eventBusEl_;
  6713. // Deal with cases where we got 3 arguments, but we are still listening to
  6714. // the evented object itself.
  6715. if (args.length >= 3) {
  6716. args.shift();
  6717. }
  6718. type = args[0];
  6719. listener = args[1];
  6720. } else {
  6721. target = args[0];
  6722. type = args[1];
  6723. listener = args[2];
  6724. }
  6725. validateTarget(target);
  6726. validateEventType(type);
  6727. validateListener(listener);
  6728. listener = Fn.bind(self, listener);
  6729. return { isTargetingSelf: isTargetingSelf, target: target, type: type, listener: listener };
  6730. };
  6731. /**
  6732. * Adds the listener to the event type(s) on the target, normalizing for
  6733. * the type of target.
  6734. *
  6735. * @private
  6736. * @param {Element|Object} target
  6737. * A DOM node or evented object.
  6738. *
  6739. * @param {string} method
  6740. * The event binding method to use ("on" or "one").
  6741. *
  6742. * @param {string|Array} type
  6743. * One or more event type(s).
  6744. *
  6745. * @param {Function} listener
  6746. * A listener function.
  6747. */
  6748. var listen = function listen(target, method, type, listener) {
  6749. validateTarget(target);
  6750. if (target.nodeName) {
  6751. Events[method](target, type, listener);
  6752. } else {
  6753. target[method](type, listener);
  6754. }
  6755. };
  6756. /**
  6757. * Contains methods that provide event capabilites to an object which is passed
  6758. * to {@link module:evented|evented}.
  6759. *
  6760. * @mixin EventedMixin
  6761. */
  6762. var EventedMixin = {
  6763. /**
  6764. * Add a listener to an event (or events) on this object or another evented
  6765. * object.
  6766. *
  6767. * @param {string|Array|Element|Object} targetOrType
  6768. * If this is a string or array, it represents the event type(s)
  6769. * that will trigger the listener.
  6770. *
  6771. * Another evented object can be passed here instead, which will
  6772. * cause the listener to listen for events on _that_ object.
  6773. *
  6774. * In either case, the listener's `this` value will be bound to
  6775. * this object.
  6776. *
  6777. * @param {string|Array|Function} typeOrListener
  6778. * If the first argument was a string or array, this should be the
  6779. * listener function. Otherwise, this is a string or array of event
  6780. * type(s).
  6781. *
  6782. * @param {Function} [listener]
  6783. * If the first argument was another evented object, this will be
  6784. * the listener function.
  6785. */
  6786. on: function on() {
  6787. var _this = this;
  6788. for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
  6789. args[_key] = arguments[_key];
  6790. }
  6791. var _normalizeListenArgs = normalizeListenArgs(this, args),
  6792. isTargetingSelf = _normalizeListenArgs.isTargetingSelf,
  6793. target = _normalizeListenArgs.target,
  6794. type = _normalizeListenArgs.type,
  6795. listener = _normalizeListenArgs.listener;
  6796. listen(target, 'on', type, listener);
  6797. // If this object is listening to another evented object.
  6798. if (!isTargetingSelf) {
  6799. // If this object is disposed, remove the listener.
  6800. var removeListenerOnDispose = function removeListenerOnDispose() {
  6801. return _this.off(target, type, listener);
  6802. };
  6803. // Use the same function ID as the listener so we can remove it later it
  6804. // using the ID of the original listener.
  6805. removeListenerOnDispose.guid = listener.guid;
  6806. // Add a listener to the target's dispose event as well. This ensures
  6807. // that if the target is disposed BEFORE this object, we remove the
  6808. // removal listener that was just added. Otherwise, we create a memory leak.
  6809. var removeRemoverOnTargetDispose = function removeRemoverOnTargetDispose() {
  6810. return _this.off('dispose', removeListenerOnDispose);
  6811. };
  6812. // Use the same function ID as the listener so we can remove it later
  6813. // it using the ID of the original listener.
  6814. removeRemoverOnTargetDispose.guid = listener.guid;
  6815. listen(this, 'on', 'dispose', removeListenerOnDispose);
  6816. listen(target, 'on', 'dispose', removeRemoverOnTargetDispose);
  6817. }
  6818. },
  6819. /**
  6820. * Add a listener to an event (or events) on this object or another evented
  6821. * object. The listener will only be called once and then removed.
  6822. *
  6823. * @param {string|Array|Element|Object} targetOrType
  6824. * If this is a string or array, it represents the event type(s)
  6825. * that will trigger the listener.
  6826. *
  6827. * Another evented object can be passed here instead, which will
  6828. * cause the listener to listen for events on _that_ object.
  6829. *
  6830. * In either case, the listener's `this` value will be bound to
  6831. * this object.
  6832. *
  6833. * @param {string|Array|Function} typeOrListener
  6834. * If the first argument was a string or array, this should be the
  6835. * listener function. Otherwise, this is a string or array of event
  6836. * type(s).
  6837. *
  6838. * @param {Function} [listener]
  6839. * If the first argument was another evented object, this will be
  6840. * the listener function.
  6841. */
  6842. one: function one() {
  6843. var _this2 = this;
  6844. for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
  6845. args[_key2] = arguments[_key2];
  6846. }
  6847. var _normalizeListenArgs2 = normalizeListenArgs(this, args),
  6848. isTargetingSelf = _normalizeListenArgs2.isTargetingSelf,
  6849. target = _normalizeListenArgs2.target,
  6850. type = _normalizeListenArgs2.type,
  6851. listener = _normalizeListenArgs2.listener;
  6852. // Targeting this evented object.
  6853. if (isTargetingSelf) {
  6854. listen(target, 'one', type, listener);
  6855. // Targeting another evented object.
  6856. } else {
  6857. var wrapper = function wrapper() {
  6858. for (var _len3 = arguments.length, largs = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
  6859. largs[_key3] = arguments[_key3];
  6860. }
  6861. _this2.off(target, type, wrapper);
  6862. listener.apply(null, largs);
  6863. };
  6864. // Use the same function ID as the listener so we can remove it later
  6865. // it using the ID of the original listener.
  6866. wrapper.guid = listener.guid;
  6867. listen(target, 'one', type, wrapper);
  6868. }
  6869. },
  6870. /**
  6871. * Removes listener(s) from event(s) on an evented object.
  6872. *
  6873. * @param {string|Array|Element|Object} [targetOrType]
  6874. * If this is a string or array, it represents the event type(s).
  6875. *
  6876. * Another evented object can be passed here instead, in which case
  6877. * ALL 3 arguments are _required_.
  6878. *
  6879. * @param {string|Array|Function} [typeOrListener]
  6880. * If the first argument was a string or array, this may be the
  6881. * listener function. Otherwise, this is a string or array of event
  6882. * type(s).
  6883. *
  6884. * @param {Function} [listener]
  6885. * If the first argument was another evented object, this will be
  6886. * the listener function; otherwise, _all_ listeners bound to the
  6887. * event type(s) will be removed.
  6888. */
  6889. off: function off(targetOrType, typeOrListener, listener) {
  6890. // Targeting this evented object.
  6891. if (!targetOrType || isValidEventType(targetOrType)) {
  6892. Events.off(this.eventBusEl_, targetOrType, typeOrListener);
  6893. // Targeting another evented object.
  6894. } else {
  6895. var target = targetOrType;
  6896. var type = typeOrListener;
  6897. // Fail fast and in a meaningful way!
  6898. validateTarget(target);
  6899. validateEventType(type);
  6900. validateListener(listener);
  6901. // Ensure there's at least a guid, even if the function hasn't been used
  6902. listener = Fn.bind(this, listener);
  6903. // Remove the dispose listener on this evented object, which was given
  6904. // the same guid as the event listener in on().
  6905. this.off('dispose', listener);
  6906. if (target.nodeName) {
  6907. Events.off(target, type, listener);
  6908. Events.off(target, 'dispose', listener);
  6909. } else if (isEvented(target)) {
  6910. target.off(type, listener);
  6911. target.off('dispose', listener);
  6912. }
  6913. }
  6914. },
  6915. /**
  6916. * Fire an event on this evented object, causing its listeners to be called.
  6917. *
  6918. * @param {string|Object} event
  6919. * An event type or an object with a type property.
  6920. *
  6921. * @param {Object} [hash]
  6922. * An additional object to pass along to listeners.
  6923. *
  6924. * @returns {boolean}
  6925. * Whether or not the default behavior was prevented.
  6926. */
  6927. trigger: function trigger(event, hash) {
  6928. return Events.trigger(this.eventBusEl_, event, hash);
  6929. }
  6930. };
  6931. /**
  6932. * Applies {@link module:evented~EventedMixin|EventedMixin} to a target object.
  6933. *
  6934. * @param {Object} target
  6935. * The object to which to add event methods.
  6936. *
  6937. * @param {Object} [options={}]
  6938. * Options for customizing the mixin behavior.
  6939. *
  6940. * @param {String} [options.eventBusKey]
  6941. * By default, adds a `eventBusEl_` DOM element to the target object,
  6942. * which is used as an event bus. If the target object already has a
  6943. * DOM element that should be used, pass its key here.
  6944. *
  6945. * @return {Object}
  6946. * The target object.
  6947. */
  6948. function evented(target) {
  6949. var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  6950. var eventBusKey = options.eventBusKey;
  6951. // Set or create the eventBusEl_.
  6952. if (eventBusKey) {
  6953. if (!target[eventBusKey].nodeName) {
  6954. throw new Error('The eventBusKey "' + eventBusKey + '" does not refer to an element.');
  6955. }
  6956. target.eventBusEl_ = target[eventBusKey];
  6957. } else {
  6958. target.eventBusEl_ = Dom.createEl('span', { className: 'vjs-event-bus' });
  6959. }
  6960. Obj.assign(target, EventedMixin);
  6961. // When any evented object is disposed, it removes all its listeners.
  6962. target.on('dispose', function () {
  6963. return target.off();
  6964. });
  6965. return target;
  6966. }
  6967. exports['default'] = evented;
  6968. exports.isEvented = isEvented;
  6969. },{"45":45,"85":85,"86":86,"88":88,"93":93}],54:[function(_dereq_,module,exports){
  6970. 'use strict';
  6971. exports.__esModule = true;
  6972. var _evented = _dereq_(53);
  6973. var _obj = _dereq_(93);
  6974. var Obj = _interopRequireWildcard(_obj);
  6975. function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
  6976. /**
  6977. * Contains methods that provide statefulness to an object which is passed
  6978. * to {@link module:stateful}.
  6979. *
  6980. * @mixin StatefulMixin
  6981. */
  6982. /**
  6983. * @file mixins/stateful.js
  6984. * @module stateful
  6985. */
  6986. var StatefulMixin = {
  6987. /**
  6988. * A hash containing arbitrary keys and values representing the state of
  6989. * the object.
  6990. *
  6991. * @type {Object}
  6992. */
  6993. state: {},
  6994. /**
  6995. * Set the state of an object by mutating its
  6996. * {@link module:stateful~StatefulMixin.state|state} object in place.
  6997. *
  6998. * @fires module:stateful~StatefulMixin#statechanged
  6999. * @param {Object|Function} stateUpdates
  7000. * A new set of properties to shallow-merge into the plugin state.
  7001. * Can be a plain object or a function returning a plain object.
  7002. *
  7003. * @returns {Object|undefined}
  7004. * An object containing changes that occurred. If no changes
  7005. * occurred, returns `undefined`.
  7006. */
  7007. setState: function setState(stateUpdates) {
  7008. var _this = this;
  7009. // Support providing the `stateUpdates` state as a function.
  7010. if (typeof stateUpdates === 'function') {
  7011. stateUpdates = stateUpdates();
  7012. }
  7013. var changes = void 0;
  7014. Obj.each(stateUpdates, function (value, key) {
  7015. // Record the change if the value is different from what's in the
  7016. // current state.
  7017. if (_this.state[key] !== value) {
  7018. changes = changes || {};
  7019. changes[key] = {
  7020. from: _this.state[key],
  7021. to: value
  7022. };
  7023. }
  7024. _this.state[key] = value;
  7025. });
  7026. // Only trigger "statechange" if there were changes AND we have a trigger
  7027. // function. This allows us to not require that the target object be an
  7028. // evented object.
  7029. if (changes && (0, _evented.isEvented)(this)) {
  7030. /**
  7031. * An event triggered on an object that is both
  7032. * {@link module:stateful|stateful} and {@link module:evented|evented}
  7033. * indicating that its state has changed.
  7034. *
  7035. * @event module:stateful~StatefulMixin#statechanged
  7036. * @type {Object}
  7037. * @property {Object} changes
  7038. * A hash containing the properties that were changed and
  7039. * the values they were changed `from` and `to`.
  7040. */
  7041. this.trigger({
  7042. changes: changes,
  7043. type: 'statechanged'
  7044. });
  7045. }
  7046. return changes;
  7047. }
  7048. };
  7049. /**
  7050. * Applies {@link module:stateful~StatefulMixin|StatefulMixin} to a target
  7051. * object.
  7052. *
  7053. * If the target object is {@link module:evented|evented} and has a
  7054. * `handleStateChanged` method, that method will be automatically bound to the
  7055. * `statechanged` event on itself.
  7056. *
  7057. * @param {Object} target
  7058. * The object to be made stateful.
  7059. *
  7060. * @param {Object} [defaultState]
  7061. * A default set of properties to populate the newly-stateful object's
  7062. * `state` property.
  7063. *
  7064. * @returns {Object}
  7065. * Returns the `target`.
  7066. */
  7067. function stateful(target, defaultState) {
  7068. Obj.assign(target, StatefulMixin);
  7069. // This happens after the mixing-in because we need to replace the `state`
  7070. // added in that step.
  7071. target.state = Obj.assign({}, target.state, defaultState);
  7072. // Auto-bind the `handleStateChanged` method of the target object if it exists.
  7073. if (typeof target.handleStateChanged === 'function' && (0, _evented.isEvented)(target)) {
  7074. target.on('statechanged', target.handleStateChanged);
  7075. }
  7076. return target;
  7077. }
  7078. exports['default'] = stateful;
  7079. },{"53":53,"93":93}],55:[function(_dereq_,module,exports){
  7080. 'use strict';
  7081. exports.__esModule = true;
  7082. var _dom = _dereq_(85);
  7083. var Dom = _interopRequireWildcard(_dom);
  7084. var _fn = _dereq_(88);
  7085. var Fn = _interopRequireWildcard(_fn);
  7086. var _component = _dereq_(5);
  7087. var _component2 = _interopRequireDefault(_component);
  7088. var _window = _dereq_(100);
  7089. var _window2 = _interopRequireDefault(_window);
  7090. var _document = _dereq_(99);
  7091. var _document2 = _interopRequireDefault(_document);
  7092. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  7093. function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
  7094. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  7095. function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
  7096. function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
  7097. * @file modal-dialog.js
  7098. */
  7099. var MODAL_CLASS_NAME = 'vjs-modal-dialog';
  7100. var ESC = 27;
  7101. /**
  7102. * The `ModalDialog` displays over the video and its controls, which blocks
  7103. * interaction with the player until it is closed.
  7104. *
  7105. * Modal dialogs include a "Close" button and will close when that button
  7106. * is activated - or when ESC is pressed anywhere.
  7107. *
  7108. * @extends Component
  7109. */
  7110. var ModalDialog = function (_Component) {
  7111. _inherits(ModalDialog, _Component);
  7112. /**
  7113. * Create an instance of this class.
  7114. *
  7115. * @param {Player} player
  7116. * The `Player` that this class should be attached to.
  7117. *
  7118. * @param {Object} [options]
  7119. * The key/value store of player options.
  7120. *
  7121. * @param {Mixed} [options.content=undefined]
  7122. * Provide customized content for this modal.
  7123. *
  7124. * @param {string} [options.description]
  7125. * A text description for the modal, primarily for accessibility.
  7126. *
  7127. * @param {boolean} [options.fillAlways=false]
  7128. * Normally, modals are automatically filled only the first time
  7129. * they open. This tells the modal to refresh its content
  7130. * every time it opens.
  7131. *
  7132. * @param {string} [options.label]
  7133. * A text label for the modal, primarily for accessibility.
  7134. *
  7135. * @param {boolean} [options.temporary=true]
  7136. * If `true`, the modal can only be opened once; it will be
  7137. * disposed as soon as it's closed.
  7138. *
  7139. * @param {boolean} [options.uncloseable=false]
  7140. * If `true`, the user will not be able to close the modal
  7141. * through the UI in the normal ways. Programmatic closing is
  7142. * still possible.
  7143. */
  7144. function ModalDialog(player, options) {
  7145. _classCallCheck(this, ModalDialog);
  7146. var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
  7147. _this.opened_ = _this.hasBeenOpened_ = _this.hasBeenFilled_ = false;
  7148. _this.closeable(!_this.options_.uncloseable);
  7149. _this.content(_this.options_.content);
  7150. // Make sure the contentEl is defined AFTER any children are initialized
  7151. // because we only want the contents of the modal in the contentEl
  7152. // (not the UI elements like the close button).
  7153. _this.contentEl_ = Dom.createEl('div', {
  7154. className: MODAL_CLASS_NAME + '-content'
  7155. }, {
  7156. role: 'document'
  7157. });
  7158. _this.descEl_ = Dom.createEl('p', {
  7159. className: MODAL_CLASS_NAME + '-description vjs-control-text',
  7160. id: _this.el().getAttribute('aria-describedby')
  7161. });
  7162. Dom.textContent(_this.descEl_, _this.description());
  7163. _this.el_.appendChild(_this.descEl_);
  7164. _this.el_.appendChild(_this.contentEl_);
  7165. return _this;
  7166. }
  7167. /**
  7168. * Create the `ModalDialog`'s DOM element
  7169. *
  7170. * @return {Element}
  7171. * The DOM element that gets created.
  7172. */
  7173. ModalDialog.prototype.createEl = function createEl() {
  7174. return _Component.prototype.createEl.call(this, 'div', {
  7175. className: this.buildCSSClass(),
  7176. tabIndex: -1
  7177. }, {
  7178. 'aria-describedby': this.id() + '_description',
  7179. 'aria-hidden': 'true',
  7180. 'aria-label': this.label(),
  7181. 'role': 'dialog'
  7182. });
  7183. };
  7184. /**
  7185. * Builds the default DOM `className`.
  7186. *
  7187. * @return {string}
  7188. * The DOM `className` for this object.
  7189. */
  7190. ModalDialog.prototype.buildCSSClass = function buildCSSClass() {
  7191. return MODAL_CLASS_NAME + ' vjs-hidden ' + _Component.prototype.buildCSSClass.call(this);
  7192. };
  7193. /**
  7194. * Handles `keydown` events on the document, looking for ESC, which closes
  7195. * the modal.
  7196. *
  7197. * @param {EventTarget~Event} e
  7198. * The keypress that triggered this event.
  7199. *
  7200. * @listens keydown
  7201. */
  7202. ModalDialog.prototype.handleKeyPress = function handleKeyPress(e) {
  7203. if (e.which === ESC && this.closeable()) {
  7204. this.close();
  7205. }
  7206. };
  7207. /**
  7208. * Returns the label string for this modal. Primarily used for accessibility.
  7209. *
  7210. * @return {string}
  7211. * the localized or raw label of this modal.
  7212. */
  7213. ModalDialog.prototype.label = function label() {
  7214. return this.localize(this.options_.label || 'Modal Window');
  7215. };
  7216. /**
  7217. * Returns the description string for this modal. Primarily used for
  7218. * accessibility.
  7219. *
  7220. * @return {string}
  7221. * The localized or raw description of this modal.
  7222. */
  7223. ModalDialog.prototype.description = function description() {
  7224. var desc = this.options_.description || this.localize('This is a modal window.');
  7225. // Append a universal closeability message if the modal is closeable.
  7226. if (this.closeable()) {
  7227. desc += ' ' + this.localize('This modal can be closed by pressing the Escape key or activating the close button.');
  7228. }
  7229. return desc;
  7230. };
  7231. /**
  7232. * Opens the modal.
  7233. *
  7234. * @fires ModalDialog#beforemodalopen
  7235. * @fires ModalDialog#modalopen
  7236. */
  7237. ModalDialog.prototype.open = function open() {
  7238. if (!this.opened_) {
  7239. var player = this.player();
  7240. /**
  7241. * Fired just before a `ModalDialog` is opened.
  7242. *
  7243. * @event ModalDialog#beforemodalopen
  7244. * @type {EventTarget~Event}
  7245. */
  7246. this.trigger('beforemodalopen');
  7247. this.opened_ = true;
  7248. // Fill content if the modal has never opened before and
  7249. // never been filled.
  7250. if (this.options_.fillAlways || !this.hasBeenOpened_ && !this.hasBeenFilled_) {
  7251. this.fill();
  7252. }
  7253. // If the player was playing, pause it and take note of its previously
  7254. // playing state.
  7255. this.wasPlaying_ = !player.paused();
  7256. if (this.wasPlaying_) {
  7257. player.pause();
  7258. }
  7259. if (this.closeable()) {
  7260. this.on(this.el_.ownerDocument, 'keydown', Fn.bind(this, this.handleKeyPress));
  7261. }
  7262. player.controls(false);
  7263. this.show();
  7264. this.conditionalFocus_();
  7265. this.el().setAttribute('aria-hidden', 'false');
  7266. /**
  7267. * Fired just after a `ModalDialog` is opened.
  7268. *
  7269. * @event ModalDialog#modalopen
  7270. * @type {EventTarget~Event}
  7271. */
  7272. this.trigger('modalopen');
  7273. this.hasBeenOpened_ = true;
  7274. }
  7275. };
  7276. /**
  7277. * If the `ModalDialog` is currently open or closed.
  7278. *
  7279. * @param {boolean} [value]
  7280. * If given, it will open (`true`) or close (`false`) the modal.
  7281. *
  7282. * @return {boolean}
  7283. * the current open state of the modaldialog
  7284. */
  7285. ModalDialog.prototype.opened = function opened(value) {
  7286. if (typeof value === 'boolean') {
  7287. this[value ? 'open' : 'close']();
  7288. }
  7289. return this.opened_;
  7290. };
  7291. /**
  7292. * Closes the modal, does nothing if the `ModalDialog` is
  7293. * not open.
  7294. *
  7295. * @fires ModalDialog#beforemodalclose
  7296. * @fires ModalDialog#modalclose
  7297. */
  7298. ModalDialog.prototype.close = function close() {
  7299. if (!this.opened_) {
  7300. return;
  7301. }
  7302. var player = this.player();
  7303. /**
  7304. * Fired just before a `ModalDialog` is closed.
  7305. *
  7306. * @event ModalDialog#beforemodalclose
  7307. * @type {EventTarget~Event}
  7308. */
  7309. this.trigger('beforemodalclose');
  7310. this.opened_ = false;
  7311. if (this.wasPlaying_) {
  7312. player.play();
  7313. }
  7314. if (this.closeable()) {
  7315. this.off(this.el_.ownerDocument, 'keydown', Fn.bind(this, this.handleKeyPress));
  7316. }
  7317. player.controls(true);
  7318. this.hide();
  7319. this.el().setAttribute('aria-hidden', 'true');
  7320. /**
  7321. * Fired just after a `ModalDialog` is closed.
  7322. *
  7323. * @event ModalDialog#modalclose
  7324. * @type {EventTarget~Event}
  7325. */
  7326. this.trigger('modalclose');
  7327. this.conditionalBlur_();
  7328. if (this.options_.temporary) {
  7329. this.dispose();
  7330. }
  7331. };
  7332. /**
  7333. * Check to see if the `ModalDialog` is closeable via the UI.
  7334. *
  7335. * @param {boolean} [value]
  7336. * If given as a boolean, it will set the `closeable` option.
  7337. *
  7338. * @return {boolean}
  7339. * Returns the final value of the closable option.
  7340. */
  7341. ModalDialog.prototype.closeable = function closeable(value) {
  7342. if (typeof value === 'boolean') {
  7343. var closeable = this.closeable_ = !!value;
  7344. var close = this.getChild('closeButton');
  7345. // If this is being made closeable and has no close button, add one.
  7346. if (closeable && !close) {
  7347. // The close button should be a child of the modal - not its
  7348. // content element, so temporarily change the content element.
  7349. var temp = this.contentEl_;
  7350. this.contentEl_ = this.el_;
  7351. close = this.addChild('closeButton', { controlText: 'Close Modal Dialog' });
  7352. this.contentEl_ = temp;
  7353. this.on(close, 'close', this.close);
  7354. }
  7355. // If this is being made uncloseable and has a close button, remove it.
  7356. if (!closeable && close) {
  7357. this.off(close, 'close', this.close);
  7358. this.removeChild(close);
  7359. close.dispose();
  7360. }
  7361. }
  7362. return this.closeable_;
  7363. };
  7364. /**
  7365. * Fill the modal's content element with the modal's "content" option.
  7366. * The content element will be emptied before this change takes place.
  7367. */
  7368. ModalDialog.prototype.fill = function fill() {
  7369. this.fillWith(this.content());
  7370. };
  7371. /**
  7372. * Fill the modal's content element with arbitrary content.
  7373. * The content element will be emptied before this change takes place.
  7374. *
  7375. * @fires ModalDialog#beforemodalfill
  7376. * @fires ModalDialog#modalfill
  7377. *
  7378. * @param {Mixed} [content]
  7379. * The same rules apply to this as apply to the `content` option.
  7380. */
  7381. ModalDialog.prototype.fillWith = function fillWith(content) {
  7382. var contentEl = this.contentEl();
  7383. var parentEl = contentEl.parentNode;
  7384. var nextSiblingEl = contentEl.nextSibling;
  7385. /**
  7386. * Fired just before a `ModalDialog` is filled with content.
  7387. *
  7388. * @event ModalDialog#beforemodalfill
  7389. * @type {EventTarget~Event}
  7390. */
  7391. this.trigger('beforemodalfill');
  7392. this.hasBeenFilled_ = true;
  7393. // Detach the content element from the DOM before performing
  7394. // manipulation to avoid modifying the live DOM multiple times.
  7395. parentEl.removeChild(contentEl);
  7396. this.empty();
  7397. Dom.insertContent(contentEl, content);
  7398. /**
  7399. * Fired just after a `ModalDialog` is filled with content.
  7400. *
  7401. * @event ModalDialog#modalfill
  7402. * @type {EventTarget~Event}
  7403. */
  7404. this.trigger('modalfill');
  7405. // Re-inject the re-filled content element.
  7406. if (nextSiblingEl) {
  7407. parentEl.insertBefore(contentEl, nextSiblingEl);
  7408. } else {
  7409. parentEl.appendChild(contentEl);
  7410. }
  7411. // make sure that the close button is last in the dialog DOM
  7412. var closeButton = this.getChild('closeButton');
  7413. if (closeButton) {
  7414. parentEl.appendChild(closeButton.el_);
  7415. }
  7416. };
  7417. /**
  7418. * Empties the content element. This happens anytime the modal is filled.
  7419. *
  7420. * @fires ModalDialog#beforemodalempty
  7421. * @fires ModalDialog#modalempty
  7422. */
  7423. ModalDialog.prototype.empty = function empty() {
  7424. /**
  7425. * Fired just before a `ModalDialog` is emptied.
  7426. *
  7427. * @event ModalDialog#beforemodalempty
  7428. * @type {EventTarget~Event}
  7429. */
  7430. this.trigger('beforemodalempty');
  7431. Dom.emptyEl(this.contentEl());
  7432. /**
  7433. * Fired just after a `ModalDialog` is emptied.
  7434. *
  7435. * @event ModalDialog#modalempty
  7436. * @type {EventTarget~Event}
  7437. */
  7438. this.trigger('modalempty');
  7439. };
  7440. /**
  7441. * Gets or sets the modal content, which gets normalized before being
  7442. * rendered into the DOM.
  7443. *
  7444. * This does not update the DOM or fill the modal, but it is called during
  7445. * that process.
  7446. *
  7447. * @param {Mixed} [value]
  7448. * If defined, sets the internal content value to be used on the
  7449. * next call(s) to `fill`. This value is normalized before being
  7450. * inserted. To "clear" the internal content value, pass `null`.
  7451. *
  7452. * @return {Mixed}
  7453. * The current content of the modal dialog
  7454. */
  7455. ModalDialog.prototype.content = function content(value) {
  7456. if (typeof value !== 'undefined') {
  7457. this.content_ = value;
  7458. }
  7459. return this.content_;
  7460. };
  7461. /**
  7462. * conditionally focus the modal dialog if focus was previously on the player.
  7463. *
  7464. * @private
  7465. */
  7466. ModalDialog.prototype.conditionalFocus_ = function conditionalFocus_() {
  7467. var activeEl = _document2['default'].activeElement;
  7468. var playerEl = this.player_.el_;
  7469. this.previouslyActiveEl_ = null;
  7470. if (playerEl.contains(activeEl) || playerEl === activeEl) {
  7471. this.previouslyActiveEl_ = activeEl;
  7472. this.focus();
  7473. this.on(_document2['default'], 'keydown', this.handleKeyDown);
  7474. }
  7475. };
  7476. /**
  7477. * conditionally blur the element and refocus the last focused element
  7478. *
  7479. * @private
  7480. */
  7481. ModalDialog.prototype.conditionalBlur_ = function conditionalBlur_() {
  7482. if (this.previouslyActiveEl_) {
  7483. this.previouslyActiveEl_.focus();
  7484. this.previouslyActiveEl_ = null;
  7485. }
  7486. this.off(_document2['default'], 'keydown', this.handleKeyDown);
  7487. };
  7488. /**
  7489. * Keydown handler. Attached when modal is focused.
  7490. *
  7491. * @listens keydown
  7492. */
  7493. ModalDialog.prototype.handleKeyDown = function handleKeyDown(event) {
  7494. // exit early if it isn't a tab key
  7495. if (event.which !== 9) {
  7496. return;
  7497. }
  7498. var focusableEls = this.focusableEls_();
  7499. var activeEl = this.el_.querySelector(':focus');
  7500. var focusIndex = void 0;
  7501. for (var i = 0; i < focusableEls.length; i++) {
  7502. if (activeEl === focusableEls[i]) {
  7503. focusIndex = i;
  7504. break;
  7505. }
  7506. }
  7507. if (_document2['default'].activeElement === this.el_) {
  7508. focusIndex = 0;
  7509. }
  7510. if (event.shiftKey && focusIndex === 0) {
  7511. focusableEls[focusableEls.length - 1].focus();
  7512. event.preventDefault();
  7513. } else if (!event.shiftKey && focusIndex === focusableEls.length - 1) {
  7514. focusableEls[0].focus();
  7515. event.preventDefault();
  7516. }
  7517. };
  7518. /**
  7519. * get all focusable elements
  7520. *
  7521. * @private
  7522. */
  7523. ModalDialog.prototype.focusableEls_ = function focusableEls_() {
  7524. var allChildren = this.el_.querySelectorAll('*');
  7525. return Array.prototype.filter.call(allChildren, function (child) {
  7526. return (child instanceof _window2['default'].HTMLAnchorElement || child instanceof _window2['default'].HTMLAreaElement) && child.hasAttribute('href') || (child instanceof _window2['default'].HTMLInputElement || child instanceof _window2['default'].HTMLSelectElement || child instanceof _window2['default'].HTMLTextAreaElement || child instanceof _window2['default'].HTMLButtonElement) && !child.hasAttribute('disabled') || child instanceof _window2['default'].HTMLIFrameElement || child instanceof _window2['default'].HTMLObjectElement || child instanceof _window2['default'].HTMLEmbedElement || child.hasAttribute('tabindex') && child.getAttribute('tabindex') !== -1 || child.hasAttribute('contenteditable');
  7527. });
  7528. };
  7529. return ModalDialog;
  7530. }(_component2['default']);
  7531. /**
  7532. * Default options for `ModalDialog` default options.
  7533. *
  7534. * @type {Object}
  7535. * @private
  7536. */
  7537. ModalDialog.prototype.options_ = {
  7538. temporary: true
  7539. };
  7540. _component2['default'].registerComponent('ModalDialog', ModalDialog);
  7541. exports['default'] = ModalDialog;
  7542. },{"100":100,"5":5,"85":85,"88":88,"99":99}],56:[function(_dereq_,module,exports){
  7543. 'use strict';
  7544. exports.__esModule = true;
  7545. var _templateObject = _taggedTemplateLiteralLoose(['\n Using the tech directly can be dangerous. I hope you know what you\'re doing.\n See https://github.com/videojs/video.js/issues/2617 for more info.\n '], ['\n Using the tech directly can be dangerous. I hope you know what you\'re doing.\n See https://github.com/videojs/video.js/issues/2617 for more info.\n ']);
  7546. var _component = _dereq_(5);
  7547. var _component2 = _interopRequireDefault(_component);
  7548. var _document = _dereq_(99);
  7549. var _document2 = _interopRequireDefault(_document);
  7550. var _window = _dereq_(100);
  7551. var _window2 = _interopRequireDefault(_window);
  7552. var _tsml = _dereq_(103);
  7553. var _tsml2 = _interopRequireDefault(_tsml);
  7554. var _evented = _dereq_(53);
  7555. var _evented2 = _interopRequireDefault(_evented);
  7556. var _events = _dereq_(86);
  7557. var Events = _interopRequireWildcard(_events);
  7558. var _dom = _dereq_(85);
  7559. var Dom = _interopRequireWildcard(_dom);
  7560. var _fn = _dereq_(88);
  7561. var Fn = _interopRequireWildcard(_fn);
  7562. var _guid = _dereq_(90);
  7563. var Guid = _interopRequireWildcard(_guid);
  7564. var _browser = _dereq_(81);
  7565. var browser = _interopRequireWildcard(_browser);
  7566. var _log = _dereq_(91);
  7567. var _log2 = _interopRequireDefault(_log);
  7568. var _toTitleCase = _dereq_(96);
  7569. var _toTitleCase2 = _interopRequireDefault(_toTitleCase);
  7570. var _timeRanges = _dereq_(95);
  7571. var _buffer = _dereq_(82);
  7572. var _stylesheet = _dereq_(94);
  7573. var stylesheet = _interopRequireWildcard(_stylesheet);
  7574. var _fullscreenApi = _dereq_(47);
  7575. var _fullscreenApi2 = _interopRequireDefault(_fullscreenApi);
  7576. var _mediaError = _dereq_(49);
  7577. var _mediaError2 = _interopRequireDefault(_mediaError);
  7578. var _tuple = _dereq_(102);
  7579. var _tuple2 = _interopRequireDefault(_tuple);
  7580. var _obj = _dereq_(93);
  7581. var _mergeOptions = _dereq_(92);
  7582. var _mergeOptions2 = _interopRequireDefault(_mergeOptions);
  7583. var _textTrackListConverter = _dereq_(71);
  7584. var _textTrackListConverter2 = _interopRequireDefault(_textTrackListConverter);
  7585. var _modalDialog = _dereq_(55);
  7586. var _modalDialog2 = _interopRequireDefault(_modalDialog);
  7587. var _tech = _dereq_(64);
  7588. var _tech2 = _interopRequireDefault(_tech);
  7589. var _middleware = _dereq_(63);
  7590. var middleware = _interopRequireWildcard(_middleware);
  7591. var _trackTypes = _dereq_(77);
  7592. var _filterSource = _dereq_(87);
  7593. var _filterSource2 = _interopRequireDefault(_filterSource);
  7594. _dereq_(62);
  7595. _dereq_(58);
  7596. _dereq_(70);
  7597. _dereq_(48);
  7598. _dereq_(1);
  7599. _dereq_(4);
  7600. _dereq_(8);
  7601. _dereq_(44);
  7602. _dereq_(73);
  7603. _dereq_(61);
  7604. function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
  7605. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  7606. function _taggedTemplateLiteralLoose(strings, raw) { strings.raw = raw; return strings; }
  7607. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  7608. function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
  7609. function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
  7610. * @file player.js
  7611. */
  7612. // Subclasses Component
  7613. // The following imports are used only to ensure that the corresponding modules
  7614. // are always included in the video.js package. Importing the modules will
  7615. // execute them and they will register themselves with video.js.
  7616. // Import Html5 tech, at least for disposing the original video tag.
  7617. // The following tech events are simply re-triggered
  7618. // on the player when they happen
  7619. var TECH_EVENTS_RETRIGGER = [
  7620. /**
  7621. * Fired while the user agent is downloading media data.
  7622. *
  7623. * @event Player#progress
  7624. * @type {EventTarget~Event}
  7625. */
  7626. /**
  7627. * Retrigger the `progress` event that was triggered by the {@link Tech}.
  7628. *
  7629. * @private
  7630. * @method Player#handleTechProgress_
  7631. * @fires Player#progress
  7632. * @listens Tech#progress
  7633. */
  7634. 'progress',
  7635. /**
  7636. * Fires when the loading of an audio/video is aborted.
  7637. *
  7638. * @event Player#abort
  7639. * @type {EventTarget~Event}
  7640. */
  7641. /**
  7642. * Retrigger the `abort` event that was triggered by the {@link Tech}.
  7643. *
  7644. * @private
  7645. * @method Player#handleTechAbort_
  7646. * @fires Player#abort
  7647. * @listens Tech#abort
  7648. */
  7649. 'abort',
  7650. /**
  7651. * Fires when the browser is intentionally not getting media data.
  7652. *
  7653. * @event Player#suspend
  7654. * @type {EventTarget~Event}
  7655. */
  7656. /**
  7657. * Retrigger the `suspend` event that was triggered by the {@link Tech}.
  7658. *
  7659. * @private
  7660. * @method Player#handleTechSuspend_
  7661. * @fires Player#suspend
  7662. * @listens Tech#suspend
  7663. */
  7664. 'suspend',
  7665. /**
  7666. * Fires when the current playlist is empty.
  7667. *
  7668. * @event Player#emptied
  7669. * @type {EventTarget~Event}
  7670. */
  7671. /**
  7672. * Retrigger the `emptied` event that was triggered by the {@link Tech}.
  7673. *
  7674. * @private
  7675. * @method Player#handleTechEmptied_
  7676. * @fires Player#emptied
  7677. * @listens Tech#emptied
  7678. */
  7679. 'emptied',
  7680. /**
  7681. * Fires when the browser is trying to get media data, but data is not available.
  7682. *
  7683. * @event Player#stalled
  7684. * @type {EventTarget~Event}
  7685. */
  7686. /**
  7687. * Retrigger the `stalled` event that was triggered by the {@link Tech}.
  7688. *
  7689. * @private
  7690. * @method Player#handleTechStalled_
  7691. * @fires Player#stalled
  7692. * @listens Tech#stalled
  7693. */
  7694. 'stalled',
  7695. /**
  7696. * Fires when the browser has loaded meta data for the audio/video.
  7697. *
  7698. * @event Player#loadedmetadata
  7699. * @type {EventTarget~Event}
  7700. */
  7701. /**
  7702. * Retrigger the `stalled` event that was triggered by the {@link Tech}.
  7703. *
  7704. * @private
  7705. * @method Player#handleTechLoadedmetadata_
  7706. * @fires Player#loadedmetadata
  7707. * @listens Tech#loadedmetadata
  7708. */
  7709. 'loadedmetadata',
  7710. /**
  7711. * Fires when the browser has loaded the current frame of the audio/video.
  7712. *
  7713. * @event player#loadeddata
  7714. * @type {event}
  7715. */
  7716. /**
  7717. * Retrigger the `loadeddata` event that was triggered by the {@link Tech}.
  7718. *
  7719. * @private
  7720. * @method Player#handleTechLoaddeddata_
  7721. * @fires Player#loadeddata
  7722. * @listens Tech#loadeddata
  7723. */
  7724. 'loadeddata',
  7725. /**
  7726. * Fires when the current playback position has changed.
  7727. *
  7728. * @event player#timeupdate
  7729. * @type {event}
  7730. */
  7731. /**
  7732. * Retrigger the `timeupdate` event that was triggered by the {@link Tech}.
  7733. *
  7734. * @private
  7735. * @method Player#handleTechTimeUpdate_
  7736. * @fires Player#timeupdate
  7737. * @listens Tech#timeupdate
  7738. */
  7739. 'timeupdate',
  7740. /**
  7741. * Fires when the playing speed of the audio/video is changed
  7742. *
  7743. * @event player#ratechange
  7744. * @type {event}
  7745. */
  7746. /**
  7747. * Retrigger the `ratechange` event that was triggered by the {@link Tech}.
  7748. *
  7749. * @private
  7750. * @method Player#handleTechRatechange_
  7751. * @fires Player#ratechange
  7752. * @listens Tech#ratechange
  7753. */
  7754. 'ratechange',
  7755. /**
  7756. * Fires when the video's intrinsic dimensions change
  7757. *
  7758. * @event Player#resize
  7759. * @type {event}
  7760. */
  7761. /**
  7762. * Retrigger the `resize` event that was triggered by the {@link Tech}.
  7763. *
  7764. * @private
  7765. * @method Player#handleTechResize_
  7766. * @fires Player#resize
  7767. * @listens Tech#resize
  7768. */
  7769. 'resize',
  7770. /**
  7771. * Fires when the volume has been changed
  7772. *
  7773. * @event player#volumechange
  7774. * @type {event}
  7775. */
  7776. /**
  7777. * Retrigger the `volumechange` event that was triggered by the {@link Tech}.
  7778. *
  7779. * @private
  7780. * @method Player#handleTechVolumechange_
  7781. * @fires Player#volumechange
  7782. * @listens Tech#volumechange
  7783. */
  7784. 'volumechange',
  7785. /**
  7786. * Fires when the text track has been changed
  7787. *
  7788. * @event player#texttrackchange
  7789. * @type {event}
  7790. */
  7791. /**
  7792. * Retrigger the `texttrackchange` event that was triggered by the {@link Tech}.
  7793. *
  7794. * @private
  7795. * @method Player#handleTechTexttrackchange_
  7796. * @fires Player#texttrackchange
  7797. * @listens Tech#texttrackchange
  7798. */
  7799. 'texttrackchange'];
  7800. /**
  7801. * An instance of the `Player` class is created when any of the Video.js setup methods
  7802. * are used to initialize a video.
  7803. *
  7804. * After an instance has been created it can be accessed globally in two ways:
  7805. * 1. By calling `videojs('example_video_1');`
  7806. * 2. By using it directly via `videojs.players.example_video_1;`
  7807. *
  7808. * @extends Component
  7809. */
  7810. var Player = function (_Component) {
  7811. _inherits(Player, _Component);
  7812. /**
  7813. * Create an instance of this class.
  7814. *
  7815. * @param {Element} tag
  7816. * The original video DOM element used for configuring options.
  7817. *
  7818. * @param {Object} [options]
  7819. * Object of option names and values.
  7820. *
  7821. * @param {Component~ReadyCallback} [ready]
  7822. * Ready callback function.
  7823. */
  7824. function Player(tag, options, ready) {
  7825. _classCallCheck(this, Player);
  7826. // Make sure tag ID exists
  7827. tag.id = tag.id || 'vjs_video_' + Guid.newGUID();
  7828. // Set Options
  7829. // The options argument overrides options set in the video tag
  7830. // which overrides globally set options.
  7831. // This latter part coincides with the load order
  7832. // (tag must exist before Player)
  7833. options = (0, _obj.assign)(Player.getTagSettings(tag), options);
  7834. // Delay the initialization of children because we need to set up
  7835. // player properties first, and can't use `this` before `super()`
  7836. options.initChildren = false;
  7837. // Same with creating the element
  7838. options.createEl = false;
  7839. // we don't want the player to report touch activity on itself
  7840. // see enableTouchActivity in Component
  7841. options.reportTouchActivity = false;
  7842. // If language is not set, get the closest lang attribute
  7843. if (!options.language) {
  7844. if (typeof tag.closest === 'function') {
  7845. var closest = tag.closest('[lang]');
  7846. if (closest) {
  7847. options.language = closest.getAttribute('lang');
  7848. }
  7849. } else {
  7850. var element = tag;
  7851. while (element && element.nodeType === 1) {
  7852. if (Dom.getAttributes(element).hasOwnProperty('lang')) {
  7853. options.language = element.getAttribute('lang');
  7854. break;
  7855. }
  7856. element = element.parentNode;
  7857. }
  7858. }
  7859. }
  7860. // Run base component initializing with new options
  7861. // Turn off API access because we're loading a new tech that might load asynchronously
  7862. var _this = _possibleConstructorReturn(this, _Component.call(this, null, options, ready));
  7863. _this.isReady_ = false;
  7864. // if the global option object was accidentally blown away by
  7865. // someone, bail early with an informative error
  7866. if (!_this.options_ || !_this.options_.techOrder || !_this.options_.techOrder.length) {
  7867. throw new Error('No techOrder specified. Did you overwrite ' + 'videojs.options instead of just changing the ' + 'properties you want to override?');
  7868. }
  7869. // Store the original tag used to set options
  7870. _this.tag = tag;
  7871. // Store the tag attributes used to restore html5 element
  7872. _this.tagAttributes = tag && Dom.getAttributes(tag);
  7873. // Update current language
  7874. _this.language(_this.options_.language);
  7875. // Update Supported Languages
  7876. if (options.languages) {
  7877. // Normalise player option languages to lowercase
  7878. var languagesToLower = {};
  7879. Object.getOwnPropertyNames(options.languages).forEach(function (name) {
  7880. languagesToLower[name.toLowerCase()] = options.languages[name];
  7881. });
  7882. _this.languages_ = languagesToLower;
  7883. } else {
  7884. _this.languages_ = Player.prototype.options_.languages;
  7885. }
  7886. // Cache for video property values.
  7887. _this.cache_ = {};
  7888. // Set poster
  7889. _this.poster_ = options.poster || '';
  7890. // Set controls
  7891. _this.controls_ = !!options.controls;
  7892. // Set default values for lastVolume
  7893. _this.cache_.lastVolume = 1;
  7894. // Original tag settings stored in options
  7895. // now remove immediately so native controls don't flash.
  7896. // May be turned back on by HTML5 tech if nativeControlsForTouch is true
  7897. tag.controls = false;
  7898. /*
  7899. * Store the internal state of scrubbing
  7900. *
  7901. * @private
  7902. * @return {Boolean} True if the user is scrubbing
  7903. */
  7904. _this.scrubbing_ = false;
  7905. _this.el_ = _this.createEl();
  7906. // Make this an evented object and use `el_` as its event bus.
  7907. (0, _evented2['default'])(_this, { eventBusKey: 'el_' });
  7908. // We also want to pass the original player options to each component and plugin
  7909. // as well so they don't need to reach back into the player for options later.
  7910. // We also need to do another copy of this.options_ so we don't end up with
  7911. // an infinite loop.
  7912. var playerOptionsCopy = (0, _mergeOptions2['default'])(_this.options_);
  7913. // Load plugins
  7914. if (options.plugins) {
  7915. var plugins = options.plugins;
  7916. Object.keys(plugins).forEach(function (name) {
  7917. if (typeof this[name] === 'function') {
  7918. this[name](plugins[name]);
  7919. } else {
  7920. throw new Error('plugin "' + name + '" does not exist');
  7921. }
  7922. }, _this);
  7923. }
  7924. _this.options_.playerOptions = playerOptionsCopy;
  7925. _this.middleware_ = [];
  7926. _this.initChildren();
  7927. // Set isAudio based on whether or not an audio tag was used
  7928. _this.isAudio(tag.nodeName.toLowerCase() === 'audio');
  7929. // Update controls className. Can't do this when the controls are initially
  7930. // set because the element doesn't exist yet.
  7931. if (_this.controls()) {
  7932. _this.addClass('vjs-controls-enabled');
  7933. } else {
  7934. _this.addClass('vjs-controls-disabled');
  7935. }
  7936. // Set ARIA label and region role depending on player type
  7937. _this.el_.setAttribute('role', 'region');
  7938. if (_this.isAudio()) {
  7939. _this.el_.setAttribute('aria-label', _this.localize('Audio Player'));
  7940. } else {
  7941. _this.el_.setAttribute('aria-label', _this.localize('Video Player'));
  7942. }
  7943. if (_this.isAudio()) {
  7944. _this.addClass('vjs-audio');
  7945. }
  7946. if (_this.flexNotSupported_()) {
  7947. _this.addClass('vjs-no-flex');
  7948. }
  7949. // TODO: Make this smarter. Toggle user state between touching/mousing
  7950. // using events, since devices can have both touch and mouse events.
  7951. // if (browser.TOUCH_ENABLED) {
  7952. // this.addClass('vjs-touch-enabled');
  7953. // }
  7954. // iOS Safari has broken hover handling
  7955. if (!browser.IS_IOS) {
  7956. _this.addClass('vjs-workinghover');
  7957. }
  7958. // Make player easily findable by ID
  7959. Player.players[_this.id_] = _this;
  7960. // When the player is first initialized, trigger activity so components
  7961. // like the control bar show themselves if needed
  7962. _this.userActive(true);
  7963. _this.reportUserActivity();
  7964. _this.listenForUserActivity_();
  7965. _this.on('fullscreenchange', _this.handleFullscreenChange_);
  7966. _this.on('stageclick', _this.handleStageClick_);
  7967. _this.changingSrc_ = false;
  7968. return _this;
  7969. }
  7970. /**
  7971. * Destroys the video player and does any necessary cleanup.
  7972. *
  7973. * This is especially helpful if you are dynamically adding and removing videos
  7974. * to/from the DOM.
  7975. *
  7976. * @fires Player#dispose
  7977. */
  7978. Player.prototype.dispose = function dispose() {
  7979. /**
  7980. * Called when the player is being disposed of.
  7981. *
  7982. * @event Player#dispose
  7983. * @type {EventTarget~Event}
  7984. */
  7985. this.trigger('dispose');
  7986. // prevent dispose from being called twice
  7987. this.off('dispose');
  7988. if (this.styleEl_ && this.styleEl_.parentNode) {
  7989. this.styleEl_.parentNode.removeChild(this.styleEl_);
  7990. }
  7991. // Kill reference to this player
  7992. Player.players[this.id_] = null;
  7993. if (this.tag && this.tag.player) {
  7994. this.tag.player = null;
  7995. }
  7996. if (this.el_ && this.el_.player) {
  7997. this.el_.player = null;
  7998. }
  7999. if (this.tech_) {
  8000. this.tech_.dispose();
  8001. }
  8002. _Component.prototype.dispose.call(this);
  8003. };
  8004. /**
  8005. * Create the `Player`'s DOM element.
  8006. *
  8007. * @return {Element}
  8008. * The DOM element that gets created.
  8009. */
  8010. Player.prototype.createEl = function createEl() {
  8011. var tag = this.tag;
  8012. var el = void 0;
  8013. var playerElIngest = this.playerElIngest_ = tag.parentNode && tag.parentNode.hasAttribute && tag.parentNode.hasAttribute('data-vjs-player');
  8014. if (playerElIngest) {
  8015. el = this.el_ = tag.parentNode;
  8016. } else {
  8017. el = this.el_ = _Component.prototype.createEl.call(this, 'div');
  8018. }
  8019. // set tabindex to -1 so we could focus on the player element
  8020. tag.setAttribute('tabindex', '-1');
  8021. // Remove width/height attrs from tag so CSS can make it 100% width/height
  8022. tag.removeAttribute('width');
  8023. tag.removeAttribute('height');
  8024. // Copy over all the attributes from the tag, including ID and class
  8025. // ID will now reference player box, not the video tag
  8026. var attrs = Dom.getAttributes(tag);
  8027. Object.getOwnPropertyNames(attrs).forEach(function (attr) {
  8028. // workaround so we don't totally break IE7
  8029. // http://stackoverflow.com/questions/3653444/css-styles-not-applied-on-dynamic-elements-in-internet-explorer-7
  8030. if (attr === 'class') {
  8031. el.className += ' ' + attrs[attr];
  8032. } else {
  8033. el.setAttribute(attr, attrs[attr]);
  8034. }
  8035. });
  8036. // Update tag id/class for use as HTML5 playback tech
  8037. // Might think we should do this after embedding in container so .vjs-tech class
  8038. // doesn't flash 100% width/height, but class only applies with .video-js parent
  8039. tag.playerId = tag.id;
  8040. tag.id += '_html5_api';
  8041. tag.className = 'vjs-tech';
  8042. // Make player findable on elements
  8043. tag.player = el.player = this;
  8044. // Default state of video is paused
  8045. this.addClass('vjs-paused');
  8046. // Add a style element in the player that we'll use to set the width/height
  8047. // of the player in a way that's still overrideable by CSS, just like the
  8048. // video element
  8049. if (_window2['default'].VIDEOJS_NO_DYNAMIC_STYLE !== true) {
  8050. this.styleEl_ = stylesheet.createStyleElement('vjs-styles-dimensions');
  8051. var defaultsStyleEl = Dom.$('.vjs-styles-defaults');
  8052. var head = Dom.$('head');
  8053. head.insertBefore(this.styleEl_, defaultsStyleEl ? defaultsStyleEl.nextSibling : head.firstChild);
  8054. }
  8055. // Pass in the width/height/aspectRatio options which will update the style el
  8056. this.width(this.options_.width);
  8057. this.height(this.options_.height);
  8058. this.fluid(this.options_.fluid);
  8059. this.aspectRatio(this.options_.aspectRatio);
  8060. // Hide any links within the video/audio tag, because IE doesn't hide them completely.
  8061. var links = tag.getElementsByTagName('a');
  8062. for (var i = 0; i < links.length; i++) {
  8063. var linkEl = links.item(i);
  8064. Dom.addClass(linkEl, 'vjs-hidden');
  8065. linkEl.setAttribute('hidden', 'hidden');
  8066. }
  8067. // insertElFirst seems to cause the networkState to flicker from 3 to 2, so
  8068. // keep track of the original for later so we can know if the source originally failed
  8069. tag.initNetworkState_ = tag.networkState;
  8070. // Wrap video tag in div (el/box) container
  8071. if (tag.parentNode && !playerElIngest) {
  8072. tag.parentNode.insertBefore(el, tag);
  8073. }
  8074. // insert the tag as the first child of the player element
  8075. // then manually add it to the children array so that this.addChild
  8076. // will work properly for other components
  8077. //
  8078. // Breaks iPhone, fixed in HTML5 setup.
  8079. Dom.prependTo(tag, el);
  8080. this.children_.unshift(tag);
  8081. // Set lang attr on player to ensure CSS :lang() in consistent with player
  8082. // if it's been set to something different to the doc
  8083. this.el_.setAttribute('lang', this.language_);
  8084. this.el_ = el;
  8085. return el;
  8086. };
  8087. /**
  8088. * A getter/setter for the `Player`'s width.
  8089. *
  8090. * @param {number} [value]
  8091. * The value to set the `Player's width to.
  8092. *
  8093. * @return {number}
  8094. * The current width of the `Player` when getting.
  8095. */
  8096. Player.prototype.width = function width(value) {
  8097. return this.dimension('width', value);
  8098. };
  8099. /**
  8100. * A getter/setter for the `Player`'s height.
  8101. *
  8102. * @param {number} [value]
  8103. * The value to set the `Player's heigth to.
  8104. *
  8105. * @return {number}
  8106. * The current height of the `Player` when getting.
  8107. */
  8108. Player.prototype.height = function height(value) {
  8109. return this.dimension('height', value);
  8110. };
  8111. /**
  8112. * A getter/setter for the `Player`'s width & height.
  8113. *
  8114. * @param {string} dimension
  8115. * This string can be:
  8116. * - 'width'
  8117. * - 'height'
  8118. *
  8119. * @param {number} [value]
  8120. * Value for dimension specified in the first argument.
  8121. *
  8122. * @return {number}
  8123. * The dimension arguments value when getting (width/height).
  8124. */
  8125. Player.prototype.dimension = function dimension(_dimension, value) {
  8126. var privDimension = _dimension + '_';
  8127. if (value === undefined) {
  8128. return this[privDimension] || 0;
  8129. }
  8130. if (value === '') {
  8131. // If an empty string is given, reset the dimension to be automatic
  8132. this[privDimension] = undefined;
  8133. } else {
  8134. var parsedVal = parseFloat(value);
  8135. if (isNaN(parsedVal)) {
  8136. _log2['default'].error('Improper value "' + value + '" supplied for for ' + _dimension);
  8137. return;
  8138. }
  8139. this[privDimension] = parsedVal;
  8140. }
  8141. this.updateStyleEl_();
  8142. };
  8143. /**
  8144. * A getter/setter/toggler for the vjs-fluid `className` on the `Player`.
  8145. *
  8146. * @param {boolean} [bool]
  8147. * - A value of true adds the class.
  8148. * - A value of false removes the class.
  8149. * - No value will toggle the fluid class.
  8150. *
  8151. * @return {boolean|undefined}
  8152. * - The value of fluid when getting.
  8153. * - `undefined` when setting.
  8154. */
  8155. Player.prototype.fluid = function fluid(bool) {
  8156. if (bool === undefined) {
  8157. return !!this.fluid_;
  8158. }
  8159. this.fluid_ = !!bool;
  8160. if (bool) {
  8161. this.addClass('vjs-fluid');
  8162. } else {
  8163. this.removeClass('vjs-fluid');
  8164. }
  8165. this.updateStyleEl_();
  8166. };
  8167. /**
  8168. * Get/Set the aspect ratio
  8169. *
  8170. * @param {string} [ratio]
  8171. * Aspect ratio for player
  8172. *
  8173. * @return {string|undefined}
  8174. * returns the current aspect ratio when getting
  8175. */
  8176. /**
  8177. * A getter/setter for the `Player`'s aspect ratio.
  8178. *
  8179. * @param {string} [ratio]
  8180. * The value to set the `Player's aspect ratio to.
  8181. *
  8182. * @return {string|undefined}
  8183. * - The current aspect ratio of the `Player` when getting.
  8184. * - undefined when setting
  8185. */
  8186. Player.prototype.aspectRatio = function aspectRatio(ratio) {
  8187. if (ratio === undefined) {
  8188. return this.aspectRatio_;
  8189. }
  8190. // Check for width:height format
  8191. if (!/^\d+\:\d+$/.test(ratio)) {
  8192. throw new Error('Improper value supplied for aspect ratio. The format should be width:height, for example 16:9.');
  8193. }
  8194. this.aspectRatio_ = ratio;
  8195. // We're assuming if you set an aspect ratio you want fluid mode,
  8196. // because in fixed mode you could calculate width and height yourself.
  8197. this.fluid(true);
  8198. this.updateStyleEl_();
  8199. };
  8200. /**
  8201. * Update styles of the `Player` element (height, width and aspect ratio).
  8202. *
  8203. * @private
  8204. * @listens Tech#loadedmetadata
  8205. */
  8206. Player.prototype.updateStyleEl_ = function updateStyleEl_() {
  8207. if (_window2['default'].VIDEOJS_NO_DYNAMIC_STYLE === true) {
  8208. var _width = typeof this.width_ === 'number' ? this.width_ : this.options_.width;
  8209. var _height = typeof this.height_ === 'number' ? this.height_ : this.options_.height;
  8210. var techEl = this.tech_ && this.tech_.el();
  8211. if (techEl) {
  8212. if (_width >= 0) {
  8213. techEl.width = _width;
  8214. }
  8215. if (_height >= 0) {
  8216. techEl.height = _height;
  8217. }
  8218. }
  8219. return;
  8220. }
  8221. var width = void 0;
  8222. var height = void 0;
  8223. var aspectRatio = void 0;
  8224. var idClass = void 0;
  8225. // The aspect ratio is either used directly or to calculate width and height.
  8226. if (this.aspectRatio_ !== undefined && this.aspectRatio_ !== 'auto') {
  8227. // Use any aspectRatio that's been specifically set
  8228. aspectRatio = this.aspectRatio_;
  8229. } else if (this.videoWidth() > 0) {
  8230. // Otherwise try to get the aspect ratio from the video metadata
  8231. aspectRatio = this.videoWidth() + ':' + this.videoHeight();
  8232. } else {
  8233. // Or use a default. The video element's is 2:1, but 16:9 is more common.
  8234. aspectRatio = '16:9';
  8235. }
  8236. // Get the ratio as a decimal we can use to calculate dimensions
  8237. var ratioParts = aspectRatio.split(':');
  8238. var ratioMultiplier = ratioParts[1] / ratioParts[0];
  8239. if (this.width_ !== undefined) {
  8240. // Use any width that's been specifically set
  8241. width = this.width_;
  8242. } else if (this.height_ !== undefined) {
  8243. // Or calulate the width from the aspect ratio if a height has been set
  8244. width = this.height_ / ratioMultiplier;
  8245. } else {
  8246. // Or use the video's metadata, or use the video el's default of 300
  8247. width = this.videoWidth() || 300;
  8248. }
  8249. if (this.height_ !== undefined) {
  8250. // Use any height that's been specifically set
  8251. height = this.height_;
  8252. } else {
  8253. // Otherwise calculate the height from the ratio and the width
  8254. height = width * ratioMultiplier;
  8255. }
  8256. // Ensure the CSS class is valid by starting with an alpha character
  8257. if (/^[^a-zA-Z]/.test(this.id())) {
  8258. idClass = 'dimensions-' + this.id();
  8259. } else {
  8260. idClass = this.id() + '-dimensions';
  8261. }
  8262. // Ensure the right class is still on the player for the style element
  8263. this.addClass(idClass);
  8264. stylesheet.setTextContent(this.styleEl_, '\n .' + idClass + ' {\n width: ' + width + 'px;\n height: ' + height + 'px;\n }\n\n .' + idClass + '.vjs-fluid {\n padding-top: ' + ratioMultiplier * 100 + '%;\n }\n ');
  8265. };
  8266. /**
  8267. * Load/Create an instance of playback {@link Tech} including element
  8268. * and API methods. Then append the `Tech` element in `Player` as a child.
  8269. *
  8270. * @param {string} techName
  8271. * name of the playback technology
  8272. *
  8273. * @param {string} source
  8274. * video source
  8275. *
  8276. * @private
  8277. */
  8278. Player.prototype.loadTech_ = function loadTech_(techName, source) {
  8279. var _this2 = this;
  8280. // Pause and remove current playback technology
  8281. if (this.tech_) {
  8282. this.unloadTech_();
  8283. }
  8284. var titleTechName = (0, _toTitleCase2['default'])(techName);
  8285. var camelTechName = techName.charAt(0).toLowerCase() + techName.slice(1);
  8286. // get rid of the HTML5 video tag as soon as we are using another tech
  8287. if (titleTechName !== 'Html5' && this.tag) {
  8288. _tech2['default'].getTech('Html5').disposeMediaElement(this.tag);
  8289. this.tag.player = null;
  8290. this.tag = null;
  8291. }
  8292. this.techName_ = titleTechName;
  8293. // Turn off API access because we're loading a new tech that might load asynchronously
  8294. this.isReady_ = false;
  8295. // Grab tech-specific options from player options and add source and parent element to use.
  8296. var techOptions = {
  8297. source: source,
  8298. 'nativeControlsForTouch': this.options_.nativeControlsForTouch,
  8299. 'playerId': this.id(),
  8300. 'techId': this.id() + '_' + titleTechName + '_api',
  8301. 'autoplay': this.options_.autoplay,
  8302. 'preload': this.options_.preload,
  8303. 'loop': this.options_.loop,
  8304. 'muted': this.options_.muted,
  8305. 'poster': this.poster(),
  8306. 'language': this.language(),
  8307. 'playerElIngest': this.playerElIngest_ || false,
  8308. 'vtt.js': this.options_['vtt.js']
  8309. };
  8310. _trackTypes.ALL.names.forEach(function (name) {
  8311. var props = _trackTypes.ALL[name];
  8312. techOptions[props.getterName] = _this2[props.privateName];
  8313. });
  8314. (0, _obj.assign)(techOptions, this.options_[titleTechName]);
  8315. (0, _obj.assign)(techOptions, this.options_[camelTechName]);
  8316. (0, _obj.assign)(techOptions, this.options_[techName.toLowerCase()]);
  8317. if (this.tag) {
  8318. techOptions.tag = this.tag;
  8319. }
  8320. if (source && source.src === this.cache_.src && this.cache_.currentTime > 0) {
  8321. techOptions.startTime = this.cache_.currentTime;
  8322. }
  8323. // Initialize tech instance
  8324. var TechClass = _tech2['default'].getTech(techName);
  8325. if (!TechClass) {
  8326. throw new Error('No Tech named \'' + titleTechName + '\' exists! \'' + titleTechName + '\' should be registered using videojs.registerTech()\'');
  8327. }
  8328. this.tech_ = new TechClass(techOptions);
  8329. // player.triggerReady is always async, so don't need this to be async
  8330. this.tech_.ready(Fn.bind(this, this.handleTechReady_), true);
  8331. _textTrackListConverter2['default'].jsonToTextTracks(this.textTracksJson_ || [], this.tech_);
  8332. // Listen to all HTML5-defined events and trigger them on the player
  8333. TECH_EVENTS_RETRIGGER.forEach(function (event) {
  8334. _this2.on(_this2.tech_, event, _this2['handleTech' + (0, _toTitleCase2['default'])(event) + '_']);
  8335. });
  8336. this.on(this.tech_, 'loadstart', this.handleTechLoadStart_);
  8337. this.on(this.tech_, 'waiting', this.handleTechWaiting_);
  8338. this.on(this.tech_, 'canplay', this.handleTechCanPlay_);
  8339. this.on(this.tech_, 'canplaythrough', this.handleTechCanPlayThrough_);
  8340. this.on(this.tech_, 'playing', this.handleTechPlaying_);
  8341. this.on(this.tech_, 'ended', this.handleTechEnded_);
  8342. this.on(this.tech_, 'seeking', this.handleTechSeeking_);
  8343. this.on(this.tech_, 'seeked', this.handleTechSeeked_);
  8344. this.on(this.tech_, 'play', this.handleTechPlay_);
  8345. this.on(this.tech_, 'firstplay', this.handleTechFirstPlay_);
  8346. this.on(this.tech_, 'pause', this.handleTechPause_);
  8347. this.on(this.tech_, 'durationchange', this.handleTechDurationChange_);
  8348. this.on(this.tech_, 'fullscreenchange', this.handleTechFullscreenChange_);
  8349. this.on(this.tech_, 'error', this.handleTechError_);
  8350. this.on(this.tech_, 'loadedmetadata', this.updateStyleEl_);
  8351. this.on(this.tech_, 'posterchange', this.handleTechPosterChange_);
  8352. this.on(this.tech_, 'textdata', this.handleTechTextData_);
  8353. this.usingNativeControls(this.techGet_('controls'));
  8354. if (this.controls() && !this.usingNativeControls()) {
  8355. this.addTechControlsListeners_();
  8356. }
  8357. // Add the tech element in the DOM if it was not already there
  8358. // Make sure to not insert the original video element if using Html5
  8359. if (this.tech_.el().parentNode !== this.el() && (titleTechName !== 'Html5' || !this.tag)) {
  8360. Dom.prependTo(this.tech_.el(), this.el());
  8361. }
  8362. // Get rid of the original video tag reference after the first tech is loaded
  8363. if (this.tag) {
  8364. this.tag.player = null;
  8365. this.tag = null;
  8366. }
  8367. };
  8368. /**
  8369. * Unload and dispose of the current playback {@link Tech}.
  8370. *
  8371. * @private
  8372. */
  8373. Player.prototype.unloadTech_ = function unloadTech_() {
  8374. var _this3 = this;
  8375. // Save the current text tracks so that we can reuse the same text tracks with the next tech
  8376. _trackTypes.ALL.names.forEach(function (name) {
  8377. var props = _trackTypes.ALL[name];
  8378. _this3[props.privateName] = _this3[props.getterName]();
  8379. });
  8380. this.textTracksJson_ = _textTrackListConverter2['default'].textTracksToJson(this.tech_);
  8381. this.isReady_ = false;
  8382. this.tech_.dispose();
  8383. this.tech_ = false;
  8384. };
  8385. /**
  8386. * Return a reference to the current {@link Tech}.
  8387. * It will print a warning by default about the danger of using the tech directly
  8388. * but any argument that is passed in will silence the warning.
  8389. *
  8390. * @param {*} [safety]
  8391. * Anything passed in to silence the warning
  8392. *
  8393. * @return {Tech}
  8394. * The Tech
  8395. */
  8396. Player.prototype.tech = function tech(safety) {
  8397. if (safety === undefined) {
  8398. _log2['default'].warn((0, _tsml2['default'])(_templateObject));
  8399. }
  8400. return this.tech_;
  8401. };
  8402. /**
  8403. * Set up click and touch listeners for the playback element
  8404. *
  8405. * - On desktops: a click on the video itself will toggle playback
  8406. * - On mobile devices: a click on the video toggles controls
  8407. * which is done by toggling the user state between active and
  8408. * inactive
  8409. * - A tap can signal that a user has become active or has become inactive
  8410. * e.g. a quick tap on an iPhone movie should reveal the controls. Another
  8411. * quick tap should hide them again (signaling the user is in an inactive
  8412. * viewing state)
  8413. * - In addition to this, we still want the user to be considered inactive after
  8414. * a few seconds of inactivity.
  8415. *
  8416. * > Note: the only part of iOS interaction we can't mimic with this setup
  8417. * is a touch and hold on the video element counting as activity in order to
  8418. * keep the controls showing, but that shouldn't be an issue. A touch and hold
  8419. * on any controls will still keep the user active
  8420. *
  8421. * @private
  8422. */
  8423. Player.prototype.addTechControlsListeners_ = function addTechControlsListeners_() {
  8424. // Make sure to remove all the previous listeners in case we are called multiple times.
  8425. this.removeTechControlsListeners_();
  8426. // Some browsers (Chrome & IE) don't trigger a click on a flash swf, but do
  8427. // trigger mousedown/up.
  8428. // http://stackoverflow.com/questions/1444562/javascript-onclick-event-over-flash-object
  8429. // Any touch events are set to block the mousedown event from happening
  8430. this.on(this.tech_, 'mousedown', this.handleTechClick_);
  8431. // If the controls were hidden we don't want that to change without a tap event
  8432. // so we'll check if the controls were already showing before reporting user
  8433. // activity
  8434. this.on(this.tech_, 'touchstart', this.handleTechTouchStart_);
  8435. this.on(this.tech_, 'touchmove', this.handleTechTouchMove_);
  8436. this.on(this.tech_, 'touchend', this.handleTechTouchEnd_);
  8437. // The tap listener needs to come after the touchend listener because the tap
  8438. // listener cancels out any reportedUserActivity when setting userActive(false)
  8439. this.on(this.tech_, 'tap', this.handleTechTap_);
  8440. };
  8441. /**
  8442. * Remove the listeners used for click and tap controls. This is needed for
  8443. * toggling to controls disabled, where a tap/touch should do nothing.
  8444. *
  8445. * @private
  8446. */
  8447. Player.prototype.removeTechControlsListeners_ = function removeTechControlsListeners_() {
  8448. // We don't want to just use `this.off()` because there might be other needed
  8449. // listeners added by techs that extend this.
  8450. this.off(this.tech_, 'tap', this.handleTechTap_);
  8451. this.off(this.tech_, 'touchstart', this.handleTechTouchStart_);
  8452. this.off(this.tech_, 'touchmove', this.handleTechTouchMove_);
  8453. this.off(this.tech_, 'touchend', this.handleTechTouchEnd_);
  8454. this.off(this.tech_, 'mousedown', this.handleTechClick_);
  8455. };
  8456. /**
  8457. * Player waits for the tech to be ready
  8458. *
  8459. * @private
  8460. */
  8461. Player.prototype.handleTechReady_ = function handleTechReady_() {
  8462. this.triggerReady();
  8463. // Keep the same volume as before
  8464. if (this.cache_.volume) {
  8465. this.techCall_('setVolume', this.cache_.volume);
  8466. }
  8467. // Look if the tech found a higher resolution poster while loading
  8468. this.handleTechPosterChange_();
  8469. // Update the duration if available
  8470. this.handleTechDurationChange_();
  8471. // Chrome and Safari both have issues with autoplay.
  8472. // In Safari (5.1.1), when we move the video element into the container div, autoplay doesn't work.
  8473. // In Chrome (15), if you have autoplay + a poster + no controls, the video gets hidden (but audio plays)
  8474. // This fixes both issues. Need to wait for API, so it updates displays correctly
  8475. if ((this.src() || this.currentSrc()) && this.tag && this.options_.autoplay && this.paused()) {
  8476. try {
  8477. // Chrome Fix. Fixed in Chrome v16.
  8478. delete this.tag.poster;
  8479. } catch (e) {
  8480. (0, _log2['default'])('deleting tag.poster throws in some browsers', e);
  8481. }
  8482. this.play();
  8483. }
  8484. };
  8485. /**
  8486. * Retrigger the `loadstart` event that was triggered by the {@link Tech}. This
  8487. * function will also trigger {@link Player#firstplay} if it is the first loadstart
  8488. * for a video.
  8489. *
  8490. * @fires Player#loadstart
  8491. * @fires Player#firstplay
  8492. * @listens Tech#loadstart
  8493. * @private
  8494. */
  8495. Player.prototype.handleTechLoadStart_ = function handleTechLoadStart_() {
  8496. // TODO: Update to use `emptied` event instead. See #1277.
  8497. this.removeClass('vjs-ended');
  8498. this.removeClass('vjs-seeking');
  8499. // reset the error state
  8500. this.error(null);
  8501. // If it's already playing we want to trigger a firstplay event now.
  8502. // The firstplay event relies on both the play and loadstart events
  8503. // which can happen in any order for a new source
  8504. if (!this.paused()) {
  8505. /**
  8506. * Fired when the user agent begins looking for media data
  8507. *
  8508. * @event Player#loadstart
  8509. * @type {EventTarget~Event}
  8510. */
  8511. this.trigger('loadstart');
  8512. this.trigger('firstplay');
  8513. } else {
  8514. // reset the hasStarted state
  8515. this.hasStarted(false);
  8516. this.trigger('loadstart');
  8517. }
  8518. };
  8519. /**
  8520. * Add/remove the vjs-has-started class
  8521. *
  8522. * @fires Player#firstplay
  8523. *
  8524. * @param {boolean} hasStarted
  8525. * - true: adds the class
  8526. * - false: remove the class
  8527. *
  8528. * @return {boolean}
  8529. * the boolean value of hasStarted
  8530. */
  8531. Player.prototype.hasStarted = function hasStarted(_hasStarted) {
  8532. if (_hasStarted !== undefined) {
  8533. // only update if this is a new value
  8534. if (this.hasStarted_ !== _hasStarted) {
  8535. this.hasStarted_ = _hasStarted;
  8536. if (_hasStarted) {
  8537. this.addClass('vjs-has-started');
  8538. // trigger the firstplay event if this newly has played
  8539. this.trigger('firstplay');
  8540. } else {
  8541. this.removeClass('vjs-has-started');
  8542. }
  8543. }
  8544. return;
  8545. }
  8546. return !!this.hasStarted_;
  8547. };
  8548. /**
  8549. * Fired whenever the media begins or resumes playback
  8550. *
  8551. * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#dom-media-play}
  8552. * @fires Player#play
  8553. * @listens Tech#play
  8554. * @private
  8555. */
  8556. Player.prototype.handleTechPlay_ = function handleTechPlay_() {
  8557. this.removeClass('vjs-ended');
  8558. this.removeClass('vjs-paused');
  8559. this.addClass('vjs-playing');
  8560. // hide the poster when the user hits play
  8561. this.hasStarted(true);
  8562. /**
  8563. * Triggered whenever an {@link Tech#play} event happens. Indicates that
  8564. * playback has started or resumed.
  8565. *
  8566. * @event Player#play
  8567. * @type {EventTarget~Event}
  8568. */
  8569. this.trigger('play');
  8570. };
  8571. /**
  8572. * Retrigger the `waiting` event that was triggered by the {@link Tech}.
  8573. *
  8574. * @fires Player#waiting
  8575. * @listens Tech#waiting
  8576. * @private
  8577. */
  8578. Player.prototype.handleTechWaiting_ = function handleTechWaiting_() {
  8579. var _this4 = this;
  8580. this.addClass('vjs-waiting');
  8581. /**
  8582. * A readyState change on the DOM element has caused playback to stop.
  8583. *
  8584. * @event Player#waiting
  8585. * @type {EventTarget~Event}
  8586. */
  8587. this.trigger('waiting');
  8588. this.one('timeupdate', function () {
  8589. return _this4.removeClass('vjs-waiting');
  8590. });
  8591. };
  8592. /**
  8593. * Retrigger the `canplay` event that was triggered by the {@link Tech}.
  8594. * > Note: This is not consistent between browsers. See #1351
  8595. *
  8596. * @fires Player#canplay
  8597. * @listens Tech#canplay
  8598. * @private
  8599. */
  8600. Player.prototype.handleTechCanPlay_ = function handleTechCanPlay_() {
  8601. this.removeClass('vjs-waiting');
  8602. /**
  8603. * The media has a readyState of HAVE_FUTURE_DATA or greater.
  8604. *
  8605. * @event Player#canplay
  8606. * @type {EventTarget~Event}
  8607. */
  8608. this.trigger('canplay');
  8609. };
  8610. /**
  8611. * Retrigger the `canplaythrough` event that was triggered by the {@link Tech}.
  8612. *
  8613. * @fires Player#canplaythrough
  8614. * @listens Tech#canplaythrough
  8615. * @private
  8616. */
  8617. Player.prototype.handleTechCanPlayThrough_ = function handleTechCanPlayThrough_() {
  8618. this.removeClass('vjs-waiting');
  8619. /**
  8620. * The media has a readyState of HAVE_ENOUGH_DATA or greater. This means that the
  8621. * entire media file can be played without buffering.
  8622. *
  8623. * @event Player#canplaythrough
  8624. * @type {EventTarget~Event}
  8625. */
  8626. this.trigger('canplaythrough');
  8627. };
  8628. /**
  8629. * Retrigger the `playing` event that was triggered by the {@link Tech}.
  8630. *
  8631. * @fires Player#playing
  8632. * @listens Tech#playing
  8633. * @private
  8634. */
  8635. Player.prototype.handleTechPlaying_ = function handleTechPlaying_() {
  8636. this.removeClass('vjs-waiting');
  8637. /**
  8638. * The media is no longer blocked from playback, and has started playing.
  8639. *
  8640. * @event Player#playing
  8641. * @type {EventTarget~Event}
  8642. */
  8643. this.trigger('playing');
  8644. };
  8645. /**
  8646. * Retrigger the `seeking` event that was triggered by the {@link Tech}.
  8647. *
  8648. * @fires Player#seeking
  8649. * @listens Tech#seeking
  8650. * @private
  8651. */
  8652. Player.prototype.handleTechSeeking_ = function handleTechSeeking_() {
  8653. this.addClass('vjs-seeking');
  8654. /**
  8655. * Fired whenever the player is jumping to a new time
  8656. *
  8657. * @event Player#seeking
  8658. * @type {EventTarget~Event}
  8659. */
  8660. this.trigger('seeking');
  8661. };
  8662. /**
  8663. * Retrigger the `seeked` event that was triggered by the {@link Tech}.
  8664. *
  8665. * @fires Player#seeked
  8666. * @listens Tech#seeked
  8667. * @private
  8668. */
  8669. Player.prototype.handleTechSeeked_ = function handleTechSeeked_() {
  8670. this.removeClass('vjs-seeking');
  8671. /**
  8672. * Fired when the player has finished jumping to a new time
  8673. *
  8674. * @event Player#seeked
  8675. * @type {EventTarget~Event}
  8676. */
  8677. this.trigger('seeked');
  8678. };
  8679. /**
  8680. * Retrigger the `firstplay` event that was triggered by the {@link Tech}.
  8681. *
  8682. * @fires Player#firstplay
  8683. * @listens Tech#firstplay
  8684. * @deprecated As of 6.0 passing the `starttime` option to the player will be deprecated
  8685. * @private
  8686. */
  8687. Player.prototype.handleTechFirstPlay_ = function handleTechFirstPlay_() {
  8688. // If the first starttime attribute is specified
  8689. // then we will start at the given offset in seconds
  8690. if (this.options_.starttime) {
  8691. _log2['default'].warn('Passing the `starttime` option to the player will be deprecated in 6.0');
  8692. this.currentTime(this.options_.starttime);
  8693. }
  8694. this.addClass('vjs-has-started');
  8695. /**
  8696. * Fired the first time a video is played. Not part of the HLS spec, and this is
  8697. * probably not the best implementation yet, so use sparingly. If you don't have a
  8698. * reason to prevent playback, use `myPlayer.one('play');` instead.
  8699. *
  8700. * @event Player#firstplay
  8701. * @type {EventTarget~Event}
  8702. */
  8703. this.trigger('firstplay');
  8704. };
  8705. /**
  8706. * Retrigger the `pause` event that was triggered by the {@link Tech}.
  8707. *
  8708. * @fires Player#pause
  8709. * @listens Tech#pause
  8710. * @private
  8711. */
  8712. Player.prototype.handleTechPause_ = function handleTechPause_() {
  8713. this.removeClass('vjs-playing');
  8714. this.addClass('vjs-paused');
  8715. /**
  8716. * Fired whenever the media has been paused
  8717. *
  8718. * @event Player#pause
  8719. * @type {EventTarget~Event}
  8720. */
  8721. this.trigger('pause');
  8722. };
  8723. /**
  8724. * Retrigger the `ended` event that was triggered by the {@link Tech}.
  8725. *
  8726. * @fires Player#ended
  8727. * @listens Tech#ended
  8728. * @private
  8729. */
  8730. Player.prototype.handleTechEnded_ = function handleTechEnded_() {
  8731. this.addClass('vjs-ended');
  8732. if (this.options_.loop) {
  8733. this.currentTime(0);
  8734. this.play();
  8735. } else if (!this.paused()) {
  8736. this.pause();
  8737. }
  8738. /**
  8739. * Fired when the end of the media resource is reached (currentTime == duration)
  8740. *
  8741. * @event Player#ended
  8742. * @type {EventTarget~Event}
  8743. */
  8744. this.trigger('ended');
  8745. };
  8746. /**
  8747. * Fired when the duration of the media resource is first known or changed
  8748. *
  8749. * @listens Tech#durationchange
  8750. * @private
  8751. */
  8752. Player.prototype.handleTechDurationChange_ = function handleTechDurationChange_() {
  8753. this.duration(this.techGet_('duration'));
  8754. };
  8755. /**
  8756. * Handle a click on the media element to play/pause
  8757. *
  8758. * @param {EventTarget~Event} event
  8759. * the event that caused this function to trigger
  8760. *
  8761. * @listens Tech#mousedown
  8762. * @private
  8763. */
  8764. Player.prototype.handleTechClick_ = function handleTechClick_(event) {
  8765. // We're using mousedown to detect clicks thanks to Flash, but mousedown
  8766. // will also be triggered with right-clicks, so we need to prevent that
  8767. if (event.button !== 0) {
  8768. return;
  8769. }
  8770. // When controls are disabled a click should not toggle playback because
  8771. // the click is considered a control
  8772. if (this.controls()) {
  8773. if (this.paused()) {
  8774. this.play();
  8775. } else {
  8776. this.pause();
  8777. }
  8778. }
  8779. };
  8780. /**
  8781. * Handle a tap on the media element. It will toggle the user
  8782. * activity state, which hides and shows the controls.
  8783. *
  8784. * @listens Tech#tap
  8785. * @private
  8786. */
  8787. Player.prototype.handleTechTap_ = function handleTechTap_() {
  8788. this.userActive(!this.userActive());
  8789. };
  8790. /**
  8791. * Handle touch to start
  8792. *
  8793. * @listens Tech#touchstart
  8794. * @private
  8795. */
  8796. Player.prototype.handleTechTouchStart_ = function handleTechTouchStart_() {
  8797. this.userWasActive = this.userActive();
  8798. };
  8799. /**
  8800. * Handle touch to move
  8801. *
  8802. * @listens Tech#touchmove
  8803. * @private
  8804. */
  8805. Player.prototype.handleTechTouchMove_ = function handleTechTouchMove_() {
  8806. if (this.userWasActive) {
  8807. this.reportUserActivity();
  8808. }
  8809. };
  8810. /**
  8811. * Handle touch to end
  8812. *
  8813. * @param {EventTarget~Event} event
  8814. * the touchend event that triggered
  8815. * this function
  8816. *
  8817. * @listens Tech#touchend
  8818. * @private
  8819. */
  8820. Player.prototype.handleTechTouchEnd_ = function handleTechTouchEnd_(event) {
  8821. // Stop the mouse events from also happening
  8822. event.preventDefault();
  8823. };
  8824. /**
  8825. * Fired when the player switches in or out of fullscreen mode
  8826. *
  8827. * @private
  8828. * @listens Player#fullscreenchange
  8829. */
  8830. Player.prototype.handleFullscreenChange_ = function handleFullscreenChange_() {
  8831. if (this.isFullscreen()) {
  8832. this.addClass('vjs-fullscreen');
  8833. } else {
  8834. this.removeClass('vjs-fullscreen');
  8835. }
  8836. };
  8837. /**
  8838. * native click events on the SWF aren't triggered on IE11, Win8.1RT
  8839. * use stageclick events triggered from inside the SWF instead
  8840. *
  8841. * @private
  8842. * @listens stageclick
  8843. */
  8844. Player.prototype.handleStageClick_ = function handleStageClick_() {
  8845. this.reportUserActivity();
  8846. };
  8847. /**
  8848. * Handle Tech Fullscreen Change
  8849. *
  8850. * @param {EventTarget~Event} event
  8851. * the fullscreenchange event that triggered this function
  8852. *
  8853. * @param {Object} data
  8854. * the data that was sent with the event
  8855. *
  8856. * @private
  8857. * @listens Tech#fullscreenchange
  8858. * @fires Player#fullscreenchange
  8859. */
  8860. Player.prototype.handleTechFullscreenChange_ = function handleTechFullscreenChange_(event, data) {
  8861. if (data) {
  8862. this.isFullscreen(data.isFullscreen);
  8863. }
  8864. /**
  8865. * Fired when going in and out of fullscreen.
  8866. *
  8867. * @event Player#fullscreenchange
  8868. * @type {EventTarget~Event}
  8869. */
  8870. this.trigger('fullscreenchange');
  8871. };
  8872. /**
  8873. * Fires when an error occurred during the loading of an audio/video.
  8874. *
  8875. * @private
  8876. * @listens Tech#error
  8877. */
  8878. Player.prototype.handleTechError_ = function handleTechError_() {
  8879. var error = this.tech_.error();
  8880. this.error(error);
  8881. };
  8882. /**
  8883. * Retrigger the `textdata` event that was triggered by the {@link Tech}.
  8884. *
  8885. * @fires Player#textdata
  8886. * @listens Tech#textdata
  8887. * @private
  8888. */
  8889. Player.prototype.handleTechTextData_ = function handleTechTextData_() {
  8890. var data = null;
  8891. if (arguments.length > 1) {
  8892. data = arguments[1];
  8893. }
  8894. /**
  8895. * Fires when we get a textdata event from tech
  8896. *
  8897. * @event Player#textdata
  8898. * @type {EventTarget~Event}
  8899. */
  8900. this.trigger('textdata', data);
  8901. };
  8902. /**
  8903. * Get object for cached values.
  8904. *
  8905. * @return {Object}
  8906. * get the current object cache
  8907. */
  8908. Player.prototype.getCache = function getCache() {
  8909. return this.cache_;
  8910. };
  8911. /**
  8912. * Pass values to the playback tech
  8913. *
  8914. * @param {string} [method]
  8915. * the method to call
  8916. *
  8917. * @param {Object} arg
  8918. * the argument to pass
  8919. *
  8920. * @private
  8921. */
  8922. Player.prototype.techCall_ = function techCall_(method, arg) {
  8923. // If it's not ready yet, call method when it is
  8924. this.ready(function () {
  8925. if (method in middleware.allowedSetters) {
  8926. return middleware.set(this.middleware_, this.tech_, method, arg);
  8927. }
  8928. try {
  8929. if (this.tech_) {
  8930. this.tech_[method](arg);
  8931. }
  8932. } catch (e) {
  8933. (0, _log2['default'])(e);
  8934. throw e;
  8935. }
  8936. }, true);
  8937. };
  8938. /**
  8939. * Get calls can't wait for the tech, and sometimes don't need to.
  8940. *
  8941. * @param {string} method
  8942. * Tech method
  8943. *
  8944. * @return {Function|undefined}
  8945. * the method or undefined
  8946. *
  8947. * @private
  8948. */
  8949. Player.prototype.techGet_ = function techGet_(method) {
  8950. if (this.tech_ && this.tech_.isReady_) {
  8951. if (method in middleware.allowedGetters) {
  8952. return middleware.get(this.middleware_, this.tech_, method);
  8953. }
  8954. // Flash likes to die and reload when you hide or reposition it.
  8955. // In these cases the object methods go away and we get errors.
  8956. // When that happens we'll catch the errors and inform tech that it's not ready any more.
  8957. try {
  8958. return this.tech_[method]();
  8959. } catch (e) {
  8960. // When building additional tech libs, an expected method may not be defined yet
  8961. if (this.tech_[method] === undefined) {
  8962. (0, _log2['default'])('Video.js: ' + method + ' method not defined for ' + this.techName_ + ' playback technology.', e);
  8963. // When a method isn't available on the object it throws a TypeError
  8964. } else if (e.name === 'TypeError') {
  8965. (0, _log2['default'])('Video.js: ' + method + ' unavailable on ' + this.techName_ + ' playback technology element.', e);
  8966. this.tech_.isReady_ = false;
  8967. } else {
  8968. (0, _log2['default'])(e);
  8969. }
  8970. throw e;
  8971. }
  8972. }
  8973. return;
  8974. };
  8975. /**
  8976. * start media playback
  8977. *
  8978. * @return {Promise|undefined}
  8979. * Returns a `Promise` if the browser returns one, for most browsers this will
  8980. * return undefined.
  8981. */
  8982. Player.prototype.play = function play() {
  8983. if (this.changingSrc_) {
  8984. this.ready(function () {
  8985. this.techCall_('play');
  8986. });
  8987. // Only calls the tech's play if we already have a src loaded
  8988. } else if (this.isReady_ && (this.src() || this.currentSrc())) {
  8989. return this.techGet_('play');
  8990. } else {
  8991. this.ready(function () {
  8992. this.tech_.one('loadstart', function () {
  8993. var retval = this.play();
  8994. // silence errors (unhandled promise from play)
  8995. if (retval !== undefined && typeof retval.then === 'function') {
  8996. retval.then(null, function (e) {});
  8997. }
  8998. });
  8999. });
  9000. }
  9001. };
  9002. /**
  9003. * Pause the video playback
  9004. *
  9005. * @return {Player}
  9006. * A reference to the player object this function was called on
  9007. */
  9008. Player.prototype.pause = function pause() {
  9009. this.techCall_('pause');
  9010. };
  9011. /**
  9012. * Check if the player is paused or has yet to play
  9013. *
  9014. * @return {boolean}
  9015. * - false: if the media is currently playing
  9016. * - true: if media is not currently playing
  9017. */
  9018. Player.prototype.paused = function paused() {
  9019. // The initial state of paused should be true (in Safari it's actually false)
  9020. return this.techGet_('paused') === false ? false : true;
  9021. };
  9022. /**
  9023. * Get a TimeRange object representing the current ranges of time that the user
  9024. * has played.
  9025. *
  9026. * @return {TimeRange}
  9027. * A time range object that represents all the increments of time that have
  9028. * been played.
  9029. */
  9030. Player.prototype.played = function played() {
  9031. return this.techGet_('played') || (0, _timeRanges.createTimeRange)(0, 0);
  9032. };
  9033. /**
  9034. * Returns whether or not the user is "scrubbing". Scrubbing is
  9035. * when the user has clicked the progress bar handle and is
  9036. * dragging it along the progress bar.
  9037. *
  9038. * @param {boolean} [isScrubbing]
  9039. * wether the user is or is not scrubbing
  9040. *
  9041. * @return {boolean}
  9042. * The value of scrubbing when getting
  9043. */
  9044. Player.prototype.scrubbing = function scrubbing(isScrubbing) {
  9045. if (typeof isScrubbing === 'undefined') {
  9046. return this.scrubbing_;
  9047. }
  9048. this.scrubbing_ = !!isScrubbing;
  9049. if (isScrubbing) {
  9050. this.addClass('vjs-scrubbing');
  9051. } else {
  9052. this.removeClass('vjs-scrubbing');
  9053. }
  9054. };
  9055. /**
  9056. * Get or set the current time (in seconds)
  9057. *
  9058. * @param {number|string} [seconds]
  9059. * The time to seek to in seconds
  9060. *
  9061. * @return {number}
  9062. * - the current time in seconds when getting
  9063. */
  9064. Player.prototype.currentTime = function currentTime(seconds) {
  9065. if (typeof seconds !== 'undefined') {
  9066. this.techCall_('setCurrentTime', seconds);
  9067. return;
  9068. }
  9069. // cache last currentTime and return. default to 0 seconds
  9070. //
  9071. // Caching the currentTime is meant to prevent a massive amount of reads on the tech's
  9072. // currentTime when scrubbing, but may not provide much performance benefit afterall.
  9073. // Should be tested. Also something has to read the actual current time or the cache will
  9074. // never get updated.
  9075. this.cache_.currentTime = this.techGet_('currentTime') || 0;
  9076. return this.cache_.currentTime;
  9077. };
  9078. /**
  9079. * Normally gets the length in time of the video in seconds;
  9080. * in all but the rarest use cases an argument will NOT be passed to the method
  9081. *
  9082. * > **NOTE**: The video must have started loading before the duration can be
  9083. * known, and in the case of Flash, may not be known until the video starts
  9084. * playing.
  9085. *
  9086. * @fires Player#durationchange
  9087. *
  9088. * @param {number} [seconds]
  9089. * The duration of the video to set in seconds
  9090. *
  9091. * @return {number}
  9092. * - The duration of the video in seconds when getting
  9093. */
  9094. Player.prototype.duration = function duration(seconds) {
  9095. if (seconds === undefined) {
  9096. return this.cache_.duration || 0;
  9097. }
  9098. seconds = parseFloat(seconds) || 0;
  9099. // Standardize on Inifity for signaling video is live
  9100. if (seconds < 0) {
  9101. seconds = Infinity;
  9102. }
  9103. if (seconds !== this.cache_.duration) {
  9104. // Cache the last set value for optimized scrubbing (esp. Flash)
  9105. this.cache_.duration = seconds;
  9106. if (seconds === Infinity) {
  9107. this.addClass('vjs-live');
  9108. } else {
  9109. this.removeClass('vjs-live');
  9110. }
  9111. /**
  9112. * @event Player#durationchange
  9113. * @type {EventTarget~Event}
  9114. */
  9115. this.trigger('durationchange');
  9116. }
  9117. };
  9118. /**
  9119. * Calculates how much time is left in the video. Not part
  9120. * of the native video API.
  9121. *
  9122. * @return {number}
  9123. * The time remaining in seconds
  9124. */
  9125. Player.prototype.remainingTime = function remainingTime() {
  9126. return this.duration() - this.currentTime();
  9127. };
  9128. //
  9129. // Kind of like an array of portions of the video that have been downloaded.
  9130. /**
  9131. * Get a TimeRange object with an array of the times of the video
  9132. * that have been downloaded. If you just want the percent of the
  9133. * video that's been downloaded, use bufferedPercent.
  9134. *
  9135. * @see [Buffered Spec]{@link http://dev.w3.org/html5/spec/video.html#dom-media-buffered}
  9136. *
  9137. * @return {TimeRange}
  9138. * A mock TimeRange object (following HTML spec)
  9139. */
  9140. Player.prototype.buffered = function buffered() {
  9141. var buffered = this.techGet_('buffered');
  9142. if (!buffered || !buffered.length) {
  9143. buffered = (0, _timeRanges.createTimeRange)(0, 0);
  9144. }
  9145. return buffered;
  9146. };
  9147. /**
  9148. * Get the percent (as a decimal) of the video that's been downloaded.
  9149. * This method is not a part of the native HTML video API.
  9150. *
  9151. * @return {number}
  9152. * A decimal between 0 and 1 representing the percent
  9153. * that is bufferred 0 being 0% and 1 being 100%
  9154. */
  9155. Player.prototype.bufferedPercent = function bufferedPercent() {
  9156. return (0, _buffer.bufferedPercent)(this.buffered(), this.duration());
  9157. };
  9158. /**
  9159. * Get the ending time of the last buffered time range
  9160. * This is used in the progress bar to encapsulate all time ranges.
  9161. *
  9162. * @return {number}
  9163. * The end of the last buffered time range
  9164. */
  9165. Player.prototype.bufferedEnd = function bufferedEnd() {
  9166. var buffered = this.buffered();
  9167. var duration = this.duration();
  9168. var end = buffered.end(buffered.length - 1);
  9169. if (end > duration) {
  9170. end = duration;
  9171. }
  9172. return end;
  9173. };
  9174. /**
  9175. * Get or set the current volume of the media
  9176. *
  9177. * @param {number} [percentAsDecimal]
  9178. * The new volume as a decimal percent:
  9179. * - 0 is muted/0%/off
  9180. * - 1.0 is 100%/full
  9181. * - 0.5 is half volume or 50%
  9182. *
  9183. * @return {number}
  9184. * The current volume as a percent when getting
  9185. */
  9186. Player.prototype.volume = function volume(percentAsDecimal) {
  9187. var vol = void 0;
  9188. if (percentAsDecimal !== undefined) {
  9189. // Force value to between 0 and 1
  9190. vol = Math.max(0, Math.min(1, parseFloat(percentAsDecimal)));
  9191. this.cache_.volume = vol;
  9192. this.techCall_('setVolume', vol);
  9193. if (vol > 0) {
  9194. this.lastVolume_(vol);
  9195. }
  9196. return;
  9197. }
  9198. // Default to 1 when returning current volume.
  9199. vol = parseFloat(this.techGet_('volume'));
  9200. return isNaN(vol) ? 1 : vol;
  9201. };
  9202. /**
  9203. * Get the current muted state, or turn mute on or off
  9204. *
  9205. * @param {boolean} [muted]
  9206. * - true to mute
  9207. * - false to unmute
  9208. *
  9209. * @return {boolean}
  9210. * - true if mute is on and getting
  9211. * - false if mute is off and getting
  9212. */
  9213. Player.prototype.muted = function muted(_muted) {
  9214. if (_muted !== undefined) {
  9215. this.techCall_('setMuted', _muted);
  9216. return;
  9217. }
  9218. return this.techGet_('muted') || false;
  9219. };
  9220. /**
  9221. * Get the current defaultMuted state, or turn defaultMuted on or off. defaultMuted
  9222. * indicates the state of muted on intial playback.
  9223. *
  9224. * ```js
  9225. * var myPlayer = videojs('some-player-id');
  9226. *
  9227. * myPlayer.src("http://www.example.com/path/to/video.mp4");
  9228. *
  9229. * // get, should be false
  9230. * console.log(myPlayer.defaultMuted());
  9231. * // set to true
  9232. * myPlayer.defaultMuted(true);
  9233. * // get should be true
  9234. * console.log(myPlayer.defaultMuted());
  9235. * ```
  9236. *
  9237. * @param {boolean} [defaultMuted]
  9238. * - true to mute
  9239. * - false to unmute
  9240. *
  9241. * @return {boolean|Player}
  9242. * - true if defaultMuted is on and getting
  9243. * - false if defaultMuted is off and getting
  9244. * - A reference to the current player when setting
  9245. */
  9246. Player.prototype.defaultMuted = function defaultMuted(_defaultMuted) {
  9247. if (_defaultMuted !== undefined) {
  9248. return this.techCall_('setDefaultMuted', _defaultMuted);
  9249. }
  9250. return this.techGet_('defaultMuted') || false;
  9251. };
  9252. /**
  9253. * Get the last volume, or set it
  9254. *
  9255. * @param {number} [percentAsDecimal]
  9256. * The new last volume as a decimal percent:
  9257. * - 0 is muted/0%/off
  9258. * - 1.0 is 100%/full
  9259. * - 0.5 is half volume or 50%
  9260. *
  9261. * @return {number}
  9262. * the current value of lastVolume as a percent when getting
  9263. *
  9264. * @private
  9265. */
  9266. Player.prototype.lastVolume_ = function lastVolume_(percentAsDecimal) {
  9267. if (percentAsDecimal !== undefined && percentAsDecimal !== 0) {
  9268. this.cache_.lastVolume = percentAsDecimal;
  9269. return;
  9270. }
  9271. return this.cache_.lastVolume;
  9272. };
  9273. /**
  9274. * Check if current tech can support native fullscreen
  9275. * (e.g. with built in controls like iOS, so not our flash swf)
  9276. *
  9277. * @return {boolean}
  9278. * if native fullscreen is supported
  9279. */
  9280. Player.prototype.supportsFullScreen = function supportsFullScreen() {
  9281. return this.techGet_('supportsFullScreen') || false;
  9282. };
  9283. /**
  9284. * Check if the player is in fullscreen mode or tell the player that it
  9285. * is or is not in fullscreen mode.
  9286. *
  9287. * > NOTE: As of the latest HTML5 spec, isFullscreen is no longer an official
  9288. * property and instead document.fullscreenElement is used. But isFullscreen is
  9289. * still a valuable property for internal player workings.
  9290. *
  9291. * @param {boolean} [isFS]
  9292. * Set the players current fullscreen state
  9293. *
  9294. * @return {boolean}
  9295. * - true if fullscreen is on and getting
  9296. * - false if fullscreen is off and getting
  9297. */
  9298. Player.prototype.isFullscreen = function isFullscreen(isFS) {
  9299. if (isFS !== undefined) {
  9300. this.isFullscreen_ = !!isFS;
  9301. return;
  9302. }
  9303. return !!this.isFullscreen_;
  9304. };
  9305. /**
  9306. * Increase the size of the video to full screen
  9307. * In some browsers, full screen is not supported natively, so it enters
  9308. * "full window mode", where the video fills the browser window.
  9309. * In browsers and devices that support native full screen, sometimes the
  9310. * browser's default controls will be shown, and not the Video.js custom skin.
  9311. * This includes most mobile devices (iOS, Android) and older versions of
  9312. * Safari.
  9313. *
  9314. * @fires Player#fullscreenchange
  9315. */
  9316. Player.prototype.requestFullscreen = function requestFullscreen() {
  9317. var fsApi = _fullscreenApi2['default'];
  9318. this.isFullscreen(true);
  9319. if (fsApi.requestFullscreen) {
  9320. // the browser supports going fullscreen at the element level so we can
  9321. // take the controls fullscreen as well as the video
  9322. // Trigger fullscreenchange event after change
  9323. // We have to specifically add this each time, and remove
  9324. // when canceling fullscreen. Otherwise if there's multiple
  9325. // players on a page, they would all be reacting to the same fullscreen
  9326. // events
  9327. Events.on(_document2['default'], fsApi.fullscreenchange, Fn.bind(this, function documentFullscreenChange(e) {
  9328. this.isFullscreen(_document2['default'][fsApi.fullscreenElement]);
  9329. // If cancelling fullscreen, remove event listener.
  9330. if (this.isFullscreen() === false) {
  9331. Events.off(_document2['default'], fsApi.fullscreenchange, documentFullscreenChange);
  9332. }
  9333. /**
  9334. * @event Player#fullscreenchange
  9335. * @type {EventTarget~Event}
  9336. */
  9337. this.trigger('fullscreenchange');
  9338. }));
  9339. this.el_[fsApi.requestFullscreen]();
  9340. } else if (this.tech_.supportsFullScreen()) {
  9341. // we can't take the video.js controls fullscreen but we can go fullscreen
  9342. // with native controls
  9343. this.techCall_('enterFullScreen');
  9344. } else {
  9345. // fullscreen isn't supported so we'll just stretch the video element to
  9346. // fill the viewport
  9347. this.enterFullWindow();
  9348. /**
  9349. * @event Player#fullscreenchange
  9350. * @type {EventTarget~Event}
  9351. */
  9352. this.trigger('fullscreenchange');
  9353. }
  9354. };
  9355. /**
  9356. * Return the video to its normal size after having been in full screen mode
  9357. *
  9358. * @fires Player#fullscreenchange
  9359. */
  9360. Player.prototype.exitFullscreen = function exitFullscreen() {
  9361. var fsApi = _fullscreenApi2['default'];
  9362. this.isFullscreen(false);
  9363. // Check for browser element fullscreen support
  9364. if (fsApi.requestFullscreen) {
  9365. _document2['default'][fsApi.exitFullscreen]();
  9366. } else if (this.tech_.supportsFullScreen()) {
  9367. this.techCall_('exitFullScreen');
  9368. } else {
  9369. this.exitFullWindow();
  9370. /**
  9371. * @event Player#fullscreenchange
  9372. * @type {EventTarget~Event}
  9373. */
  9374. this.trigger('fullscreenchange');
  9375. }
  9376. };
  9377. /**
  9378. * When fullscreen isn't supported we can stretch the
  9379. * video container to as wide as the browser will let us.
  9380. *
  9381. * @fires Player#enterFullWindow
  9382. */
  9383. Player.prototype.enterFullWindow = function enterFullWindow() {
  9384. this.isFullWindow = true;
  9385. // Storing original doc overflow value to return to when fullscreen is off
  9386. this.docOrigOverflow = _document2['default'].documentElement.style.overflow;
  9387. // Add listener for esc key to exit fullscreen
  9388. Events.on(_document2['default'], 'keydown', Fn.bind(this, this.fullWindowOnEscKey));
  9389. // Hide any scroll bars
  9390. _document2['default'].documentElement.style.overflow = 'hidden';
  9391. // Apply fullscreen styles
  9392. Dom.addClass(_document2['default'].body, 'vjs-full-window');
  9393. /**
  9394. * @event Player#enterFullWindow
  9395. * @type {EventTarget~Event}
  9396. */
  9397. this.trigger('enterFullWindow');
  9398. };
  9399. /**
  9400. * Check for call to either exit full window or
  9401. * full screen on ESC key
  9402. *
  9403. * @param {string} event
  9404. * Event to check for key press
  9405. */
  9406. Player.prototype.fullWindowOnEscKey = function fullWindowOnEscKey(event) {
  9407. if (event.keyCode === 27) {
  9408. if (this.isFullscreen() === true) {
  9409. this.exitFullscreen();
  9410. } else {
  9411. this.exitFullWindow();
  9412. }
  9413. }
  9414. };
  9415. /**
  9416. * Exit full window
  9417. *
  9418. * @fires Player#exitFullWindow
  9419. */
  9420. Player.prototype.exitFullWindow = function exitFullWindow() {
  9421. this.isFullWindow = false;
  9422. Events.off(_document2['default'], 'keydown', this.fullWindowOnEscKey);
  9423. // Unhide scroll bars.
  9424. _document2['default'].documentElement.style.overflow = this.docOrigOverflow;
  9425. // Remove fullscreen styles
  9426. Dom.removeClass(_document2['default'].body, 'vjs-full-window');
  9427. // Resize the box, controller, and poster to original sizes
  9428. // this.positionAll();
  9429. /**
  9430. * @event Player#exitFullWindow
  9431. * @type {EventTarget~Event}
  9432. */
  9433. this.trigger('exitFullWindow');
  9434. };
  9435. /**
  9436. * Check whether the player can play a given mimetype
  9437. *
  9438. * @see https://www.w3.org/TR/2011/WD-html5-20110113/video.html#dom-navigator-canplaytype
  9439. *
  9440. * @param {string} type
  9441. * The mimetype to check
  9442. *
  9443. * @return {string}
  9444. * 'probably', 'maybe', or '' (empty string)
  9445. */
  9446. Player.prototype.canPlayType = function canPlayType(type) {
  9447. var can = void 0;
  9448. // Loop through each playback technology in the options order
  9449. for (var i = 0, j = this.options_.techOrder; i < j.length; i++) {
  9450. var techName = j[i];
  9451. var tech = _tech2['default'].getTech(techName);
  9452. // Support old behavior of techs being registered as components.
  9453. // Remove once that deprecated behavior is removed.
  9454. if (!tech) {
  9455. tech = _component2['default'].getComponent(techName);
  9456. }
  9457. // Check if the current tech is defined before continuing
  9458. if (!tech) {
  9459. _log2['default'].error('The "' + techName + '" tech is undefined. Skipped browser support check for that tech.');
  9460. continue;
  9461. }
  9462. // Check if the browser supports this technology
  9463. if (tech.isSupported()) {
  9464. can = tech.canPlayType(type);
  9465. if (can) {
  9466. return can;
  9467. }
  9468. }
  9469. }
  9470. return '';
  9471. };
  9472. /**
  9473. * Select source based on tech-order or source-order
  9474. * Uses source-order selection if `options.sourceOrder` is truthy. Otherwise,
  9475. * defaults to tech-order selection
  9476. *
  9477. * @param {Array} sources
  9478. * The sources for a media asset
  9479. *
  9480. * @return {Object|boolean}
  9481. * Object of source and tech order or false
  9482. */
  9483. Player.prototype.selectSource = function selectSource(sources) {
  9484. var _this5 = this;
  9485. // Get only the techs specified in `techOrder` that exist and are supported by the
  9486. // current platform
  9487. var techs = this.options_.techOrder.map(function (techName) {
  9488. return [techName, _tech2['default'].getTech(techName)];
  9489. }).filter(function (_ref) {
  9490. var techName = _ref[0],
  9491. tech = _ref[1];
  9492. // Check if the current tech is defined before continuing
  9493. if (tech) {
  9494. // Check if the browser supports this technology
  9495. return tech.isSupported();
  9496. }
  9497. _log2['default'].error('The "' + techName + '" tech is undefined. Skipped browser support check for that tech.');
  9498. return false;
  9499. });
  9500. // Iterate over each `innerArray` element once per `outerArray` element and execute
  9501. // `tester` with both. If `tester` returns a non-falsy value, exit early and return
  9502. // that value.
  9503. var findFirstPassingTechSourcePair = function findFirstPassingTechSourcePair(outerArray, innerArray, tester) {
  9504. var found = void 0;
  9505. outerArray.some(function (outerChoice) {
  9506. return innerArray.some(function (innerChoice) {
  9507. found = tester(outerChoice, innerChoice);
  9508. if (found) {
  9509. return true;
  9510. }
  9511. });
  9512. });
  9513. return found;
  9514. };
  9515. var foundSourceAndTech = void 0;
  9516. var flip = function flip(fn) {
  9517. return function (a, b) {
  9518. return fn(b, a);
  9519. };
  9520. };
  9521. var finder = function finder(_ref2, source) {
  9522. var techName = _ref2[0],
  9523. tech = _ref2[1];
  9524. if (tech.canPlaySource(source, _this5.options_[techName.toLowerCase()])) {
  9525. return { source: source, tech: techName };
  9526. }
  9527. };
  9528. // Depending on the truthiness of `options.sourceOrder`, we swap the order of techs and sources
  9529. // to select from them based on their priority.
  9530. if (this.options_.sourceOrder) {
  9531. // Source-first ordering
  9532. foundSourceAndTech = findFirstPassingTechSourcePair(sources, techs, flip(finder));
  9533. } else {
  9534. // Tech-first ordering
  9535. foundSourceAndTech = findFirstPassingTechSourcePair(techs, sources, finder);
  9536. }
  9537. return foundSourceAndTech || false;
  9538. };
  9539. /**
  9540. * The source function updates the video source
  9541. * There are three types of variables you can pass as the argument.
  9542. * **URL string**: A URL to the the video file. Use this method if you are sure
  9543. * the current playback technology (HTML5/Flash) can support the source you
  9544. * provide. Currently only MP4 files can be used in both HTML5 and Flash.
  9545. *
  9546. * @param {Tech~SourceObject|Tech~SourceObject[]} [source]
  9547. * One SourceObject or an array of SourceObjects
  9548. *
  9549. * @return {string}
  9550. * The current video source when getting
  9551. */
  9552. Player.prototype.src = function src(source) {
  9553. var _this6 = this;
  9554. // getter usage
  9555. if (typeof source === 'undefined') {
  9556. return this.cache_.src;
  9557. }
  9558. // filter out invalid sources and turn our source into
  9559. // an array of source objects
  9560. var sources = (0, _filterSource2['default'])(source);
  9561. // if a source was passed in then it is invalid because
  9562. // it was filtered to a zero length Array. So we have to
  9563. // show an error
  9564. if (!sources.length) {
  9565. this.setTimeout(function () {
  9566. this.error({ code: 4, message: this.localize(this.options_.notSupportedMessage) });
  9567. }, 0);
  9568. return;
  9569. }
  9570. // intial sources
  9571. this.cache_.sources = sources;
  9572. this.changingSrc_ = true;
  9573. // intial source
  9574. this.cache_.source = sources[0];
  9575. // middlewareSource is the source after it has been changed by middleware
  9576. middleware.setSource(this, sources[0], function (middlewareSource, mws) {
  9577. _this6.middleware_ = mws;
  9578. var err = _this6.src_(middlewareSource);
  9579. if (err) {
  9580. if (sources.length > 1) {
  9581. return _this6.src(sources.slice(1));
  9582. }
  9583. // We need to wrap this in a timeout to give folks a chance to add error event handlers
  9584. _this6.setTimeout(function () {
  9585. this.error({ code: 4, message: this.localize(this.options_.notSupportedMessage) });
  9586. }, 0);
  9587. // we could not find an appropriate tech, but let's still notify the delegate that this is it
  9588. // this needs a better comment about why this is needed
  9589. _this6.triggerReady();
  9590. return;
  9591. }
  9592. _this6.changingSrc_ = false;
  9593. // video element listed source
  9594. _this6.cache_.src = middlewareSource.src;
  9595. middleware.setTech(mws, _this6.tech_);
  9596. });
  9597. };
  9598. /**
  9599. * Set the source object on the tech, returns a boolean that indicates wether
  9600. * there is a tech that can play the source or not
  9601. *
  9602. * @param {Tech~SourceObject} source
  9603. * The source object to set on the Tech
  9604. *
  9605. * @return {Boolean}
  9606. * - True if there is no Tech to playback this source
  9607. * - False otherwise
  9608. *
  9609. * @private
  9610. */
  9611. Player.prototype.src_ = function src_(source) {
  9612. var sourceTech = this.selectSource([source]);
  9613. if (!sourceTech) {
  9614. return true;
  9615. }
  9616. if (sourceTech.tech !== this.techName_) {
  9617. this.changingSrc_ = true;
  9618. // load this technology with the chosen source
  9619. this.loadTech_(sourceTech.tech, sourceTech.source);
  9620. return false;
  9621. }
  9622. // wait until the tech is ready to set the source
  9623. this.ready(function () {
  9624. // The setSource tech method was added with source handlers
  9625. // so older techs won't support it
  9626. // We need to check the direct prototype for the case where subclasses
  9627. // of the tech do not support source handlers
  9628. if (this.tech_.constructor.prototype.hasOwnProperty('setSource')) {
  9629. this.techCall_('setSource', source);
  9630. } else {
  9631. this.techCall_('src', source.src);
  9632. }
  9633. if (this.options_.preload === 'auto') {
  9634. this.load();
  9635. }
  9636. if (this.options_.autoplay) {
  9637. this.play();
  9638. }
  9639. // Set the source synchronously if possible (#2326)
  9640. }, true);
  9641. return false;
  9642. };
  9643. /**
  9644. * Begin loading the src data.
  9645. */
  9646. Player.prototype.load = function load() {
  9647. this.techCall_('load');
  9648. };
  9649. /**
  9650. * Reset the player. Loads the first tech in the techOrder,
  9651. * and calls `reset` on the tech`.
  9652. */
  9653. Player.prototype.reset = function reset() {
  9654. this.loadTech_(this.options_.techOrder[0], null);
  9655. this.techCall_('reset');
  9656. };
  9657. /**
  9658. * Returns all of the current source objects.
  9659. *
  9660. * @return {Tech~SourceObject[]}
  9661. * The current source objects
  9662. */
  9663. Player.prototype.currentSources = function currentSources() {
  9664. var source = this.currentSource();
  9665. var sources = [];
  9666. // assume `{}` or `{ src }`
  9667. if (Object.keys(source).length !== 0) {
  9668. sources.push(source);
  9669. }
  9670. return this.cache_.sources || sources;
  9671. };
  9672. /**
  9673. * Returns the current source object.
  9674. *
  9675. * @return {Tech~SourceObject}
  9676. * The current source object
  9677. */
  9678. Player.prototype.currentSource = function currentSource() {
  9679. return this.cache_.source || {};
  9680. };
  9681. /**
  9682. * Returns the fully qualified URL of the current source value e.g. http://mysite.com/video.mp4
  9683. * Can be used in conjuction with `currentType` to assist in rebuilding the current source object.
  9684. *
  9685. * @return {string}
  9686. * The current source
  9687. */
  9688. Player.prototype.currentSrc = function currentSrc() {
  9689. return this.currentSource() && this.currentSource().src || '';
  9690. };
  9691. /**
  9692. * Get the current source type e.g. video/mp4
  9693. * This can allow you rebuild the current source object so that you could load the same
  9694. * source and tech later
  9695. *
  9696. * @return {string}
  9697. * The source MIME type
  9698. */
  9699. Player.prototype.currentType = function currentType() {
  9700. return this.currentSource() && this.currentSource().type || '';
  9701. };
  9702. /**
  9703. * Get or set the preload attribute
  9704. *
  9705. * @param {boolean} [value]
  9706. * - true means that we should preload
  9707. * - false maens that we should not preload
  9708. *
  9709. * @return {string}
  9710. * The preload attribute value when getting
  9711. */
  9712. Player.prototype.preload = function preload(value) {
  9713. if (value !== undefined) {
  9714. this.techCall_('setPreload', value);
  9715. this.options_.preload = value;
  9716. return;
  9717. }
  9718. return this.techGet_('preload');
  9719. };
  9720. /**
  9721. * Get or set the autoplay attribute.
  9722. *
  9723. * @param {boolean} [value]
  9724. * - true means that we should autoplay
  9725. * - false means that we should not autoplay
  9726. *
  9727. * @return {string}
  9728. * The current value of autoplay when getting
  9729. */
  9730. Player.prototype.autoplay = function autoplay(value) {
  9731. if (value !== undefined) {
  9732. this.techCall_('setAutoplay', value);
  9733. this.options_.autoplay = value;
  9734. return;
  9735. }
  9736. return this.techGet_('autoplay', value);
  9737. };
  9738. /**
  9739. * Get or set the loop attribute on the video element.
  9740. *
  9741. * @param {boolean} [value]
  9742. * - true means that we should loop the video
  9743. * - false means that we should not loop the video
  9744. *
  9745. * @return {string}
  9746. * The current value of loop when getting
  9747. */
  9748. Player.prototype.loop = function loop(value) {
  9749. if (value !== undefined) {
  9750. this.techCall_('setLoop', value);
  9751. this.options_.loop = value;
  9752. return;
  9753. }
  9754. return this.techGet_('loop');
  9755. };
  9756. /**
  9757. * Get or set the poster image source url
  9758. *
  9759. * @fires Player#posterchange
  9760. *
  9761. * @param {string} [src]
  9762. * Poster image source URL
  9763. *
  9764. * @return {string}
  9765. * The current value of poster when getting
  9766. */
  9767. Player.prototype.poster = function poster(src) {
  9768. if (src === undefined) {
  9769. return this.poster_;
  9770. }
  9771. // The correct way to remove a poster is to set as an empty string
  9772. // other falsey values will throw errors
  9773. if (!src) {
  9774. src = '';
  9775. }
  9776. // update the internal poster variable
  9777. this.poster_ = src;
  9778. // update the tech's poster
  9779. this.techCall_('setPoster', src);
  9780. // alert components that the poster has been set
  9781. /**
  9782. * This event fires when the poster image is changed on the player.
  9783. *
  9784. * @event Player#posterchange
  9785. * @type {EventTarget~Event}
  9786. */
  9787. this.trigger('posterchange');
  9788. };
  9789. /**
  9790. * Some techs (e.g. YouTube) can provide a poster source in an
  9791. * asynchronous way. We want the poster component to use this
  9792. * poster source so that it covers up the tech's controls.
  9793. * (YouTube's play button). However we only want to use this
  9794. * soruce if the player user hasn't set a poster through
  9795. * the normal APIs.
  9796. *
  9797. * @fires Player#posterchange
  9798. * @listens Tech#posterchange
  9799. * @private
  9800. */
  9801. Player.prototype.handleTechPosterChange_ = function handleTechPosterChange_() {
  9802. if (!this.poster_ && this.tech_ && this.tech_.poster) {
  9803. this.poster_ = this.tech_.poster() || '';
  9804. // Let components know the poster has changed
  9805. this.trigger('posterchange');
  9806. }
  9807. };
  9808. /**
  9809. * Get or set whether or not the controls are showing.
  9810. *
  9811. * @fires Player#controlsenabled
  9812. *
  9813. * @param {boolean} [bool]
  9814. * - true to turn controls on
  9815. * - false to turn controls off
  9816. *
  9817. * @return {boolean}
  9818. * The current value of controls when getting
  9819. */
  9820. Player.prototype.controls = function controls(bool) {
  9821. if (bool !== undefined) {
  9822. bool = !!bool;
  9823. // Don't trigger a change event unless it actually changed
  9824. if (this.controls_ !== bool) {
  9825. this.controls_ = bool;
  9826. if (this.usingNativeControls()) {
  9827. this.techCall_('setControls', bool);
  9828. }
  9829. if (bool) {
  9830. this.removeClass('vjs-controls-disabled');
  9831. this.addClass('vjs-controls-enabled');
  9832. /**
  9833. * @event Player#controlsenabled
  9834. * @type {EventTarget~Event}
  9835. */
  9836. this.trigger('controlsenabled');
  9837. if (!this.usingNativeControls()) {
  9838. this.addTechControlsListeners_();
  9839. }
  9840. } else {
  9841. this.removeClass('vjs-controls-enabled');
  9842. this.addClass('vjs-controls-disabled');
  9843. /**
  9844. * @event Player#controlsdisabled
  9845. * @type {EventTarget~Event}
  9846. */
  9847. this.trigger('controlsdisabled');
  9848. if (!this.usingNativeControls()) {
  9849. this.removeTechControlsListeners_();
  9850. }
  9851. }
  9852. }
  9853. return;
  9854. }
  9855. return !!this.controls_;
  9856. };
  9857. /**
  9858. * Toggle native controls on/off. Native controls are the controls built into
  9859. * devices (e.g. default iPhone controls), Flash, or other techs
  9860. * (e.g. Vimeo Controls)
  9861. * **This should only be set by the current tech, because only the tech knows
  9862. * if it can support native controls**
  9863. *
  9864. * @fires Player#usingnativecontrols
  9865. * @fires Player#usingcustomcontrols
  9866. *
  9867. * @param {boolean} [bool]
  9868. * - true to turn native controls on
  9869. * - false to turn native controls off
  9870. *
  9871. * @return {boolean}
  9872. * The current value of native controls when getting
  9873. */
  9874. Player.prototype.usingNativeControls = function usingNativeControls(bool) {
  9875. if (bool !== undefined) {
  9876. bool = !!bool;
  9877. // Don't trigger a change event unless it actually changed
  9878. if (this.usingNativeControls_ !== bool) {
  9879. this.usingNativeControls_ = bool;
  9880. if (bool) {
  9881. this.addClass('vjs-using-native-controls');
  9882. /**
  9883. * player is using the native device controls
  9884. *
  9885. * @event Player#usingnativecontrols
  9886. * @type {EventTarget~Event}
  9887. */
  9888. this.trigger('usingnativecontrols');
  9889. } else {
  9890. this.removeClass('vjs-using-native-controls');
  9891. /**
  9892. * player is using the custom HTML controls
  9893. *
  9894. * @event Player#usingcustomcontrols
  9895. * @type {EventTarget~Event}
  9896. */
  9897. this.trigger('usingcustomcontrols');
  9898. }
  9899. }
  9900. return;
  9901. }
  9902. return !!this.usingNativeControls_;
  9903. };
  9904. /**
  9905. * Set or get the current MediaError
  9906. *
  9907. * @fires Player#error
  9908. *
  9909. * @param {MediaError|string|number} [err]
  9910. * A MediaError or a string/number to be turned
  9911. * into a MediaError
  9912. *
  9913. * @return {MediaError|null}
  9914. * The current MediaError when getting (or null)
  9915. */
  9916. Player.prototype.error = function error(err) {
  9917. if (err === undefined) {
  9918. return this.error_ || null;
  9919. }
  9920. // restoring to default
  9921. if (err === null) {
  9922. this.error_ = err;
  9923. this.removeClass('vjs-error');
  9924. if (this.errorDisplay) {
  9925. this.errorDisplay.close();
  9926. }
  9927. return;
  9928. }
  9929. this.error_ = new _mediaError2['default'](err);
  9930. // add the vjs-error classname to the player
  9931. this.addClass('vjs-error');
  9932. // log the name of the error type and any message
  9933. // ie8 just logs "[object object]" if you just log the error object
  9934. _log2['default'].error('(CODE:' + this.error_.code + ' ' + _mediaError2['default'].errorTypes[this.error_.code] + ')', this.error_.message, this.error_);
  9935. /**
  9936. * @event Player#error
  9937. * @type {EventTarget~Event}
  9938. */
  9939. this.trigger('error');
  9940. return;
  9941. };
  9942. /**
  9943. * Report user activity
  9944. *
  9945. * @param {Object} event
  9946. * Event object
  9947. */
  9948. Player.prototype.reportUserActivity = function reportUserActivity(event) {
  9949. this.userActivity_ = true;
  9950. };
  9951. /**
  9952. * Get/set if user is active
  9953. *
  9954. * @fires Player#useractive
  9955. * @fires Player#userinactive
  9956. *
  9957. * @param {boolean} [bool]
  9958. * - true if the user is active
  9959. * - false if the user is inactive
  9960. *
  9961. * @return {boolean}
  9962. * The current value of userActive when getting
  9963. */
  9964. Player.prototype.userActive = function userActive(bool) {
  9965. if (bool !== undefined) {
  9966. bool = !!bool;
  9967. if (bool !== this.userActive_) {
  9968. this.userActive_ = bool;
  9969. if (bool) {
  9970. // If the user was inactive and is now active we want to reset the
  9971. // inactivity timer
  9972. this.userActivity_ = true;
  9973. this.removeClass('vjs-user-inactive');
  9974. this.addClass('vjs-user-active');
  9975. /**
  9976. * @event Player#useractive
  9977. * @type {EventTarget~Event}
  9978. */
  9979. this.trigger('useractive');
  9980. } else {
  9981. // We're switching the state to inactive manually, so erase any other
  9982. // activity
  9983. this.userActivity_ = false;
  9984. // Chrome/Safari/IE have bugs where when you change the cursor it can
  9985. // trigger a mousemove event. This causes an issue when you're hiding
  9986. // the cursor when the user is inactive, and a mousemove signals user
  9987. // activity. Making it impossible to go into inactive mode. Specifically
  9988. // this happens in fullscreen when we really need to hide the cursor.
  9989. //
  9990. // When this gets resolved in ALL browsers it can be removed
  9991. // https://code.google.com/p/chromium/issues/detail?id=103041
  9992. if (this.tech_) {
  9993. this.tech_.one('mousemove', function (e) {
  9994. e.stopPropagation();
  9995. e.preventDefault();
  9996. });
  9997. }
  9998. this.removeClass('vjs-user-active');
  9999. this.addClass('vjs-user-inactive');
  10000. /**
  10001. * @event Player#userinactive
  10002. * @type {EventTarget~Event}
  10003. */
  10004. this.trigger('userinactive');
  10005. }
  10006. }
  10007. return;
  10008. }
  10009. return this.userActive_;
  10010. };
  10011. /**
  10012. * Listen for user activity based on timeout value
  10013. *
  10014. * @private
  10015. */
  10016. Player.prototype.listenForUserActivity_ = function listenForUserActivity_() {
  10017. var mouseInProgress = void 0;
  10018. var lastMoveX = void 0;
  10019. var lastMoveY = void 0;
  10020. var handleActivity = Fn.bind(this, this.reportUserActivity);
  10021. var handleMouseMove = function handleMouseMove(e) {
  10022. // #1068 - Prevent mousemove spamming
  10023. // Chrome Bug: https://code.google.com/p/chromium/issues/detail?id=366970
  10024. if (e.screenX !== lastMoveX || e.screenY !== lastMoveY) {
  10025. lastMoveX = e.screenX;
  10026. lastMoveY = e.screenY;
  10027. handleActivity();
  10028. }
  10029. };
  10030. var handleMouseDown = function handleMouseDown() {
  10031. handleActivity();
  10032. // For as long as the they are touching the device or have their mouse down,
  10033. // we consider them active even if they're not moving their finger or mouse.
  10034. // So we want to continue to update that they are active
  10035. this.clearInterval(mouseInProgress);
  10036. // Setting userActivity=true now and setting the interval to the same time
  10037. // as the activityCheck interval (250) should ensure we never miss the
  10038. // next activityCheck
  10039. mouseInProgress = this.setInterval(handleActivity, 250);
  10040. };
  10041. var handleMouseUp = function handleMouseUp(event) {
  10042. handleActivity();
  10043. // Stop the interval that maintains activity if the mouse/touch is down
  10044. this.clearInterval(mouseInProgress);
  10045. };
  10046. // Any mouse movement will be considered user activity
  10047. this.on('mousedown', handleMouseDown);
  10048. this.on('mousemove', handleMouseMove);
  10049. this.on('mouseup', handleMouseUp);
  10050. // Listen for keyboard navigation
  10051. // Shouldn't need to use inProgress interval because of key repeat
  10052. this.on('keydown', handleActivity);
  10053. this.on('keyup', handleActivity);
  10054. // Run an interval every 250 milliseconds instead of stuffing everything into
  10055. // the mousemove/touchmove function itself, to prevent performance degradation.
  10056. // `this.reportUserActivity` simply sets this.userActivity_ to true, which
  10057. // then gets picked up by this loop
  10058. // http://ejohn.org/blog/learning-from-twitter/
  10059. var inactivityTimeout = void 0;
  10060. this.setInterval(function () {
  10061. // Check to see if mouse/touch activity has happened
  10062. if (this.userActivity_) {
  10063. // Reset the activity tracker
  10064. this.userActivity_ = false;
  10065. // If the user state was inactive, set the state to active
  10066. this.userActive(true);
  10067. // Clear any existing inactivity timeout to start the timer over
  10068. this.clearTimeout(inactivityTimeout);
  10069. var timeout = this.options_.inactivityTimeout;
  10070. if (timeout > 0) {
  10071. // In <timeout> milliseconds, if no more activity has occurred the
  10072. // user will be considered inactive
  10073. inactivityTimeout = this.setTimeout(function () {
  10074. // Protect against the case where the inactivityTimeout can trigger just
  10075. // before the next user activity is picked up by the activity check loop
  10076. // causing a flicker
  10077. if (!this.userActivity_) {
  10078. this.userActive(false);
  10079. }
  10080. }, timeout);
  10081. }
  10082. }
  10083. }, 250);
  10084. };
  10085. /**
  10086. * Gets or sets the current playback rate. A playback rate of
  10087. * 1.0 represents normal speed and 0.5 would indicate half-speed
  10088. * playback, for instance.
  10089. *
  10090. * @see https://html.spec.whatwg.org/multipage/embedded-content.html#dom-media-playbackrate
  10091. *
  10092. * @param {number} [rate]
  10093. * New playback rate to set.
  10094. *
  10095. * @return {number}
  10096. * The current playback rate when getting or 1.0
  10097. */
  10098. Player.prototype.playbackRate = function playbackRate(rate) {
  10099. if (rate !== undefined) {
  10100. this.techCall_('setPlaybackRate', rate);
  10101. return;
  10102. }
  10103. if (this.tech_ && this.tech_.featuresPlaybackRate) {
  10104. return this.techGet_('playbackRate');
  10105. }
  10106. return 1.0;
  10107. };
  10108. /**
  10109. * Gets or sets the current default playback rate. A default playback rate of
  10110. * 1.0 represents normal speed and 0.5 would indicate half-speed playback, for instance.
  10111. * defaultPlaybackRate will only represent what the intial playbackRate of a video was, not
  10112. * not the current playbackRate.
  10113. *
  10114. * @see https://html.spec.whatwg.org/multipage/embedded-content.html#dom-media-defaultplaybackrate
  10115. *
  10116. * @param {number} [rate]
  10117. * New default playback rate to set.
  10118. *
  10119. * @return {number|Player}
  10120. * - The default playback rate when getting or 1.0
  10121. * - the player when setting
  10122. */
  10123. Player.prototype.defaultPlaybackRate = function defaultPlaybackRate(rate) {
  10124. if (rate !== undefined) {
  10125. return this.techCall_('setDefaultPlaybackRate', rate);
  10126. }
  10127. if (this.tech_ && this.tech_.featuresPlaybackRate) {
  10128. return this.techGet_('defaultPlaybackRate');
  10129. }
  10130. return 1.0;
  10131. };
  10132. /**
  10133. * Gets or sets the audio flag
  10134. *
  10135. * @param {boolean} bool
  10136. * - true signals that this is an audio player
  10137. * - false signals that this is not an audio player
  10138. *
  10139. * @return {boolean}
  10140. * The current value of isAudio when getting
  10141. */
  10142. Player.prototype.isAudio = function isAudio(bool) {
  10143. if (bool !== undefined) {
  10144. this.isAudio_ = !!bool;
  10145. return;
  10146. }
  10147. return !!this.isAudio_;
  10148. };
  10149. /**
  10150. * A helper method for adding a {@link TextTrack} to our
  10151. * {@link TextTrackList}.
  10152. *
  10153. * In addition to the W3C settings we allow adding additional info through options.
  10154. *
  10155. * @see http://www.w3.org/html/wg/drafts/html/master/embedded-content-0.html#dom-media-addtexttrack
  10156. *
  10157. * @param {string} [kind]
  10158. * the kind of TextTrack you are adding
  10159. *
  10160. * @param {string} [label]
  10161. * the label to give the TextTrack label
  10162. *
  10163. * @param {string} [language]
  10164. * the language to set on the TextTrack
  10165. *
  10166. * @return {TextTrack|undefined}
  10167. * the TextTrack that was added or undefined
  10168. * if there is no tech
  10169. */
  10170. Player.prototype.addTextTrack = function addTextTrack(kind, label, language) {
  10171. if (this.tech_) {
  10172. return this.tech_.addTextTrack(kind, label, language);
  10173. }
  10174. };
  10175. /**
  10176. * Create a remote {@link TextTrack} and an {@link HTMLTrackElement}. It will
  10177. * automatically removed from the video element whenever the source changes, unless
  10178. * manualCleanup is set to false.
  10179. *
  10180. * @param {Object} options
  10181. * Options to pass to {@link HTMLTrackElement} during creation. See
  10182. * {@link HTMLTrackElement} for object properties that you should use.
  10183. *
  10184. * @param {boolean} [manualCleanup=true] if set to false, the TextTrack will be
  10185. *
  10186. * @return {HTMLTrackElement}
  10187. * the HTMLTrackElement that was created and added
  10188. * to the HTMLTrackElementList and the remote
  10189. * TextTrackList
  10190. *
  10191. * @deprecated The default value of the "manualCleanup" parameter will default
  10192. * to "false" in upcoming versions of Video.js
  10193. */
  10194. Player.prototype.addRemoteTextTrack = function addRemoteTextTrack(options, manualCleanup) {
  10195. if (this.tech_) {
  10196. return this.tech_.addRemoteTextTrack(options, manualCleanup);
  10197. }
  10198. };
  10199. /**
  10200. * Remove a remote {@link TextTrack} from the respective
  10201. * {@link TextTrackList} and {@link HTMLTrackElementList}.
  10202. *
  10203. * @param {Object} track
  10204. * Remote {@link TextTrack} to remove
  10205. *
  10206. * @return {undefined}
  10207. * does not return anything
  10208. */
  10209. Player.prototype.removeRemoteTextTrack = function removeRemoteTextTrack() {
  10210. var _ref3 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
  10211. _ref3$track = _ref3.track,
  10212. track = _ref3$track === undefined ? arguments[0] : _ref3$track;
  10213. // destructure the input into an object with a track argument, defaulting to arguments[0]
  10214. // default the whole argument to an empty object if nothing was passed in
  10215. if (this.tech_) {
  10216. return this.tech_.removeRemoteTextTrack(track);
  10217. }
  10218. };
  10219. /**
  10220. * Get video width
  10221. *
  10222. * @return {number}
  10223. * current video width
  10224. */
  10225. Player.prototype.videoWidth = function videoWidth() {
  10226. return this.tech_ && this.tech_.videoWidth && this.tech_.videoWidth() || 0;
  10227. };
  10228. /**
  10229. * Get video height
  10230. *
  10231. * @return {number}
  10232. * current video height
  10233. */
  10234. Player.prototype.videoHeight = function videoHeight() {
  10235. return this.tech_ && this.tech_.videoHeight && this.tech_.videoHeight() || 0;
  10236. };
  10237. /**
  10238. * The player's language code
  10239. * NOTE: The language should be set in the player options if you want the
  10240. * the controls to be built with a specific language. Changing the lanugage
  10241. * later will not update controls text.
  10242. *
  10243. * @param {string} [code]
  10244. * the language code to set the player to
  10245. *
  10246. * @return {string}
  10247. * The current language code when getting
  10248. */
  10249. Player.prototype.language = function language(code) {
  10250. if (code === undefined) {
  10251. return this.language_;
  10252. }
  10253. this.language_ = String(code).toLowerCase();
  10254. };
  10255. /**
  10256. * Get the player's language dictionary
  10257. * Merge every time, because a newly added plugin might call videojs.addLanguage() at any time
  10258. * Languages specified directly in the player options have precedence
  10259. *
  10260. * @return {Array}
  10261. * An array of of supported languages
  10262. */
  10263. Player.prototype.languages = function languages() {
  10264. return (0, _mergeOptions2['default'])(Player.prototype.options_.languages, this.languages_);
  10265. };
  10266. /**
  10267. * returns a JavaScript object reperesenting the current track
  10268. * information. **DOES not return it as JSON**
  10269. *
  10270. * @return {Object}
  10271. * Object representing the current of track info
  10272. */
  10273. Player.prototype.toJSON = function toJSON() {
  10274. var options = (0, _mergeOptions2['default'])(this.options_);
  10275. var tracks = options.tracks;
  10276. options.tracks = [];
  10277. for (var i = 0; i < tracks.length; i++) {
  10278. var track = tracks[i];
  10279. // deep merge tracks and null out player so no circular references
  10280. track = (0, _mergeOptions2['default'])(track);
  10281. track.player = undefined;
  10282. options.tracks[i] = track;
  10283. }
  10284. return options;
  10285. };
  10286. /**
  10287. * Creates a simple modal dialog (an instance of the {@link ModalDialog}
  10288. * component) that immediately overlays the player with arbitrary
  10289. * content and removes itself when closed.
  10290. *
  10291. * @param {string|Function|Element|Array|null} content
  10292. * Same as {@link ModalDialog#content}'s param of the same name.
  10293. * The most straight-forward usage is to provide a string or DOM
  10294. * element.
  10295. *
  10296. * @param {Object} [options]
  10297. * Extra options which will be passed on to the {@link ModalDialog}.
  10298. *
  10299. * @return {ModalDialog}
  10300. * the {@link ModalDialog} that was created
  10301. */
  10302. Player.prototype.createModal = function createModal(content, options) {
  10303. var _this7 = this;
  10304. options = options || {};
  10305. options.content = content || '';
  10306. var modal = new _modalDialog2['default'](this, options);
  10307. this.addChild(modal);
  10308. modal.on('dispose', function () {
  10309. _this7.removeChild(modal);
  10310. });
  10311. modal.open();
  10312. return modal;
  10313. };
  10314. /**
  10315. * Gets tag settings
  10316. *
  10317. * @param {Element} tag
  10318. * The player tag
  10319. *
  10320. * @return {Object}
  10321. * An object containing all of the settings
  10322. * for a player tag
  10323. */
  10324. Player.getTagSettings = function getTagSettings(tag) {
  10325. var baseOptions = {
  10326. sources: [],
  10327. tracks: []
  10328. };
  10329. var tagOptions = Dom.getAttributes(tag);
  10330. var dataSetup = tagOptions['data-setup'];
  10331. if (Dom.hasClass(tag, 'vjs-fluid')) {
  10332. tagOptions.fluid = true;
  10333. }
  10334. // Check if data-setup attr exists.
  10335. if (dataSetup !== null) {
  10336. // Parse options JSON
  10337. // If empty string, make it a parsable json object.
  10338. var _safeParseTuple = (0, _tuple2['default'])(dataSetup || '{}'),
  10339. err = _safeParseTuple[0],
  10340. data = _safeParseTuple[1];
  10341. if (err) {
  10342. _log2['default'].error(err);
  10343. }
  10344. (0, _obj.assign)(tagOptions, data);
  10345. }
  10346. (0, _obj.assign)(baseOptions, tagOptions);
  10347. // Get tag children settings
  10348. if (tag.hasChildNodes()) {
  10349. var children = tag.childNodes;
  10350. for (var i = 0, j = children.length; i < j; i++) {
  10351. var child = children[i];
  10352. // Change case needed: http://ejohn.org/blog/nodename-case-sensitivity/
  10353. var childName = child.nodeName.toLowerCase();
  10354. if (childName === 'source') {
  10355. baseOptions.sources.push(Dom.getAttributes(child));
  10356. } else if (childName === 'track') {
  10357. baseOptions.tracks.push(Dom.getAttributes(child));
  10358. }
  10359. }
  10360. }
  10361. return baseOptions;
  10362. };
  10363. /**
  10364. * Determine wether or not flexbox is supported
  10365. *
  10366. * @return {boolean}
  10367. * - true if flexbox is supported
  10368. * - false if flexbox is not supported
  10369. */
  10370. Player.prototype.flexNotSupported_ = function flexNotSupported_() {
  10371. var elem = _document2['default'].createElement('i');
  10372. // Note: We don't actually use flexBasis (or flexOrder), but it's one of the more
  10373. // common flex features that we can rely on when checking for flex support.
  10374. return !('flexBasis' in elem.style || 'webkitFlexBasis' in elem.style || 'mozFlexBasis' in elem.style || 'msFlexBasis' in elem.style ||
  10375. // IE10-specific (2012 flex spec)
  10376. 'msFlexOrder' in elem.style);
  10377. };
  10378. return Player;
  10379. }(_component2['default']);
  10380. /**
  10381. * Get the {@link VideoTrackList}
  10382. * @link https://html.spec.whatwg.org/multipage/embedded-content.html#videotracklist
  10383. *
  10384. * @return {VideoTrackList}
  10385. * the current video track list
  10386. *
  10387. * @method Player.prototype.videoTracks
  10388. */
  10389. /**
  10390. * Get the {@link AudioTrackList}
  10391. * @link https://html.spec.whatwg.org/multipage/embedded-content.html#audiotracklist
  10392. *
  10393. * @return {AudioTrackList}
  10394. * the current audio track list
  10395. *
  10396. * @method Player.prototype.audioTracks
  10397. */
  10398. /**
  10399. * Get the {@link TextTrackList}
  10400. *
  10401. * @link http://www.w3.org/html/wg/drafts/html/master/embedded-content-0.html#dom-media-texttracks
  10402. *
  10403. * @return {TextTrackList}
  10404. * the current text track list
  10405. *
  10406. * @method Player.prototype.textTracks
  10407. */
  10408. /**
  10409. * Get the remote {@link TextTrackList}
  10410. *
  10411. * @return {TextTrackList}
  10412. * The current remote text track list
  10413. *
  10414. * @method Player.prototype.textTracks
  10415. */
  10416. /**
  10417. * Get the remote {@link HTMLTrackElementList} tracks.
  10418. *
  10419. * @return {HTMLTrackElementList}
  10420. * The current remote text track element list
  10421. *
  10422. * @method Player.prototype.remoteTextTrackEls
  10423. */
  10424. _trackTypes.ALL.names.forEach(function (name) {
  10425. var props = _trackTypes.ALL[name];
  10426. Player.prototype[props.getterName] = function () {
  10427. if (this.tech_) {
  10428. return this.tech_[props.getterName]();
  10429. }
  10430. // if we have not yet loadTech_, we create {video,audio,text}Tracks_
  10431. // these will be passed to the tech during loading
  10432. this[props.privateName] = this[props.privateName] || new props.ListClass();
  10433. return this[props.privateName];
  10434. };
  10435. });
  10436. /**
  10437. * Global player list
  10438. *
  10439. * @type {Object}
  10440. */
  10441. Player.players = {};
  10442. var navigator = _window2['default'].navigator;
  10443. /*
  10444. * Player instance options, surfaced using options
  10445. * options = Player.prototype.options_
  10446. * Make changes in options, not here.
  10447. *
  10448. * @type {Object}
  10449. * @private
  10450. */
  10451. Player.prototype.options_ = {
  10452. // Default order of fallback technology
  10453. techOrder: _tech2['default'].defaultTechOrder_,
  10454. html5: {},
  10455. flash: {},
  10456. // default inactivity timeout
  10457. inactivityTimeout: 2000,
  10458. // default playback rates
  10459. playbackRates: [],
  10460. // Add playback rate selection by adding rates
  10461. // 'playbackRates': [0.5, 1, 1.5, 2],
  10462. // Included control sets
  10463. children: ['mediaLoader', 'posterImage', 'textTrackDisplay', 'loadingSpinner', 'bigPlayButton', 'controlBar', 'errorDisplay', 'textTrackSettings'],
  10464. language: navigator && (navigator.languages && navigator.languages[0] || navigator.userLanguage || navigator.language) || 'en',
  10465. // locales and their language translations
  10466. languages: {},
  10467. // Default message to show when a video cannot be played.
  10468. notSupportedMessage: 'No compatible source was found for this media.'
  10469. };
  10470. [
  10471. /**
  10472. * Returns whether or not the player is in the "ended" state.
  10473. *
  10474. * @return {Boolean} True if the player is in the ended state, false if not.
  10475. * @method Player#ended
  10476. */
  10477. 'ended',
  10478. /**
  10479. * Returns whether or not the player is in the "seeking" state.
  10480. *
  10481. * @return {Boolean} True if the player is in the seeking state, false if not.
  10482. * @method Player#seeking
  10483. */
  10484. 'seeking',
  10485. /**
  10486. * Returns the TimeRanges of the media that are currently available
  10487. * for seeking to.
  10488. *
  10489. * @return {TimeRanges} the seekable intervals of the media timeline
  10490. * @method Player#seekable
  10491. */
  10492. 'seekable',
  10493. /**
  10494. * Returns the current state of network activity for the element, from
  10495. * the codes in the list below.
  10496. * - NETWORK_EMPTY (numeric value 0)
  10497. * The element has not yet been initialised. All attributes are in
  10498. * their initial states.
  10499. * - NETWORK_IDLE (numeric value 1)
  10500. * The element's resource selection algorithm is active and has
  10501. * selected a resource, but it is not actually using the network at
  10502. * this time.
  10503. * - NETWORK_LOADING (numeric value 2)
  10504. * The user agent is actively trying to download data.
  10505. * - NETWORK_NO_SOURCE (numeric value 3)
  10506. * The element's resource selection algorithm is active, but it has
  10507. * not yet found a resource to use.
  10508. *
  10509. * @see https://html.spec.whatwg.org/multipage/embedded-content.html#network-states
  10510. * @return {number} the current network activity state
  10511. * @method Player#networkState
  10512. */
  10513. 'networkState',
  10514. /**
  10515. * Returns a value that expresses the current state of the element
  10516. * with respect to rendering the current playback position, from the
  10517. * codes in the list below.
  10518. * - HAVE_NOTHING (numeric value 0)
  10519. * No information regarding the media resource is available.
  10520. * - HAVE_METADATA (numeric value 1)
  10521. * Enough of the resource has been obtained that the duration of the
  10522. * resource is available.
  10523. * - HAVE_CURRENT_DATA (numeric value 2)
  10524. * Data for the immediate current playback position is available.
  10525. * - HAVE_FUTURE_DATA (numeric value 3)
  10526. * Data for the immediate current playback position is available, as
  10527. * well as enough data for the user agent to advance the current
  10528. * playback position in the direction of playback.
  10529. * - HAVE_ENOUGH_DATA (numeric value 4)
  10530. * The user agent estimates that enough data is available for
  10531. * playback to proceed uninterrupted.
  10532. *
  10533. * @see https://html.spec.whatwg.org/multipage/embedded-content.html#dom-media-readystate
  10534. * @return {number} the current playback rendering state
  10535. * @method Player#readyState
  10536. */
  10537. 'readyState'].forEach(function (fn) {
  10538. Player.prototype[fn] = function () {
  10539. return this.techGet_(fn);
  10540. };
  10541. });
  10542. TECH_EVENTS_RETRIGGER.forEach(function (event) {
  10543. Player.prototype['handleTech' + (0, _toTitleCase2['default'])(event) + '_'] = function () {
  10544. return this.trigger(event);
  10545. };
  10546. });
  10547. /**
  10548. * Fired when the player has initial duration and dimension information
  10549. *
  10550. * @event Player#loadedmetadata
  10551. * @type {EventTarget~Event}
  10552. */
  10553. /**
  10554. * Fired when the player has downloaded data at the current playback position
  10555. *
  10556. * @event Player#loadeddata
  10557. * @type {EventTarget~Event}
  10558. */
  10559. /**
  10560. * Fired when the current playback position has changed *
  10561. * During playback this is fired every 15-250 milliseconds, depending on the
  10562. * playback technology in use.
  10563. *
  10564. * @event Player#timeupdate
  10565. * @type {EventTarget~Event}
  10566. */
  10567. /**
  10568. * Fired when the volume changes
  10569. *
  10570. * @event Player#volumechange
  10571. * @type {EventTarget~Event}
  10572. */
  10573. /**
  10574. * Reports whether or not a player has a plugin available.
  10575. *
  10576. * This does not report whether or not the plugin has ever been initialized
  10577. * on this player. For that, [usingPlugin]{@link Player#usingPlugin}.
  10578. *
  10579. * @method Player#hasPlugin
  10580. * @param {string} name
  10581. * The name of a plugin.
  10582. *
  10583. * @return {boolean}
  10584. * Whether or not this player has the requested plugin available.
  10585. */
  10586. /**
  10587. * Reports whether or not a player is using a plugin by name.
  10588. *
  10589. * For basic plugins, this only reports whether the plugin has _ever_ been
  10590. * initialized on this player.
  10591. *
  10592. * @method Player#usingPlugin
  10593. * @param {string} name
  10594. * The name of a plugin.
  10595. *
  10596. * @return {boolean}
  10597. * Whether or not this player is using the requested plugin.
  10598. */
  10599. _component2['default'].registerComponent('Player', Player);
  10600. exports['default'] = Player;
  10601. },{"1":1,"100":100,"102":102,"103":103,"4":4,"44":44,"47":47,"48":48,"49":49,"5":5,"53":53,"55":55,"58":58,"61":61,"62":62,"63":63,"64":64,"70":70,"71":71,"73":73,"77":77,"8":8,"81":81,"82":82,"85":85,"86":86,"87":87,"88":88,"90":90,"91":91,"92":92,"93":93,"94":94,"95":95,"96":96,"99":99}],57:[function(_dereq_,module,exports){
  10602. 'use strict';
  10603. exports.__esModule = true;
  10604. var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
  10605. var _evented = _dereq_(53);
  10606. var _evented2 = _interopRequireDefault(_evented);
  10607. var _stateful = _dereq_(54);
  10608. var _stateful2 = _interopRequireDefault(_stateful);
  10609. var _events = _dereq_(86);
  10610. var Events = _interopRequireWildcard(_events);
  10611. var _fn = _dereq_(88);
  10612. var Fn = _interopRequireWildcard(_fn);
  10613. var _log = _dereq_(91);
  10614. var _log2 = _interopRequireDefault(_log);
  10615. var _player = _dereq_(56);
  10616. var _player2 = _interopRequireDefault(_player);
  10617. function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
  10618. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  10619. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } /**
  10620. * @file plugin.js
  10621. */
  10622. /**
  10623. * The base plugin name.
  10624. *
  10625. * @private
  10626. * @constant
  10627. * @type {string}
  10628. */
  10629. var BASE_PLUGIN_NAME = 'plugin';
  10630. /**
  10631. * The key on which a player's active plugins cache is stored.
  10632. *
  10633. * @private
  10634. * @constant
  10635. * @type {string}
  10636. */
  10637. var PLUGIN_CACHE_KEY = 'activePlugins_';
  10638. /**
  10639. * Stores registered plugins in a private space.
  10640. *
  10641. * @private
  10642. * @type {Object}
  10643. */
  10644. var pluginStorage = {};
  10645. /**
  10646. * Reports whether or not a plugin has been registered.
  10647. *
  10648. * @private
  10649. * @param {string} name
  10650. * The name of a plugin.
  10651. *
  10652. * @returns {boolean}
  10653. * Whether or not the plugin has been registered.
  10654. */
  10655. var pluginExists = function pluginExists(name) {
  10656. return pluginStorage.hasOwnProperty(name);
  10657. };
  10658. /**
  10659. * Get a single registered plugin by name.
  10660. *
  10661. * @private
  10662. * @param {string} name
  10663. * The name of a plugin.
  10664. *
  10665. * @returns {Function|undefined}
  10666. * The plugin (or undefined).
  10667. */
  10668. var getPlugin = function getPlugin(name) {
  10669. return pluginExists(name) ? pluginStorage[name] : undefined;
  10670. };
  10671. /**
  10672. * Marks a plugin as "active" on a player.
  10673. *
  10674. * Also, ensures that the player has an object for tracking active plugins.
  10675. *
  10676. * @private
  10677. * @param {Player} player
  10678. * A Video.js player instance.
  10679. *
  10680. * @param {string} name
  10681. * The name of a plugin.
  10682. */
  10683. var markPluginAsActive = function markPluginAsActive(player, name) {
  10684. player[PLUGIN_CACHE_KEY] = player[PLUGIN_CACHE_KEY] || {};
  10685. player[PLUGIN_CACHE_KEY][name] = true;
  10686. };
  10687. /**
  10688. * Takes a basic plugin function and returns a wrapper function which marks
  10689. * on the player that the plugin has been activated.
  10690. *
  10691. * @private
  10692. * @param {string} name
  10693. * The name of the plugin.
  10694. *
  10695. * @param {Function} plugin
  10696. * The basic plugin.
  10697. *
  10698. * @returns {Function}
  10699. * A wrapper function for the given plugin.
  10700. */
  10701. var createBasicPlugin = function createBasicPlugin(name, plugin) {
  10702. var basicPluginWrapper = function basicPluginWrapper() {
  10703. var instance = plugin.apply(this, arguments);
  10704. markPluginAsActive(this, name);
  10705. // We trigger the "pluginsetup" event on the player regardless, but we want
  10706. // the hash to be consistent with the hash provided for advanced plugins.
  10707. // The only potentially counter-intuitive thing here is the `instance` is the
  10708. // value returned by the `plugin` function.
  10709. this.trigger('pluginsetup', { name: name, plugin: plugin, instance: instance });
  10710. return instance;
  10711. };
  10712. Object.keys(plugin).forEach(function (prop) {
  10713. basicPluginWrapper[prop] = plugin[prop];
  10714. });
  10715. return basicPluginWrapper;
  10716. };
  10717. /**
  10718. * Takes a plugin sub-class and returns a factory function for generating
  10719. * instances of it.
  10720. *
  10721. * This factory function will replace itself with an instance of the requested
  10722. * sub-class of Plugin.
  10723. *
  10724. * @private
  10725. * @param {string} name
  10726. * The name of the plugin.
  10727. *
  10728. * @param {Plugin} PluginSubClass
  10729. * The advanced plugin.
  10730. *
  10731. * @returns {Function}
  10732. */
  10733. var createPluginFactory = function createPluginFactory(name, PluginSubClass) {
  10734. // Add a `name` property to the plugin prototype so that each plugin can
  10735. // refer to itself by name.
  10736. PluginSubClass.prototype.name = name;
  10737. return function () {
  10738. for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
  10739. args[_key] = arguments[_key];
  10740. }
  10741. var instance = new (Function.prototype.bind.apply(PluginSubClass, [null].concat([this].concat(args))))();
  10742. // The plugin is replaced by a function that returns the current instance.
  10743. this[name] = function () {
  10744. return instance;
  10745. };
  10746. return instance;
  10747. };
  10748. };
  10749. /**
  10750. * Parent class for all advanced plugins.
  10751. *
  10752. * @mixes module:evented~EventedMixin
  10753. * @mixes module:stateful~StatefulMixin
  10754. * @fires Player#pluginsetup
  10755. * @listens Player#dispose
  10756. * @throws {Error}
  10757. * If attempting to instantiate the base {@link Plugin} class
  10758. * directly instead of via a sub-class.
  10759. */
  10760. var Plugin = function () {
  10761. /**
  10762. * Creates an instance of this class.
  10763. *
  10764. * Sub-classes should call `super` to ensure plugins are properly initialized.
  10765. *
  10766. * @param {Player} player
  10767. * A Video.js player instance.
  10768. */
  10769. function Plugin(player) {
  10770. _classCallCheck(this, Plugin);
  10771. this.player = player;
  10772. if (this.constructor === Plugin) {
  10773. throw new Error('Plugin must be sub-classed; not directly instantiated.');
  10774. }
  10775. // Make this object evented, but remove the added `trigger` method so we
  10776. // use the prototype version instead.
  10777. (0, _evented2['default'])(this);
  10778. delete this.trigger;
  10779. (0, _stateful2['default'])(this, this.constructor.defaultState);
  10780. markPluginAsActive(player, this.name);
  10781. // Auto-bind the dispose method so we can use it as a listener and unbind
  10782. // it later easily.
  10783. this.dispose = Fn.bind(this, this.dispose);
  10784. // If the player is disposed, dispose the plugin.
  10785. player.on('dispose', this.dispose);
  10786. player.trigger('pluginsetup', this.getEventHash());
  10787. }
  10788. /**
  10789. * Each event triggered by plugins includes a hash of additional data with
  10790. * conventional properties.
  10791. *
  10792. * This returns that object or mutates an existing hash.
  10793. *
  10794. * @param {Object} [hash={}]
  10795. * An object to be used as event an event hash.
  10796. *
  10797. * @returns {Plugin~PluginEventHash}
  10798. * An event hash object with provided properties mixed-in.
  10799. */
  10800. Plugin.prototype.getEventHash = function getEventHash() {
  10801. var hash = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  10802. hash.name = this.name;
  10803. hash.plugin = this.constructor;
  10804. hash.instance = this;
  10805. return hash;
  10806. };
  10807. /**
  10808. * Triggers an event on the plugin object and overrides
  10809. * {@link module:evented~EventedMixin.trigger|EventedMixin.trigger}.
  10810. *
  10811. * @param {string|Object} event
  10812. * An event type or an object with a type property.
  10813. *
  10814. * @param {Object} [hash={}]
  10815. * Additional data hash to merge with a
  10816. * {@link Plugin~PluginEventHash|PluginEventHash}.
  10817. *
  10818. * @returns {boolean}
  10819. * Whether or not default was prevented.
  10820. */
  10821. Plugin.prototype.trigger = function trigger(event) {
  10822. var hash = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  10823. return Events.trigger(this.eventBusEl_, event, this.getEventHash(hash));
  10824. };
  10825. /**
  10826. * Handles "statechanged" events on the plugin. No-op by default, override by
  10827. * subclassing.
  10828. *
  10829. * @abstract
  10830. * @param {Event} e
  10831. * An event object provided by a "statechanged" event.
  10832. *
  10833. * @param {Object} e.changes
  10834. * An object describing changes that occurred with the "statechanged"
  10835. * event.
  10836. */
  10837. Plugin.prototype.handleStateChanged = function handleStateChanged(e) {};
  10838. /**
  10839. * Disposes a plugin.
  10840. *
  10841. * Subclasses can override this if they want, but for the sake of safety,
  10842. * it's probably best to subscribe the "dispose" event.
  10843. *
  10844. * @fires Plugin#dispose
  10845. */
  10846. Plugin.prototype.dispose = function dispose() {
  10847. var name = this.name,
  10848. player = this.player;
  10849. /**
  10850. * Signals that a advanced plugin is about to be disposed.
  10851. *
  10852. * @event Plugin#dispose
  10853. * @type {EventTarget~Event}
  10854. */
  10855. this.trigger('dispose');
  10856. this.off();
  10857. player.off('dispose', this.dispose);
  10858. // Eliminate any possible sources of leaking memory by clearing up
  10859. // references between the player and the plugin instance and nulling out
  10860. // the plugin's state and replacing methods with a function that throws.
  10861. player[PLUGIN_CACHE_KEY][name] = false;
  10862. this.player = this.state = null;
  10863. // Finally, replace the plugin name on the player with a new factory
  10864. // function, so that the plugin is ready to be set up again.
  10865. player[name] = createPluginFactory(name, pluginStorage[name]);
  10866. };
  10867. /**
  10868. * Determines if a plugin is a basic plugin (i.e. not a sub-class of `Plugin`).
  10869. *
  10870. * @param {string|Function} plugin
  10871. * If a string, matches the name of a plugin. If a function, will be
  10872. * tested directly.
  10873. *
  10874. * @returns {boolean}
  10875. * Whether or not a plugin is a basic plugin.
  10876. */
  10877. Plugin.isBasic = function isBasic(plugin) {
  10878. var p = typeof plugin === 'string' ? getPlugin(plugin) : plugin;
  10879. return typeof p === 'function' && !Plugin.prototype.isPrototypeOf(p.prototype);
  10880. };
  10881. /**
  10882. * Register a Video.js plugin.
  10883. *
  10884. * @param {string} name
  10885. * The name of the plugin to be registered. Must be a string and
  10886. * must not match an existing plugin or a method on the `Player`
  10887. * prototype.
  10888. *
  10889. * @param {Function} plugin
  10890. * A sub-class of `Plugin` or a function for basic plugins.
  10891. *
  10892. * @returns {Function}
  10893. * For advanced plugins, a factory function for that plugin. For
  10894. * basic plugins, a wrapper function that initializes the plugin.
  10895. */
  10896. Plugin.registerPlugin = function registerPlugin(name, plugin) {
  10897. if (typeof name !== 'string') {
  10898. throw new Error('Illegal plugin name, "' + name + '", must be a string, was ' + (typeof name === 'undefined' ? 'undefined' : _typeof(name)) + '.');
  10899. }
  10900. if (pluginExists(name)) {
  10901. _log2['default'].warn('A plugin named "' + name + '" already exists. You may want to avoid re-registering plugins!');
  10902. } else if (_player2['default'].prototype.hasOwnProperty(name)) {
  10903. throw new Error('Illegal plugin name, "' + name + '", cannot share a name with an existing player method!');
  10904. }
  10905. if (typeof plugin !== 'function') {
  10906. throw new Error('Illegal plugin for "' + name + '", must be a function, was ' + (typeof plugin === 'undefined' ? 'undefined' : _typeof(plugin)) + '.');
  10907. }
  10908. pluginStorage[name] = plugin;
  10909. // Add a player prototype method for all sub-classed plugins (but not for
  10910. // the base Plugin class).
  10911. if (name !== BASE_PLUGIN_NAME) {
  10912. if (Plugin.isBasic(plugin)) {
  10913. _player2['default'].prototype[name] = createBasicPlugin(name, plugin);
  10914. } else {
  10915. _player2['default'].prototype[name] = createPluginFactory(name, plugin);
  10916. }
  10917. }
  10918. return plugin;
  10919. };
  10920. /**
  10921. * De-register a Video.js plugin.
  10922. *
  10923. * @param {string} name
  10924. * The name of the plugin to be deregistered.
  10925. */
  10926. Plugin.deregisterPlugin = function deregisterPlugin(name) {
  10927. if (name === BASE_PLUGIN_NAME) {
  10928. throw new Error('Cannot de-register base plugin.');
  10929. }
  10930. if (pluginExists(name)) {
  10931. delete pluginStorage[name];
  10932. delete _player2['default'].prototype[name];
  10933. }
  10934. };
  10935. /**
  10936. * Gets an object containing multiple Video.js plugins.
  10937. *
  10938. * @param {Array} [names]
  10939. * If provided, should be an array of plugin names. Defaults to _all_
  10940. * plugin names.
  10941. *
  10942. * @returns {Object|undefined}
  10943. * An object containing plugin(s) associated with their name(s) or
  10944. * `undefined` if no matching plugins exist).
  10945. */
  10946. Plugin.getPlugins = function getPlugins() {
  10947. var names = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : Object.keys(pluginStorage);
  10948. var result = void 0;
  10949. names.forEach(function (name) {
  10950. var plugin = getPlugin(name);
  10951. if (plugin) {
  10952. result = result || {};
  10953. result[name] = plugin;
  10954. }
  10955. });
  10956. return result;
  10957. };
  10958. /**
  10959. * Gets a plugin's version, if available
  10960. *
  10961. * @param {string} name
  10962. * The name of a plugin.
  10963. *
  10964. * @returns {string}
  10965. * The plugin's version or an empty string.
  10966. */
  10967. Plugin.getPluginVersion = function getPluginVersion(name) {
  10968. var plugin = getPlugin(name);
  10969. return plugin && plugin.VERSION || '';
  10970. };
  10971. return Plugin;
  10972. }();
  10973. /**
  10974. * Gets a plugin by name if it exists.
  10975. *
  10976. * @static
  10977. * @method getPlugin
  10978. * @memberOf Plugin
  10979. * @param {string} name
  10980. * The name of a plugin.
  10981. *
  10982. * @returns {Function|undefined}
  10983. * The plugin (or `undefined`).
  10984. */
  10985. Plugin.getPlugin = getPlugin;
  10986. /**
  10987. * The name of the base plugin class as it is registered.
  10988. *
  10989. * @type {string}
  10990. */
  10991. Plugin.BASE_PLUGIN_NAME = BASE_PLUGIN_NAME;
  10992. Plugin.registerPlugin(BASE_PLUGIN_NAME, Plugin);
  10993. /**
  10994. * Documented in player.js
  10995. *
  10996. * @ignore
  10997. */
  10998. _player2['default'].prototype.usingPlugin = function (name) {
  10999. return !!this[PLUGIN_CACHE_KEY] && this[PLUGIN_CACHE_KEY][name] === true;
  11000. };
  11001. /**
  11002. * Documented in player.js
  11003. *
  11004. * @ignore
  11005. */
  11006. _player2['default'].prototype.hasPlugin = function (name) {
  11007. return !!pluginExists(name);
  11008. };
  11009. exports['default'] = Plugin;
  11010. /**
  11011. * Signals that a plugin has just been set up on a player.
  11012. *
  11013. * @event Player#pluginsetup
  11014. * @type {Plugin~PluginEventHash}
  11015. */
  11016. /**
  11017. * @typedef {Object} Plugin~PluginEventHash
  11018. *
  11019. * @property {string} instance
  11020. * For basic plugins, the return value of the plugin function. For
  11021. * advanced plugins, the plugin instance on which the event is fired.
  11022. *
  11023. * @property {string} name
  11024. * The name of the plugin.
  11025. *
  11026. * @property {string} plugin
  11027. * For basic plugins, the plugin function. For advanced plugins, the
  11028. * plugin class/constructor.
  11029. */
  11030. },{"53":53,"54":54,"56":56,"86":86,"88":88,"91":91}],58:[function(_dereq_,module,exports){
  11031. 'use strict';
  11032. exports.__esModule = true;
  11033. var _clickableComponent = _dereq_(3);
  11034. var _clickableComponent2 = _interopRequireDefault(_clickableComponent);
  11035. var _component = _dereq_(5);
  11036. var _component2 = _interopRequireDefault(_component);
  11037. var _fn = _dereq_(88);
  11038. var Fn = _interopRequireWildcard(_fn);
  11039. var _dom = _dereq_(85);
  11040. var Dom = _interopRequireWildcard(_dom);
  11041. var _browser = _dereq_(81);
  11042. var browser = _interopRequireWildcard(_browser);
  11043. function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
  11044. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  11045. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  11046. function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
  11047. function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
  11048. * @file poster-image.js
  11049. */
  11050. /**
  11051. * A `ClickableComponent` that handles showing the poster image for the player.
  11052. *
  11053. * @extends ClickableComponent
  11054. */
  11055. var PosterImage = function (_ClickableComponent) {
  11056. _inherits(PosterImage, _ClickableComponent);
  11057. /**
  11058. * Create an instance of this class.
  11059. *
  11060. * @param {Player} player
  11061. * The `Player` that this class should attach to.
  11062. *
  11063. * @param {Object} [options]
  11064. * The key/value store of player options.
  11065. */
  11066. function PosterImage(player, options) {
  11067. _classCallCheck(this, PosterImage);
  11068. var _this = _possibleConstructorReturn(this, _ClickableComponent.call(this, player, options));
  11069. _this.update();
  11070. player.on('posterchange', Fn.bind(_this, _this.update));
  11071. return _this;
  11072. }
  11073. /**
  11074. * Clean up and dispose of the `PosterImage`.
  11075. */
  11076. PosterImage.prototype.dispose = function dispose() {
  11077. this.player().off('posterchange', this.update);
  11078. _ClickableComponent.prototype.dispose.call(this);
  11079. };
  11080. /**
  11081. * Create the `PosterImage`s DOM element.
  11082. *
  11083. * @return {Element}
  11084. * The element that gets created.
  11085. */
  11086. PosterImage.prototype.createEl = function createEl() {
  11087. var el = Dom.createEl('div', {
  11088. className: 'vjs-poster',
  11089. // Don't want poster to be tabbable.
  11090. tabIndex: -1
  11091. });
  11092. // To ensure the poster image resizes while maintaining its original aspect
  11093. // ratio, use a div with `background-size` when available. For browsers that
  11094. // do not support `background-size` (e.g. IE8), fall back on using a regular
  11095. // img element.
  11096. if (!browser.BACKGROUND_SIZE_SUPPORTED) {
  11097. this.fallbackImg_ = Dom.createEl('img');
  11098. el.appendChild(this.fallbackImg_);
  11099. }
  11100. return el;
  11101. };
  11102. /**
  11103. * An {@link EventTarget~EventListener} for {@link Player#posterchange} events.
  11104. *
  11105. * @listens Player#posterchange
  11106. *
  11107. * @param {EventTarget~Event} [event]
  11108. * The `Player#posterchange` event that triggered this function.
  11109. */
  11110. PosterImage.prototype.update = function update(event) {
  11111. var url = this.player().poster();
  11112. this.setSrc(url);
  11113. // If there's no poster source we should display:none on this component
  11114. // so it's not still clickable or right-clickable
  11115. if (url) {
  11116. this.show();
  11117. } else {
  11118. this.hide();
  11119. }
  11120. };
  11121. /**
  11122. * Set the source of the `PosterImage` depending on the display method.
  11123. *
  11124. * @param {string} url
  11125. * The URL to the source for the `PosterImage`.
  11126. */
  11127. PosterImage.prototype.setSrc = function setSrc(url) {
  11128. if (this.fallbackImg_) {
  11129. this.fallbackImg_.src = url;
  11130. } else {
  11131. var backgroundImage = '';
  11132. // Any falsey values should stay as an empty string, otherwise
  11133. // this will throw an extra error
  11134. if (url) {
  11135. backgroundImage = 'url("' + url + '")';
  11136. }
  11137. this.el_.style.backgroundImage = backgroundImage;
  11138. }
  11139. };
  11140. /**
  11141. * An {@link EventTarget~EventListener} for clicks on the `PosterImage`. See
  11142. * {@link ClickableComponent#handleClick} for instances where this will be triggered.
  11143. *
  11144. * @listens tap
  11145. * @listens click
  11146. * @listens keydown
  11147. *
  11148. * @param {EventTarget~Event} event
  11149. + The `click`, `tap` or `keydown` event that caused this function to be called.
  11150. */
  11151. PosterImage.prototype.handleClick = function handleClick(event) {
  11152. // We don't want a click to trigger playback when controls are disabled
  11153. if (!this.player_.controls()) {
  11154. return;
  11155. }
  11156. if (this.player_.paused()) {
  11157. this.player_.play();
  11158. } else {
  11159. this.player_.pause();
  11160. }
  11161. };
  11162. return PosterImage;
  11163. }(_clickableComponent2['default']);
  11164. _component2['default'].registerComponent('PosterImage', PosterImage);
  11165. exports['default'] = PosterImage;
  11166. },{"3":3,"5":5,"81":81,"85":85,"88":88}],59:[function(_dereq_,module,exports){
  11167. 'use strict';
  11168. exports.__esModule = true;
  11169. exports.hasLoaded = exports.autoSetupTimeout = exports.autoSetup = undefined;
  11170. var _dom = _dereq_(85);
  11171. var Dom = _interopRequireWildcard(_dom);
  11172. var _events = _dereq_(86);
  11173. var Events = _interopRequireWildcard(_events);
  11174. var _document = _dereq_(99);
  11175. var _document2 = _interopRequireDefault(_document);
  11176. var _window = _dereq_(100);
  11177. var _window2 = _interopRequireDefault(_window);
  11178. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  11179. function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
  11180. /**
  11181. * @file setup.js - Functions for setting up a player without
  11182. * user interaction based on the data-setup `attribute` of the video tag.
  11183. *
  11184. * @module setup
  11185. */
  11186. var _windowLoaded = false;
  11187. var videojs = void 0;
  11188. /**
  11189. * Set up any tags that have a data-setup `attribute` when the player is started.
  11190. */
  11191. var autoSetup = function autoSetup() {
  11192. // Protect against breakage in non-browser environments.
  11193. if (!Dom.isReal()) {
  11194. return;
  11195. }
  11196. // One day, when we stop supporting IE8, go back to this, but in the meantime...*hack hack hack*
  11197. // var vids = Array.prototype.slice.call(document.getElementsByTagName('video'));
  11198. // var audios = Array.prototype.slice.call(document.getElementsByTagName('audio'));
  11199. // var mediaEls = vids.concat(audios);
  11200. // Because IE8 doesn't support calling slice on a node list, we need to loop
  11201. // through each list of elements to build up a new, combined list of elements.
  11202. var vids = _document2['default'].getElementsByTagName('video');
  11203. var audios = _document2['default'].getElementsByTagName('audio');
  11204. var mediaEls = [];
  11205. if (vids && vids.length > 0) {
  11206. for (var i = 0, e = vids.length; i < e; i++) {
  11207. mediaEls.push(vids[i]);
  11208. }
  11209. }
  11210. if (audios && audios.length > 0) {
  11211. for (var _i = 0, _e = audios.length; _i < _e; _i++) {
  11212. mediaEls.push(audios[_i]);
  11213. }
  11214. }
  11215. // Check if any media elements exist
  11216. if (mediaEls && mediaEls.length > 0) {
  11217. for (var _i2 = 0, _e2 = mediaEls.length; _i2 < _e2; _i2++) {
  11218. var mediaEl = mediaEls[_i2];
  11219. // Check if element exists, has getAttribute func.
  11220. // IE seems to consider typeof el.getAttribute == 'object' instead of
  11221. // 'function' like expected, at least when loading the player immediately.
  11222. if (mediaEl && mediaEl.getAttribute) {
  11223. // Make sure this player hasn't already been set up.
  11224. if (mediaEl.player === undefined) {
  11225. var options = mediaEl.getAttribute('data-setup');
  11226. // Check if data-setup attr exists.
  11227. // We only auto-setup if they've added the data-setup attr.
  11228. if (options !== null) {
  11229. // Create new video.js instance.
  11230. videojs(mediaEl);
  11231. }
  11232. }
  11233. // If getAttribute isn't defined, we need to wait for the DOM.
  11234. } else {
  11235. autoSetupTimeout(1);
  11236. break;
  11237. }
  11238. }
  11239. // No videos were found, so keep looping unless page is finished loading.
  11240. } else if (!_windowLoaded) {
  11241. autoSetupTimeout(1);
  11242. }
  11243. };
  11244. /**
  11245. * Wait until the page is loaded before running autoSetup. This will be called in
  11246. * autoSetup if `hasLoaded` returns false.
  11247. *
  11248. * @param {number} wait
  11249. * How long to wait in ms
  11250. *
  11251. * @param {videojs} [vjs]
  11252. * The videojs library function
  11253. */
  11254. function autoSetupTimeout(wait, vjs) {
  11255. if (vjs) {
  11256. videojs = vjs;
  11257. }
  11258. _window2['default'].setTimeout(autoSetup, wait);
  11259. }
  11260. if (Dom.isReal() && _document2['default'].readyState === 'complete') {
  11261. _windowLoaded = true;
  11262. } else {
  11263. /**
  11264. * Listen for the load event on window, and set _windowLoaded to true.
  11265. *
  11266. * @listens load
  11267. */
  11268. Events.one(_window2['default'], 'load', function () {
  11269. _windowLoaded = true;
  11270. });
  11271. }
  11272. /**
  11273. * check if the document has been loaded
  11274. */
  11275. var hasLoaded = function hasLoaded() {
  11276. return _windowLoaded;
  11277. };
  11278. exports.autoSetup = autoSetup;
  11279. exports.autoSetupTimeout = autoSetupTimeout;
  11280. exports.hasLoaded = hasLoaded;
  11281. },{"100":100,"85":85,"86":86,"99":99}],60:[function(_dereq_,module,exports){
  11282. 'use strict';
  11283. exports.__esModule = true;
  11284. var _component = _dereq_(5);
  11285. var _component2 = _interopRequireDefault(_component);
  11286. var _dom = _dereq_(85);
  11287. var Dom = _interopRequireWildcard(_dom);
  11288. var _obj = _dereq_(93);
  11289. function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
  11290. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  11291. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  11292. function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
  11293. function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
  11294. * @file slider.js
  11295. */
  11296. /**
  11297. * The base functionality for a slider. Can be vertical or horizontal.
  11298. * For instance the volume bar or the seek bar on a video is a slider.
  11299. *
  11300. * @extends Component
  11301. */
  11302. var Slider = function (_Component) {
  11303. _inherits(Slider, _Component);
  11304. /**
  11305. * Create an instance of this class
  11306. *
  11307. * @param {Player} player
  11308. * The `Player` that this class should be attached to.
  11309. *
  11310. * @param {Object} [options]
  11311. * The key/value store of player options.
  11312. */
  11313. function Slider(player, options) {
  11314. _classCallCheck(this, Slider);
  11315. // Set property names to bar to match with the child Slider class is looking for
  11316. var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
  11317. _this.bar = _this.getChild(_this.options_.barName);
  11318. // Set a horizontal or vertical class on the slider depending on the slider type
  11319. _this.vertical(!!_this.options_.vertical);
  11320. _this.on('mousedown', _this.handleMouseDown);
  11321. _this.on('touchstart', _this.handleMouseDown);
  11322. _this.on('focus', _this.handleFocus);
  11323. _this.on('blur', _this.handleBlur);
  11324. _this.on('click', _this.handleClick);
  11325. _this.on(player, 'controlsvisible', _this.update);
  11326. if (_this.playerEvent) {
  11327. _this.on(player, _this.playerEvent, _this.update);
  11328. }
  11329. return _this;
  11330. }
  11331. /**
  11332. * Create the `Button`s DOM element.
  11333. *
  11334. * @param {string} type
  11335. * Type of element to create.
  11336. *
  11337. * @param {Object} [props={}]
  11338. * List of properties in Object form.
  11339. *
  11340. * @param {Object} [attributes={}]
  11341. * list of attributes in Object form.
  11342. *
  11343. * @return {Element}
  11344. * The element that gets created.
  11345. */
  11346. Slider.prototype.createEl = function createEl(type) {
  11347. var props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  11348. var attributes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
  11349. // Add the slider element class to all sub classes
  11350. props.className = props.className + ' vjs-slider';
  11351. props = (0, _obj.assign)({
  11352. tabIndex: 0
  11353. }, props);
  11354. attributes = (0, _obj.assign)({
  11355. 'role': 'slider',
  11356. 'aria-valuenow': 0,
  11357. 'aria-valuemin': 0,
  11358. 'aria-valuemax': 100,
  11359. 'tabIndex': 0
  11360. }, attributes);
  11361. return _Component.prototype.createEl.call(this, type, props, attributes);
  11362. };
  11363. /**
  11364. * Handle `mousedown` or `touchstart` events on the `Slider`.
  11365. *
  11366. * @param {EventTarget~Event} event
  11367. * `mousedown` or `touchstart` event that triggered this function
  11368. *
  11369. * @listens mousedown
  11370. * @listens touchstart
  11371. * @fires Slider#slideractive
  11372. */
  11373. Slider.prototype.handleMouseDown = function handleMouseDown(event) {
  11374. var doc = this.bar.el_.ownerDocument;
  11375. event.preventDefault();
  11376. Dom.blockTextSelection();
  11377. this.addClass('vjs-sliding');
  11378. /**
  11379. * Triggered when the slider is in an active state
  11380. *
  11381. * @event Slider#slideractive
  11382. * @type {EventTarget~Event}
  11383. */
  11384. this.trigger('slideractive');
  11385. this.on(doc, 'mousemove', this.handleMouseMove);
  11386. this.on(doc, 'mouseup', this.handleMouseUp);
  11387. this.on(doc, 'touchmove', this.handleMouseMove);
  11388. this.on(doc, 'touchend', this.handleMouseUp);
  11389. this.handleMouseMove(event);
  11390. };
  11391. /**
  11392. * Handle the `mousemove`, `touchmove`, and `mousedown` events on this `Slider`.
  11393. * The `mousemove` and `touchmove` events will only only trigger this function during
  11394. * `mousedown` and `touchstart`. This is due to {@link Slider#handleMouseDown} and
  11395. * {@link Slider#handleMouseUp}.
  11396. *
  11397. * @param {EventTarget~Event} event
  11398. * `mousedown`, `mousemove`, `touchstart`, or `touchmove` event that triggered
  11399. * this function
  11400. *
  11401. * @listens mousemove
  11402. * @listens touchmove
  11403. */
  11404. Slider.prototype.handleMouseMove = function handleMouseMove(event) {};
  11405. /**
  11406. * Handle `mouseup` or `touchend` events on the `Slider`.
  11407. *
  11408. * @param {EventTarget~Event} event
  11409. * `mouseup` or `touchend` event that triggered this function.
  11410. *
  11411. * @listens touchend
  11412. * @listens mouseup
  11413. * @fires Slider#sliderinactive
  11414. */
  11415. Slider.prototype.handleMouseUp = function handleMouseUp() {
  11416. var doc = this.bar.el_.ownerDocument;
  11417. Dom.unblockTextSelection();
  11418. this.removeClass('vjs-sliding');
  11419. /**
  11420. * Triggered when the slider is no longer in an active state.
  11421. *
  11422. * @event Slider#sliderinactive
  11423. * @type {EventTarget~Event}
  11424. */
  11425. this.trigger('sliderinactive');
  11426. this.off(doc, 'mousemove', this.handleMouseMove);
  11427. this.off(doc, 'mouseup', this.handleMouseUp);
  11428. this.off(doc, 'touchmove', this.handleMouseMove);
  11429. this.off(doc, 'touchend', this.handleMouseUp);
  11430. this.update();
  11431. };
  11432. /**
  11433. * Update the progress bar of the `Slider`.
  11434. *
  11435. * @returns {number}
  11436. * The percentage of progress the progress bar represents as a
  11437. * number from 0 to 1.
  11438. */
  11439. Slider.prototype.update = function update() {
  11440. // In VolumeBar init we have a setTimeout for update that pops and update
  11441. // to the end of the execution stack. The player is destroyed before then
  11442. // update will cause an error
  11443. if (!this.el_) {
  11444. return;
  11445. }
  11446. // If scrubbing, we could use a cached value to make the handle keep up
  11447. // with the user's mouse. On HTML5 browsers scrubbing is really smooth, but
  11448. // some flash players are slow, so we might want to utilize this later.
  11449. // var progress = (this.player_.scrubbing()) ? this.player_.getCache().currentTime / this.player_.duration() : this.player_.currentTime() / this.player_.duration();
  11450. var progress = this.getPercent();
  11451. var bar = this.bar;
  11452. // If there's no bar...
  11453. if (!bar) {
  11454. return;
  11455. }
  11456. // Protect against no duration and other division issues
  11457. if (typeof progress !== 'number' || progress !== progress || progress < 0 || progress === Infinity) {
  11458. progress = 0;
  11459. }
  11460. // Convert to a percentage for setting
  11461. var percentage = (progress * 100).toFixed(2) + '%';
  11462. var style = bar.el().style;
  11463. // Set the new bar width or height
  11464. if (this.vertical()) {
  11465. style.height = percentage;
  11466. } else {
  11467. style.width = percentage;
  11468. }
  11469. return progress;
  11470. };
  11471. /**
  11472. * Calculate distance for slider
  11473. *
  11474. * @param {EventTarget~Event} event
  11475. * The event that caused this function to run.
  11476. *
  11477. * @return {number}
  11478. * The current position of the Slider.
  11479. * - postition.x for vertical `Slider`s
  11480. * - postition.y for horizontal `Slider`s
  11481. */
  11482. Slider.prototype.calculateDistance = function calculateDistance(event) {
  11483. var position = Dom.getPointerPosition(this.el_, event);
  11484. if (this.vertical()) {
  11485. return position.y;
  11486. }
  11487. return position.x;
  11488. };
  11489. /**
  11490. * Handle a `focus` event on this `Slider`.
  11491. *
  11492. * @param {EventTarget~Event} event
  11493. * The `focus` event that caused this function to run.
  11494. *
  11495. * @listens focus
  11496. */
  11497. Slider.prototype.handleFocus = function handleFocus() {
  11498. this.on(this.bar.el_.ownerDocument, 'keydown', this.handleKeyPress);
  11499. };
  11500. /**
  11501. * Handle a `keydown` event on the `Slider`. Watches for left, rigth, up, and down
  11502. * arrow keys. This function will only be called when the slider has focus. See
  11503. * {@link Slider#handleFocus} and {@link Slider#handleBlur}.
  11504. *
  11505. * @param {EventTarget~Event} event
  11506. * the `keydown` event that caused this function to run.
  11507. *
  11508. * @listens keydown
  11509. */
  11510. Slider.prototype.handleKeyPress = function handleKeyPress(event) {
  11511. // Left and Down Arrows
  11512. if (event.which === 37 || event.which === 40) {
  11513. event.preventDefault();
  11514. this.stepBack();
  11515. // Up and Right Arrows
  11516. } else if (event.which === 38 || event.which === 39) {
  11517. event.preventDefault();
  11518. this.stepForward();
  11519. }
  11520. };
  11521. /**
  11522. * Handle a `blur` event on this `Slider`.
  11523. *
  11524. * @param {EventTarget~Event} event
  11525. * The `blur` event that caused this function to run.
  11526. *
  11527. * @listens blur
  11528. */
  11529. Slider.prototype.handleBlur = function handleBlur() {
  11530. this.off(this.bar.el_.ownerDocument, 'keydown', this.handleKeyPress);
  11531. };
  11532. /**
  11533. * Listener for click events on slider, used to prevent clicks
  11534. * from bubbling up to parent elements like button menus.
  11535. *
  11536. * @param {Object} event
  11537. * Event that caused this object to run
  11538. */
  11539. Slider.prototype.handleClick = function handleClick(event) {
  11540. event.stopImmediatePropagation();
  11541. event.preventDefault();
  11542. };
  11543. /**
  11544. * Get/set if slider is horizontal for vertical
  11545. *
  11546. * @param {boolean} [bool]
  11547. * - true if slider is vertical,
  11548. * - false is horizontal
  11549. *
  11550. * @return {boolean}
  11551. * - true if slider is vertical, and getting
  11552. * - false if the slider is horizontal, and getting
  11553. */
  11554. Slider.prototype.vertical = function vertical(bool) {
  11555. if (bool === undefined) {
  11556. return this.vertical_ || false;
  11557. }
  11558. this.vertical_ = !!bool;
  11559. if (this.vertical_) {
  11560. this.addClass('vjs-slider-vertical');
  11561. } else {
  11562. this.addClass('vjs-slider-horizontal');
  11563. }
  11564. };
  11565. return Slider;
  11566. }(_component2['default']);
  11567. _component2['default'].registerComponent('Slider', Slider);
  11568. exports['default'] = Slider;
  11569. },{"5":5,"85":85,"93":93}],61:[function(_dereq_,module,exports){
  11570. 'use strict';
  11571. exports.__esModule = true;
  11572. var _templateObject = _taggedTemplateLiteralLoose(['Text Tracks are being loaded from another origin but the crossorigin attribute isn\'t used.\n This may prevent text tracks from loading.'], ['Text Tracks are being loaded from another origin but the crossorigin attribute isn\'t used.\n This may prevent text tracks from loading.']);
  11573. var _tech = _dereq_(64);
  11574. var _tech2 = _interopRequireDefault(_tech);
  11575. var _dom = _dereq_(85);
  11576. var Dom = _interopRequireWildcard(_dom);
  11577. var _url = _dereq_(97);
  11578. var Url = _interopRequireWildcard(_url);
  11579. var _log = _dereq_(91);
  11580. var _log2 = _interopRequireDefault(_log);
  11581. var _tsml = _dereq_(103);
  11582. var _tsml2 = _interopRequireDefault(_tsml);
  11583. var _browser = _dereq_(81);
  11584. var browser = _interopRequireWildcard(_browser);
  11585. var _document = _dereq_(99);
  11586. var _document2 = _interopRequireDefault(_document);
  11587. var _window = _dereq_(100);
  11588. var _window2 = _interopRequireDefault(_window);
  11589. var _obj = _dereq_(93);
  11590. var _mergeOptions = _dereq_(92);
  11591. var _mergeOptions2 = _interopRequireDefault(_mergeOptions);
  11592. var _toTitleCase = _dereq_(96);
  11593. var _toTitleCase2 = _interopRequireDefault(_toTitleCase);
  11594. var _trackTypes = _dereq_(77);
  11595. function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
  11596. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  11597. function _taggedTemplateLiteralLoose(strings, raw) { strings.raw = raw; return strings; }
  11598. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  11599. function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
  11600. function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
  11601. * @file html5.js
  11602. */
  11603. /**
  11604. * HTML5 Media Controller - Wrapper for HTML5 Media API
  11605. *
  11606. * @mixes Tech~SouceHandlerAdditions
  11607. * @extends Tech
  11608. */
  11609. var Html5 = function (_Tech) {
  11610. _inherits(Html5, _Tech);
  11611. /**
  11612. * Create an instance of this Tech.
  11613. *
  11614. * @param {Object} [options]
  11615. * The key/value store of player options.
  11616. *
  11617. * @param {Component~ReadyCallback} ready
  11618. * Callback function to call when the `HTML5` Tech is ready.
  11619. */
  11620. function Html5(options, ready) {
  11621. _classCallCheck(this, Html5);
  11622. var _this = _possibleConstructorReturn(this, _Tech.call(this, options, ready));
  11623. var source = options.source;
  11624. var crossoriginTracks = false;
  11625. // Set the source if one is provided
  11626. // 1) Check if the source is new (if not, we want to keep the original so playback isn't interrupted)
  11627. // 2) Check to see if the network state of the tag was failed at init, and if so, reset the source
  11628. // anyway so the error gets fired.
  11629. if (source && (_this.el_.currentSrc !== source.src || options.tag && options.tag.initNetworkState_ === 3)) {
  11630. _this.setSource(source);
  11631. } else {
  11632. _this.handleLateInit_(_this.el_);
  11633. }
  11634. if (_this.el_.hasChildNodes()) {
  11635. var nodes = _this.el_.childNodes;
  11636. var nodesLength = nodes.length;
  11637. var removeNodes = [];
  11638. while (nodesLength--) {
  11639. var node = nodes[nodesLength];
  11640. var nodeName = node.nodeName.toLowerCase();
  11641. if (nodeName === 'track') {
  11642. if (!_this.featuresNativeTextTracks) {
  11643. // Empty video tag tracks so the built-in player doesn't use them also.
  11644. // This may not be fast enough to stop HTML5 browsers from reading the tags
  11645. // so we'll need to turn off any default tracks if we're manually doing
  11646. // captions and subtitles. videoElement.textTracks
  11647. removeNodes.push(node);
  11648. } else {
  11649. // store HTMLTrackElement and TextTrack to remote list
  11650. _this.remoteTextTrackEls().addTrackElement_(node);
  11651. _this.remoteTextTracks().addTrack(node.track);
  11652. _this.textTracks().addTrack(node.track);
  11653. if (!crossoriginTracks && !_this.el_.hasAttribute('crossorigin') && Url.isCrossOrigin(node.src)) {
  11654. crossoriginTracks = true;
  11655. }
  11656. }
  11657. }
  11658. }
  11659. for (var i = 0; i < removeNodes.length; i++) {
  11660. _this.el_.removeChild(removeNodes[i]);
  11661. }
  11662. }
  11663. _this.proxyNativeTracks_();
  11664. if (_this.featuresNativeTextTracks && crossoriginTracks) {
  11665. _log2['default'].warn((0, _tsml2['default'])(_templateObject));
  11666. }
  11667. // Determine if native controls should be used
  11668. // Our goal should be to get the custom controls on mobile solid everywhere
  11669. // so we can remove this all together. Right now this will block custom
  11670. // controls on touch enabled laptops like the Chrome Pixel
  11671. if ((browser.TOUCH_ENABLED || browser.IS_IPHONE || browser.IS_NATIVE_ANDROID) && options.nativeControlsForTouch === true) {
  11672. _this.setControls(true);
  11673. }
  11674. // on iOS, we want to proxy `webkitbeginfullscreen` and `webkitendfullscreen`
  11675. // into a `fullscreenchange` event
  11676. _this.proxyWebkitFullscreen_();
  11677. _this.triggerReady();
  11678. return _this;
  11679. }
  11680. /**
  11681. * Dispose of `HTML5` media element and remove all tracks.
  11682. */
  11683. Html5.prototype.dispose = function dispose() {
  11684. Html5.disposeMediaElement(this.el_);
  11685. // tech will handle clearing of the emulated track list
  11686. _Tech.prototype.dispose.call(this);
  11687. };
  11688. /**
  11689. * Proxy all native track list events to our track lists if the browser we are playing
  11690. * in supports that type of track list.
  11691. *
  11692. * @private
  11693. */
  11694. Html5.prototype.proxyNativeTracks_ = function proxyNativeTracks_() {
  11695. var _this2 = this;
  11696. _trackTypes.NORMAL.names.forEach(function (name) {
  11697. var props = _trackTypes.NORMAL[name];
  11698. var elTracks = _this2.el()[props.getterName];
  11699. var techTracks = _this2[props.getterName]();
  11700. if (!_this2['featuresNative' + props.capitalName + 'Tracks'] || !elTracks || !elTracks.addEventListener) {
  11701. return;
  11702. }
  11703. var listeners = {
  11704. change: function change(e) {
  11705. techTracks.trigger({
  11706. type: 'change',
  11707. target: techTracks,
  11708. currentTarget: techTracks,
  11709. srcElement: techTracks
  11710. });
  11711. },
  11712. addtrack: function addtrack(e) {
  11713. techTracks.addTrack(e.track);
  11714. },
  11715. removetrack: function removetrack(e) {
  11716. techTracks.removeTrack(e.track);
  11717. }
  11718. };
  11719. var removeOldTracks = function removeOldTracks() {
  11720. var removeTracks = [];
  11721. for (var i = 0; i < techTracks.length; i++) {
  11722. var found = false;
  11723. for (var j = 0; j < elTracks.length; j++) {
  11724. if (elTracks[j] === techTracks[i]) {
  11725. found = true;
  11726. break;
  11727. }
  11728. }
  11729. if (!found) {
  11730. removeTracks.push(techTracks[i]);
  11731. }
  11732. }
  11733. while (removeTracks.length) {
  11734. techTracks.removeTrack(removeTracks.shift());
  11735. }
  11736. };
  11737. Object.keys(listeners).forEach(function (eventName) {
  11738. var listener = listeners[eventName];
  11739. elTracks.addEventListener(eventName, listener);
  11740. _this2.on('dispose', function (e) {
  11741. return elTracks.removeEventListener(eventName, listener);
  11742. });
  11743. });
  11744. // Remove (native) tracks that are not used anymore
  11745. _this2.on('loadstart', removeOldTracks);
  11746. _this2.on('dispose', function (e) {
  11747. return _this2.off('loadstart', removeOldTracks);
  11748. });
  11749. });
  11750. };
  11751. /**
  11752. * Create the `Html5` Tech's DOM element.
  11753. *
  11754. * @return {Element}
  11755. * The element that gets created.
  11756. */
  11757. Html5.prototype.createEl = function createEl() {
  11758. var el = this.options_.tag;
  11759. // Check if this browser supports moving the element into the box.
  11760. // On the iPhone video will break if you move the element,
  11761. // So we have to create a brand new element.
  11762. // If we ingested the player div, we do not need to move the media element.
  11763. if (!el || !(this.options_.playerElIngest || this.movingMediaElementInDOM)) {
  11764. // If the original tag is still there, clone and remove it.
  11765. if (el) {
  11766. var clone = el.cloneNode(true);
  11767. if (el.parentNode) {
  11768. el.parentNode.insertBefore(clone, el);
  11769. }
  11770. Html5.disposeMediaElement(el);
  11771. el = clone;
  11772. } else {
  11773. el = _document2['default'].createElement('video');
  11774. // determine if native controls should be used
  11775. var tagAttributes = this.options_.tag && Dom.getAttributes(this.options_.tag);
  11776. var attributes = (0, _mergeOptions2['default'])({}, tagAttributes);
  11777. if (!browser.TOUCH_ENABLED || this.options_.nativeControlsForTouch !== true) {
  11778. delete attributes.controls;
  11779. }
  11780. Dom.setAttributes(el, (0, _obj.assign)(attributes, {
  11781. id: this.options_.techId,
  11782. 'class': 'vjs-tech'
  11783. }));
  11784. }
  11785. el.playerId = this.options_.playerId;
  11786. }
  11787. // Update specific tag settings, in case they were overridden
  11788. var settingsAttrs = ['autoplay', 'preload', 'loop', 'muted'];
  11789. for (var i = settingsAttrs.length - 1; i >= 0; i--) {
  11790. var attr = settingsAttrs[i];
  11791. var overwriteAttrs = {};
  11792. if (typeof this.options_[attr] !== 'undefined') {
  11793. overwriteAttrs[attr] = this.options_[attr];
  11794. }
  11795. Dom.setAttributes(el, overwriteAttrs);
  11796. }
  11797. return el;
  11798. };
  11799. /**
  11800. * This will be triggered if the loadstart event has already fired, before videojs was
  11801. * ready. Two known examples of when this can happen are:
  11802. * 1. If we're loading the playback object after it has started loading
  11803. * 2. The media is already playing the (often with autoplay on) then
  11804. *
  11805. * This function will fire another loadstart so that videojs can catchup.
  11806. *
  11807. * @fires Tech#loadstart
  11808. *
  11809. * @return {undefined}
  11810. * returns nothing.
  11811. */
  11812. Html5.prototype.handleLateInit_ = function handleLateInit_(el) {
  11813. if (el.networkState === 0 || el.networkState === 3) {
  11814. // The video element hasn't started loading the source yet
  11815. // or didn't find a source
  11816. return;
  11817. }
  11818. if (el.readyState === 0) {
  11819. // NetworkState is set synchronously BUT loadstart is fired at the
  11820. // end of the current stack, usually before setInterval(fn, 0).
  11821. // So at this point we know loadstart may have already fired or is
  11822. // about to fire, and either way the player hasn't seen it yet.
  11823. // We don't want to fire loadstart prematurely here and cause a
  11824. // double loadstart so we'll wait and see if it happens between now
  11825. // and the next loop, and fire it if not.
  11826. // HOWEVER, we also want to make sure it fires before loadedmetadata
  11827. // which could also happen between now and the next loop, so we'll
  11828. // watch for that also.
  11829. var loadstartFired = false;
  11830. var setLoadstartFired = function setLoadstartFired() {
  11831. loadstartFired = true;
  11832. };
  11833. this.on('loadstart', setLoadstartFired);
  11834. var triggerLoadstart = function triggerLoadstart() {
  11835. // We did miss the original loadstart. Make sure the player
  11836. // sees loadstart before loadedmetadata
  11837. if (!loadstartFired) {
  11838. this.trigger('loadstart');
  11839. }
  11840. };
  11841. this.on('loadedmetadata', triggerLoadstart);
  11842. this.ready(function () {
  11843. this.off('loadstart', setLoadstartFired);
  11844. this.off('loadedmetadata', triggerLoadstart);
  11845. if (!loadstartFired) {
  11846. // We did miss the original native loadstart. Fire it now.
  11847. this.trigger('loadstart');
  11848. }
  11849. });
  11850. return;
  11851. }
  11852. // From here on we know that loadstart already fired and we missed it.
  11853. // The other readyState events aren't as much of a problem if we double
  11854. // them, so not going to go to as much trouble as loadstart to prevent
  11855. // that unless we find reason to.
  11856. var eventsToTrigger = ['loadstart'];
  11857. // loadedmetadata: newly equal to HAVE_METADATA (1) or greater
  11858. eventsToTrigger.push('loadedmetadata');
  11859. // loadeddata: newly increased to HAVE_CURRENT_DATA (2) or greater
  11860. if (el.readyState >= 2) {
  11861. eventsToTrigger.push('loadeddata');
  11862. }
  11863. // canplay: newly increased to HAVE_FUTURE_DATA (3) or greater
  11864. if (el.readyState >= 3) {
  11865. eventsToTrigger.push('canplay');
  11866. }
  11867. // canplaythrough: newly equal to HAVE_ENOUGH_DATA (4)
  11868. if (el.readyState >= 4) {
  11869. eventsToTrigger.push('canplaythrough');
  11870. }
  11871. // We still need to give the player time to add event listeners
  11872. this.ready(function () {
  11873. eventsToTrigger.forEach(function (type) {
  11874. this.trigger(type);
  11875. }, this);
  11876. });
  11877. };
  11878. /**
  11879. * Set current time for the `HTML5` tech.
  11880. *
  11881. * @param {number} seconds
  11882. * Set the current time of the media to this.
  11883. */
  11884. Html5.prototype.setCurrentTime = function setCurrentTime(seconds) {
  11885. try {
  11886. this.el_.currentTime = seconds;
  11887. } catch (e) {
  11888. (0, _log2['default'])(e, 'Video is not ready. (Video.js)');
  11889. // this.warning(VideoJS.warnings.videoNotReady);
  11890. }
  11891. };
  11892. /**
  11893. * Get the current duration of the HTML5 media element.
  11894. *
  11895. * @return {number}
  11896. * The duration of the media or 0 if there is no duration.
  11897. */
  11898. Html5.prototype.duration = function duration() {
  11899. var _this3 = this;
  11900. // Android Chrome will report duration as Infinity for VOD HLS until after
  11901. // playback has started, which triggers the live display erroneously.
  11902. // Return NaN if playback has not started and trigger a durationupdate once
  11903. // the duration can be reliably known.
  11904. if (this.el_.duration === Infinity && browser.IS_ANDROID && browser.IS_CHROME) {
  11905. if (this.el_.currentTime === 0) {
  11906. // Wait for the first `timeupdate` with currentTime > 0 - there may be
  11907. // several with 0
  11908. var checkProgress = function checkProgress() {
  11909. if (_this3.el_.currentTime > 0) {
  11910. // Trigger durationchange for genuinely live video
  11911. if (_this3.el_.duration === Infinity) {
  11912. _this3.trigger('durationchange');
  11913. }
  11914. _this3.off('timeupdate', checkProgress);
  11915. }
  11916. };
  11917. this.on('timeupdate', checkProgress);
  11918. return NaN;
  11919. }
  11920. }
  11921. return this.el_.duration || NaN;
  11922. };
  11923. /**
  11924. * Get the current width of the HTML5 media element.
  11925. *
  11926. * @return {number}
  11927. * The width of the HTML5 media element.
  11928. */
  11929. Html5.prototype.width = function width() {
  11930. return this.el_.offsetWidth;
  11931. };
  11932. /**
  11933. * Get the current height of the HTML5 media element.
  11934. *
  11935. * @return {number}
  11936. * The heigth of the HTML5 media element.
  11937. */
  11938. Html5.prototype.height = function height() {
  11939. return this.el_.offsetHeight;
  11940. };
  11941. /**
  11942. * Proxy iOS `webkitbeginfullscreen` and `webkitendfullscreen` into
  11943. * `fullscreenchange` event.
  11944. *
  11945. * @private
  11946. * @fires fullscreenchange
  11947. * @listens webkitendfullscreen
  11948. * @listens webkitbeginfullscreen
  11949. * @listens webkitbeginfullscreen
  11950. */
  11951. Html5.prototype.proxyWebkitFullscreen_ = function proxyWebkitFullscreen_() {
  11952. var _this4 = this;
  11953. if (!('webkitDisplayingFullscreen' in this.el_)) {
  11954. return;
  11955. }
  11956. var endFn = function endFn() {
  11957. this.trigger('fullscreenchange', { isFullscreen: false });
  11958. };
  11959. var beginFn = function beginFn() {
  11960. this.one('webkitendfullscreen', endFn);
  11961. this.trigger('fullscreenchange', { isFullscreen: true });
  11962. };
  11963. this.on('webkitbeginfullscreen', beginFn);
  11964. this.on('dispose', function () {
  11965. _this4.off('webkitbeginfullscreen', beginFn);
  11966. _this4.off('webkitendfullscreen', endFn);
  11967. });
  11968. };
  11969. /**
  11970. * Check if fullscreen is supported on the current playback device.
  11971. *
  11972. * @return {boolean}
  11973. * - True if fullscreen is supported.
  11974. * - False if fullscreen is not supported.
  11975. */
  11976. Html5.prototype.supportsFullScreen = function supportsFullScreen() {
  11977. if (typeof this.el_.webkitEnterFullScreen === 'function') {
  11978. var userAgent = _window2['default'].navigator && _window2['default'].navigator.userAgent || '';
  11979. // Seems to be broken in Chromium/Chrome && Safari in Leopard
  11980. if (/Android/.test(userAgent) || !/Chrome|Mac OS X 10.5/.test(userAgent)) {
  11981. return true;
  11982. }
  11983. }
  11984. return false;
  11985. };
  11986. /**
  11987. * Request that the `HTML5` Tech enter fullscreen.
  11988. */
  11989. Html5.prototype.enterFullScreen = function enterFullScreen() {
  11990. var video = this.el_;
  11991. if (video.paused && video.networkState <= video.HAVE_METADATA) {
  11992. // attempt to prime the video element for programmatic access
  11993. // this isn't necessary on the desktop but shouldn't hurt
  11994. this.el_.play();
  11995. // playing and pausing synchronously during the transition to fullscreen
  11996. // can get iOS ~6.1 devices into a play/pause loop
  11997. this.setTimeout(function () {
  11998. video.pause();
  11999. video.webkitEnterFullScreen();
  12000. }, 0);
  12001. } else {
  12002. video.webkitEnterFullScreen();
  12003. }
  12004. };
  12005. /**
  12006. * Request that the `HTML5` Tech exit fullscreen.
  12007. */
  12008. Html5.prototype.exitFullScreen = function exitFullScreen() {
  12009. this.el_.webkitExitFullScreen();
  12010. };
  12011. /**
  12012. * A getter/setter for the `Html5` Tech's source object.
  12013. * > Note: Please use {@link Html5#setSource}
  12014. *
  12015. * @param {Tech~SourceObject} [src]
  12016. * The source object you want to set on the `HTML5` techs element.
  12017. *
  12018. * @return {Tech~SourceObject|undefined}
  12019. * - The current source object when a source is not passed in.
  12020. * - undefined when setting
  12021. *
  12022. * @deprecated Since version 5.
  12023. */
  12024. Html5.prototype.src = function src(_src) {
  12025. if (_src === undefined) {
  12026. return this.el_.src;
  12027. }
  12028. // Setting src through `src` instead of `setSrc` will be deprecated
  12029. this.setSrc(_src);
  12030. };
  12031. /**
  12032. * Reset the tech by removing all sources and then calling
  12033. * {@link Html5.resetMediaElement}.
  12034. */
  12035. Html5.prototype.reset = function reset() {
  12036. Html5.resetMediaElement(this.el_);
  12037. };
  12038. /**
  12039. * Get the current source on the `HTML5` Tech. Falls back to returning the source from
  12040. * the HTML5 media element.
  12041. *
  12042. * @return {Tech~SourceObject}
  12043. * The current source object from the HTML5 tech. With a fallback to the
  12044. * elements source.
  12045. */
  12046. Html5.prototype.currentSrc = function currentSrc() {
  12047. if (this.currentSource_) {
  12048. return this.currentSource_.src;
  12049. }
  12050. return this.el_.currentSrc;
  12051. };
  12052. /**
  12053. * Set controls attribute for the HTML5 media Element.
  12054. *
  12055. * @param {string} val
  12056. * Value to set the controls attribute to
  12057. */
  12058. Html5.prototype.setControls = function setControls(val) {
  12059. this.el_.controls = !!val;
  12060. };
  12061. /**
  12062. * Create and returns a remote {@link TextTrack} object.
  12063. *
  12064. * @param {string} kind
  12065. * `TextTrack` kind (subtitles, captions, descriptions, chapters, or metadata)
  12066. *
  12067. * @param {string} [label]
  12068. * Label to identify the text track
  12069. *
  12070. * @param {string} [language]
  12071. * Two letter language abbreviation
  12072. *
  12073. * @return {TextTrack}
  12074. * The TextTrack that gets created.
  12075. */
  12076. Html5.prototype.addTextTrack = function addTextTrack(kind, label, language) {
  12077. if (!this.featuresNativeTextTracks) {
  12078. return _Tech.prototype.addTextTrack.call(this, kind, label, language);
  12079. }
  12080. return this.el_.addTextTrack(kind, label, language);
  12081. };
  12082. /**
  12083. * Creates either native TextTrack or an emulated TextTrack depending
  12084. * on the value of `featuresNativeTextTracks`
  12085. *
  12086. * @param {Object} options
  12087. * The object should contain the options to intialize the TextTrack with.
  12088. *
  12089. * @param {string} [options.kind]
  12090. * `TextTrack` kind (subtitles, captions, descriptions, chapters, or metadata).
  12091. *
  12092. * @param {string} [options.label].
  12093. * Label to identify the text track
  12094. *
  12095. * @param {string} [options.language]
  12096. * Two letter language abbreviation.
  12097. *
  12098. * @param {boolean} [options.default]
  12099. * Default this track to on.
  12100. *
  12101. * @param {string} [options.id]
  12102. * The internal id to assign this track.
  12103. *
  12104. * @param {string} [options.src]
  12105. * A source url for the track.
  12106. *
  12107. * @return {HTMLTrackElement}
  12108. * The track element that gets created.
  12109. */
  12110. Html5.prototype.createRemoteTextTrack = function createRemoteTextTrack(options) {
  12111. if (!this.featuresNativeTextTracks) {
  12112. return _Tech.prototype.createRemoteTextTrack.call(this, options);
  12113. }
  12114. var htmlTrackElement = _document2['default'].createElement('track');
  12115. if (options.kind) {
  12116. htmlTrackElement.kind = options.kind;
  12117. }
  12118. if (options.label) {
  12119. htmlTrackElement.label = options.label;
  12120. }
  12121. if (options.language || options.srclang) {
  12122. htmlTrackElement.srclang = options.language || options.srclang;
  12123. }
  12124. if (options['default']) {
  12125. htmlTrackElement['default'] = options['default'];
  12126. }
  12127. if (options.id) {
  12128. htmlTrackElement.id = options.id;
  12129. }
  12130. if (options.src) {
  12131. htmlTrackElement.src = options.src;
  12132. }
  12133. return htmlTrackElement;
  12134. };
  12135. /**
  12136. * Creates a remote text track object and returns an html track element.
  12137. *
  12138. * @param {Object} options The object should contain values for
  12139. * kind, language, label, and src (location of the WebVTT file)
  12140. * @param {Boolean} [manualCleanup=true] if set to false, the TextTrack will be
  12141. * automatically removed from the video element whenever the source changes
  12142. * @return {HTMLTrackElement} An Html Track Element.
  12143. * This can be an emulated {@link HTMLTrackElement} or a native one.
  12144. * @deprecated The default value of the "manualCleanup" parameter will default
  12145. * to "false" in upcoming versions of Video.js
  12146. */
  12147. Html5.prototype.addRemoteTextTrack = function addRemoteTextTrack(options, manualCleanup) {
  12148. var htmlTrackElement = _Tech.prototype.addRemoteTextTrack.call(this, options, manualCleanup);
  12149. if (this.featuresNativeTextTracks) {
  12150. this.el().appendChild(htmlTrackElement);
  12151. }
  12152. return htmlTrackElement;
  12153. };
  12154. /**
  12155. * Remove remote `TextTrack` from `TextTrackList` object
  12156. *
  12157. * @param {TextTrack} track
  12158. * `TextTrack` object to remove
  12159. */
  12160. Html5.prototype.removeRemoteTextTrack = function removeRemoteTextTrack(track) {
  12161. _Tech.prototype.removeRemoteTextTrack.call(this, track);
  12162. if (this.featuresNativeTextTracks) {
  12163. var tracks = this.$$('track');
  12164. var i = tracks.length;
  12165. while (i--) {
  12166. if (track === tracks[i] || track === tracks[i].track) {
  12167. this.el().removeChild(tracks[i]);
  12168. }
  12169. }
  12170. }
  12171. };
  12172. return Html5;
  12173. }(_tech2['default']);
  12174. /* HTML5 Support Testing ---------------------------------------------------- */
  12175. if (Dom.isReal()) {
  12176. /**
  12177. * Element for testing browser HTML5 media capabilities
  12178. *
  12179. * @type {Element}
  12180. * @constant
  12181. * @private
  12182. */
  12183. Html5.TEST_VID = _document2['default'].createElement('video');
  12184. var track = _document2['default'].createElement('track');
  12185. track.kind = 'captions';
  12186. track.srclang = 'en';
  12187. track.label = 'English';
  12188. Html5.TEST_VID.appendChild(track);
  12189. }
  12190. /**
  12191. * Check if HTML5 media is supported by this browser/device.
  12192. *
  12193. * @return {boolean}
  12194. * - True if HTML5 media is supported.
  12195. * - False if HTML5 media is not supported.
  12196. */
  12197. Html5.isSupported = function () {
  12198. // IE9 with no Media Player is a LIAR! (#984)
  12199. try {
  12200. Html5.TEST_VID.volume = 0.5;
  12201. } catch (e) {
  12202. return false;
  12203. }
  12204. return !!(Html5.TEST_VID && Html5.TEST_VID.canPlayType);
  12205. };
  12206. /**
  12207. * Check if the tech can support the given type
  12208. *
  12209. * @param {string} type
  12210. * The mimetype to check
  12211. * @return {string} 'probably', 'maybe', or '' (empty string)
  12212. */
  12213. Html5.canPlayType = function (type) {
  12214. return Html5.TEST_VID.canPlayType(type);
  12215. };
  12216. /**
  12217. * Check if the tech can support the given source
  12218. * @param {Object} srcObj
  12219. * The source object
  12220. * @param {Object} options
  12221. * The options passed to the tech
  12222. * @return {string} 'probably', 'maybe', or '' (empty string)
  12223. */
  12224. Html5.canPlaySource = function (srcObj, options) {
  12225. return Html5.canPlayType(srcObj.type);
  12226. };
  12227. /**
  12228. * Check if the volume can be changed in this browser/device.
  12229. * Volume cannot be changed in a lot of mobile devices.
  12230. * Specifically, it can't be changed from 1 on iOS.
  12231. *
  12232. * @return {boolean}
  12233. * - True if volume can be controlled
  12234. * - False otherwise
  12235. */
  12236. Html5.canControlVolume = function () {
  12237. // IE will error if Windows Media Player not installed #3315
  12238. try {
  12239. var volume = Html5.TEST_VID.volume;
  12240. Html5.TEST_VID.volume = volume / 2 + 0.1;
  12241. return volume !== Html5.TEST_VID.volume;
  12242. } catch (e) {
  12243. return false;
  12244. }
  12245. };
  12246. /**
  12247. * Check if the playback rate can be changed in this browser/device.
  12248. *
  12249. * @return {boolean}
  12250. * - True if playback rate can be controlled
  12251. * - False otherwise
  12252. */
  12253. Html5.canControlPlaybackRate = function () {
  12254. // Playback rate API is implemented in Android Chrome, but doesn't do anything
  12255. // https://github.com/videojs/video.js/issues/3180
  12256. if (browser.IS_ANDROID && browser.IS_CHROME) {
  12257. return false;
  12258. }
  12259. // IE will error if Windows Media Player not installed #3315
  12260. try {
  12261. var playbackRate = Html5.TEST_VID.playbackRate;
  12262. Html5.TEST_VID.playbackRate = playbackRate / 2 + 0.1;
  12263. return playbackRate !== Html5.TEST_VID.playbackRate;
  12264. } catch (e) {
  12265. return false;
  12266. }
  12267. };
  12268. /**
  12269. * Check to see if native `TextTrack`s are supported by this browser/device.
  12270. *
  12271. * @return {boolean}
  12272. * - True if native `TextTrack`s are supported.
  12273. * - False otherwise
  12274. */
  12275. Html5.supportsNativeTextTracks = function () {
  12276. return browser.IS_ANY_SAFARI;
  12277. };
  12278. /**
  12279. * Check to see if native `VideoTrack`s are supported by this browser/device
  12280. *
  12281. * @return {boolean}
  12282. * - True if native `VideoTrack`s are supported.
  12283. * - False otherwise
  12284. */
  12285. Html5.supportsNativeVideoTracks = function () {
  12286. return !!(Html5.TEST_VID && Html5.TEST_VID.videoTracks);
  12287. };
  12288. /**
  12289. * Check to see if native `AudioTrack`s are supported by this browser/device
  12290. *
  12291. * @return {boolean}
  12292. * - True if native `AudioTrack`s are supported.
  12293. * - False otherwise
  12294. */
  12295. Html5.supportsNativeAudioTracks = function () {
  12296. return !!(Html5.TEST_VID && Html5.TEST_VID.audioTracks);
  12297. };
  12298. /**
  12299. * An array of events available on the Html5 tech.
  12300. *
  12301. * @private
  12302. * @type {Array}
  12303. */
  12304. Html5.Events = ['loadstart', 'suspend', 'abort', 'error', 'emptied', 'stalled', 'loadedmetadata', 'loadeddata', 'canplay', 'canplaythrough', 'playing', 'waiting', 'seeking', 'seeked', 'ended', 'durationchange', 'timeupdate', 'progress', 'play', 'pause', 'ratechange', 'resize', 'volumechange'];
  12305. /**
  12306. * Boolean indicating whether the `Tech` supports volume control.
  12307. *
  12308. * @type {boolean}
  12309. * @default {@link Html5.canControlVolume}
  12310. */
  12311. Html5.prototype.featuresVolumeControl = Html5.canControlVolume();
  12312. /**
  12313. * Boolean indicating whether the `Tech` supports changing the speed at which the media
  12314. * plays. Examples:
  12315. * - Set player to play 2x (twice) as fast
  12316. * - Set player to play 0.5x (half) as fast
  12317. *
  12318. * @type {boolean}
  12319. * @default {@link Html5.canControlPlaybackRate}
  12320. */
  12321. Html5.prototype.featuresPlaybackRate = Html5.canControlPlaybackRate();
  12322. /**
  12323. * Boolean indicating whether the `HTML5` tech currently supports the media element
  12324. * moving in the DOM. iOS breaks if you move the media element, so this is set this to
  12325. * false there. Everywhere else this should be true.
  12326. *
  12327. * @type {boolean}
  12328. * @default
  12329. */
  12330. Html5.prototype.movingMediaElementInDOM = !browser.IS_IOS;
  12331. // TODO: Previous comment: No longer appears to be used. Can probably be removed.
  12332. // Is this true?
  12333. /**
  12334. * Boolean indicating whether the `HTML5` tech currently supports automatic media resize
  12335. * when going into fullscreen.
  12336. *
  12337. * @type {boolean}
  12338. * @default
  12339. */
  12340. Html5.prototype.featuresFullscreenResize = true;
  12341. /**
  12342. * Boolean indicating whether the `HTML5` tech currently supports the progress event.
  12343. * If this is false, manual `progress` events will be triggred instead.
  12344. *
  12345. * @type {boolean}
  12346. * @default
  12347. */
  12348. Html5.prototype.featuresProgressEvents = true;
  12349. /**
  12350. * Boolean indicating whether the `HTML5` tech currently supports the timeupdate event.
  12351. * If this is false, manual `timeupdate` events will be triggred instead.
  12352. *
  12353. * @default
  12354. */
  12355. Html5.prototype.featuresTimeupdateEvents = true;
  12356. /**
  12357. * Boolean indicating whether the `HTML5` tech currently supports native `TextTrack`s.
  12358. *
  12359. * @type {boolean}
  12360. * @default {@link Html5.supportsNativeTextTracks}
  12361. */
  12362. Html5.prototype.featuresNativeTextTracks = Html5.supportsNativeTextTracks();
  12363. /**
  12364. * Boolean indicating whether the `HTML5` tech currently supports native `VideoTrack`s.
  12365. *
  12366. * @type {boolean}
  12367. * @default {@link Html5.supportsNativeVideoTracks}
  12368. */
  12369. Html5.prototype.featuresNativeVideoTracks = Html5.supportsNativeVideoTracks();
  12370. /**
  12371. * Boolean indicating whether the `HTML5` tech currently supports native `AudioTrack`s.
  12372. *
  12373. * @type {boolean}
  12374. * @default {@link Html5.supportsNativeAudioTracks}
  12375. */
  12376. Html5.prototype.featuresNativeAudioTracks = Html5.supportsNativeAudioTracks();
  12377. // HTML5 Feature detection and Device Fixes --------------------------------- //
  12378. var canPlayType = Html5.TEST_VID && Html5.TEST_VID.constructor.prototype.canPlayType;
  12379. var mpegurlRE = /^application\/(?:x-|vnd\.apple\.)mpegurl/i;
  12380. var mp4RE = /^video\/mp4/i;
  12381. Html5.patchCanPlayType = function () {
  12382. // Android 4.0 and above can play HLS to some extent but it reports being unable to do so
  12383. if (browser.ANDROID_VERSION >= 4.0 && !browser.IS_FIREFOX) {
  12384. Html5.TEST_VID.constructor.prototype.canPlayType = function (type) {
  12385. if (type && mpegurlRE.test(type)) {
  12386. return 'maybe';
  12387. }
  12388. return canPlayType.call(this, type);
  12389. };
  12390. // Override Android 2.2 and less canPlayType method which is broken
  12391. } else if (browser.IS_OLD_ANDROID) {
  12392. Html5.TEST_VID.constructor.prototype.canPlayType = function (type) {
  12393. if (type && mp4RE.test(type)) {
  12394. return 'maybe';
  12395. }
  12396. return canPlayType.call(this, type);
  12397. };
  12398. }
  12399. };
  12400. Html5.unpatchCanPlayType = function () {
  12401. var r = Html5.TEST_VID.constructor.prototype.canPlayType;
  12402. Html5.TEST_VID.constructor.prototype.canPlayType = canPlayType;
  12403. return r;
  12404. };
  12405. // by default, patch the media element
  12406. Html5.patchCanPlayType();
  12407. Html5.disposeMediaElement = function (el) {
  12408. if (!el) {
  12409. return;
  12410. }
  12411. if (el.parentNode) {
  12412. el.parentNode.removeChild(el);
  12413. }
  12414. // remove any child track or source nodes to prevent their loading
  12415. while (el.hasChildNodes()) {
  12416. el.removeChild(el.firstChild);
  12417. }
  12418. // remove any src reference. not setting `src=''` because that causes a warning
  12419. // in firefox
  12420. el.removeAttribute('src');
  12421. // force the media element to update its loading state by calling load()
  12422. // however IE on Windows 7N has a bug that throws an error so need a try/catch (#793)
  12423. if (typeof el.load === 'function') {
  12424. // wrapping in an iife so it's not deoptimized (#1060#discussion_r10324473)
  12425. (function () {
  12426. try {
  12427. el.load();
  12428. } catch (e) {
  12429. // not supported
  12430. }
  12431. })();
  12432. }
  12433. };
  12434. Html5.resetMediaElement = function (el) {
  12435. if (!el) {
  12436. return;
  12437. }
  12438. var sources = el.querySelectorAll('source');
  12439. var i = sources.length;
  12440. while (i--) {
  12441. el.removeChild(sources[i]);
  12442. }
  12443. // remove any src reference.
  12444. // not setting `src=''` because that throws an error
  12445. el.removeAttribute('src');
  12446. if (typeof el.load === 'function') {
  12447. // wrapping in an iife so it's not deoptimized (#1060#discussion_r10324473)
  12448. (function () {
  12449. try {
  12450. el.load();
  12451. } catch (e) {
  12452. // satisfy linter
  12453. }
  12454. })();
  12455. }
  12456. };
  12457. /* Native HTML5 element property wrapping ----------------------------------- */
  12458. // Wrap native properties with a getter
  12459. [
  12460. /**
  12461. * Get the value of `paused` from the media element. `paused` indicates whether the media element
  12462. * is currently paused or not.
  12463. *
  12464. * @method Html5#paused
  12465. * @return {boolean}
  12466. * The value of `paused` from the media element.
  12467. *
  12468. * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-paused}
  12469. */
  12470. 'paused',
  12471. /**
  12472. * Get the value of `currentTime` from the media element. `currentTime` indicates
  12473. * the current second that the media is at in playback.
  12474. *
  12475. * @method Html5#currentTime
  12476. * @return {number}
  12477. * The value of `currentTime` from the media element.
  12478. *
  12479. * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-currenttime}
  12480. */
  12481. 'currentTime',
  12482. /**
  12483. * Get the value of `buffered` from the media element. `buffered` is a `TimeRange`
  12484. * object that represents the parts of the media that are already downloaded and
  12485. * available for playback.
  12486. *
  12487. * @method Html5#buffered
  12488. * @return {TimeRange}
  12489. * The value of `buffered` from the media element.
  12490. *
  12491. * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-buffered}
  12492. */
  12493. 'buffered',
  12494. /**
  12495. * Get the value of `volume` from the media element. `volume` indicates
  12496. * the current playback volume of audio for a media. `volume` will be a value from 0
  12497. * (silent) to 1 (loudest and default).
  12498. *
  12499. * @method Html5#volume
  12500. * @return {number}
  12501. * The value of `volume` from the media element. Value will be between 0-1.
  12502. *
  12503. * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-a-volume}
  12504. */
  12505. 'volume',
  12506. /**
  12507. * Get the value of `muted` from the media element. `muted` indicates
  12508. * that the volume for the media should be set to silent. This does not actually change
  12509. * the `volume` attribute.
  12510. *
  12511. * @method Html5#muted
  12512. * @return {boolean}
  12513. * - True if the value of `volume` should be ignored and the audio set to silent.
  12514. * - False if the value of `volume` should be used.
  12515. *
  12516. * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-muted}
  12517. */
  12518. 'muted',
  12519. /**
  12520. * Get the value of `defaultMuted` from the media element. `defaultMuted` indicates
  12521. * that the volume for the media should be set to silent when the video first starts.
  12522. * This does not actually change the `volume` attribute. After playback has started `muted`
  12523. * will indicate the current status of the volume and `defaultMuted` will not.
  12524. *
  12525. * @method Html5.prototype.defaultMuted
  12526. * @return {boolean}
  12527. * - True if the value of `volume` should be ignored and the audio set to silent.
  12528. * - False if the value of `volume` should be used.
  12529. *
  12530. * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-defaultmuted}
  12531. */
  12532. 'defaultMuted',
  12533. /**
  12534. * Get the value of `poster` from the media element. `poster` indicates
  12535. * that the url of an image file that can/will be shown when no media data is available.
  12536. *
  12537. * @method Html5#poster
  12538. * @return {string}
  12539. * The value of `poster` from the media element. Value will be a url to an
  12540. * image.
  12541. *
  12542. * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-video-poster}
  12543. */
  12544. 'poster',
  12545. /**
  12546. * Get the value of `preload` from the media element. `preload` indicates
  12547. * what should download before the media is interacted with. It can have the following
  12548. * values:
  12549. * - none: nothing should be downloaded
  12550. * - metadata: poster and the first few frames of the media may be downloaded to get
  12551. * media dimensions and other metadata
  12552. * - auto: allow the media and metadata for the media to be downloaded before
  12553. * interaction
  12554. *
  12555. * @method Html5#preload
  12556. * @return {string}
  12557. * The value of `preload` from the media element. Will be 'none', 'metadata',
  12558. * or 'auto'.
  12559. *
  12560. * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-preload}
  12561. */
  12562. 'preload',
  12563. /**
  12564. * Get the value of `autoplay` from the media element. `autoplay` indicates
  12565. * that the media should start to play as soon as the page is ready.
  12566. *
  12567. * @method Html5#autoplay
  12568. * @return {boolean}
  12569. * - The value of `autoplay` from the media element.
  12570. * - True indicates that the media should start as soon as the page loads.
  12571. * - False indicates that the media should not start as soon as the page loads.
  12572. *
  12573. * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-autoplay}
  12574. */
  12575. 'autoplay',
  12576. /**
  12577. * Get the value of `controls` from the media element. `controls` indicates
  12578. * whether the native media controls should be shown or hidden.
  12579. *
  12580. * @method Html5#controls
  12581. * @return {boolean}
  12582. * - The value of `controls` from the media element.
  12583. * - True indicates that native controls should be showing.
  12584. * - False indicates that native controls should be hidden.
  12585. *
  12586. * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-controls}
  12587. */
  12588. 'controls',
  12589. /**
  12590. * Get the value of `loop` from the media element. `loop` indicates
  12591. * that the media should return to the start of the media and continue playing once
  12592. * it reaches the end.
  12593. *
  12594. * @method Html5#loop
  12595. * @return {boolean}
  12596. * - The value of `loop` from the media element.
  12597. * - True indicates that playback should seek back to start once
  12598. * the end of a media is reached.
  12599. * - False indicates that playback should not loop back to the start when the
  12600. * end of the media is reached.
  12601. *
  12602. * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-loop}
  12603. */
  12604. 'loop',
  12605. /**
  12606. * Get the value of the `error` from the media element. `error` indicates any
  12607. * MediaError that may have occured during playback. If error returns null there is no
  12608. * current error.
  12609. *
  12610. * @method Html5#error
  12611. * @return {MediaError|null}
  12612. * The value of `error` from the media element. Will be `MediaError` if there
  12613. * is a current error and null otherwise.
  12614. *
  12615. * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-error}
  12616. */
  12617. 'error',
  12618. /**
  12619. * Get the value of `seeking` from the media element. `seeking` indicates whether the
  12620. * media is currently seeking to a new position or not.
  12621. *
  12622. * @method Html5#seeking
  12623. * @return {boolean}
  12624. * - The value of `seeking` from the media element.
  12625. * - True indicates that the media is currently seeking to a new position.
  12626. * - Flase indicates that the media is not seeking to a new position at this time.
  12627. *
  12628. * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-seeking}
  12629. */
  12630. 'seeking',
  12631. /**
  12632. * Get the value of `seekable` from the media element. `seekable` returns a
  12633. * `TimeRange` object indicating ranges of time that can currently be `seeked` to.
  12634. *
  12635. * @method Html5#seekable
  12636. * @return {TimeRange}
  12637. * The value of `seekable` from the media element. A `TimeRange` object
  12638. * indicating the current ranges of time that can be seeked to.
  12639. *
  12640. * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-seekable}
  12641. */
  12642. 'seekable',
  12643. /**
  12644. * Get the value of `ended` from the media element. `ended` indicates whether
  12645. * the media has reached the end or not.
  12646. *
  12647. * @method Html5#ended
  12648. * @return {boolean}
  12649. * - The value of `ended` from the media element.
  12650. * - True indicates that the media has ended.
  12651. * - False indicates that the media has not ended.
  12652. *
  12653. * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-ended}
  12654. */
  12655. 'ended',
  12656. /**
  12657. * Get the value of `defaultMuted` from the media element. `defaultMuted` indicates
  12658. * whether the media should start muted or not. Only changes the default state of the
  12659. * media. `muted` and `defaultMuted` can have different values. {@link Html5#muted} indicates the
  12660. * current state.
  12661. *
  12662. * @method Html5#defaultMuted
  12663. * @return {boolean}
  12664. * - The value of `defaultMuted` from the media element.
  12665. * - True indicates that the media should start muted.
  12666. * - False indicates that the media should not start muted
  12667. *
  12668. * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-defaultmuted}
  12669. */
  12670. 'defaultMuted',
  12671. /**
  12672. * Get the value of `playbackRate` from the media element. `playbackRate` indicates
  12673. * the rate at which the media is currently playing back. Examples:
  12674. * - if playbackRate is set to 2, media will play twice as fast.
  12675. * - if playbackRate is set to 0.5, media will play half as fast.
  12676. *
  12677. * @method Html5#playbackRate
  12678. * @return {number}
  12679. * The value of `playbackRate` from the media element. A number indicating
  12680. * the current playback speed of the media, where 1 is normal speed.
  12681. *
  12682. * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-playbackrate}
  12683. */
  12684. 'playbackRate',
  12685. /**
  12686. * Get the value of `defaultPlaybackRate` from the media element. `defaultPlaybackRate` indicates
  12687. * the rate at which the media is currently playing back. This value will not indicate the current
  12688. * `playbackRate` after playback has started, use {@link Html5#playbackRate} for that.
  12689. *
  12690. * Examples:
  12691. * - if defaultPlaybackRate is set to 2, media will play twice as fast.
  12692. * - if defaultPlaybackRate is set to 0.5, media will play half as fast.
  12693. *
  12694. * @method Html5.prototype.defaultPlaybackRate
  12695. * @return {number}
  12696. * The value of `defaultPlaybackRate` from the media element. A number indicating
  12697. * the current playback speed of the media, where 1 is normal speed.
  12698. *
  12699. * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-playbackrate}
  12700. */
  12701. 'defaultPlaybackRate',
  12702. /**
  12703. * Get the value of `played` from the media element. `played` returns a `TimeRange`
  12704. * object representing points in the media timeline that have been played.
  12705. *
  12706. * @method Html5#played
  12707. * @return {TimeRange}
  12708. * The value of `played` from the media element. A `TimeRange` object indicating
  12709. * the ranges of time that have been played.
  12710. *
  12711. * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-played}
  12712. */
  12713. 'played',
  12714. /**
  12715. * Get the value of `networkState` from the media element. `networkState` indicates
  12716. * the current network state. It returns an enumeration from the following list:
  12717. * - 0: NETWORK_EMPTY
  12718. * - 1: NEWORK_IDLE
  12719. * - 2: NETWORK_LOADING
  12720. * - 3: NETWORK_NO_SOURCE
  12721. *
  12722. * @method Html5#networkState
  12723. * @return {number}
  12724. * The value of `networkState` from the media element. This will be a number
  12725. * from the list in the description.
  12726. *
  12727. * @see [Spec] {@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-networkstate}
  12728. */
  12729. 'networkState',
  12730. /**
  12731. * Get the value of `readyState` from the media element. `readyState` indicates
  12732. * the current state of the media element. It returns an enumeration from the
  12733. * following list:
  12734. * - 0: HAVE_NOTHING
  12735. * - 1: HAVE_METADATA
  12736. * - 2: HAVE_CURRENT_DATA
  12737. * - 3: HAVE_FUTURE_DATA
  12738. * - 4: HAVE_ENOUGH_DATA
  12739. *
  12740. * @method Html5#readyState
  12741. * @return {number}
  12742. * The value of `readyState` from the media element. This will be a number
  12743. * from the list in the description.
  12744. *
  12745. * @see [Spec] {@link https://www.w3.org/TR/html5/embedded-content-0.html#ready-states}
  12746. */
  12747. 'readyState',
  12748. /**
  12749. * Get the value of `videoWidth` from the video element. `videoWidth` indicates
  12750. * the current width of the video in css pixels.
  12751. *
  12752. * @method Html5#videoWidth
  12753. * @return {number}
  12754. * The value of `videoWidth` from the video element. This will be a number
  12755. * in css pixels.
  12756. *
  12757. * @see [Spec] {@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-video-videowidth}
  12758. */
  12759. 'videoWidth',
  12760. /**
  12761. * Get the value of `videoHeight` from the video element. `videoHeigth` indicates
  12762. * the current height of the video in css pixels.
  12763. *
  12764. * @method Html5#videoHeight
  12765. * @return {number}
  12766. * The value of `videoHeight` from the video element. This will be a number
  12767. * in css pixels.
  12768. *
  12769. * @see [Spec] {@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-video-videowidth}
  12770. */
  12771. 'videoHeight'].forEach(function (prop) {
  12772. Html5.prototype[prop] = function () {
  12773. return this.el_[prop];
  12774. };
  12775. });
  12776. // Wrap native properties with a setter in this format:
  12777. // set + toTitleCase(name)
  12778. [
  12779. /**
  12780. * Set the value of `volume` on the media element. `volume` indicates the current
  12781. * audio level as a percentage in decimal form. This means that 1 is 100%, 0.5 is 50%, and
  12782. * so on.
  12783. *
  12784. * @method Html5#setVolume
  12785. * @param {number} percentAsDecimal
  12786. * The volume percent as a decimal. Valid range is from 0-1.
  12787. *
  12788. * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-a-volume}
  12789. */
  12790. 'volume',
  12791. /**
  12792. * Set the value of `muted` on the media element. `muted` indicates that the current
  12793. * audio level should be silent.
  12794. *
  12795. * @method Html5#setMuted
  12796. * @param {boolean} muted
  12797. * - True if the audio should be set to silent
  12798. * - False otherwise
  12799. *
  12800. * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-muted}
  12801. */
  12802. 'muted',
  12803. /**
  12804. * Set the value of `defaultMuted` on the media element. `defaultMuted` indicates that the current
  12805. * audio level should be silent, but will only effect the muted level on intial playback..
  12806. *
  12807. * @method Html5.prototype.setDefaultMuted
  12808. * @param {boolean} defaultMuted
  12809. * - True if the audio should be set to silent
  12810. * - False otherwise
  12811. *
  12812. * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-defaultmuted}
  12813. */
  12814. 'defaultMuted',
  12815. /**
  12816. * Set the value of `src` on the media element. `src` indicates the current
  12817. * {@link Tech~SourceObject} for the media.
  12818. *
  12819. * @method Html5#setSrc
  12820. * @param {Tech~SourceObject} src
  12821. * The source object to set as the current source.
  12822. *
  12823. * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-src}
  12824. */
  12825. 'src',
  12826. /**
  12827. * Set the value of `poster` on the media element. `poster` is the url to
  12828. * an image file that can/will be shown when no media data is available.
  12829. *
  12830. * @method Html5#setPoster
  12831. * @param {string} poster
  12832. * The url to an image that should be used as the `poster` for the media
  12833. * element.
  12834. *
  12835. * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-poster}
  12836. */
  12837. 'poster',
  12838. /**
  12839. * Set the value of `preload` on the media element. `preload` indicates
  12840. * what should download before the media is interacted with. It can have the following
  12841. * values:
  12842. * - none: nothing should be downloaded
  12843. * - metadata: poster and the first few frames of the media may be downloaded to get
  12844. * media dimensions and other metadata
  12845. * - auto: allow the media and metadata for the media to be downloaded before
  12846. * interaction
  12847. *
  12848. * @method Html5#setPreload
  12849. * @param {string} preload
  12850. * The value of `preload` to set on the media element. Must be 'none', 'metadata',
  12851. * or 'auto'.
  12852. *
  12853. * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-preload}
  12854. */
  12855. 'preload',
  12856. /**
  12857. * Set the value of `autoplay` on the media element. `autoplay` indicates
  12858. * that the media should start to play as soon as the page is ready.
  12859. *
  12860. * @method Html5#setAutoplay
  12861. * @param {boolean} autoplay
  12862. * - True indicates that the media should start as soon as the page loads.
  12863. * - False indicates that the media should not start as soon as the page loads.
  12864. *
  12865. * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-autoplay}
  12866. */
  12867. 'autoplay',
  12868. /**
  12869. * Set the value of `loop` on the media element. `loop` indicates
  12870. * that the media should return to the start of the media and continue playing once
  12871. * it reaches the end.
  12872. *
  12873. * @method Html5#setLoop
  12874. * @param {boolean} loop
  12875. * - True indicates that playback should seek back to start once
  12876. * the end of a media is reached.
  12877. * - False indicates that playback should not loop back to the start when the
  12878. * end of the media is reached.
  12879. *
  12880. * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-loop}
  12881. */
  12882. 'loop',
  12883. /**
  12884. * Set the value of `playbackRate` on the media element. `playbackRate` indicates
  12885. * the rate at which the media should play back. Examples:
  12886. * - if playbackRate is set to 2, media will play twice as fast.
  12887. * - if playbackRate is set to 0.5, media will play half as fast.
  12888. *
  12889. * @method Html5#setPlaybackRate
  12890. * @return {number}
  12891. * The value of `playbackRate` from the media element. A number indicating
  12892. * the current playback speed of the media, where 1 is normal speed.
  12893. *
  12894. * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-playbackrate}
  12895. */
  12896. 'playbackRate',
  12897. /**
  12898. * Set the value of `defaultPlaybackRate` on the media element. `defaultPlaybackRate` indicates
  12899. * the rate at which the media should play back upon initial startup. Changing this value
  12900. * after a video has started will do nothing. Instead you should used {@link Html5#setPlaybackRate}.
  12901. *
  12902. * Example Values:
  12903. * - if playbackRate is set to 2, media will play twice as fast.
  12904. * - if playbackRate is set to 0.5, media will play half as fast.
  12905. *
  12906. * @method Html5.prototype.setDefaultPlaybackRate
  12907. * @return {number}
  12908. * The value of `defaultPlaybackRate` from the media element. A number indicating
  12909. * the current playback speed of the media, where 1 is normal speed.
  12910. *
  12911. * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-defaultplaybackrate}
  12912. */
  12913. 'defaultPlaybackRate'].forEach(function (prop) {
  12914. Html5.prototype['set' + (0, _toTitleCase2['default'])(prop)] = function (v) {
  12915. this.el_[prop] = v;
  12916. };
  12917. });
  12918. // wrap native functions with a function
  12919. [
  12920. /**
  12921. * A wrapper around the media elements `pause` function. This will call the `HTML5`
  12922. * media elements `pause` function.
  12923. *
  12924. * @method Html5#pause
  12925. * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-pause}
  12926. */
  12927. 'pause',
  12928. /**
  12929. * A wrapper around the media elements `load` function. This will call the `HTML5`s
  12930. * media element `load` function.
  12931. *
  12932. * @method Html5#load
  12933. * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-load}
  12934. */
  12935. 'load',
  12936. /**
  12937. * A wrapper around the media elements `play` function. This will call the `HTML5`s
  12938. * media element `play` function.
  12939. *
  12940. * @method Html5#play
  12941. * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-play}
  12942. */
  12943. 'play'].forEach(function (prop) {
  12944. Html5.prototype[prop] = function () {
  12945. return this.el_[prop]();
  12946. };
  12947. });
  12948. _tech2['default'].withSourceHandlers(Html5);
  12949. /**
  12950. * Native source handler for Html5, simply passes the source to the media element.
  12951. *
  12952. * @proprety {Tech~SourceObject} source
  12953. * The source object
  12954. *
  12955. * @proprety {Html5} tech
  12956. * The instance of the HTML5 tech.
  12957. */
  12958. Html5.nativeSourceHandler = {};
  12959. /**
  12960. * Check if the media element can play the given mime type.
  12961. *
  12962. * @param {string} type
  12963. * The mimetype to check
  12964. *
  12965. * @return {string}
  12966. * 'probably', 'maybe', or '' (empty string)
  12967. */
  12968. Html5.nativeSourceHandler.canPlayType = function (type) {
  12969. // IE9 on Windows 7 without MediaPlayer throws an error here
  12970. // https://github.com/videojs/video.js/issues/519
  12971. try {
  12972. return Html5.TEST_VID.canPlayType(type);
  12973. } catch (e) {
  12974. return '';
  12975. }
  12976. };
  12977. /**
  12978. * Check if the media element can handle a source natively.
  12979. *
  12980. * @param {Tech~SourceObject} source
  12981. * The source object
  12982. *
  12983. * @param {Object} [options]
  12984. * Options to be passed to the tech.
  12985. *
  12986. * @return {string}
  12987. * 'probably', 'maybe', or '' (empty string).
  12988. */
  12989. Html5.nativeSourceHandler.canHandleSource = function (source, options) {
  12990. // If a type was provided we should rely on that
  12991. if (source.type) {
  12992. return Html5.nativeSourceHandler.canPlayType(source.type);
  12993. // If no type, fall back to checking 'video/[EXTENSION]'
  12994. } else if (source.src) {
  12995. var ext = Url.getFileExtension(source.src);
  12996. return Html5.nativeSourceHandler.canPlayType('video/' + ext);
  12997. }
  12998. return '';
  12999. };
  13000. /**
  13001. * Pass the source to the native media element.
  13002. *
  13003. * @param {Tech~SourceObject} source
  13004. * The source object
  13005. *
  13006. * @param {Html5} tech
  13007. * The instance of the Html5 tech
  13008. *
  13009. * @param {Object} [options]
  13010. * The options to pass to the source
  13011. */
  13012. Html5.nativeSourceHandler.handleSource = function (source, tech, options) {
  13013. tech.setSrc(source.src);
  13014. };
  13015. /**
  13016. * A noop for the native dispose function, as cleanup is not needed.
  13017. */
  13018. Html5.nativeSourceHandler.dispose = function () {};
  13019. // Register the native source handler
  13020. Html5.registerSourceHandler(Html5.nativeSourceHandler);
  13021. _tech2['default'].registerTech('Html5', Html5);
  13022. exports['default'] = Html5;
  13023. },{"100":100,"103":103,"64":64,"77":77,"81":81,"85":85,"91":91,"92":92,"93":93,"96":96,"97":97,"99":99}],62:[function(_dereq_,module,exports){
  13024. 'use strict';
  13025. exports.__esModule = true;
  13026. var _component = _dereq_(5);
  13027. var _component2 = _interopRequireDefault(_component);
  13028. var _tech = _dereq_(64);
  13029. var _tech2 = _interopRequireDefault(_tech);
  13030. var _toTitleCase = _dereq_(96);
  13031. var _toTitleCase2 = _interopRequireDefault(_toTitleCase);
  13032. var _mergeOptions = _dereq_(92);
  13033. var _mergeOptions2 = _interopRequireDefault(_mergeOptions);
  13034. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  13035. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  13036. function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
  13037. function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
  13038. * @file loader.js
  13039. */
  13040. /**
  13041. * The `MediaLoader` is the `Component` that decides which playback technology to load
  13042. * when a player is initialized.
  13043. *
  13044. * @extends Component
  13045. */
  13046. var MediaLoader = function (_Component) {
  13047. _inherits(MediaLoader, _Component);
  13048. /**
  13049. * Create an instance of this class.
  13050. *
  13051. * @param {Player} player
  13052. * The `Player` that this class should attach to.
  13053. *
  13054. * @param {Object} [options]
  13055. * The key/value stroe of player options.
  13056. *
  13057. * @param {Component~ReadyCallback} [ready]
  13058. * The function that is run when this component is ready.
  13059. */
  13060. function MediaLoader(player, options, ready) {
  13061. _classCallCheck(this, MediaLoader);
  13062. // MediaLoader has no element
  13063. var options_ = (0, _mergeOptions2['default'])({ createEl: false }, options);
  13064. // If there are no sources when the player is initialized,
  13065. // load the first supported playback technology.
  13066. var _this = _possibleConstructorReturn(this, _Component.call(this, player, options_, ready));
  13067. if (!options.playerOptions.sources || options.playerOptions.sources.length === 0) {
  13068. for (var i = 0, j = options.playerOptions.techOrder; i < j.length; i++) {
  13069. var techName = (0, _toTitleCase2['default'])(j[i]);
  13070. var tech = _tech2['default'].getTech(techName);
  13071. // Support old behavior of techs being registered as components.
  13072. // Remove once that deprecated behavior is removed.
  13073. if (!techName) {
  13074. tech = _component2['default'].getComponent(techName);
  13075. }
  13076. // Check if the browser supports this technology
  13077. if (tech && tech.isSupported()) {
  13078. player.loadTech_(techName);
  13079. break;
  13080. }
  13081. }
  13082. } else {
  13083. // Loop through playback technologies (HTML5, Flash) and check for support.
  13084. // Then load the best source.
  13085. // A few assumptions here:
  13086. // All playback technologies respect preload false.
  13087. player.src(options.playerOptions.sources);
  13088. }
  13089. return _this;
  13090. }
  13091. return MediaLoader;
  13092. }(_component2['default']);
  13093. _component2['default'].registerComponent('MediaLoader', MediaLoader);
  13094. exports['default'] = MediaLoader;
  13095. },{"5":5,"64":64,"92":92,"96":96}],63:[function(_dereq_,module,exports){
  13096. 'use strict';
  13097. exports.__esModule = true;
  13098. exports.allowedSetters = exports.allowedGetters = undefined;
  13099. exports.use = use;
  13100. exports.getMiddleware = getMiddleware;
  13101. exports.setSource = setSource;
  13102. exports.setTech = setTech;
  13103. exports.get = get;
  13104. exports.set = set;
  13105. var _obj = _dereq_(93);
  13106. var middlewares = {};
  13107. function use(type, middleware) {
  13108. middlewares[type] = middlewares[type] || [];
  13109. middlewares[type].push(middleware);
  13110. }
  13111. function getMiddleware(type) {
  13112. if (type) {
  13113. return middlewares[type];
  13114. }
  13115. return middlewares;
  13116. }
  13117. function setSource(player, src, next) {
  13118. player.setTimeout(function () {
  13119. return setSourceHelper(src, middlewares[src.type], next, player);
  13120. }, 1);
  13121. }
  13122. function setTech(middleware, tech) {
  13123. middleware.forEach(function (mw) {
  13124. return mw.setTech && mw.setTech(tech);
  13125. });
  13126. }
  13127. function get(middleware, tech, method) {
  13128. return middleware.reduceRight(middlewareIterator(method), tech[method]());
  13129. }
  13130. function set(middleware, tech, method, arg) {
  13131. return tech[method](middleware.reduce(middlewareIterator(method), arg));
  13132. }
  13133. var allowedGetters = exports.allowedGetters = {
  13134. buffered: 1,
  13135. currentTime: 1,
  13136. duration: 1,
  13137. seekable: 1,
  13138. played: 1
  13139. };
  13140. var allowedSetters = exports.allowedSetters = {
  13141. setCurrentTime: 1
  13142. };
  13143. function middlewareIterator(method) {
  13144. return function (value, mw) {
  13145. if (mw[method]) {
  13146. return mw[method](value);
  13147. }
  13148. return value;
  13149. };
  13150. }
  13151. function setSourceHelper() {
  13152. var src = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  13153. var middleware = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
  13154. var next = arguments[2];
  13155. var player = arguments[3];
  13156. var acc = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : [];
  13157. var lastRun = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : false;
  13158. var mwFactory = middleware[0],
  13159. mwrest = middleware.slice(1);
  13160. // if mwFactory is a string, then we're at a fork in the road
  13161. if (typeof mwFactory === 'string') {
  13162. setSourceHelper(src, middlewares[mwFactory], next, player, acc, lastRun);
  13163. // if we have an mwFactory, call it with the player to get the mw,
  13164. // then call the mw's setSource method
  13165. } else if (mwFactory) {
  13166. var mw = mwFactory(player);
  13167. mw.setSource((0, _obj.assign)({}, src), function (err, _src) {
  13168. // something happened, try the next middleware on the current level
  13169. // make sure to use the old src
  13170. if (err) {
  13171. return setSourceHelper(src, mwrest, next, player, acc, lastRun);
  13172. }
  13173. // we've succeeded, now we need to go deeper
  13174. acc.push(mw);
  13175. // if it's the same time, continue does the current chain
  13176. // otherwise, we want to go down the new chain
  13177. setSourceHelper(_src, src.type === _src.type ? mwrest : middlewares[_src.type], next, player, acc, lastRun);
  13178. });
  13179. } else if (mwrest.length) {
  13180. setSourceHelper(src, mwrest, next, player, acc, lastRun);
  13181. } else if (lastRun) {
  13182. next(src, acc);
  13183. } else {
  13184. setSourceHelper(src, middlewares['*'], next, player, acc, true);
  13185. }
  13186. }
  13187. },{"93":93}],64:[function(_dereq_,module,exports){
  13188. 'use strict';
  13189. exports.__esModule = true;
  13190. var _component = _dereq_(5);
  13191. var _component2 = _interopRequireDefault(_component);
  13192. var _mergeOptions = _dereq_(92);
  13193. var _mergeOptions2 = _interopRequireDefault(_mergeOptions);
  13194. var _fn = _dereq_(88);
  13195. var Fn = _interopRequireWildcard(_fn);
  13196. var _log = _dereq_(91);
  13197. var _log2 = _interopRequireDefault(_log);
  13198. var _timeRanges = _dereq_(95);
  13199. var _buffer = _dereq_(82);
  13200. var _mediaError = _dereq_(49);
  13201. var _mediaError2 = _interopRequireDefault(_mediaError);
  13202. var _window = _dereq_(100);
  13203. var _window2 = _interopRequireDefault(_window);
  13204. var _document = _dereq_(99);
  13205. var _document2 = _interopRequireDefault(_document);
  13206. var _obj = _dereq_(93);
  13207. var _trackTypes = _dereq_(77);
  13208. var TRACK_TYPES = _interopRequireWildcard(_trackTypes);
  13209. var _toTitleCase = _dereq_(96);
  13210. var _toTitleCase2 = _interopRequireDefault(_toTitleCase);
  13211. function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
  13212. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  13213. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  13214. function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
  13215. function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
  13216. * @file tech.js
  13217. */
  13218. /**
  13219. * An Object containing a structure like: `{src: 'url', type: 'mimetype'}` or string
  13220. * that just contains the src url alone.
  13221. * * `var SourceObject = {src: 'http://ex.com/video.mp4', type: 'video/mp4'};`
  13222. * `var SourceString = 'http://example.com/some-video.mp4';`
  13223. *
  13224. * @typedef {Object|string} Tech~SourceObject
  13225. *
  13226. * @property {string} src
  13227. * The url to the source
  13228. *
  13229. * @property {string} type
  13230. * The mime type of the source
  13231. */
  13232. /**
  13233. * A function used by {@link Tech} to create a new {@link TextTrack}.
  13234. *
  13235. * @private
  13236. *
  13237. * @param {Tech} self
  13238. * An instance of the Tech class.
  13239. *
  13240. * @param {string} kind
  13241. * `TextTrack` kind (subtitles, captions, descriptions, chapters, or metadata)
  13242. *
  13243. * @param {string} [label]
  13244. * Label to identify the text track
  13245. *
  13246. * @param {string} [language]
  13247. * Two letter language abbreviation
  13248. *
  13249. * @param {Object} [options={}]
  13250. * An object with additional text track options
  13251. *
  13252. * @return {TextTrack}
  13253. * The text track that was created.
  13254. */
  13255. function createTrackHelper(self, kind, label, language) {
  13256. var options = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {};
  13257. var tracks = self.textTracks();
  13258. options.kind = kind;
  13259. if (label) {
  13260. options.label = label;
  13261. }
  13262. if (language) {
  13263. options.language = language;
  13264. }
  13265. options.tech = self;
  13266. var track = new TRACK_TYPES.ALL.text.TrackClass(options);
  13267. tracks.addTrack(track);
  13268. return track;
  13269. }
  13270. /**
  13271. * This is the base class for media playback technology controllers, such as
  13272. * {@link Flash} and {@link HTML5}
  13273. *
  13274. * @extends Component
  13275. */
  13276. var Tech = function (_Component) {
  13277. _inherits(Tech, _Component);
  13278. /**
  13279. * Create an instance of this Tech.
  13280. *
  13281. * @param {Object} [options]
  13282. * The key/value store of player options.
  13283. *
  13284. * @param {Component~ReadyCallback} ready
  13285. * Callback function to call when the `HTML5` Tech is ready.
  13286. */
  13287. function Tech() {
  13288. var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  13289. var ready = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : function () {};
  13290. _classCallCheck(this, Tech);
  13291. // we don't want the tech to report user activity automatically.
  13292. // This is done manually in addControlsListeners
  13293. options.reportTouchActivity = false;
  13294. // keep track of whether the current source has played at all to
  13295. // implement a very limited played()
  13296. var _this = _possibleConstructorReturn(this, _Component.call(this, null, options, ready));
  13297. _this.hasStarted_ = false;
  13298. _this.on('playing', function () {
  13299. this.hasStarted_ = true;
  13300. });
  13301. _this.on('loadstart', function () {
  13302. this.hasStarted_ = false;
  13303. });
  13304. TRACK_TYPES.ALL.names.forEach(function (name) {
  13305. var props = TRACK_TYPES.ALL[name];
  13306. if (options && options[props.getterName]) {
  13307. _this[props.privateName] = options[props.getterName];
  13308. }
  13309. });
  13310. // Manually track progress in cases where the browser/flash player doesn't report it.
  13311. if (!_this.featuresProgressEvents) {
  13312. _this.manualProgressOn();
  13313. }
  13314. // Manually track timeupdates in cases where the browser/flash player doesn't report it.
  13315. if (!_this.featuresTimeupdateEvents) {
  13316. _this.manualTimeUpdatesOn();
  13317. }
  13318. ['Text', 'Audio', 'Video'].forEach(function (track) {
  13319. if (options['native' + track + 'Tracks'] === false) {
  13320. _this['featuresNative' + track + 'Tracks'] = false;
  13321. }
  13322. });
  13323. if (options.nativeCaptions === false || options.nativeTextTracks === false) {
  13324. _this.featuresNativeTextTracks = false;
  13325. } else if (options.nativeCaptions === true || options.nativeTextTracks === true) {
  13326. _this.featuresNativeTextTracks = true;
  13327. }
  13328. if (!_this.featuresNativeTextTracks) {
  13329. _this.emulateTextTracks();
  13330. }
  13331. _this.autoRemoteTextTracks_ = new TRACK_TYPES.ALL.text.ListClass();
  13332. _this.initTrackListeners();
  13333. // Turn on component tap events only if not using native controls
  13334. if (!options.nativeControlsForTouch) {
  13335. _this.emitTapEvents();
  13336. }
  13337. if (_this.constructor) {
  13338. _this.name_ = _this.constructor.name || 'Unknown Tech';
  13339. }
  13340. return _this;
  13341. }
  13342. /* Fallbacks for unsupported event types
  13343. ================================================================================ */
  13344. /**
  13345. * Polyfill the `progress` event for browsers that don't support it natively.
  13346. *
  13347. * @see {@link Tech#trackProgress}
  13348. */
  13349. Tech.prototype.manualProgressOn = function manualProgressOn() {
  13350. this.on('durationchange', this.onDurationChange);
  13351. this.manualProgress = true;
  13352. // Trigger progress watching when a source begins loading
  13353. this.one('ready', this.trackProgress);
  13354. };
  13355. /**
  13356. * Turn off the polyfill for `progress` events that was created in
  13357. * {@link Tech#manualProgressOn}
  13358. */
  13359. Tech.prototype.manualProgressOff = function manualProgressOff() {
  13360. this.manualProgress = false;
  13361. this.stopTrackingProgress();
  13362. this.off('durationchange', this.onDurationChange);
  13363. };
  13364. /**
  13365. * This is used to trigger a `progress` event when the buffered percent changes. It
  13366. * sets an interval function that will be called every 500 milliseconds to check if the
  13367. * buffer end percent has changed.
  13368. *
  13369. * > This function is called by {@link Tech#manualProgressOn}
  13370. *
  13371. * @param {EventTarget~Event} event
  13372. * The `ready` event that caused this to run.
  13373. *
  13374. * @listens Tech#ready
  13375. * @fires Tech#progress
  13376. */
  13377. Tech.prototype.trackProgress = function trackProgress(event) {
  13378. this.stopTrackingProgress();
  13379. this.progressInterval = this.setInterval(Fn.bind(this, function () {
  13380. // Don't trigger unless buffered amount is greater than last time
  13381. var numBufferedPercent = this.bufferedPercent();
  13382. if (this.bufferedPercent_ !== numBufferedPercent) {
  13383. /**
  13384. * See {@link Player#progress}
  13385. *
  13386. * @event Tech#progress
  13387. * @type {EventTarget~Event}
  13388. */
  13389. this.trigger('progress');
  13390. }
  13391. this.bufferedPercent_ = numBufferedPercent;
  13392. if (numBufferedPercent === 1) {
  13393. this.stopTrackingProgress();
  13394. }
  13395. }), 500);
  13396. };
  13397. /**
  13398. * Update our internal duration on a `durationchange` event by calling
  13399. * {@link Tech#duration}.
  13400. *
  13401. * @param {EventTarget~Event} event
  13402. * The `durationchange` event that caused this to run.
  13403. *
  13404. * @listens Tech#durationchange
  13405. */
  13406. Tech.prototype.onDurationChange = function onDurationChange(event) {
  13407. this.duration_ = this.duration();
  13408. };
  13409. /**
  13410. * Get and create a `TimeRange` object for buffering.
  13411. *
  13412. * @return {TimeRange}
  13413. * The time range object that was created.
  13414. */
  13415. Tech.prototype.buffered = function buffered() {
  13416. return (0, _timeRanges.createTimeRange)(0, 0);
  13417. };
  13418. /**
  13419. * Get the percentage of the current video that is currently buffered.
  13420. *
  13421. * @return {number}
  13422. * A number from 0 to 1 that represents the decimal percentage of the
  13423. * video that is buffered.
  13424. *
  13425. */
  13426. Tech.prototype.bufferedPercent = function bufferedPercent() {
  13427. return (0, _buffer.bufferedPercent)(this.buffered(), this.duration_);
  13428. };
  13429. /**
  13430. * Turn off the polyfill for `progress` events that was created in
  13431. * {@link Tech#manualProgressOn}
  13432. * Stop manually tracking progress events by clearing the interval that was set in
  13433. * {@link Tech#trackProgress}.
  13434. */
  13435. Tech.prototype.stopTrackingProgress = function stopTrackingProgress() {
  13436. this.clearInterval(this.progressInterval);
  13437. };
  13438. /**
  13439. * Polyfill the `timeupdate` event for browsers that don't support it.
  13440. *
  13441. * @see {@link Tech#trackCurrentTime}
  13442. */
  13443. Tech.prototype.manualTimeUpdatesOn = function manualTimeUpdatesOn() {
  13444. this.manualTimeUpdates = true;
  13445. this.on('play', this.trackCurrentTime);
  13446. this.on('pause', this.stopTrackingCurrentTime);
  13447. };
  13448. /**
  13449. * Turn off the polyfill for `timeupdate` events that was created in
  13450. * {@link Tech#manualTimeUpdatesOn}
  13451. */
  13452. Tech.prototype.manualTimeUpdatesOff = function manualTimeUpdatesOff() {
  13453. this.manualTimeUpdates = false;
  13454. this.stopTrackingCurrentTime();
  13455. this.off('play', this.trackCurrentTime);
  13456. this.off('pause', this.stopTrackingCurrentTime);
  13457. };
  13458. /**
  13459. * Sets up an interval function to track current time and trigger `timeupdate` every
  13460. * 250 milliseconds.
  13461. *
  13462. * @listens Tech#play
  13463. * @triggers Tech#timeupdate
  13464. */
  13465. Tech.prototype.trackCurrentTime = function trackCurrentTime() {
  13466. if (this.currentTimeInterval) {
  13467. this.stopTrackingCurrentTime();
  13468. }
  13469. this.currentTimeInterval = this.setInterval(function () {
  13470. /**
  13471. * Triggered at an interval of 250ms to indicated that time is passing in the video.
  13472. *
  13473. * @event Tech#timeupdate
  13474. * @type {EventTarget~Event}
  13475. */
  13476. this.trigger({ type: 'timeupdate', target: this, manuallyTriggered: true });
  13477. // 42 = 24 fps // 250 is what Webkit uses // FF uses 15
  13478. }, 250);
  13479. };
  13480. /**
  13481. * Stop the interval function created in {@link Tech#trackCurrentTime} so that the
  13482. * `timeupdate` event is no longer triggered.
  13483. *
  13484. * @listens {Tech#pause}
  13485. */
  13486. Tech.prototype.stopTrackingCurrentTime = function stopTrackingCurrentTime() {
  13487. this.clearInterval(this.currentTimeInterval);
  13488. // #1002 - if the video ends right before the next timeupdate would happen,
  13489. // the progress bar won't make it all the way to the end
  13490. this.trigger({ type: 'timeupdate', target: this, manuallyTriggered: true });
  13491. };
  13492. /**
  13493. * Turn off all event polyfills, clear the `Tech`s {@link AudioTrackList},
  13494. * {@link VideoTrackList}, and {@link TextTrackList}, and dispose of this Tech.
  13495. *
  13496. * @fires Component#dispose
  13497. */
  13498. Tech.prototype.dispose = function dispose() {
  13499. // clear out all tracks because we can't reuse them between techs
  13500. this.clearTracks(TRACK_TYPES.NORMAL.names);
  13501. // Turn off any manual progress or timeupdate tracking
  13502. if (this.manualProgress) {
  13503. this.manualProgressOff();
  13504. }
  13505. if (this.manualTimeUpdates) {
  13506. this.manualTimeUpdatesOff();
  13507. }
  13508. _Component.prototype.dispose.call(this);
  13509. };
  13510. /**
  13511. * Clear out a single `TrackList` or an array of `TrackLists` given their names.
  13512. *
  13513. * > Note: Techs without source handlers should call this between sources for `video`
  13514. * & `audio` tracks. You don't want to use them between tracks!
  13515. *
  13516. * @param {string[]|string} types
  13517. * TrackList names to clear, valid names are `video`, `audio`, and
  13518. * `text`.
  13519. */
  13520. Tech.prototype.clearTracks = function clearTracks(types) {
  13521. var _this2 = this;
  13522. types = [].concat(types);
  13523. // clear out all tracks because we can't reuse them between techs
  13524. types.forEach(function (type) {
  13525. var list = _this2[type + 'Tracks']() || [];
  13526. var i = list.length;
  13527. while (i--) {
  13528. var track = list[i];
  13529. if (type === 'text') {
  13530. _this2.removeRemoteTextTrack(track);
  13531. }
  13532. list.removeTrack(track);
  13533. }
  13534. });
  13535. };
  13536. /**
  13537. * Remove any TextTracks added via addRemoteTextTrack that are
  13538. * flagged for automatic garbage collection
  13539. */
  13540. Tech.prototype.cleanupAutoTextTracks = function cleanupAutoTextTracks() {
  13541. var list = this.autoRemoteTextTracks_ || [];
  13542. var i = list.length;
  13543. while (i--) {
  13544. var track = list[i];
  13545. this.removeRemoteTextTrack(track);
  13546. }
  13547. };
  13548. /**
  13549. * Reset the tech, which will removes all sources and reset the internal readyState.
  13550. *
  13551. * @abstract
  13552. */
  13553. Tech.prototype.reset = function reset() {};
  13554. /**
  13555. * Get or set an error on the Tech.
  13556. *
  13557. * @param {MediaError} [err]
  13558. * Error to set on the Tech
  13559. *
  13560. * @return {MediaError|null}
  13561. * The current error object on the tech, or null if there isn't one.
  13562. */
  13563. Tech.prototype.error = function error(err) {
  13564. if (err !== undefined) {
  13565. this.error_ = new _mediaError2['default'](err);
  13566. this.trigger('error');
  13567. }
  13568. return this.error_;
  13569. };
  13570. /**
  13571. * Returns the `TimeRange`s that have been played through for the current source.
  13572. *
  13573. * > NOTE: This implementation is incomplete. It does not track the played `TimeRange`.
  13574. * It only checks wether the source has played at all or not.
  13575. *
  13576. * @return {TimeRange}
  13577. * - A single time range if this video has played
  13578. * - An empty set of ranges if not.
  13579. */
  13580. Tech.prototype.played = function played() {
  13581. if (this.hasStarted_) {
  13582. return (0, _timeRanges.createTimeRange)(0, 0);
  13583. }
  13584. return (0, _timeRanges.createTimeRange)();
  13585. };
  13586. /**
  13587. * Causes a manual time update to occur if {@link Tech#manualTimeUpdatesOn} was
  13588. * previously called.
  13589. *
  13590. * @fires Tech#timeupdate
  13591. */
  13592. Tech.prototype.setCurrentTime = function setCurrentTime() {
  13593. // improve the accuracy of manual timeupdates
  13594. if (this.manualTimeUpdates) {
  13595. /**
  13596. * A manual `timeupdate` event.
  13597. *
  13598. * @event Tech#timeupdate
  13599. * @type {EventTarget~Event}
  13600. */
  13601. this.trigger({ type: 'timeupdate', target: this, manuallyTriggered: true });
  13602. }
  13603. };
  13604. /**
  13605. * Turn on listeners for {@link VideoTrackList}, {@link {AudioTrackList}, and
  13606. * {@link TextTrackList} events.
  13607. *
  13608. * This adds {@link EventTarget~EventListeners} for `addtrack`, and `removetrack`.
  13609. *
  13610. * @fires Tech#audiotrackchange
  13611. * @fires Tech#videotrackchange
  13612. * @fires Tech#texttrackchange
  13613. */
  13614. Tech.prototype.initTrackListeners = function initTrackListeners() {
  13615. var _this3 = this;
  13616. /**
  13617. * Triggered when tracks are added or removed on the Tech {@link AudioTrackList}
  13618. *
  13619. * @event Tech#audiotrackchange
  13620. * @type {EventTarget~Event}
  13621. */
  13622. /**
  13623. * Triggered when tracks are added or removed on the Tech {@link VideoTrackList}
  13624. *
  13625. * @event Tech#videotrackchange
  13626. * @type {EventTarget~Event}
  13627. */
  13628. /**
  13629. * Triggered when tracks are added or removed on the Tech {@link TextTrackList}
  13630. *
  13631. * @event Tech#texttrackchange
  13632. * @type {EventTarget~Event}
  13633. */
  13634. TRACK_TYPES.NORMAL.names.forEach(function (name) {
  13635. var props = TRACK_TYPES.NORMAL[name];
  13636. var trackListChanges = function trackListChanges() {
  13637. _this3.trigger(name + 'trackchange');
  13638. };
  13639. var tracks = _this3[props.getterName]();
  13640. tracks.addEventListener('removetrack', trackListChanges);
  13641. tracks.addEventListener('addtrack', trackListChanges);
  13642. _this3.on('dispose', function () {
  13643. tracks.removeEventListener('removetrack', trackListChanges);
  13644. tracks.removeEventListener('addtrack', trackListChanges);
  13645. });
  13646. });
  13647. };
  13648. /**
  13649. * Emulate TextTracks using vtt.js if necessary
  13650. *
  13651. * @fires Tech#vttjsloaded
  13652. * @fires Tech#vttjserror
  13653. */
  13654. Tech.prototype.addWebVttScript_ = function addWebVttScript_() {
  13655. var _this4 = this;
  13656. if (_window2['default'].WebVTT) {
  13657. return;
  13658. }
  13659. // Initially, Tech.el_ is a child of a dummy-div wait until the Component system
  13660. // signals that the Tech is ready at which point Tech.el_ is part of the DOM
  13661. // before inserting the WebVTT script
  13662. if (_document2['default'].body.contains(this.el())) {
  13663. var vtt = _dereq_(110);
  13664. // load via require if available and vtt.js script location was not passed in
  13665. // as an option. novtt builds will turn the above require call into an empty object
  13666. // which will cause this if check to always fail.
  13667. if (!this.options_['vtt.js'] && (0, _obj.isPlain)(vtt) && Object.keys(vtt).length > 0) {
  13668. this.trigger('vttjsloaded');
  13669. return;
  13670. }
  13671. // load vtt.js via the script location option or the cdn of no location was
  13672. // passed in
  13673. var script = _document2['default'].createElement('script');
  13674. script.src = this.options_['vtt.js'] || 'https://cdn.rawgit.com/gkatsev/vtt.js/vjs-v0.12.1/dist/vtt.min.js';
  13675. script.onload = function () {
  13676. /**
  13677. * Fired when vtt.js is loaded.
  13678. *
  13679. * @event Tech#vttjsloaded
  13680. * @type {EventTarget~Event}
  13681. */
  13682. _this4.trigger('vttjsloaded');
  13683. };
  13684. script.onerror = function () {
  13685. /**
  13686. * Fired when vtt.js was not loaded due to an error
  13687. *
  13688. * @event Tech#vttjsloaded
  13689. * @type {EventTarget~Event}
  13690. */
  13691. _this4.trigger('vttjserror');
  13692. };
  13693. this.on('dispose', function () {
  13694. script.onload = null;
  13695. script.onerror = null;
  13696. });
  13697. // but have not loaded yet and we set it to true before the inject so that
  13698. // we don't overwrite the injected window.WebVTT if it loads right away
  13699. _window2['default'].WebVTT = true;
  13700. this.el().parentNode.appendChild(script);
  13701. } else {
  13702. this.ready(this.addWebVttScript_);
  13703. }
  13704. };
  13705. /**
  13706. * Emulate texttracks
  13707. *
  13708. */
  13709. Tech.prototype.emulateTextTracks = function emulateTextTracks() {
  13710. var _this5 = this;
  13711. var tracks = this.textTracks();
  13712. var remoteTracks = this.remoteTextTracks();
  13713. var handleAddTrack = function handleAddTrack(e) {
  13714. return tracks.addTrack(e.track);
  13715. };
  13716. var handleRemoveTrack = function handleRemoveTrack(e) {
  13717. return tracks.removeTrack(e.track);
  13718. };
  13719. remoteTracks.on('addtrack', handleAddTrack);
  13720. remoteTracks.on('removetrack', handleRemoveTrack);
  13721. this.addWebVttScript_();
  13722. var updateDisplay = function updateDisplay() {
  13723. return _this5.trigger('texttrackchange');
  13724. };
  13725. var textTracksChanges = function textTracksChanges() {
  13726. updateDisplay();
  13727. for (var i = 0; i < tracks.length; i++) {
  13728. var track = tracks[i];
  13729. track.removeEventListener('cuechange', updateDisplay);
  13730. if (track.mode === 'showing') {
  13731. track.addEventListener('cuechange', updateDisplay);
  13732. }
  13733. }
  13734. };
  13735. textTracksChanges();
  13736. tracks.addEventListener('change', textTracksChanges);
  13737. this.on('dispose', function () {
  13738. remoteTracks.off('addtrack', handleAddTrack);
  13739. remoteTracks.off('removetrack', handleRemoveTrack);
  13740. tracks.removeEventListener('change', textTracksChanges);
  13741. for (var i = 0; i < tracks.length; i++) {
  13742. var track = tracks[i];
  13743. track.removeEventListener('cuechange', updateDisplay);
  13744. }
  13745. });
  13746. };
  13747. /**
  13748. * Create and returns a remote {@link TextTrack} object.
  13749. *
  13750. * @param {string} kind
  13751. * `TextTrack` kind (subtitles, captions, descriptions, chapters, or metadata)
  13752. *
  13753. * @param {string} [label]
  13754. * Label to identify the text track
  13755. *
  13756. * @param {string} [language]
  13757. * Two letter language abbreviation
  13758. *
  13759. * @return {TextTrack}
  13760. * The TextTrack that gets created.
  13761. */
  13762. Tech.prototype.addTextTrack = function addTextTrack(kind, label, language) {
  13763. if (!kind) {
  13764. throw new Error('TextTrack kind is required but was not provided');
  13765. }
  13766. return createTrackHelper(this, kind, label, language);
  13767. };
  13768. /**
  13769. * Create an emulated TextTrack for use by addRemoteTextTrack
  13770. *
  13771. * This is intended to be overridden by classes that inherit from
  13772. * Tech in order to create native or custom TextTracks.
  13773. *
  13774. * @param {Object} options
  13775. * The object should contain the options to initialize the TextTrack with.
  13776. *
  13777. * @param {string} [options.kind]
  13778. * `TextTrack` kind (subtitles, captions, descriptions, chapters, or metadata).
  13779. *
  13780. * @param {string} [options.label].
  13781. * Label to identify the text track
  13782. *
  13783. * @param {string} [options.language]
  13784. * Two letter language abbreviation.
  13785. *
  13786. * @return {HTMLTrackElement}
  13787. * The track element that gets created.
  13788. */
  13789. Tech.prototype.createRemoteTextTrack = function createRemoteTextTrack(options) {
  13790. var track = (0, _mergeOptions2['default'])(options, {
  13791. tech: this
  13792. });
  13793. return new TRACK_TYPES.REMOTE.remoteTextEl.TrackClass(track);
  13794. };
  13795. /**
  13796. * Creates a remote text track object and returns an html track element.
  13797. *
  13798. * > Note: This can be an emulated {@link HTMLTrackElement} or a native one.
  13799. *
  13800. * @param {Object} options
  13801. * See {@link Tech#createRemoteTextTrack} for more detailed properties.
  13802. *
  13803. * @param {boolean} [manualCleanup=true]
  13804. * - When false: the TextTrack will be automatically removed from the video
  13805. * element whenever the source changes
  13806. * - When True: The TextTrack will have to be cleaned up manually
  13807. *
  13808. * @return {HTMLTrackElement}
  13809. * An Html Track Element.
  13810. *
  13811. * @deprecated The default functionality for this function will be equivalent
  13812. * to "manualCleanup=false" in the future. The manualCleanup parameter will
  13813. * also be removed.
  13814. */
  13815. Tech.prototype.addRemoteTextTrack = function addRemoteTextTrack() {
  13816. var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  13817. var manualCleanup = arguments[1];
  13818. var htmlTrackElement = this.createRemoteTextTrack(options);
  13819. if (manualCleanup !== true && manualCleanup !== false) {
  13820. // deprecation warning
  13821. _log2['default'].warn('Calling addRemoteTextTrack without explicitly setting the "manualCleanup" parameter to `true` is deprecated and default to `false` in future version of video.js');
  13822. manualCleanup = true;
  13823. }
  13824. // store HTMLTrackElement and TextTrack to remote list
  13825. this.remoteTextTrackEls().addTrackElement_(htmlTrackElement);
  13826. this.remoteTextTracks().addTrack(htmlTrackElement.track);
  13827. if (manualCleanup !== true) {
  13828. // create the TextTrackList if it doesn't exist
  13829. this.autoRemoteTextTracks_.addTrack(htmlTrackElement.track);
  13830. }
  13831. return htmlTrackElement;
  13832. };
  13833. /**
  13834. * Remove a remote text track from the remote `TextTrackList`.
  13835. *
  13836. * @param {TextTrack} track
  13837. * `TextTrack` to remove from the `TextTrackList`
  13838. */
  13839. Tech.prototype.removeRemoteTextTrack = function removeRemoteTextTrack(track) {
  13840. var trackElement = this.remoteTextTrackEls().getTrackElementByTrack_(track);
  13841. // remove HTMLTrackElement and TextTrack from remote list
  13842. this.remoteTextTrackEls().removeTrackElement_(trackElement);
  13843. this.remoteTextTracks().removeTrack(track);
  13844. this.autoRemoteTextTracks_.removeTrack(track);
  13845. };
  13846. /**
  13847. * A method to set a poster from a `Tech`.
  13848. *
  13849. * @abstract
  13850. */
  13851. Tech.prototype.setPoster = function setPoster() {};
  13852. /*
  13853. * Check if the tech can support the given mime-type.
  13854. *
  13855. * The base tech does not support any type, but source handlers might
  13856. * overwrite this.
  13857. *
  13858. * @param {string} type
  13859. * The mimetype to check for support
  13860. *
  13861. * @return {string}
  13862. * 'probably', 'maybe', or empty string
  13863. *
  13864. * @see [Spec]{@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/canPlayType}
  13865. *
  13866. * @abstract
  13867. */
  13868. Tech.prototype.canPlayType = function canPlayType() {
  13869. return '';
  13870. };
  13871. /**
  13872. * Check if the type is supported by this tech.
  13873. *
  13874. * The base tech does not support any type, but source handlers might
  13875. * overwrite this.
  13876. *
  13877. * @param {string} type
  13878. * The media type to check
  13879. * @return {string} Returns the native video element's response
  13880. */
  13881. Tech.canPlayType = function canPlayType() {
  13882. return '';
  13883. };
  13884. /**
  13885. * Check if the tech can support the given source
  13886. * @param {Object} srcObj
  13887. * The source object
  13888. * @param {Object} options
  13889. * The options passed to the tech
  13890. * @return {string} 'probably', 'maybe', or '' (empty string)
  13891. */
  13892. Tech.canPlaySource = function canPlaySource(srcObj, options) {
  13893. return Tech.canPlayType(srcObj.type);
  13894. };
  13895. /*
  13896. * Return whether the argument is a Tech or not.
  13897. * Can be passed either a Class like `Html5` or a instance like `player.tech_`
  13898. *
  13899. * @param {Object} component
  13900. * The item to check
  13901. *
  13902. * @return {boolean}
  13903. * Whether it is a tech or not
  13904. * - True if it is a tech
  13905. * - False if it is not
  13906. */
  13907. Tech.isTech = function isTech(component) {
  13908. return component.prototype instanceof Tech || component instanceof Tech || component === Tech;
  13909. };
  13910. /**
  13911. * Registers a `Tech` into a shared list for videojs.
  13912. *
  13913. * @param {string} name
  13914. * Name of the `Tech` to register.
  13915. *
  13916. * @param {Object} tech
  13917. * The `Tech` class to register.
  13918. */
  13919. Tech.registerTech = function registerTech(name, tech) {
  13920. if (!Tech.techs_) {
  13921. Tech.techs_ = {};
  13922. }
  13923. if (!Tech.isTech(tech)) {
  13924. throw new Error('Tech ' + name + ' must be a Tech');
  13925. }
  13926. if (!Tech.canPlayType) {
  13927. throw new Error('Techs must have a static canPlayType method on them');
  13928. }
  13929. if (!Tech.canPlaySource) {
  13930. throw new Error('Techs must have a static canPlaySource method on them');
  13931. }
  13932. name = (0, _toTitleCase2['default'])(name);
  13933. Tech.techs_[name] = tech;
  13934. if (name !== 'Tech') {
  13935. // camel case the techName for use in techOrder
  13936. Tech.defaultTechOrder_.push(name);
  13937. }
  13938. return tech;
  13939. };
  13940. /**
  13941. * Get a `Tech` from the shared list by name.
  13942. *
  13943. * @param {string} name
  13944. * `camelCase` or `TitleCase` name of the Tech to get
  13945. *
  13946. * @return {Tech|undefined}
  13947. * The `Tech` or undefined if there was no tech with the name requsted.
  13948. */
  13949. Tech.getTech = function getTech(name) {
  13950. if (!name) {
  13951. return;
  13952. }
  13953. name = (0, _toTitleCase2['default'])(name);
  13954. if (Tech.techs_ && Tech.techs_[name]) {
  13955. return Tech.techs_[name];
  13956. }
  13957. if (_window2['default'] && _window2['default'].videojs && _window2['default'].videojs[name]) {
  13958. _log2['default'].warn('The ' + name + ' tech was added to the videojs object when it should be registered using videojs.registerTech(name, tech)');
  13959. return _window2['default'].videojs[name];
  13960. }
  13961. };
  13962. return Tech;
  13963. }(_component2['default']);
  13964. /**
  13965. * Get the {@link VideoTrackList}
  13966. *
  13967. * @returns {VideoTrackList}
  13968. * @method Tech.prototype.videoTracks
  13969. */
  13970. /**
  13971. * Get the {@link AudioTrackList}
  13972. *
  13973. * @returns {AudioTrackList}
  13974. * @method Tech.prototype.audioTracks
  13975. */
  13976. /**
  13977. * Get the {@link TextTrackList}
  13978. *
  13979. * @returns {TextTrackList}
  13980. * @method Tech.prototype.textTracks
  13981. */
  13982. /**
  13983. * Get the remote element {@link TextTrackList}
  13984. *
  13985. * @returns {TextTrackList}
  13986. * @method Tech.prototype.remoteTextTracks
  13987. */
  13988. /**
  13989. * Get the remote element {@link HTMLTrackElementList}
  13990. *
  13991. * @returns {HTMLTrackElementList}
  13992. * @method Tech.prototype.remoteTextTrackEls
  13993. */
  13994. TRACK_TYPES.ALL.names.forEach(function (name) {
  13995. var props = TRACK_TYPES.ALL[name];
  13996. Tech.prototype[props.getterName] = function () {
  13997. this[props.privateName] = this[props.privateName] || new props.ListClass();
  13998. return this[props.privateName];
  13999. };
  14000. });
  14001. /**
  14002. * List of associated text tracks
  14003. *
  14004. * @type {TextTrackList}
  14005. * @private
  14006. * @property Tech#textTracks_
  14007. */
  14008. /**
  14009. * List of associated audio tracks.
  14010. *
  14011. * @type {AudioTrackList}
  14012. * @private
  14013. * @property Tech#audioTracks_
  14014. */
  14015. /**
  14016. * List of associated video tracks.
  14017. *
  14018. * @type {VideoTrackList}
  14019. * @private
  14020. * @property Tech#videoTracks_
  14021. */
  14022. /**
  14023. * Boolean indicating wether the `Tech` supports volume control.
  14024. *
  14025. * @type {boolean}
  14026. * @default
  14027. */
  14028. Tech.prototype.featuresVolumeControl = true;
  14029. /**
  14030. * Boolean indicating wether the `Tech` support fullscreen resize control.
  14031. * Resizing plugins using request fullscreen reloads the plugin
  14032. *
  14033. * @type {boolean}
  14034. * @default
  14035. */
  14036. Tech.prototype.featuresFullscreenResize = false;
  14037. /**
  14038. * Boolean indicating wether the `Tech` supports changing the speed at which the video
  14039. * plays. Examples:
  14040. * - Set player to play 2x (twice) as fast
  14041. * - Set player to play 0.5x (half) as fast
  14042. *
  14043. * @type {boolean}
  14044. * @default
  14045. */
  14046. Tech.prototype.featuresPlaybackRate = false;
  14047. /**
  14048. * Boolean indicating wether the `Tech` supports the `progress` event. This is currently
  14049. * not triggered by video-js-swf. This will be used to determine if
  14050. * {@link Tech#manualProgressOn} should be called.
  14051. *
  14052. * @type {boolean}
  14053. * @default
  14054. */
  14055. Tech.prototype.featuresProgressEvents = false;
  14056. /**
  14057. * Boolean indicating wether the `Tech` supports the `timeupdate` event. This is currently
  14058. * not triggered by video-js-swf. This will be used to determine if
  14059. * {@link Tech#manualTimeUpdates} should be called.
  14060. *
  14061. * @type {boolean}
  14062. * @default
  14063. */
  14064. Tech.prototype.featuresTimeupdateEvents = false;
  14065. /**
  14066. * Boolean indicating wether the `Tech` supports the native `TextTrack`s.
  14067. * This will help us integrate with native `TextTrack`s if the browser supports them.
  14068. *
  14069. * @type {boolean}
  14070. * @default
  14071. */
  14072. Tech.prototype.featuresNativeTextTracks = false;
  14073. /**
  14074. * A functional mixin for techs that want to use the Source Handler pattern.
  14075. * Source handlers are scripts for handling specific formats.
  14076. * The source handler pattern is used for adaptive formats (HLS, DASH) that
  14077. * manually load video data and feed it into a Source Buffer (Media Source Extensions)
  14078. * Example: `Tech.withSourceHandlers.call(MyTech);`
  14079. *
  14080. * @param {Tech} _Tech
  14081. * The tech to add source handler functions to.
  14082. *
  14083. * @mixes Tech~SourceHandlerAdditions
  14084. */
  14085. Tech.withSourceHandlers = function (_Tech) {
  14086. /**
  14087. * Register a source handler
  14088. *
  14089. * @param {Function} handler
  14090. * The source handler class
  14091. *
  14092. * @param {number} [index]
  14093. * Register it at the following index
  14094. */
  14095. _Tech.registerSourceHandler = function (handler, index) {
  14096. var handlers = _Tech.sourceHandlers;
  14097. if (!handlers) {
  14098. handlers = _Tech.sourceHandlers = [];
  14099. }
  14100. if (index === undefined) {
  14101. // add to the end of the list
  14102. index = handlers.length;
  14103. }
  14104. handlers.splice(index, 0, handler);
  14105. };
  14106. /**
  14107. * Check if the tech can support the given type. Also checks the
  14108. * Techs sourceHandlers.
  14109. *
  14110. * @param {string} type
  14111. * The mimetype to check.
  14112. *
  14113. * @return {string}
  14114. * 'probably', 'maybe', or '' (empty string)
  14115. */
  14116. _Tech.canPlayType = function (type) {
  14117. var handlers = _Tech.sourceHandlers || [];
  14118. var can = void 0;
  14119. for (var i = 0; i < handlers.length; i++) {
  14120. can = handlers[i].canPlayType(type);
  14121. if (can) {
  14122. return can;
  14123. }
  14124. }
  14125. return '';
  14126. };
  14127. /**
  14128. * Returns the first source handler that supports the source.
  14129. *
  14130. * TODO: Answer question: should 'probably' be prioritized over 'maybe'
  14131. *
  14132. * @param {Tech~SourceObject} source
  14133. * The source object
  14134. *
  14135. * @param {Object} options
  14136. * The options passed to the tech
  14137. *
  14138. * @return {SourceHandler|null}
  14139. * The first source handler that supports the source or null if
  14140. * no SourceHandler supports the source
  14141. */
  14142. _Tech.selectSourceHandler = function (source, options) {
  14143. var handlers = _Tech.sourceHandlers || [];
  14144. var can = void 0;
  14145. for (var i = 0; i < handlers.length; i++) {
  14146. can = handlers[i].canHandleSource(source, options);
  14147. if (can) {
  14148. return handlers[i];
  14149. }
  14150. }
  14151. return null;
  14152. };
  14153. /**
  14154. * Check if the tech can support the given source.
  14155. *
  14156. * @param {Tech~SourceObject} srcObj
  14157. * The source object
  14158. *
  14159. * @param {Object} options
  14160. * The options passed to the tech
  14161. *
  14162. * @return {string}
  14163. * 'probably', 'maybe', or '' (empty string)
  14164. */
  14165. _Tech.canPlaySource = function (srcObj, options) {
  14166. var sh = _Tech.selectSourceHandler(srcObj, options);
  14167. if (sh) {
  14168. return sh.canHandleSource(srcObj, options);
  14169. }
  14170. return '';
  14171. };
  14172. /**
  14173. * When using a source handler, prefer its implementation of
  14174. * any function normally provided by the tech.
  14175. */
  14176. var deferrable = ['seekable', 'duration'];
  14177. /**
  14178. * A wrapper around {@link Tech#seekable} that will call a `SourceHandler`s seekable
  14179. * function if it exists, with a fallback to the Techs seekable function.
  14180. *
  14181. * @method _Tech.seekable
  14182. */
  14183. /**
  14184. * A wrapper around {@link Tech#duration} that will call a `SourceHandler`s duration
  14185. * function if it exists, otherwise it will fallback to the techs duration function.
  14186. *
  14187. * @method _Tech.duration
  14188. */
  14189. deferrable.forEach(function (fnName) {
  14190. var originalFn = this[fnName];
  14191. if (typeof originalFn !== 'function') {
  14192. return;
  14193. }
  14194. this[fnName] = function () {
  14195. if (this.sourceHandler_ && this.sourceHandler_[fnName]) {
  14196. return this.sourceHandler_[fnName].apply(this.sourceHandler_, arguments);
  14197. }
  14198. return originalFn.apply(this, arguments);
  14199. };
  14200. }, _Tech.prototype);
  14201. /**
  14202. * Create a function for setting the source using a source object
  14203. * and source handlers.
  14204. * Should never be called unless a source handler was found.
  14205. *
  14206. * @param {Tech~SourceObject} source
  14207. * A source object with src and type keys
  14208. */
  14209. _Tech.prototype.setSource = function (source) {
  14210. var sh = _Tech.selectSourceHandler(source, this.options_);
  14211. if (!sh) {
  14212. // Fall back to a native source hander when unsupported sources are
  14213. // deliberately set
  14214. if (_Tech.nativeSourceHandler) {
  14215. sh = _Tech.nativeSourceHandler;
  14216. } else {
  14217. _log2['default'].error('No source hander found for the current source.');
  14218. }
  14219. }
  14220. // Dispose any existing source handler
  14221. this.disposeSourceHandler();
  14222. this.off('dispose', this.disposeSourceHandler);
  14223. if (sh !== _Tech.nativeSourceHandler) {
  14224. this.currentSource_ = source;
  14225. }
  14226. this.sourceHandler_ = sh.handleSource(source, this, this.options_);
  14227. this.on('dispose', this.disposeSourceHandler);
  14228. };
  14229. /**
  14230. * Clean up any existing SourceHandlers and listeners when the Tech is disposed.
  14231. *
  14232. * @listens Tech#dispose
  14233. */
  14234. _Tech.prototype.disposeSourceHandler = function () {
  14235. // if we have a source and get another one
  14236. // then we are loading something new
  14237. // than clear all of our current tracks
  14238. if (this.currentSource_) {
  14239. this.clearTracks(['audio', 'video']);
  14240. this.currentSource_ = null;
  14241. }
  14242. // always clean up auto-text tracks
  14243. this.cleanupAutoTextTracks();
  14244. if (this.sourceHandler_) {
  14245. if (this.sourceHandler_.dispose) {
  14246. this.sourceHandler_.dispose();
  14247. }
  14248. this.sourceHandler_ = null;
  14249. }
  14250. };
  14251. };
  14252. // The base Tech class needs to be registered as a Component. It is the only
  14253. // Tech that can be registered as a Component.
  14254. _component2['default'].registerComponent('Tech', Tech);
  14255. Tech.registerTech('Tech', Tech);
  14256. /**
  14257. * A list of techs that should be added to techOrder on Players
  14258. *
  14259. * @private
  14260. */
  14261. Tech.defaultTechOrder_ = [];
  14262. exports['default'] = Tech;
  14263. },{"100":100,"110":110,"49":49,"5":5,"77":77,"82":82,"88":88,"91":91,"92":92,"93":93,"95":95,"96":96,"99":99}],65:[function(_dereq_,module,exports){
  14264. 'use strict';
  14265. exports.__esModule = true;
  14266. var _trackList = _dereq_(76);
  14267. var _trackList2 = _interopRequireDefault(_trackList);
  14268. var _browser = _dereq_(81);
  14269. var browser = _interopRequireWildcard(_browser);
  14270. var _document = _dereq_(99);
  14271. var _document2 = _interopRequireDefault(_document);
  14272. function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
  14273. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  14274. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  14275. function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
  14276. function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
  14277. * @file audio-track-list.js
  14278. */
  14279. /**
  14280. * Anywhere we call this function we diverge from the spec
  14281. * as we only support one enabled audiotrack at a time
  14282. *
  14283. * @param {AudioTrackList} list
  14284. * list to work on
  14285. *
  14286. * @param {AudioTrack} track
  14287. * The track to skip
  14288. *
  14289. * @private
  14290. */
  14291. var disableOthers = function disableOthers(list, track) {
  14292. for (var i = 0; i < list.length; i++) {
  14293. if (track.id === list[i].id) {
  14294. continue;
  14295. }
  14296. // another audio track is enabled, disable it
  14297. list[i].enabled = false;
  14298. }
  14299. };
  14300. /**
  14301. * The current list of {@link AudioTrack} for a media file.
  14302. *
  14303. * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#audiotracklist}
  14304. * @extends TrackList
  14305. */
  14306. var AudioTrackList = function (_TrackList) {
  14307. _inherits(AudioTrackList, _TrackList);
  14308. /**
  14309. * Create an instance of this class.
  14310. *
  14311. * @param {AudioTrack[]} [tracks=[]]
  14312. * A list of `AudioTrack` to instantiate the list with.
  14313. */
  14314. function AudioTrackList() {
  14315. var _this, _ret;
  14316. var tracks = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
  14317. _classCallCheck(this, AudioTrackList);
  14318. var list = void 0;
  14319. // make sure only 1 track is enabled
  14320. // sorted from last index to first index
  14321. for (var i = tracks.length - 1; i >= 0; i--) {
  14322. if (tracks[i].enabled) {
  14323. disableOthers(tracks, tracks[i]);
  14324. break;
  14325. }
  14326. }
  14327. // IE8 forces us to implement inheritance ourselves
  14328. // as it does not support Object.defineProperty properly
  14329. if (browser.IS_IE8) {
  14330. list = _document2['default'].createElement('custom');
  14331. for (var prop in _trackList2['default'].prototype) {
  14332. if (prop !== 'constructor') {
  14333. list[prop] = _trackList2['default'].prototype[prop];
  14334. }
  14335. }
  14336. for (var _prop in AudioTrackList.prototype) {
  14337. if (_prop !== 'constructor') {
  14338. list[_prop] = AudioTrackList.prototype[_prop];
  14339. }
  14340. }
  14341. }
  14342. list = (_this = _possibleConstructorReturn(this, _TrackList.call(this, tracks, list)), _this);
  14343. list.changing_ = false;
  14344. return _ret = list, _possibleConstructorReturn(_this, _ret);
  14345. }
  14346. /**
  14347. * Add an {@link AudioTrack} to the `AudioTrackList`.
  14348. *
  14349. * @param {AudioTrack} track
  14350. * The AudioTrack to add to the list
  14351. *
  14352. * @fires TrackList#addtrack
  14353. */
  14354. AudioTrackList.prototype.addTrack = function addTrack(track) {
  14355. var _this2 = this;
  14356. if (track.enabled) {
  14357. disableOthers(this, track);
  14358. }
  14359. _TrackList.prototype.addTrack.call(this, track);
  14360. // native tracks don't have this
  14361. if (!track.addEventListener) {
  14362. return;
  14363. }
  14364. /**
  14365. * @listens AudioTrack#enabledchange
  14366. * @fires TrackList#change
  14367. */
  14368. track.addEventListener('enabledchange', function () {
  14369. // when we are disabling other tracks (since we don't support
  14370. // more than one track at a time) we will set changing_
  14371. // to true so that we don't trigger additional change events
  14372. if (_this2.changing_) {
  14373. return;
  14374. }
  14375. _this2.changing_ = true;
  14376. disableOthers(_this2, track);
  14377. _this2.changing_ = false;
  14378. _this2.trigger('change');
  14379. });
  14380. };
  14381. return AudioTrackList;
  14382. }(_trackList2['default']);
  14383. exports['default'] = AudioTrackList;
  14384. },{"76":76,"81":81,"99":99}],66:[function(_dereq_,module,exports){
  14385. 'use strict';
  14386. exports.__esModule = true;
  14387. var _trackEnums = _dereq_(75);
  14388. var _track = _dereq_(78);
  14389. var _track2 = _interopRequireDefault(_track);
  14390. var _mergeOptions = _dereq_(92);
  14391. var _mergeOptions2 = _interopRequireDefault(_mergeOptions);
  14392. var _browser = _dereq_(81);
  14393. var browser = _interopRequireWildcard(_browser);
  14394. function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
  14395. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  14396. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  14397. function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
  14398. function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
  14399. /**
  14400. * A representation of a single `AudioTrack`. If it is part of an {@link AudioTrackList}
  14401. * only one `AudioTrack` in the list will be enabled at a time.
  14402. *
  14403. * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#audiotrack}
  14404. * @extends Track
  14405. */
  14406. var AudioTrack = function (_Track) {
  14407. _inherits(AudioTrack, _Track);
  14408. /**
  14409. * Create an instance of this class.
  14410. *
  14411. * @param {Object} [options={}]
  14412. * Object of option names and values
  14413. *
  14414. * @param {AudioTrack~Kind} [options.kind='']
  14415. * A valid audio track kind
  14416. *
  14417. * @param {string} [options.id='vjs_track_' + Guid.newGUID()]
  14418. * A unique id for this AudioTrack.
  14419. *
  14420. * @param {string} [options.label='']
  14421. * The menu label for this track.
  14422. *
  14423. * @param {string} [options.language='']
  14424. * A valid two character language code.
  14425. *
  14426. * @param {boolean} [options.enabled]
  14427. * If this track is the one that is currently playing. If this track is part of
  14428. * an {@link AudioTrackList}, only one {@link AudioTrack} will be enabled.
  14429. */
  14430. function AudioTrack() {
  14431. var _this, _ret;
  14432. var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  14433. _classCallCheck(this, AudioTrack);
  14434. var settings = (0, _mergeOptions2['default'])(options, {
  14435. kind: _trackEnums.AudioTrackKind[options.kind] || ''
  14436. });
  14437. // on IE8 this will be a document element
  14438. // for every other browser this will be a normal object
  14439. var track = (_this = _possibleConstructorReturn(this, _Track.call(this, settings)), _this);
  14440. var enabled = false;
  14441. if (browser.IS_IE8) {
  14442. for (var prop in AudioTrack.prototype) {
  14443. if (prop !== 'constructor') {
  14444. track[prop] = AudioTrack.prototype[prop];
  14445. }
  14446. }
  14447. }
  14448. /**
  14449. * @memberof AudioTrack
  14450. * @member {boolean} enabled
  14451. * If this `AudioTrack` is enabled or not. When setting this will
  14452. * fire {@link AudioTrack#enabledchange} if the state of enabled is changed.
  14453. * @instance
  14454. *
  14455. * @fires VideoTrack#selectedchange
  14456. */
  14457. Object.defineProperty(track, 'enabled', {
  14458. get: function get() {
  14459. return enabled;
  14460. },
  14461. set: function set(newEnabled) {
  14462. // an invalid or unchanged value
  14463. if (typeof newEnabled !== 'boolean' || newEnabled === enabled) {
  14464. return;
  14465. }
  14466. enabled = newEnabled;
  14467. /**
  14468. * An event that fires when enabled changes on this track. This allows
  14469. * the AudioTrackList that holds this track to act accordingly.
  14470. *
  14471. * > Note: This is not part of the spec! Native tracks will do
  14472. * this internally without an event.
  14473. *
  14474. * @event AudioTrack#enabledchange
  14475. * @type {EventTarget~Event}
  14476. */
  14477. this.trigger('enabledchange');
  14478. }
  14479. });
  14480. // if the user sets this track to selected then
  14481. // set selected to that true value otherwise
  14482. // we keep it false
  14483. if (settings.enabled) {
  14484. track.enabled = settings.enabled;
  14485. }
  14486. track.loaded_ = true;
  14487. return _ret = track, _possibleConstructorReturn(_this, _ret);
  14488. }
  14489. return AudioTrack;
  14490. }(_track2['default']);
  14491. exports['default'] = AudioTrack;
  14492. },{"75":75,"78":78,"81":81,"92":92}],67:[function(_dereq_,module,exports){
  14493. 'use strict';
  14494. exports.__esModule = true;
  14495. var _browser = _dereq_(81);
  14496. var browser = _interopRequireWildcard(_browser);
  14497. var _document = _dereq_(99);
  14498. var _document2 = _interopRequireDefault(_document);
  14499. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  14500. function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
  14501. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } /**
  14502. * @file html-track-element-list.js
  14503. */
  14504. /**
  14505. * The current list of {@link HtmlTrackElement}s.
  14506. */
  14507. var HtmlTrackElementList = function () {
  14508. /**
  14509. * Create an instance of this class.
  14510. *
  14511. * @param {HtmlTrackElement[]} [tracks=[]]
  14512. * A list of `HtmlTrackElement` to instantiate the list with.
  14513. */
  14514. function HtmlTrackElementList() {
  14515. var trackElements = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
  14516. _classCallCheck(this, HtmlTrackElementList);
  14517. var list = this; // eslint-disable-line
  14518. if (browser.IS_IE8) {
  14519. list = _document2['default'].createElement('custom');
  14520. for (var prop in HtmlTrackElementList.prototype) {
  14521. if (prop !== 'constructor') {
  14522. list[prop] = HtmlTrackElementList.prototype[prop];
  14523. }
  14524. }
  14525. }
  14526. list.trackElements_ = [];
  14527. /**
  14528. * @memberof HTMLTrackElementList
  14529. * @member {number} length
  14530. * The current number of `Track`s in the this Trackist.
  14531. * @instance
  14532. */
  14533. Object.defineProperty(list, 'length', {
  14534. get: function get() {
  14535. return this.trackElements_.length;
  14536. }
  14537. });
  14538. for (var i = 0, length = trackElements.length; i < length; i++) {
  14539. list.addTrackElement_(trackElements[i]);
  14540. }
  14541. if (browser.IS_IE8) {
  14542. return list;
  14543. }
  14544. }
  14545. /**
  14546. * Add an {@link HtmlTrackElement} to the `HtmlTrackElementList`
  14547. *
  14548. * @param {HtmlTrackElement} trackElement
  14549. * The track element to add to the list.
  14550. *
  14551. * @private
  14552. */
  14553. HtmlTrackElementList.prototype.addTrackElement_ = function addTrackElement_(trackElement) {
  14554. var index = this.trackElements_.length;
  14555. if (!('' + index in this)) {
  14556. Object.defineProperty(this, index, {
  14557. get: function get() {
  14558. return this.trackElements_[index];
  14559. }
  14560. });
  14561. }
  14562. // Do not add duplicate elements
  14563. if (this.trackElements_.indexOf(trackElement) === -1) {
  14564. this.trackElements_.push(trackElement);
  14565. }
  14566. };
  14567. /**
  14568. * Get an {@link HtmlTrackElement} from the `HtmlTrackElementList` given an
  14569. * {@link TextTrack}.
  14570. *
  14571. * @param {TextTrack} track
  14572. * The track associated with a track element.
  14573. *
  14574. * @return {HtmlTrackElement|undefined}
  14575. * The track element that was found or undefined.
  14576. *
  14577. * @private
  14578. */
  14579. HtmlTrackElementList.prototype.getTrackElementByTrack_ = function getTrackElementByTrack_(track) {
  14580. var trackElement_ = void 0;
  14581. for (var i = 0, length = this.trackElements_.length; i < length; i++) {
  14582. if (track === this.trackElements_[i].track) {
  14583. trackElement_ = this.trackElements_[i];
  14584. break;
  14585. }
  14586. }
  14587. return trackElement_;
  14588. };
  14589. /**
  14590. * Remove a {@link HtmlTrackElement} from the `HtmlTrackElementList`
  14591. *
  14592. * @param {HtmlTrackElement} trackElement
  14593. * The track element to remove from the list.
  14594. *
  14595. * @private
  14596. */
  14597. HtmlTrackElementList.prototype.removeTrackElement_ = function removeTrackElement_(trackElement) {
  14598. for (var i = 0, length = this.trackElements_.length; i < length; i++) {
  14599. if (trackElement === this.trackElements_[i]) {
  14600. this.trackElements_.splice(i, 1);
  14601. break;
  14602. }
  14603. }
  14604. };
  14605. return HtmlTrackElementList;
  14606. }();
  14607. exports['default'] = HtmlTrackElementList;
  14608. },{"81":81,"99":99}],68:[function(_dereq_,module,exports){
  14609. 'use strict';
  14610. exports.__esModule = true;
  14611. var _browser = _dereq_(81);
  14612. var browser = _interopRequireWildcard(_browser);
  14613. var _document = _dereq_(99);
  14614. var _document2 = _interopRequireDefault(_document);
  14615. var _eventTarget = _dereq_(45);
  14616. var _eventTarget2 = _interopRequireDefault(_eventTarget);
  14617. var _textTrack = _dereq_(74);
  14618. var _textTrack2 = _interopRequireDefault(_textTrack);
  14619. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  14620. function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
  14621. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  14622. function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
  14623. function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
  14624. * @file html-track-element.js
  14625. */
  14626. /**
  14627. * @memberof HTMLTrackElement
  14628. * @typedef {HTMLTrackElement~ReadyState}
  14629. * @enum {number}
  14630. */
  14631. var NONE = 0;
  14632. var LOADING = 1;
  14633. var LOADED = 2;
  14634. var ERROR = 3;
  14635. /**
  14636. * A single track represented in the DOM.
  14637. *
  14638. * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#htmltrackelement}
  14639. * @extends EventTarget
  14640. */
  14641. var HTMLTrackElement = function (_EventTarget) {
  14642. _inherits(HTMLTrackElement, _EventTarget);
  14643. /**
  14644. * Create an instance of this class.
  14645. *
  14646. * @param {Object} options={}
  14647. * Object of option names and values
  14648. *
  14649. * @param {Tech} options.tech
  14650. * A reference to the tech that owns this HTMLTrackElement.
  14651. *
  14652. * @param {TextTrack~Kind} [options.kind='subtitles']
  14653. * A valid text track kind.
  14654. *
  14655. * @param {TextTrack~Mode} [options.mode='disabled']
  14656. * A valid text track mode.
  14657. *
  14658. * @param {string} [options.id='vjs_track_' + Guid.newGUID()]
  14659. * A unique id for this TextTrack.
  14660. *
  14661. * @param {string} [options.label='']
  14662. * The menu label for this track.
  14663. *
  14664. * @param {string} [options.language='']
  14665. * A valid two character language code.
  14666. *
  14667. * @param {string} [options.srclang='']
  14668. * A valid two character language code. An alternative, but deprioritized
  14669. * vesion of `options.language`
  14670. *
  14671. * @param {string} [options.src]
  14672. * A url to TextTrack cues.
  14673. *
  14674. * @param {boolean} [options.default]
  14675. * If this track should default to on or off.
  14676. */
  14677. function HTMLTrackElement() {
  14678. var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  14679. _classCallCheck(this, HTMLTrackElement);
  14680. var _this = _possibleConstructorReturn(this, _EventTarget.call(this));
  14681. var readyState = void 0;
  14682. var trackElement = _this; // eslint-disable-line
  14683. if (browser.IS_IE8) {
  14684. trackElement = _document2['default'].createElement('custom');
  14685. for (var prop in HTMLTrackElement.prototype) {
  14686. if (prop !== 'constructor') {
  14687. trackElement[prop] = HTMLTrackElement.prototype[prop];
  14688. }
  14689. }
  14690. }
  14691. var track = new _textTrack2['default'](options);
  14692. trackElement.kind = track.kind;
  14693. trackElement.src = track.src;
  14694. trackElement.srclang = track.language;
  14695. trackElement.label = track.label;
  14696. trackElement['default'] = track['default'];
  14697. /**
  14698. * @memberof HTMLTrackElement
  14699. * @member {HTMLTrackElement~ReadyState} readyState
  14700. * The current ready state of the track element.
  14701. * @instance
  14702. */
  14703. Object.defineProperty(trackElement, 'readyState', {
  14704. get: function get() {
  14705. return readyState;
  14706. }
  14707. });
  14708. /**
  14709. * @memberof HTMLTrackElement
  14710. * @member {TextTrack} track
  14711. * The underlying TextTrack object.
  14712. * @instance
  14713. *
  14714. */
  14715. Object.defineProperty(trackElement, 'track', {
  14716. get: function get() {
  14717. return track;
  14718. }
  14719. });
  14720. readyState = NONE;
  14721. /**
  14722. * @listens TextTrack#loadeddata
  14723. * @fires HTMLTrackElement#load
  14724. */
  14725. track.addEventListener('loadeddata', function () {
  14726. readyState = LOADED;
  14727. trackElement.trigger({
  14728. type: 'load',
  14729. target: trackElement
  14730. });
  14731. });
  14732. if (browser.IS_IE8) {
  14733. var _ret;
  14734. return _ret = trackElement, _possibleConstructorReturn(_this, _ret);
  14735. }
  14736. return _this;
  14737. }
  14738. return HTMLTrackElement;
  14739. }(_eventTarget2['default']);
  14740. HTMLTrackElement.prototype.allowedEvents_ = {
  14741. load: 'load'
  14742. };
  14743. HTMLTrackElement.NONE = NONE;
  14744. HTMLTrackElement.LOADING = LOADING;
  14745. HTMLTrackElement.LOADED = LOADED;
  14746. HTMLTrackElement.ERROR = ERROR;
  14747. exports['default'] = HTMLTrackElement;
  14748. },{"45":45,"74":74,"81":81,"99":99}],69:[function(_dereq_,module,exports){
  14749. 'use strict';
  14750. exports.__esModule = true;
  14751. var _browser = _dereq_(81);
  14752. var browser = _interopRequireWildcard(_browser);
  14753. var _document = _dereq_(99);
  14754. var _document2 = _interopRequireDefault(_document);
  14755. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  14756. function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
  14757. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } /**
  14758. * @file text-track-cue-list.js
  14759. */
  14760. /**
  14761. * @typedef {Object} TextTrackCueList~TextTrackCue
  14762. *
  14763. * @property {string} id
  14764. * The unique id for this text track cue
  14765. *
  14766. * @property {number} startTime
  14767. * The start time for this text track cue
  14768. *
  14769. * @property {number} endTime
  14770. * The end time for this text track cue
  14771. *
  14772. * @property {boolean} pauseOnExit
  14773. * Pause when the end time is reached if true.
  14774. *
  14775. * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#texttrackcue}
  14776. */
  14777. /**
  14778. * A List of TextTrackCues.
  14779. *
  14780. * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#texttrackcuelist}
  14781. */
  14782. var TextTrackCueList = function () {
  14783. /**
  14784. * Create an instance of this class..
  14785. *
  14786. * @param {Array} cues
  14787. * A list of cues to be initialized with
  14788. */
  14789. function TextTrackCueList(cues) {
  14790. _classCallCheck(this, TextTrackCueList);
  14791. var list = this; // eslint-disable-line
  14792. if (browser.IS_IE8) {
  14793. list = _document2['default'].createElement('custom');
  14794. for (var prop in TextTrackCueList.prototype) {
  14795. if (prop !== 'constructor') {
  14796. list[prop] = TextTrackCueList.prototype[prop];
  14797. }
  14798. }
  14799. }
  14800. TextTrackCueList.prototype.setCues_.call(list, cues);
  14801. /**
  14802. * @memberof TextTrackCueList
  14803. * @member {number} length
  14804. * The current number of `TextTrackCue`s in the TextTrackCueList.
  14805. * @instance
  14806. */
  14807. Object.defineProperty(list, 'length', {
  14808. get: function get() {
  14809. return this.length_;
  14810. }
  14811. });
  14812. if (browser.IS_IE8) {
  14813. return list;
  14814. }
  14815. }
  14816. /**
  14817. * A setter for cues in this list. Creates getters
  14818. * an an index for the cues.
  14819. *
  14820. * @param {Array} cues
  14821. * An array of cues to set
  14822. *
  14823. * @private
  14824. */
  14825. TextTrackCueList.prototype.setCues_ = function setCues_(cues) {
  14826. var oldLength = this.length || 0;
  14827. var i = 0;
  14828. var l = cues.length;
  14829. this.cues_ = cues;
  14830. this.length_ = cues.length;
  14831. var defineProp = function defineProp(index) {
  14832. if (!('' + index in this)) {
  14833. Object.defineProperty(this, '' + index, {
  14834. get: function get() {
  14835. return this.cues_[index];
  14836. }
  14837. });
  14838. }
  14839. };
  14840. if (oldLength < l) {
  14841. i = oldLength;
  14842. for (; i < l; i++) {
  14843. defineProp.call(this, i);
  14844. }
  14845. }
  14846. };
  14847. /**
  14848. * Get a `TextTrackCue` that is currently in the `TextTrackCueList` by id.
  14849. *
  14850. * @param {string} id
  14851. * The id of the cue that should be searched for.
  14852. *
  14853. * @return {TextTrackCueList~TextTrackCue|null}
  14854. * A single cue or null if none was found.
  14855. */
  14856. TextTrackCueList.prototype.getCueById = function getCueById(id) {
  14857. var result = null;
  14858. for (var i = 0, l = this.length; i < l; i++) {
  14859. var cue = this[i];
  14860. if (cue.id === id) {
  14861. result = cue;
  14862. break;
  14863. }
  14864. }
  14865. return result;
  14866. };
  14867. return TextTrackCueList;
  14868. }();
  14869. exports['default'] = TextTrackCueList;
  14870. },{"81":81,"99":99}],70:[function(_dereq_,module,exports){
  14871. 'use strict';
  14872. exports.__esModule = true;
  14873. var _component = _dereq_(5);
  14874. var _component2 = _interopRequireDefault(_component);
  14875. var _fn = _dereq_(88);
  14876. var Fn = _interopRequireWildcard(_fn);
  14877. var _window = _dereq_(100);
  14878. var _window2 = _interopRequireDefault(_window);
  14879. function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
  14880. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  14881. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  14882. function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
  14883. function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
  14884. * @file text-track-display.js
  14885. */
  14886. var darkGray = '#222';
  14887. var lightGray = '#ccc';
  14888. var fontMap = {
  14889. monospace: 'monospace',
  14890. sansSerif: 'sans-serif',
  14891. serif: 'serif',
  14892. monospaceSansSerif: '"Andale Mono", "Lucida Console", monospace',
  14893. monospaceSerif: '"Courier New", monospace',
  14894. proportionalSansSerif: 'sans-serif',
  14895. proportionalSerif: 'serif',
  14896. casual: '"Comic Sans MS", Impact, fantasy',
  14897. script: '"Monotype Corsiva", cursive',
  14898. smallcaps: '"Andale Mono", "Lucida Console", monospace, sans-serif'
  14899. };
  14900. /**
  14901. * Construct an rgba color from a given hex color code.
  14902. *
  14903. * @param {number} color
  14904. * Hex number for color, like #f0e.
  14905. *
  14906. * @param {number} opacity
  14907. * Value for opacity, 0.0 - 1.0.
  14908. *
  14909. * @return {string}
  14910. * The rgba color that was created, like 'rgba(255, 0, 0, 0.3)'.
  14911. *
  14912. * @private
  14913. */
  14914. function constructColor(color, opacity) {
  14915. return 'rgba(' +
  14916. // color looks like "#f0e"
  14917. parseInt(color[1] + color[1], 16) + ',' + parseInt(color[2] + color[2], 16) + ',' + parseInt(color[3] + color[3], 16) + ',' + opacity + ')';
  14918. }
  14919. /**
  14920. * Try to update the style of a DOM element. Some style changes will throw an error,
  14921. * particularly in IE8. Those should be noops.
  14922. *
  14923. * @param {Element} el
  14924. * The DOM element to be styled.
  14925. *
  14926. * @param {string} style
  14927. * The CSS property on the element that should be styled.
  14928. *
  14929. * @param {string} rule
  14930. * The style rule that should be applied to the property.
  14931. *
  14932. * @private
  14933. */
  14934. function tryUpdateStyle(el, style, rule) {
  14935. try {
  14936. el.style[style] = rule;
  14937. } catch (e) {
  14938. // Satisfies linter.
  14939. return;
  14940. }
  14941. }
  14942. /**
  14943. * The component for displaying text track cues.
  14944. *
  14945. * @extends Component
  14946. */
  14947. var TextTrackDisplay = function (_Component) {
  14948. _inherits(TextTrackDisplay, _Component);
  14949. /**
  14950. * Creates an instance of this class.
  14951. *
  14952. * @param {Player} player
  14953. * The `Player` that this class should be attached to.
  14954. *
  14955. * @param {Object} [options]
  14956. * The key/value store of player options.
  14957. *
  14958. * @param {Component~ReadyCallback} [ready]
  14959. * The function to call when `TextTrackDisplay` is ready.
  14960. */
  14961. function TextTrackDisplay(player, options, ready) {
  14962. _classCallCheck(this, TextTrackDisplay);
  14963. var _this = _possibleConstructorReturn(this, _Component.call(this, player, options, ready));
  14964. player.on('loadstart', Fn.bind(_this, _this.toggleDisplay));
  14965. player.on('texttrackchange', Fn.bind(_this, _this.updateDisplay));
  14966. // This used to be called during player init, but was causing an error
  14967. // if a track should show by default and the display hadn't loaded yet.
  14968. // Should probably be moved to an external track loader when we support
  14969. // tracks that don't need a display.
  14970. player.ready(Fn.bind(_this, function () {
  14971. if (player.tech_ && player.tech_.featuresNativeTextTracks) {
  14972. this.hide();
  14973. return;
  14974. }
  14975. player.on('fullscreenchange', Fn.bind(this, this.updateDisplay));
  14976. var tracks = this.options_.playerOptions.tracks || [];
  14977. for (var i = 0; i < tracks.length; i++) {
  14978. this.player_.addRemoteTextTrack(tracks[i], true);
  14979. }
  14980. var modes = { captions: 1, subtitles: 1 };
  14981. var trackList = this.player_.textTracks();
  14982. var firstDesc = void 0;
  14983. var firstCaptions = void 0;
  14984. for (var _i = 0; _i < trackList.length; _i++) {
  14985. var track = trackList[_i];
  14986. if (track['default']) {
  14987. if (track.kind === 'descriptions' && !firstDesc) {
  14988. firstDesc = track;
  14989. } else if (track.kind in modes && !firstCaptions) {
  14990. firstCaptions = track;
  14991. }
  14992. }
  14993. }
  14994. // We want to show the first default track but captions and subtitles
  14995. // take precedence over descriptions.
  14996. // So, display the first default captions or subtitles track
  14997. // and otherwise the first default descriptions track.
  14998. if (firstCaptions) {
  14999. firstCaptions.mode = 'showing';
  15000. } else if (firstDesc) {
  15001. firstDesc.mode = 'showing';
  15002. }
  15003. }));
  15004. return _this;
  15005. }
  15006. /**
  15007. * Turn display of {@link TextTrack}'s from the current state into the other state.
  15008. * There are only two states:
  15009. * - 'shown'
  15010. * - 'hidden'
  15011. *
  15012. * @listens Player#loadstart
  15013. */
  15014. TextTrackDisplay.prototype.toggleDisplay = function toggleDisplay() {
  15015. if (this.player_.tech_ && this.player_.tech_.featuresNativeTextTracks) {
  15016. this.hide();
  15017. } else {
  15018. this.show();
  15019. }
  15020. };
  15021. /**
  15022. * Create the {@link Component}'s DOM element.
  15023. *
  15024. * @return {Element}
  15025. * The element that was created.
  15026. */
  15027. TextTrackDisplay.prototype.createEl = function createEl() {
  15028. return _Component.prototype.createEl.call(this, 'div', {
  15029. className: 'vjs-text-track-display'
  15030. }, {
  15031. 'aria-live': 'off',
  15032. 'aria-atomic': 'true'
  15033. });
  15034. };
  15035. /**
  15036. * Clear all displayed {@link TextTrack}s.
  15037. */
  15038. TextTrackDisplay.prototype.clearDisplay = function clearDisplay() {
  15039. if (typeof _window2['default'].WebVTT === 'function') {
  15040. _window2['default'].WebVTT.processCues(_window2['default'], [], this.el_);
  15041. }
  15042. };
  15043. /**
  15044. * Update the displayed TextTrack when a either a {@link Player#texttrackchange} or
  15045. * a {@link Player#fullscreenchange} is fired.
  15046. *
  15047. * @listens Player#texttrackchange
  15048. * @listens Player#fullscreenchange
  15049. */
  15050. TextTrackDisplay.prototype.updateDisplay = function updateDisplay() {
  15051. var tracks = this.player_.textTracks();
  15052. this.clearDisplay();
  15053. // Track display prioritization model: if multiple tracks are 'showing',
  15054. // display the first 'subtitles' or 'captions' track which is 'showing',
  15055. // otherwise display the first 'descriptions' track which is 'showing'
  15056. var descriptionsTrack = null;
  15057. var captionsSubtitlesTrack = null;
  15058. var i = tracks.length;
  15059. while (i--) {
  15060. var track = tracks[i];
  15061. if (track.mode === 'showing') {
  15062. if (track.kind === 'descriptions') {
  15063. descriptionsTrack = track;
  15064. } else {
  15065. captionsSubtitlesTrack = track;
  15066. }
  15067. }
  15068. }
  15069. if (captionsSubtitlesTrack) {
  15070. if (this.getAttribute('aria-live') !== 'off') {
  15071. this.setAttribute('aria-live', 'off');
  15072. }
  15073. this.updateForTrack(captionsSubtitlesTrack);
  15074. } else if (descriptionsTrack) {
  15075. if (this.getAttribute('aria-live') !== 'assertive') {
  15076. this.setAttribute('aria-live', 'assertive');
  15077. }
  15078. this.updateForTrack(descriptionsTrack);
  15079. }
  15080. };
  15081. /**
  15082. * Add an {@link Texttrack} to to the {@link Tech}s {@link TextTrackList}.
  15083. *
  15084. * @param {TextTrack} track
  15085. * Text track object to be added to the list.
  15086. */
  15087. TextTrackDisplay.prototype.updateForTrack = function updateForTrack(track) {
  15088. if (typeof _window2['default'].WebVTT !== 'function' || !track.activeCues) {
  15089. return;
  15090. }
  15091. var overrides = this.player_.textTrackSettings.getValues();
  15092. var cues = [];
  15093. for (var _i2 = 0; _i2 < track.activeCues.length; _i2++) {
  15094. cues.push(track.activeCues[_i2]);
  15095. }
  15096. _window2['default'].WebVTT.processCues(_window2['default'], cues, this.el_);
  15097. var i = cues.length;
  15098. while (i--) {
  15099. var cue = cues[i];
  15100. if (!cue) {
  15101. continue;
  15102. }
  15103. var cueDiv = cue.displayState;
  15104. if (overrides.color) {
  15105. cueDiv.firstChild.style.color = overrides.color;
  15106. }
  15107. if (overrides.textOpacity) {
  15108. tryUpdateStyle(cueDiv.firstChild, 'color', constructColor(overrides.color || '#fff', overrides.textOpacity));
  15109. }
  15110. if (overrides.backgroundColor) {
  15111. cueDiv.firstChild.style.backgroundColor = overrides.backgroundColor;
  15112. }
  15113. if (overrides.backgroundOpacity) {
  15114. tryUpdateStyle(cueDiv.firstChild, 'backgroundColor', constructColor(overrides.backgroundColor || '#000', overrides.backgroundOpacity));
  15115. }
  15116. if (overrides.windowColor) {
  15117. if (overrides.windowOpacity) {
  15118. tryUpdateStyle(cueDiv, 'backgroundColor', constructColor(overrides.windowColor, overrides.windowOpacity));
  15119. } else {
  15120. cueDiv.style.backgroundColor = overrides.windowColor;
  15121. }
  15122. }
  15123. if (overrides.edgeStyle) {
  15124. if (overrides.edgeStyle === 'dropshadow') {
  15125. cueDiv.firstChild.style.textShadow = '2px 2px 3px ' + darkGray + ', 2px 2px 4px ' + darkGray + ', 2px 2px 5px ' + darkGray;
  15126. } else if (overrides.edgeStyle === 'raised') {
  15127. cueDiv.firstChild.style.textShadow = '1px 1px ' + darkGray + ', 2px 2px ' + darkGray + ', 3px 3px ' + darkGray;
  15128. } else if (overrides.edgeStyle === 'depressed') {
  15129. cueDiv.firstChild.style.textShadow = '1px 1px ' + lightGray + ', 0 1px ' + lightGray + ', -1px -1px ' + darkGray + ', 0 -1px ' + darkGray;
  15130. } else if (overrides.edgeStyle === 'uniform') {
  15131. cueDiv.firstChild.style.textShadow = '0 0 4px ' + darkGray + ', 0 0 4px ' + darkGray + ', 0 0 4px ' + darkGray + ', 0 0 4px ' + darkGray;
  15132. }
  15133. }
  15134. if (overrides.fontPercent && overrides.fontPercent !== 1) {
  15135. var fontSize = _window2['default'].parseFloat(cueDiv.style.fontSize);
  15136. cueDiv.style.fontSize = fontSize * overrides.fontPercent + 'px';
  15137. cueDiv.style.height = 'auto';
  15138. cueDiv.style.top = 'auto';
  15139. cueDiv.style.bottom = '2px';
  15140. }
  15141. if (overrides.fontFamily && overrides.fontFamily !== 'default') {
  15142. if (overrides.fontFamily === 'small-caps') {
  15143. cueDiv.firstChild.style.fontVariant = 'small-caps';
  15144. } else {
  15145. cueDiv.firstChild.style.fontFamily = fontMap[overrides.fontFamily];
  15146. }
  15147. }
  15148. }
  15149. };
  15150. return TextTrackDisplay;
  15151. }(_component2['default']);
  15152. _component2['default'].registerComponent('TextTrackDisplay', TextTrackDisplay);
  15153. exports['default'] = TextTrackDisplay;
  15154. },{"100":100,"5":5,"88":88}],71:[function(_dereq_,module,exports){
  15155. 'use strict';
  15156. exports.__esModule = true;
  15157. /**
  15158. * @file text-track-list-converter.js Utilities for capturing text track state and
  15159. * re-creating tracks based on a capture.
  15160. *
  15161. * @module text-track-list-converter
  15162. */
  15163. /**
  15164. * Examine a single {@link TextTrack} and return a JSON-compatible javascript object that
  15165. * represents the {@link TextTrack}'s state.
  15166. *
  15167. * @param {TextTrack} track
  15168. * The text track to query.
  15169. *
  15170. * @return {Object}
  15171. * A serializable javascript representation of the TextTrack.
  15172. * @private
  15173. */
  15174. var trackToJson_ = function trackToJson_(track) {
  15175. var ret = ['kind', 'label', 'language', 'id', 'inBandMetadataTrackDispatchType', 'mode', 'src'].reduce(function (acc, prop, i) {
  15176. if (track[prop]) {
  15177. acc[prop] = track[prop];
  15178. }
  15179. return acc;
  15180. }, {
  15181. cues: track.cues && Array.prototype.map.call(track.cues, function (cue) {
  15182. return {
  15183. startTime: cue.startTime,
  15184. endTime: cue.endTime,
  15185. text: cue.text,
  15186. id: cue.id
  15187. };
  15188. })
  15189. });
  15190. return ret;
  15191. };
  15192. /**
  15193. * Examine a {@link Tech} and return a JSON-compatible javascript array that represents the
  15194. * state of all {@link TextTrack}s currently configured. The return array is compatible with
  15195. * {@link text-track-list-converter:jsonToTextTracks}.
  15196. *
  15197. * @param {Tech} tech
  15198. * The tech object to query
  15199. *
  15200. * @return {Array}
  15201. * A serializable javascript representation of the {@link Tech}s
  15202. * {@link TextTrackList}.
  15203. */
  15204. var textTracksToJson = function textTracksToJson(tech) {
  15205. var trackEls = tech.$$('track');
  15206. var trackObjs = Array.prototype.map.call(trackEls, function (t) {
  15207. return t.track;
  15208. });
  15209. var tracks = Array.prototype.map.call(trackEls, function (trackEl) {
  15210. var json = trackToJson_(trackEl.track);
  15211. if (trackEl.src) {
  15212. json.src = trackEl.src;
  15213. }
  15214. return json;
  15215. });
  15216. return tracks.concat(Array.prototype.filter.call(tech.textTracks(), function (track) {
  15217. return trackObjs.indexOf(track) === -1;
  15218. }).map(trackToJson_));
  15219. };
  15220. /**
  15221. * Create a set of remote {@link TextTrack}s on a {@link Tech} based on an array of javascript
  15222. * object {@link TextTrack} representations.
  15223. *
  15224. * @param {Array} json
  15225. * An array of `TextTrack` representation objects, like those that would be
  15226. * produced by `textTracksToJson`.
  15227. *
  15228. * @param {Tech} tech
  15229. * The `Tech` to create the `TextTrack`s on.
  15230. */
  15231. var jsonToTextTracks = function jsonToTextTracks(json, tech) {
  15232. json.forEach(function (track) {
  15233. var addedTrack = tech.addRemoteTextTrack(track).track;
  15234. if (!track.src && track.cues) {
  15235. track.cues.forEach(function (cue) {
  15236. return addedTrack.addCue(cue);
  15237. });
  15238. }
  15239. });
  15240. return tech.textTracks();
  15241. };
  15242. exports['default'] = { textTracksToJson: textTracksToJson, jsonToTextTracks: jsonToTextTracks, trackToJson_: trackToJson_ };
  15243. },{}],72:[function(_dereq_,module,exports){
  15244. 'use strict';
  15245. exports.__esModule = true;
  15246. var _trackList = _dereq_(76);
  15247. var _trackList2 = _interopRequireDefault(_trackList);
  15248. var _fn = _dereq_(88);
  15249. var Fn = _interopRequireWildcard(_fn);
  15250. var _browser = _dereq_(81);
  15251. var browser = _interopRequireWildcard(_browser);
  15252. var _document = _dereq_(99);
  15253. var _document2 = _interopRequireDefault(_document);
  15254. function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
  15255. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  15256. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  15257. function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
  15258. function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
  15259. * @file text-track-list.js
  15260. */
  15261. /**
  15262. * The current list of {@link TextTrack} for a media file.
  15263. *
  15264. * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#texttracklist}
  15265. * @extends TrackList
  15266. */
  15267. var TextTrackList = function (_TrackList) {
  15268. _inherits(TextTrackList, _TrackList);
  15269. /**
  15270. * Create an instance of this class.
  15271. *
  15272. * @param {TextTrack[]} [tracks=[]]
  15273. * A list of `TextTrack` to instantiate the list with.
  15274. */
  15275. function TextTrackList() {
  15276. var _this, _ret;
  15277. var tracks = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
  15278. _classCallCheck(this, TextTrackList);
  15279. var list = void 0;
  15280. // IE8 forces us to implement inheritance ourselves
  15281. // as it does not support Object.defineProperty properly
  15282. if (browser.IS_IE8) {
  15283. list = _document2['default'].createElement('custom');
  15284. for (var prop in _trackList2['default'].prototype) {
  15285. if (prop !== 'constructor') {
  15286. list[prop] = _trackList2['default'].prototype[prop];
  15287. }
  15288. }
  15289. for (var _prop in TextTrackList.prototype) {
  15290. if (_prop !== 'constructor') {
  15291. list[_prop] = TextTrackList.prototype[_prop];
  15292. }
  15293. }
  15294. }
  15295. list = (_this = _possibleConstructorReturn(this, _TrackList.call(this, tracks, list)), _this);
  15296. return _ret = list, _possibleConstructorReturn(_this, _ret);
  15297. }
  15298. /**
  15299. * Add a {@link TextTrack} to the `TextTrackList`
  15300. *
  15301. * @param {TextTrack} track
  15302. * The text track to add to the list.
  15303. *
  15304. * @fires TrackList#addtrack
  15305. */
  15306. TextTrackList.prototype.addTrack = function addTrack(track) {
  15307. _TrackList.prototype.addTrack.call(this, track);
  15308. /**
  15309. * @listens TextTrack#modechange
  15310. * @fires TrackList#change
  15311. */
  15312. track.addEventListener('modechange', Fn.bind(this, function () {
  15313. this.trigger('change');
  15314. }));
  15315. };
  15316. return TextTrackList;
  15317. }(_trackList2['default']);
  15318. exports['default'] = TextTrackList;
  15319. },{"76":76,"81":81,"88":88,"99":99}],73:[function(_dereq_,module,exports){
  15320. 'use strict';
  15321. exports.__esModule = true;
  15322. var _window = _dereq_(100);
  15323. var _window2 = _interopRequireDefault(_window);
  15324. var _document = _dereq_(99);
  15325. var _document2 = _interopRequireDefault(_document);
  15326. var _component = _dereq_(5);
  15327. var _component2 = _interopRequireDefault(_component);
  15328. var _modalDialog = _dereq_(55);
  15329. var _modalDialog2 = _interopRequireDefault(_modalDialog);
  15330. var _dom = _dereq_(85);
  15331. var _fn = _dereq_(88);
  15332. var Fn = _interopRequireWildcard(_fn);
  15333. var _obj = _dereq_(93);
  15334. var Obj = _interopRequireWildcard(_obj);
  15335. var _log = _dereq_(91);
  15336. var _log2 = _interopRequireDefault(_log);
  15337. function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
  15338. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  15339. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  15340. function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
  15341. function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
  15342. * @file text-track-settings.js
  15343. */
  15344. var LOCAL_STORAGE_KEY = 'vjs-text-track-settings';
  15345. var COLOR_BLACK = ['#000', 'Black'];
  15346. var COLOR_BLUE = ['#00F', 'Blue'];
  15347. var COLOR_CYAN = ['#0FF', 'Cyan'];
  15348. var COLOR_GREEN = ['#0F0', 'Green'];
  15349. var COLOR_MAGENTA = ['#F0F', 'Magenta'];
  15350. var COLOR_RED = ['#F00', 'Red'];
  15351. var COLOR_WHITE = ['#FFF', 'White'];
  15352. var COLOR_YELLOW = ['#FF0', 'Yellow'];
  15353. var OPACITY_OPAQUE = ['1', 'Opaque'];
  15354. var OPACITY_SEMI = ['0.5', 'Semi-Transparent'];
  15355. var OPACITY_TRANS = ['0', 'Transparent'];
  15356. // Configuration for the various <select> elements in the DOM of this component.
  15357. //
  15358. // Possible keys include:
  15359. //
  15360. // `default`:
  15361. // The default option index. Only needs to be provided if not zero.
  15362. // `parser`:
  15363. // A function which is used to parse the value from the selected option in
  15364. // a customized way.
  15365. // `selector`:
  15366. // The selector used to find the associated <select> element.
  15367. var selectConfigs = {
  15368. backgroundColor: {
  15369. selector: '.vjs-bg-color > select',
  15370. id: 'captions-background-color-%s',
  15371. label: 'Color',
  15372. options: [COLOR_BLACK, COLOR_WHITE, COLOR_RED, COLOR_GREEN, COLOR_BLUE, COLOR_YELLOW, COLOR_MAGENTA, COLOR_CYAN]
  15373. },
  15374. backgroundOpacity: {
  15375. selector: '.vjs-bg-opacity > select',
  15376. id: 'captions-background-opacity-%s',
  15377. label: 'Transparency',
  15378. options: [OPACITY_OPAQUE, OPACITY_SEMI, OPACITY_TRANS]
  15379. },
  15380. color: {
  15381. selector: '.vjs-fg-color > select',
  15382. id: 'captions-foreground-color-%s',
  15383. label: 'Color',
  15384. options: [COLOR_WHITE, COLOR_BLACK, COLOR_RED, COLOR_GREEN, COLOR_BLUE, COLOR_YELLOW, COLOR_MAGENTA, COLOR_CYAN]
  15385. },
  15386. edgeStyle: {
  15387. selector: '.vjs-edge-style > select',
  15388. id: '%s',
  15389. label: 'Text Edge Style',
  15390. options: [['none', 'None'], ['raised', 'Raised'], ['depressed', 'Depressed'], ['uniform', 'Uniform'], ['dropshadow', 'Dropshadow']]
  15391. },
  15392. fontFamily: {
  15393. selector: '.vjs-font-family > select',
  15394. id: 'captions-font-family-%s',
  15395. label: 'Font Family',
  15396. options: [['proportionalSansSerif', 'Proportional Sans-Serif'], ['monospaceSansSerif', 'Monospace Sans-Serif'], ['proportionalSerif', 'Proportional Serif'], ['monospaceSerif', 'Monospace Serif'], ['casual', 'Casual'], ['script', 'Script'], ['small-caps', 'Small Caps']]
  15397. },
  15398. fontPercent: {
  15399. selector: '.vjs-font-percent > select',
  15400. id: 'captions-font-size-%s',
  15401. label: 'Font Size',
  15402. options: [['0.50', '50%'], ['0.75', '75%'], ['1.00', '100%'], ['1.25', '125%'], ['1.50', '150%'], ['1.75', '175%'], ['2.00', '200%'], ['3.00', '300%'], ['4.00', '400%']],
  15403. 'default': 2,
  15404. parser: function parser(v) {
  15405. return v === '1.00' ? null : Number(v);
  15406. }
  15407. },
  15408. textOpacity: {
  15409. selector: '.vjs-text-opacity > select',
  15410. id: 'captions-foreground-opacity-%s',
  15411. label: 'Transparency',
  15412. options: [OPACITY_OPAQUE, OPACITY_SEMI]
  15413. },
  15414. // Options for this object are defined below.
  15415. windowColor: {
  15416. selector: '.vjs-window-color > select',
  15417. id: 'captions-window-color-%s',
  15418. label: 'Color'
  15419. },
  15420. // Options for this object are defined below.
  15421. windowOpacity: {
  15422. selector: '.vjs-window-opacity > select',
  15423. id: 'captions-window-opacity-%s',
  15424. label: 'Transparency',
  15425. options: [OPACITY_TRANS, OPACITY_SEMI, OPACITY_OPAQUE]
  15426. }
  15427. };
  15428. selectConfigs.windowColor.options = selectConfigs.backgroundColor.options;
  15429. /**
  15430. * Get the actual value of an option.
  15431. *
  15432. * @param {string} value
  15433. * The value to get
  15434. *
  15435. * @param {Function} [parser]
  15436. * Optional function to adjust the value.
  15437. *
  15438. * @return {Mixed}
  15439. * - Will be `undefined` if no value exists
  15440. * - Will be `undefined` if the given value is "none".
  15441. * - Will be the actual value otherwise.
  15442. *
  15443. * @private
  15444. */
  15445. function parseOptionValue(value, parser) {
  15446. if (parser) {
  15447. value = parser(value);
  15448. }
  15449. if (value && value !== 'none') {
  15450. return value;
  15451. }
  15452. }
  15453. /**
  15454. * Gets the value of the selected <option> element within a <select> element.
  15455. *
  15456. * @param {Element} el
  15457. * the element to look in
  15458. *
  15459. * @param {Function} [parser]
  15460. * Optional function to adjust the value.
  15461. *
  15462. * @return {Mixed}
  15463. * - Will be `undefined` if no value exists
  15464. * - Will be `undefined` if the given value is "none".
  15465. * - Will be the actual value otherwise.
  15466. *
  15467. * @private
  15468. */
  15469. function getSelectedOptionValue(el, parser) {
  15470. var value = el.options[el.options.selectedIndex].value;
  15471. return parseOptionValue(value, parser);
  15472. }
  15473. /**
  15474. * Sets the selected <option> element within a <select> element based on a
  15475. * given value.
  15476. *
  15477. * @param {Element} el
  15478. * The element to look in.
  15479. *
  15480. * @param {string} value
  15481. * the property to look on.
  15482. *
  15483. * @param {Function} [parser]
  15484. * Optional function to adjust the value before comparing.
  15485. *
  15486. * @private
  15487. */
  15488. function setSelectedOption(el, value, parser) {
  15489. if (!value) {
  15490. return;
  15491. }
  15492. for (var i = 0; i < el.options.length; i++) {
  15493. if (parseOptionValue(el.options[i].value, parser) === value) {
  15494. el.selectedIndex = i;
  15495. break;
  15496. }
  15497. }
  15498. }
  15499. /**
  15500. * Manipulate Text Tracks settings.
  15501. *
  15502. * @extends ModalDialog
  15503. */
  15504. var TextTrackSettings = function (_ModalDialog) {
  15505. _inherits(TextTrackSettings, _ModalDialog);
  15506. /**
  15507. * Creates an instance of this class.
  15508. *
  15509. * @param {Player} player
  15510. * The `Player` that this class should be attached to.
  15511. *
  15512. * @param {Object} [options]
  15513. * The key/value store of player options.
  15514. */
  15515. function TextTrackSettings(player, options) {
  15516. _classCallCheck(this, TextTrackSettings);
  15517. options.temporary = false;
  15518. var _this = _possibleConstructorReturn(this, _ModalDialog.call(this, player, options));
  15519. _this.contentEl().className += ' vjs-caption-settings';
  15520. _this.updateDisplay = Fn.bind(_this, _this.updateDisplay);
  15521. // fill the modal and pretend we have opened it
  15522. _this.fill();
  15523. _this.hasBeenOpened_ = _this.hasBeenFilled_ = true;
  15524. _this.endDialog = (0, _dom.createEl)('p', {
  15525. className: 'vjs-control-text',
  15526. textContent: _this.localize('End of dialog window.')
  15527. });
  15528. _this.el().appendChild(_this.endDialog);
  15529. _this.setDefaults();
  15530. // Grab `persistTextTrackSettings` from the player options if not passed in child options
  15531. if (options.persistTextTrackSettings === undefined) {
  15532. _this.options_.persistTextTrackSettings = _this.options_.playerOptions.persistTextTrackSettings;
  15533. }
  15534. _this.on(_this.$('.vjs-done-button'), 'click', function () {
  15535. _this.saveSettings();
  15536. _this.close();
  15537. });
  15538. _this.on(_this.$('.vjs-default-button'), 'click', function () {
  15539. _this.setDefaults();
  15540. _this.updateDisplay();
  15541. });
  15542. Obj.each(selectConfigs, function (config) {
  15543. _this.on(_this.$(config.selector), 'change', _this.updateDisplay);
  15544. });
  15545. if (_this.options_.persistTextTrackSettings) {
  15546. _this.restoreSettings();
  15547. }
  15548. return _this;
  15549. }
  15550. /**
  15551. * Create a <select> element with configured options.
  15552. *
  15553. * @param {string} key
  15554. * Configuration key to use during creation.
  15555. *
  15556. * @return {Element}
  15557. * The DOM element that gets created.
  15558. * @private
  15559. */
  15560. TextTrackSettings.prototype.createElSelect_ = function createElSelect_(key) {
  15561. var _this2 = this;
  15562. var legendId = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
  15563. var config = selectConfigs[key];
  15564. var id = config.id.replace('%s', this.id_);
  15565. return [(0, _dom.createEl)('label', {
  15566. id: id,
  15567. className: 'vjs-label',
  15568. textContent: this.localize(config.label)
  15569. }, {}), (0, _dom.createEl)('select', {}, {
  15570. 'aria-labelledby': legendId + ' ' + id
  15571. }, config.options.map(function (o) {
  15572. var optionId = id + '-' + o[1];
  15573. return (0, _dom.createEl)('option', {
  15574. id: optionId,
  15575. textContent: _this2.localize(o[1]),
  15576. value: o[0]
  15577. }, {
  15578. 'aria-labelledby': legendId + ' ' + id + ' ' + optionId
  15579. });
  15580. }))];
  15581. };
  15582. /**
  15583. * Create foreground color element for the component
  15584. *
  15585. * @return {Element}
  15586. * The element that was created.
  15587. *
  15588. * @private
  15589. */
  15590. TextTrackSettings.prototype.createElFgColor_ = function createElFgColor_() {
  15591. var legend = (0, _dom.createEl)('legend', {
  15592. id: 'captions-text-legend-' + this.id_,
  15593. textContent: this.localize('Text')
  15594. });
  15595. var select = this.createElSelect_('color', legend.id);
  15596. var opacity = (0, _dom.createEl)('span', {
  15597. className: 'vjs-text-opacity vjs-opacity'
  15598. }, undefined, this.createElSelect_('textOpacity', legend.id));
  15599. return (0, _dom.createEl)('fieldset', {
  15600. className: 'vjs-fg-color vjs-tracksetting'
  15601. }, undefined, [legend].concat(select, opacity));
  15602. };
  15603. /**
  15604. * Create background color element for the component
  15605. *
  15606. * @return {Element}
  15607. * The element that was created
  15608. *
  15609. * @private
  15610. */
  15611. TextTrackSettings.prototype.createElBgColor_ = function createElBgColor_() {
  15612. var legend = (0, _dom.createEl)('legend', {
  15613. id: 'captions-background-' + this.id_,
  15614. textContent: this.localize('Background')
  15615. });
  15616. var select = this.createElSelect_('backgroundColor', legend.id);
  15617. var opacity = (0, _dom.createEl)('span', {
  15618. className: 'vjs-bg-opacity vjs-opacity'
  15619. }, undefined, this.createElSelect_('backgroundOpacity', legend.id));
  15620. return (0, _dom.createEl)('fieldset', {
  15621. className: 'vjs-bg-color vjs-tracksetting'
  15622. }, undefined, [legend].concat(select, opacity));
  15623. };
  15624. /**
  15625. * Create window color element for the component
  15626. *
  15627. * @return {Element}
  15628. * The element that was created
  15629. *
  15630. * @private
  15631. */
  15632. TextTrackSettings.prototype.createElWinColor_ = function createElWinColor_() {
  15633. var legend = (0, _dom.createEl)('legend', {
  15634. id: 'captions-window-' + this.id_,
  15635. textContent: this.localize('Window')
  15636. });
  15637. var select = this.createElSelect_('windowColor', legend.id);
  15638. var opacity = (0, _dom.createEl)('span', {
  15639. className: 'vjs-window-opacity vjs-opacity'
  15640. }, undefined, this.createElSelect_('windowOpacity', legend.id));
  15641. return (0, _dom.createEl)('fieldset', {
  15642. className: 'vjs-window-color vjs-tracksetting'
  15643. }, undefined, [legend].concat(select, opacity));
  15644. };
  15645. /**
  15646. * Create color elements for the component
  15647. *
  15648. * @return {Element}
  15649. * The element that was created
  15650. *
  15651. * @private
  15652. */
  15653. TextTrackSettings.prototype.createElColors_ = function createElColors_() {
  15654. return (0, _dom.createEl)('div', {
  15655. className: 'vjs-tracksettings-colors'
  15656. }, undefined, [this.createElFgColor_(), this.createElBgColor_(), this.createElWinColor_()]);
  15657. };
  15658. /**
  15659. * Create font elements for the component
  15660. *
  15661. * @return {Element}
  15662. * The element that was created.
  15663. *
  15664. * @private
  15665. */
  15666. TextTrackSettings.prototype.createElFont_ = function createElFont_() {
  15667. var fontPercent = (0, _dom.createEl)('div', {
  15668. className: 'vjs-font-percent vjs-tracksetting'
  15669. }, undefined, this.createElSelect_('fontPercent'));
  15670. var edgeStyle = (0, _dom.createEl)('div', {
  15671. className: 'vjs-edge-style vjs-tracksetting'
  15672. }, undefined, this.createElSelect_('edgeStyle'));
  15673. var fontFamily = (0, _dom.createEl)('div', {
  15674. className: 'vjs-font-family vjs-tracksetting'
  15675. }, undefined, this.createElSelect_('fontFamily'));
  15676. return (0, _dom.createEl)('div', {
  15677. className: 'vjs-tracksettings-font'
  15678. }, undefined, [fontPercent, edgeStyle, fontFamily]);
  15679. };
  15680. /**
  15681. * Create controls for the component
  15682. *
  15683. * @return {Element}
  15684. * The element that was created.
  15685. *
  15686. * @private
  15687. */
  15688. TextTrackSettings.prototype.createElControls_ = function createElControls_() {
  15689. var defaultsDescription = this.localize('restore all settings to the default values');
  15690. var defaultsButton = (0, _dom.createEl)('button', {
  15691. className: 'vjs-default-button',
  15692. title: defaultsDescription,
  15693. innerHTML: this.localize('Reset') + '<span class=\'vjs-control-text\'> ' + defaultsDescription + '</span>'
  15694. });
  15695. var doneButton = (0, _dom.createEl)('button', {
  15696. className: 'vjs-done-button',
  15697. textContent: this.localize('Done')
  15698. });
  15699. return (0, _dom.createEl)('div', {
  15700. className: 'vjs-tracksettings-controls'
  15701. }, undefined, [defaultsButton, doneButton]);
  15702. };
  15703. /**
  15704. * Create the component's DOM element
  15705. *
  15706. * @return {Element}
  15707. * The element that was created.
  15708. */
  15709. TextTrackSettings.prototype.createEl = function createEl() {
  15710. return _ModalDialog.prototype.createEl.call(this);
  15711. };
  15712. TextTrackSettings.prototype.content = function content() {
  15713. var settings = (0, _dom.createEl)('div', {
  15714. className: 'vjs-tracksettings'
  15715. }, undefined, [this.createElColors_(), this.createElFont_(), this.createElControls_()]);
  15716. return settings;
  15717. };
  15718. TextTrackSettings.prototype.label = function label() {
  15719. return this.localize('Caption Settings Dialog');
  15720. };
  15721. TextTrackSettings.prototype.description = function description() {
  15722. return this.localize('Beginning of dialog window. Escape will cancel and close the window.');
  15723. };
  15724. TextTrackSettings.prototype.buildCSSClass = function buildCSSClass() {
  15725. return _ModalDialog.prototype.buildCSSClass.call(this) + ' vjs-text-track-settings';
  15726. };
  15727. /**
  15728. * Gets an object of text track settings (or null).
  15729. *
  15730. * @return {Object}
  15731. * An object with config values parsed from the DOM or localStorage.
  15732. */
  15733. TextTrackSettings.prototype.getValues = function getValues() {
  15734. var _this3 = this;
  15735. return Obj.reduce(selectConfigs, function (accum, config, key) {
  15736. var value = getSelectedOptionValue(_this3.$(config.selector), config.parser);
  15737. if (value !== undefined) {
  15738. accum[key] = value;
  15739. }
  15740. return accum;
  15741. }, {});
  15742. };
  15743. /**
  15744. * Sets text track settings from an object of values.
  15745. *
  15746. * @param {Object} values
  15747. * An object with config values parsed from the DOM or localStorage.
  15748. */
  15749. TextTrackSettings.prototype.setValues = function setValues(values) {
  15750. var _this4 = this;
  15751. Obj.each(selectConfigs, function (config, key) {
  15752. setSelectedOption(_this4.$(config.selector), values[key], config.parser);
  15753. });
  15754. };
  15755. /**
  15756. * Sets all `<select>` elements to their default values.
  15757. */
  15758. TextTrackSettings.prototype.setDefaults = function setDefaults() {
  15759. var _this5 = this;
  15760. Obj.each(selectConfigs, function (config) {
  15761. var index = config.hasOwnProperty('default') ? config['default'] : 0;
  15762. _this5.$(config.selector).selectedIndex = index;
  15763. });
  15764. };
  15765. /**
  15766. * Restore texttrack settings from localStorage
  15767. */
  15768. TextTrackSettings.prototype.restoreSettings = function restoreSettings() {
  15769. var values = void 0;
  15770. try {
  15771. values = JSON.parse(_window2['default'].localStorage.getItem(LOCAL_STORAGE_KEY));
  15772. } catch (err) {
  15773. _log2['default'].warn(err);
  15774. }
  15775. if (values) {
  15776. this.setValues(values);
  15777. }
  15778. };
  15779. /**
  15780. * Save text track settings to localStorage
  15781. */
  15782. TextTrackSettings.prototype.saveSettings = function saveSettings() {
  15783. if (!this.options_.persistTextTrackSettings) {
  15784. return;
  15785. }
  15786. var values = this.getValues();
  15787. try {
  15788. if (Object.keys(values).length) {
  15789. _window2['default'].localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(values));
  15790. } else {
  15791. _window2['default'].localStorage.removeItem(LOCAL_STORAGE_KEY);
  15792. }
  15793. } catch (err) {
  15794. _log2['default'].warn(err);
  15795. }
  15796. };
  15797. /**
  15798. * Update display of text track settings
  15799. */
  15800. TextTrackSettings.prototype.updateDisplay = function updateDisplay() {
  15801. var ttDisplay = this.player_.getChild('textTrackDisplay');
  15802. if (ttDisplay) {
  15803. ttDisplay.updateDisplay();
  15804. }
  15805. };
  15806. /**
  15807. * conditionally blur the element and refocus the captions button
  15808. *
  15809. * @private
  15810. */
  15811. TextTrackSettings.prototype.conditionalBlur_ = function conditionalBlur_() {
  15812. this.previouslyActiveEl_ = null;
  15813. this.off(_document2['default'], 'keydown', this.handleKeyDown);
  15814. var cb = this.player_.controlBar;
  15815. var subsCapsBtn = cb && cb.subsCapsButton;
  15816. var ccBtn = cb && cb.captionsButton;
  15817. if (subsCapsBtn) {
  15818. subsCapsBtn.focus();
  15819. } else if (ccBtn) {
  15820. ccBtn.focus();
  15821. }
  15822. };
  15823. return TextTrackSettings;
  15824. }(_modalDialog2['default']);
  15825. _component2['default'].registerComponent('TextTrackSettings', TextTrackSettings);
  15826. exports['default'] = TextTrackSettings;
  15827. },{"100":100,"5":5,"55":55,"85":85,"88":88,"91":91,"93":93,"99":99}],74:[function(_dereq_,module,exports){
  15828. 'use strict';
  15829. exports.__esModule = true;
  15830. var _textTrackCueList = _dereq_(69);
  15831. var _textTrackCueList2 = _interopRequireDefault(_textTrackCueList);
  15832. var _fn = _dereq_(88);
  15833. var Fn = _interopRequireWildcard(_fn);
  15834. var _trackEnums = _dereq_(75);
  15835. var _log = _dereq_(91);
  15836. var _log2 = _interopRequireDefault(_log);
  15837. var _window = _dereq_(100);
  15838. var _window2 = _interopRequireDefault(_window);
  15839. var _track = _dereq_(78);
  15840. var _track2 = _interopRequireDefault(_track);
  15841. var _url = _dereq_(97);
  15842. var _xhr = _dereq_(104);
  15843. var _xhr2 = _interopRequireDefault(_xhr);
  15844. var _mergeOptions = _dereq_(92);
  15845. var _mergeOptions2 = _interopRequireDefault(_mergeOptions);
  15846. var _browser = _dereq_(81);
  15847. var browser = _interopRequireWildcard(_browser);
  15848. function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
  15849. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  15850. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  15851. function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
  15852. function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
  15853. * @file text-track.js
  15854. */
  15855. /**
  15856. * Takes a webvtt file contents and parses it into cues
  15857. *
  15858. * @param {string} srcContent
  15859. * webVTT file contents
  15860. *
  15861. * @param {TextTrack} track
  15862. * TextTrack to add cues to. Cues come from the srcContent.
  15863. *
  15864. * @private
  15865. */
  15866. var parseCues = function parseCues(srcContent, track) {
  15867. var parser = new _window2['default'].WebVTT.Parser(_window2['default'], _window2['default'].vttjs, _window2['default'].WebVTT.StringDecoder());
  15868. var errors = [];
  15869. parser.oncue = function (cue) {
  15870. track.addCue(cue);
  15871. };
  15872. parser.onparsingerror = function (error) {
  15873. errors.push(error);
  15874. };
  15875. parser.onflush = function () {
  15876. track.trigger({
  15877. type: 'loadeddata',
  15878. target: track
  15879. });
  15880. };
  15881. parser.parse(srcContent);
  15882. if (errors.length > 0) {
  15883. if (_window2['default'].console && _window2['default'].console.groupCollapsed) {
  15884. _window2['default'].console.groupCollapsed('Text Track parsing errors for ' + track.src);
  15885. }
  15886. errors.forEach(function (error) {
  15887. return _log2['default'].error(error);
  15888. });
  15889. if (_window2['default'].console && _window2['default'].console.groupEnd) {
  15890. _window2['default'].console.groupEnd();
  15891. }
  15892. }
  15893. parser.flush();
  15894. };
  15895. /**
  15896. * Load a `TextTrack` from a specifed url.
  15897. *
  15898. * @param {string} src
  15899. * Url to load track from.
  15900. *
  15901. * @param {TextTrack} track
  15902. * Track to add cues to. Comes from the content at the end of `url`.
  15903. *
  15904. * @private
  15905. */
  15906. var loadTrack = function loadTrack(src, track) {
  15907. var opts = {
  15908. uri: src
  15909. };
  15910. var crossOrigin = (0, _url.isCrossOrigin)(src);
  15911. if (crossOrigin) {
  15912. opts.cors = crossOrigin;
  15913. }
  15914. (0, _xhr2['default'])(opts, Fn.bind(this, function (err, response, responseBody) {
  15915. if (err) {
  15916. return _log2['default'].error(err, response);
  15917. }
  15918. track.loaded_ = true;
  15919. // Make sure that vttjs has loaded, otherwise, wait till it finished loading
  15920. // NOTE: this is only used for the alt/video.novtt.js build
  15921. if (typeof _window2['default'].WebVTT !== 'function') {
  15922. if (track.tech_) {
  15923. var loadHandler = function loadHandler() {
  15924. return parseCues(responseBody, track);
  15925. };
  15926. track.tech_.on('vttjsloaded', loadHandler);
  15927. track.tech_.on('vttjserror', function () {
  15928. _log2['default'].error('vttjs failed to load, stopping trying to process ' + track.src);
  15929. track.tech_.off('vttjsloaded', loadHandler);
  15930. });
  15931. }
  15932. } else {
  15933. parseCues(responseBody, track);
  15934. }
  15935. }));
  15936. };
  15937. /**
  15938. * A representation of a single `TextTrack`.
  15939. *
  15940. * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#texttrack}
  15941. * @extends Track
  15942. */
  15943. var TextTrack = function (_Track) {
  15944. _inherits(TextTrack, _Track);
  15945. /**
  15946. * Create an instance of this class.
  15947. *
  15948. * @param {Object} options={}
  15949. * Object of option names and values
  15950. *
  15951. * @param {Tech} options.tech
  15952. * A reference to the tech that owns this TextTrack.
  15953. *
  15954. * @param {TextTrack~Kind} [options.kind='subtitles']
  15955. * A valid text track kind.
  15956. *
  15957. * @param {TextTrack~Mode} [options.mode='disabled']
  15958. * A valid text track mode.
  15959. *
  15960. * @param {string} [options.id='vjs_track_' + Guid.newGUID()]
  15961. * A unique id for this TextTrack.
  15962. *
  15963. * @param {string} [options.label='']
  15964. * The menu label for this track.
  15965. *
  15966. * @param {string} [options.language='']
  15967. * A valid two character language code.
  15968. *
  15969. * @param {string} [options.srclang='']
  15970. * A valid two character language code. An alternative, but deprioritized
  15971. * vesion of `options.language`
  15972. *
  15973. * @param {string} [options.src]
  15974. * A url to TextTrack cues.
  15975. *
  15976. * @param {boolean} [options.default]
  15977. * If this track should default to on or off.
  15978. */
  15979. function TextTrack() {
  15980. var _this, _ret;
  15981. var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  15982. _classCallCheck(this, TextTrack);
  15983. if (!options.tech) {
  15984. throw new Error('A tech was not provided.');
  15985. }
  15986. var settings = (0, _mergeOptions2['default'])(options, {
  15987. kind: _trackEnums.TextTrackKind[options.kind] || 'subtitles',
  15988. language: options.language || options.srclang || ''
  15989. });
  15990. var mode = _trackEnums.TextTrackMode[settings.mode] || 'disabled';
  15991. var default_ = settings['default'];
  15992. if (settings.kind === 'metadata' || settings.kind === 'chapters') {
  15993. mode = 'hidden';
  15994. }
  15995. // on IE8 this will be a document element
  15996. // for every other browser this will be a normal object
  15997. var tt = (_this = _possibleConstructorReturn(this, _Track.call(this, settings)), _this);
  15998. tt.tech_ = settings.tech;
  15999. if (browser.IS_IE8) {
  16000. for (var prop in TextTrack.prototype) {
  16001. if (prop !== 'constructor') {
  16002. tt[prop] = TextTrack.prototype[prop];
  16003. }
  16004. }
  16005. }
  16006. tt.cues_ = [];
  16007. tt.activeCues_ = [];
  16008. var cues = new _textTrackCueList2['default'](tt.cues_);
  16009. var activeCues = new _textTrackCueList2['default'](tt.activeCues_);
  16010. var changed = false;
  16011. var timeupdateHandler = Fn.bind(tt, function () {
  16012. // Accessing this.activeCues for the side-effects of updating itself
  16013. // due to it's nature as a getter function. Do not remove or cues will
  16014. // stop updating!
  16015. /* eslint-disable no-unused-expressions */
  16016. this.activeCues;
  16017. /* eslint-enable no-unused-expressions */
  16018. if (changed) {
  16019. this.trigger('cuechange');
  16020. changed = false;
  16021. }
  16022. });
  16023. if (mode !== 'disabled') {
  16024. tt.tech_.ready(function () {
  16025. tt.tech_.on('timeupdate', timeupdateHandler);
  16026. }, true);
  16027. }
  16028. /**
  16029. * @memberof TextTrack
  16030. * @member {boolean} default
  16031. * If this track was set to be on or off by default. Cannot be changed after
  16032. * creation.
  16033. * @instance
  16034. *
  16035. * @readonly
  16036. */
  16037. Object.defineProperty(tt, 'default', {
  16038. get: function get() {
  16039. return default_;
  16040. },
  16041. set: function set() {}
  16042. });
  16043. /**
  16044. * @memberof TextTrack
  16045. * @member {string} mode
  16046. * Set the mode of this TextTrack to a valid {@link TextTrack~Mode}. Will
  16047. * not be set if setting to an invalid mode.
  16048. * @instance
  16049. *
  16050. * @fires TextTrack#modechange
  16051. */
  16052. Object.defineProperty(tt, 'mode', {
  16053. get: function get() {
  16054. return mode;
  16055. },
  16056. set: function set(newMode) {
  16057. var _this2 = this;
  16058. if (!_trackEnums.TextTrackMode[newMode]) {
  16059. return;
  16060. }
  16061. mode = newMode;
  16062. if (mode === 'showing') {
  16063. this.tech_.ready(function () {
  16064. _this2.tech_.on('timeupdate', timeupdateHandler);
  16065. }, true);
  16066. }
  16067. /**
  16068. * An event that fires when mode changes on this track. This allows
  16069. * the TextTrackList that holds this track to act accordingly.
  16070. *
  16071. * > Note: This is not part of the spec!
  16072. *
  16073. * @event TextTrack#modechange
  16074. * @type {EventTarget~Event}
  16075. */
  16076. this.trigger('modechange');
  16077. }
  16078. });
  16079. /**
  16080. * @memberof TextTrack
  16081. * @member {TextTrackCueList} cues
  16082. * The text track cue list for this TextTrack.
  16083. * @instance
  16084. */
  16085. Object.defineProperty(tt, 'cues', {
  16086. get: function get() {
  16087. if (!this.loaded_) {
  16088. return null;
  16089. }
  16090. return cues;
  16091. },
  16092. set: function set() {}
  16093. });
  16094. /**
  16095. * @memberof TextTrack
  16096. * @member {TextTrackCueList} activeCues
  16097. * The list text track cues that are currently active for this TextTrack.
  16098. * @instance
  16099. */
  16100. Object.defineProperty(tt, 'activeCues', {
  16101. get: function get() {
  16102. if (!this.loaded_) {
  16103. return null;
  16104. }
  16105. // nothing to do
  16106. if (this.cues.length === 0) {
  16107. return activeCues;
  16108. }
  16109. var ct = this.tech_.currentTime();
  16110. var active = [];
  16111. for (var i = 0, l = this.cues.length; i < l; i++) {
  16112. var cue = this.cues[i];
  16113. if (cue.startTime <= ct && cue.endTime >= ct) {
  16114. active.push(cue);
  16115. } else if (cue.startTime === cue.endTime && cue.startTime <= ct && cue.startTime + 0.5 >= ct) {
  16116. active.push(cue);
  16117. }
  16118. }
  16119. changed = false;
  16120. if (active.length !== this.activeCues_.length) {
  16121. changed = true;
  16122. } else {
  16123. for (var _i = 0; _i < active.length; _i++) {
  16124. if (this.activeCues_.indexOf(active[_i]) === -1) {
  16125. changed = true;
  16126. }
  16127. }
  16128. }
  16129. this.activeCues_ = active;
  16130. activeCues.setCues_(this.activeCues_);
  16131. return activeCues;
  16132. },
  16133. set: function set() {}
  16134. });
  16135. if (settings.src) {
  16136. tt.src = settings.src;
  16137. loadTrack(settings.src, tt);
  16138. } else {
  16139. tt.loaded_ = true;
  16140. }
  16141. return _ret = tt, _possibleConstructorReturn(_this, _ret);
  16142. }
  16143. /**
  16144. * Add a cue to the internal list of cues.
  16145. *
  16146. * @param {TextTrack~Cue} cue
  16147. * The cue to add to our internal list
  16148. */
  16149. TextTrack.prototype.addCue = function addCue(originalCue) {
  16150. var cue = originalCue;
  16151. if (_window2['default'].vttjs && !(originalCue instanceof _window2['default'].vttjs.VTTCue)) {
  16152. cue = new _window2['default'].vttjs.VTTCue(originalCue.startTime, originalCue.endTime, originalCue.text);
  16153. for (var prop in originalCue) {
  16154. if (!(prop in cue)) {
  16155. cue[prop] = originalCue[prop];
  16156. }
  16157. }
  16158. // make sure that `id` is copied over
  16159. cue.id = originalCue.id;
  16160. }
  16161. var tracks = this.tech_.textTracks();
  16162. for (var i = 0; i < tracks.length; i++) {
  16163. if (tracks[i] !== this) {
  16164. tracks[i].removeCue(cue);
  16165. }
  16166. }
  16167. this.cues_.push(cue);
  16168. this.cues.setCues_(this.cues_);
  16169. };
  16170. /**
  16171. * Remove a cue from our internal list
  16172. *
  16173. * @param {TextTrack~Cue} removeCue
  16174. * The cue to remove from our internal list
  16175. */
  16176. TextTrack.prototype.removeCue = function removeCue(_removeCue) {
  16177. var removed = false;
  16178. for (var i = 0, l = this.cues_.length; i < l; i++) {
  16179. var cue = this.cues_[i];
  16180. if (cue === _removeCue) {
  16181. this.cues_.splice(i, 1);
  16182. removed = true;
  16183. }
  16184. }
  16185. if (removed) {
  16186. this.cues.setCues_(this.cues_);
  16187. }
  16188. };
  16189. return TextTrack;
  16190. }(_track2['default']);
  16191. /**
  16192. * cuechange - One or more cues in the track have become active or stopped being active.
  16193. */
  16194. TextTrack.prototype.allowedEvents_ = {
  16195. cuechange: 'cuechange'
  16196. };
  16197. exports['default'] = TextTrack;
  16198. },{"100":100,"104":104,"69":69,"75":75,"78":78,"81":81,"88":88,"91":91,"92":92,"97":97}],75:[function(_dereq_,module,exports){
  16199. 'use strict';
  16200. exports.__esModule = true;
  16201. /**
  16202. * @file track-kinds.js
  16203. */
  16204. /**
  16205. * All possible `VideoTrackKind`s
  16206. *
  16207. * @see https://html.spec.whatwg.org/multipage/embedded-content.html#dom-videotrack-kind
  16208. * @typedef VideoTrack~Kind
  16209. * @enum
  16210. */
  16211. var VideoTrackKind = exports.VideoTrackKind = {
  16212. alternative: 'alternative',
  16213. captions: 'captions',
  16214. main: 'main',
  16215. sign: 'sign',
  16216. subtitles: 'subtitles',
  16217. commentary: 'commentary'
  16218. };
  16219. /**
  16220. * All possible `AudioTrackKind`s
  16221. *
  16222. * @see https://html.spec.whatwg.org/multipage/embedded-content.html#dom-audiotrack-kind
  16223. * @typedef AudioTrack~Kind
  16224. * @enum
  16225. */
  16226. var AudioTrackKind = exports.AudioTrackKind = {
  16227. 'alternative': 'alternative',
  16228. 'descriptions': 'descriptions',
  16229. 'main': 'main',
  16230. 'main-desc': 'main-desc',
  16231. 'translation': 'translation',
  16232. 'commentary': 'commentary'
  16233. };
  16234. /**
  16235. * All possible `TextTrackKind`s
  16236. *
  16237. * @see https://html.spec.whatwg.org/multipage/embedded-content.html#dom-texttrack-kind
  16238. * @typedef TextTrack~Kind
  16239. * @enum
  16240. */
  16241. var TextTrackKind = exports.TextTrackKind = {
  16242. subtitles: 'subtitles',
  16243. captions: 'captions',
  16244. descriptions: 'descriptions',
  16245. chapters: 'chapters',
  16246. metadata: 'metadata'
  16247. };
  16248. /**
  16249. * All possible `TextTrackMode`s
  16250. *
  16251. * @see https://html.spec.whatwg.org/multipage/embedded-content.html#texttrackmode
  16252. * @typedef TextTrack~Mode
  16253. * @enum
  16254. */
  16255. var TextTrackMode = exports.TextTrackMode = {
  16256. disabled: 'disabled',
  16257. hidden: 'hidden',
  16258. showing: 'showing'
  16259. };
  16260. },{}],76:[function(_dereq_,module,exports){
  16261. 'use strict';
  16262. exports.__esModule = true;
  16263. var _eventTarget = _dereq_(45);
  16264. var _eventTarget2 = _interopRequireDefault(_eventTarget);
  16265. var _browser = _dereq_(81);
  16266. var browser = _interopRequireWildcard(_browser);
  16267. var _document = _dereq_(99);
  16268. var _document2 = _interopRequireDefault(_document);
  16269. function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
  16270. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  16271. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  16272. function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
  16273. function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
  16274. * @file track-list.js
  16275. */
  16276. /**
  16277. * Common functionaliy between {@link TextTrackList}, {@link AudioTrackList}, and
  16278. * {@link VideoTrackList}
  16279. *
  16280. * @extends EventTarget
  16281. */
  16282. var TrackList = function (_EventTarget) {
  16283. _inherits(TrackList, _EventTarget);
  16284. /**
  16285. * Create an instance of this class
  16286. *
  16287. * @param {Track[]} tracks
  16288. * A list of tracks to initialize the list with.
  16289. *
  16290. * @param {Object} [list]
  16291. * The child object with inheritance done manually for ie8.
  16292. *
  16293. * @abstract
  16294. */
  16295. function TrackList() {
  16296. var tracks = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
  16297. var _ret;
  16298. var list = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
  16299. _classCallCheck(this, TrackList);
  16300. var _this = _possibleConstructorReturn(this, _EventTarget.call(this));
  16301. if (!list) {
  16302. list = _this; // eslint-disable-line
  16303. if (browser.IS_IE8) {
  16304. list = _document2['default'].createElement('custom');
  16305. for (var prop in TrackList.prototype) {
  16306. if (prop !== 'constructor') {
  16307. list[prop] = TrackList.prototype[prop];
  16308. }
  16309. }
  16310. }
  16311. }
  16312. list.tracks_ = [];
  16313. /**
  16314. * @memberof TrackList
  16315. * @member {number} length
  16316. * The current number of `Track`s in the this Trackist.
  16317. * @instance
  16318. */
  16319. Object.defineProperty(list, 'length', {
  16320. get: function get() {
  16321. return this.tracks_.length;
  16322. }
  16323. });
  16324. for (var i = 0; i < tracks.length; i++) {
  16325. list.addTrack(tracks[i]);
  16326. }
  16327. // must return the object, as for ie8 it will not be this
  16328. // but a reference to a document object
  16329. return _ret = list, _possibleConstructorReturn(_this, _ret);
  16330. }
  16331. /**
  16332. * Add a {@link Track} to the `TrackList`
  16333. *
  16334. * @param {Track} track
  16335. * The audio, video, or text track to add to the list.
  16336. *
  16337. * @fires TrackList#addtrack
  16338. */
  16339. TrackList.prototype.addTrack = function addTrack(track) {
  16340. var index = this.tracks_.length;
  16341. if (!('' + index in this)) {
  16342. Object.defineProperty(this, index, {
  16343. get: function get() {
  16344. return this.tracks_[index];
  16345. }
  16346. });
  16347. }
  16348. // Do not add duplicate tracks
  16349. if (this.tracks_.indexOf(track) === -1) {
  16350. this.tracks_.push(track);
  16351. /**
  16352. * Triggered when a track is added to a track list.
  16353. *
  16354. * @event TrackList#addtrack
  16355. * @type {EventTarget~Event}
  16356. * @property {Track} track
  16357. * A reference to track that was added.
  16358. */
  16359. this.trigger({
  16360. track: track,
  16361. type: 'addtrack'
  16362. });
  16363. }
  16364. };
  16365. /**
  16366. * Remove a {@link Track} from the `TrackList`
  16367. *
  16368. * @param {Track} rtrack
  16369. * The audio, video, or text track to remove from the list.
  16370. *
  16371. * @fires TrackList#removetrack
  16372. */
  16373. TrackList.prototype.removeTrack = function removeTrack(rtrack) {
  16374. var track = void 0;
  16375. for (var i = 0, l = this.length; i < l; i++) {
  16376. if (this[i] === rtrack) {
  16377. track = this[i];
  16378. if (track.off) {
  16379. track.off();
  16380. }
  16381. this.tracks_.splice(i, 1);
  16382. break;
  16383. }
  16384. }
  16385. if (!track) {
  16386. return;
  16387. }
  16388. /**
  16389. * Triggered when a track is removed from track list.
  16390. *
  16391. * @event TrackList#removetrack
  16392. * @type {EventTarget~Event}
  16393. * @property {Track} track
  16394. * A reference to track that was removed.
  16395. */
  16396. this.trigger({
  16397. track: track,
  16398. type: 'removetrack'
  16399. });
  16400. };
  16401. /**
  16402. * Get a Track from the TrackList by a tracks id
  16403. *
  16404. * @param {String} id - the id of the track to get
  16405. * @method getTrackById
  16406. * @return {Track}
  16407. * @private
  16408. */
  16409. TrackList.prototype.getTrackById = function getTrackById(id) {
  16410. var result = null;
  16411. for (var i = 0, l = this.length; i < l; i++) {
  16412. var track = this[i];
  16413. if (track.id === id) {
  16414. result = track;
  16415. break;
  16416. }
  16417. }
  16418. return result;
  16419. };
  16420. return TrackList;
  16421. }(_eventTarget2['default']);
  16422. /**
  16423. * Triggered when a different track is selected/enabled.
  16424. *
  16425. * @event TrackList#change
  16426. * @type {EventTarget~Event}
  16427. */
  16428. /**
  16429. * Events that can be called with on + eventName. See {@link EventHandler}.
  16430. *
  16431. * @property {Object} TrackList#allowedEvents_
  16432. * @private
  16433. */
  16434. TrackList.prototype.allowedEvents_ = {
  16435. change: 'change',
  16436. addtrack: 'addtrack',
  16437. removetrack: 'removetrack'
  16438. };
  16439. // emulate attribute EventHandler support to allow for feature detection
  16440. for (var event in TrackList.prototype.allowedEvents_) {
  16441. TrackList.prototype['on' + event] = null;
  16442. }
  16443. exports['default'] = TrackList;
  16444. },{"45":45,"81":81,"99":99}],77:[function(_dereq_,module,exports){
  16445. 'use strict';
  16446. exports.__esModule = true;
  16447. exports.ALL = exports.REMOTE = exports.NORMAL = undefined;
  16448. var _audioTrackList = _dereq_(65);
  16449. var _audioTrackList2 = _interopRequireDefault(_audioTrackList);
  16450. var _videoTrackList = _dereq_(79);
  16451. var _videoTrackList2 = _interopRequireDefault(_videoTrackList);
  16452. var _textTrackList = _dereq_(72);
  16453. var _textTrackList2 = _interopRequireDefault(_textTrackList);
  16454. var _htmlTrackElementList = _dereq_(67);
  16455. var _htmlTrackElementList2 = _interopRequireDefault(_htmlTrackElementList);
  16456. var _textTrack = _dereq_(74);
  16457. var _textTrack2 = _interopRequireDefault(_textTrack);
  16458. var _audioTrack = _dereq_(66);
  16459. var _audioTrack2 = _interopRequireDefault(_audioTrack);
  16460. var _videoTrack = _dereq_(80);
  16461. var _videoTrack2 = _interopRequireDefault(_videoTrack);
  16462. var _htmlTrackElement = _dereq_(68);
  16463. var _htmlTrackElement2 = _interopRequireDefault(_htmlTrackElement);
  16464. var _mergeOptions = _dereq_(92);
  16465. var _mergeOptions2 = _interopRequireDefault(_mergeOptions);
  16466. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  16467. /*
  16468. * This file contains all track properties that are used in
  16469. * player.js, tech.js, html5.js and possibly other techs in the future.
  16470. */
  16471. var NORMAL = {
  16472. audio: {
  16473. ListClass: _audioTrackList2['default'],
  16474. TrackClass: _audioTrack2['default'],
  16475. capitalName: 'Audio'
  16476. },
  16477. video: {
  16478. ListClass: _videoTrackList2['default'],
  16479. TrackClass: _videoTrack2['default'],
  16480. capitalName: 'Video'
  16481. },
  16482. text: {
  16483. ListClass: _textTrackList2['default'],
  16484. TrackClass: _textTrack2['default'],
  16485. capitalName: 'Text'
  16486. }
  16487. };
  16488. Object.keys(NORMAL).forEach(function (type) {
  16489. NORMAL[type].getterName = type + 'Tracks';
  16490. NORMAL[type].privateName = type + 'Tracks_';
  16491. });
  16492. var REMOTE = {
  16493. remoteText: {
  16494. ListClass: _textTrackList2['default'],
  16495. TrackClass: _textTrack2['default'],
  16496. capitalName: 'RemoteText',
  16497. getterName: 'remoteTextTracks',
  16498. privateName: 'remoteTextTracks_'
  16499. },
  16500. remoteTextEl: {
  16501. ListClass: _htmlTrackElementList2['default'],
  16502. TrackClass: _htmlTrackElement2['default'],
  16503. capitalName: 'RemoteTextTrackEls',
  16504. getterName: 'remoteTextTrackEls',
  16505. privateName: 'remoteTextTrackEls_'
  16506. }
  16507. };
  16508. var ALL = (0, _mergeOptions2['default'])(NORMAL, REMOTE);
  16509. REMOTE.names = Object.keys(REMOTE);
  16510. NORMAL.names = Object.keys(NORMAL);
  16511. ALL.names = [].concat(REMOTE.names).concat(NORMAL.names);
  16512. exports.NORMAL = NORMAL;
  16513. exports.REMOTE = REMOTE;
  16514. exports.ALL = ALL;
  16515. },{"65":65,"66":66,"67":67,"68":68,"72":72,"74":74,"79":79,"80":80,"92":92}],78:[function(_dereq_,module,exports){
  16516. 'use strict';
  16517. exports.__esModule = true;
  16518. var _browser = _dereq_(81);
  16519. var browser = _interopRequireWildcard(_browser);
  16520. var _document = _dereq_(99);
  16521. var _document2 = _interopRequireDefault(_document);
  16522. var _guid = _dereq_(90);
  16523. var Guid = _interopRequireWildcard(_guid);
  16524. var _eventTarget = _dereq_(45);
  16525. var _eventTarget2 = _interopRequireDefault(_eventTarget);
  16526. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  16527. function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
  16528. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  16529. function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
  16530. function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
  16531. * @file track.js
  16532. */
  16533. /**
  16534. * A Track class that contains all of the common functionality for {@link AudioTrack},
  16535. * {@link VideoTrack}, and {@link TextTrack}.
  16536. *
  16537. * > Note: This class should not be used directly
  16538. *
  16539. * @see {@link https://html.spec.whatwg.org/multipage/embedded-content.html}
  16540. * @extends EventTarget
  16541. * @abstract
  16542. */
  16543. var Track = function (_EventTarget) {
  16544. _inherits(Track, _EventTarget);
  16545. /**
  16546. * Create an instance of this class.
  16547. *
  16548. * @param {Object} [options={}]
  16549. * Object of option names and values
  16550. *
  16551. * @param {string} [options.kind='']
  16552. * A valid kind for the track type you are creating.
  16553. *
  16554. * @param {string} [options.id='vjs_track_' + Guid.newGUID()]
  16555. * A unique id for this AudioTrack.
  16556. *
  16557. * @param {string} [options.label='']
  16558. * The menu label for this track.
  16559. *
  16560. * @param {string} [options.language='']
  16561. * A valid two character language code.
  16562. *
  16563. * @abstract
  16564. */
  16565. function Track() {
  16566. var _ret;
  16567. var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  16568. _classCallCheck(this, Track);
  16569. var _this = _possibleConstructorReturn(this, _EventTarget.call(this));
  16570. var track = _this; // eslint-disable-line
  16571. if (browser.IS_IE8) {
  16572. track = _document2['default'].createElement('custom');
  16573. for (var prop in Track.prototype) {
  16574. if (prop !== 'constructor') {
  16575. track[prop] = Track.prototype[prop];
  16576. }
  16577. }
  16578. }
  16579. var trackProps = {
  16580. id: options.id || 'vjs_track_' + Guid.newGUID(),
  16581. kind: options.kind || '',
  16582. label: options.label || '',
  16583. language: options.language || ''
  16584. };
  16585. /**
  16586. * @memberof Track
  16587. * @member {string} id
  16588. * The id of this track. Cannot be changed after creation.
  16589. * @instance
  16590. *
  16591. * @readonly
  16592. */
  16593. /**
  16594. * @memberof Track
  16595. * @member {string} kind
  16596. * The kind of track that this is. Cannot be changed after creation.
  16597. * @instance
  16598. *
  16599. * @readonly
  16600. */
  16601. /**
  16602. * @memberof Track
  16603. * @member {string} label
  16604. * The label of this track. Cannot be changed after creation.
  16605. * @instance
  16606. *
  16607. * @readonly
  16608. */
  16609. /**
  16610. * @memberof Track
  16611. * @member {string} language
  16612. * The two letter language code for this track. Cannot be changed after
  16613. * creation.
  16614. * @instance
  16615. *
  16616. * @readonly
  16617. */
  16618. var _loop = function _loop(key) {
  16619. Object.defineProperty(track, key, {
  16620. get: function get() {
  16621. return trackProps[key];
  16622. },
  16623. set: function set() {}
  16624. });
  16625. };
  16626. for (var key in trackProps) {
  16627. _loop(key);
  16628. }
  16629. return _ret = track, _possibleConstructorReturn(_this, _ret);
  16630. }
  16631. return Track;
  16632. }(_eventTarget2['default']);
  16633. exports['default'] = Track;
  16634. },{"45":45,"81":81,"90":90,"99":99}],79:[function(_dereq_,module,exports){
  16635. 'use strict';
  16636. exports.__esModule = true;
  16637. var _trackList = _dereq_(76);
  16638. var _trackList2 = _interopRequireDefault(_trackList);
  16639. var _browser = _dereq_(81);
  16640. var browser = _interopRequireWildcard(_browser);
  16641. var _document = _dereq_(99);
  16642. var _document2 = _interopRequireDefault(_document);
  16643. function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
  16644. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  16645. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  16646. function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
  16647. function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
  16648. * @file video-track-list.js
  16649. */
  16650. /**
  16651. * Un-select all other {@link VideoTrack}s that are selected.
  16652. *
  16653. * @param {VideoTrackList} list
  16654. * list to work on
  16655. *
  16656. * @param {VideoTrack} track
  16657. * The track to skip
  16658. *
  16659. * @private
  16660. */
  16661. var disableOthers = function disableOthers(list, track) {
  16662. for (var i = 0; i < list.length; i++) {
  16663. if (track.id === list[i].id) {
  16664. continue;
  16665. }
  16666. // another video track is enabled, disable it
  16667. list[i].selected = false;
  16668. }
  16669. };
  16670. /**
  16671. * The current list of {@link VideoTrack} for a video.
  16672. *
  16673. * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#videotracklist}
  16674. * @extends TrackList
  16675. */
  16676. var VideoTrackList = function (_TrackList) {
  16677. _inherits(VideoTrackList, _TrackList);
  16678. /**
  16679. * Create an instance of this class.
  16680. *
  16681. * @param {VideoTrack[]} [tracks=[]]
  16682. * A list of `VideoTrack` to instantiate the list with.
  16683. */
  16684. function VideoTrackList() {
  16685. var _this, _ret;
  16686. var tracks = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
  16687. _classCallCheck(this, VideoTrackList);
  16688. var list = void 0;
  16689. // make sure only 1 track is enabled
  16690. // sorted from last index to first index
  16691. for (var i = tracks.length - 1; i >= 0; i--) {
  16692. if (tracks[i].selected) {
  16693. disableOthers(tracks, tracks[i]);
  16694. break;
  16695. }
  16696. }
  16697. // IE8 forces us to implement inheritance ourselves
  16698. // as it does not support Object.defineProperty properly
  16699. if (browser.IS_IE8) {
  16700. list = _document2['default'].createElement('custom');
  16701. for (var prop in _trackList2['default'].prototype) {
  16702. if (prop !== 'constructor') {
  16703. list[prop] = _trackList2['default'].prototype[prop];
  16704. }
  16705. }
  16706. for (var _prop in VideoTrackList.prototype) {
  16707. if (_prop !== 'constructor') {
  16708. list[_prop] = VideoTrackList.prototype[_prop];
  16709. }
  16710. }
  16711. }
  16712. list = (_this = _possibleConstructorReturn(this, _TrackList.call(this, tracks, list)), _this);
  16713. list.changing_ = false;
  16714. /**
  16715. * @member {number} VideoTrackList#selectedIndex
  16716. * The current index of the selected {@link VideoTrack`}.
  16717. */
  16718. Object.defineProperty(list, 'selectedIndex', {
  16719. get: function get() {
  16720. for (var _i = 0; _i < this.length; _i++) {
  16721. if (this[_i].selected) {
  16722. return _i;
  16723. }
  16724. }
  16725. return -1;
  16726. },
  16727. set: function set() {}
  16728. });
  16729. return _ret = list, _possibleConstructorReturn(_this, _ret);
  16730. }
  16731. /**
  16732. * Add a {@link VideoTrack} to the `VideoTrackList`.
  16733. *
  16734. * @param {VideoTrack} track
  16735. * The VideoTrack to add to the list
  16736. *
  16737. * @fires TrackList#addtrack
  16738. */
  16739. VideoTrackList.prototype.addTrack = function addTrack(track) {
  16740. var _this2 = this;
  16741. if (track.selected) {
  16742. disableOthers(this, track);
  16743. }
  16744. _TrackList.prototype.addTrack.call(this, track);
  16745. // native tracks don't have this
  16746. if (!track.addEventListener) {
  16747. return;
  16748. }
  16749. /**
  16750. * @listens VideoTrack#selectedchange
  16751. * @fires TrackList#change
  16752. */
  16753. track.addEventListener('selectedchange', function () {
  16754. if (_this2.changing_) {
  16755. return;
  16756. }
  16757. _this2.changing_ = true;
  16758. disableOthers(_this2, track);
  16759. _this2.changing_ = false;
  16760. _this2.trigger('change');
  16761. });
  16762. };
  16763. return VideoTrackList;
  16764. }(_trackList2['default']);
  16765. exports['default'] = VideoTrackList;
  16766. },{"76":76,"81":81,"99":99}],80:[function(_dereq_,module,exports){
  16767. 'use strict';
  16768. exports.__esModule = true;
  16769. var _trackEnums = _dereq_(75);
  16770. var _track = _dereq_(78);
  16771. var _track2 = _interopRequireDefault(_track);
  16772. var _mergeOptions = _dereq_(92);
  16773. var _mergeOptions2 = _interopRequireDefault(_mergeOptions);
  16774. var _browser = _dereq_(81);
  16775. var browser = _interopRequireWildcard(_browser);
  16776. function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
  16777. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  16778. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  16779. function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
  16780. function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
  16781. /**
  16782. * A representation of a single `VideoTrack`.
  16783. *
  16784. * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#videotrack}
  16785. * @extends Track
  16786. */
  16787. var VideoTrack = function (_Track) {
  16788. _inherits(VideoTrack, _Track);
  16789. /**
  16790. * Create an instance of this class.
  16791. *
  16792. * @param {Object} [options={}]
  16793. * Object of option names and values
  16794. *
  16795. * @param {string} [options.kind='']
  16796. * A valid {@link VideoTrack~Kind}
  16797. *
  16798. * @param {string} [options.id='vjs_track_' + Guid.newGUID()]
  16799. * A unique id for this AudioTrack.
  16800. *
  16801. * @param {string} [options.label='']
  16802. * The menu label for this track.
  16803. *
  16804. * @param {string} [options.language='']
  16805. * A valid two character language code.
  16806. *
  16807. * @param {boolean} [options.selected]
  16808. * If this track is the one that is currently playing.
  16809. */
  16810. function VideoTrack() {
  16811. var _this, _ret;
  16812. var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  16813. _classCallCheck(this, VideoTrack);
  16814. var settings = (0, _mergeOptions2['default'])(options, {
  16815. kind: _trackEnums.VideoTrackKind[options.kind] || ''
  16816. });
  16817. // on IE8 this will be a document element
  16818. // for every other browser this will be a normal object
  16819. var track = (_this = _possibleConstructorReturn(this, _Track.call(this, settings)), _this);
  16820. var selected = false;
  16821. if (browser.IS_IE8) {
  16822. for (var prop in VideoTrack.prototype) {
  16823. if (prop !== 'constructor') {
  16824. track[prop] = VideoTrack.prototype[prop];
  16825. }
  16826. }
  16827. }
  16828. /**
  16829. * @memberof VideoTrack
  16830. * @member {boolean} selected
  16831. * If this `VideoTrack` is selected or not. When setting this will
  16832. * fire {@link VideoTrack#selectedchange} if the state of selected changed.
  16833. * @instance
  16834. *
  16835. * @fires VideoTrack#selectedchange
  16836. */
  16837. Object.defineProperty(track, 'selected', {
  16838. get: function get() {
  16839. return selected;
  16840. },
  16841. set: function set(newSelected) {
  16842. // an invalid or unchanged value
  16843. if (typeof newSelected !== 'boolean' || newSelected === selected) {
  16844. return;
  16845. }
  16846. selected = newSelected;
  16847. /**
  16848. * An event that fires when selected changes on this track. This allows
  16849. * the VideoTrackList that holds this track to act accordingly.
  16850. *
  16851. * > Note: This is not part of the spec! Native tracks will do
  16852. * this internally without an event.
  16853. *
  16854. * @event VideoTrack#selectedchange
  16855. * @type {EventTarget~Event}
  16856. */
  16857. this.trigger('selectedchange');
  16858. }
  16859. });
  16860. // if the user sets this track to selected then
  16861. // set selected to that true value otherwise
  16862. // we keep it false
  16863. if (settings.selected) {
  16864. track.selected = settings.selected;
  16865. }
  16866. return _ret = track, _possibleConstructorReturn(_this, _ret);
  16867. }
  16868. return VideoTrack;
  16869. }(_track2['default']);
  16870. exports['default'] = VideoTrack;
  16871. },{"75":75,"78":78,"81":81,"92":92}],81:[function(_dereq_,module,exports){
  16872. 'use strict';
  16873. exports.__esModule = true;
  16874. exports.BACKGROUND_SIZE_SUPPORTED = exports.TOUCH_ENABLED = exports.IS_ANY_SAFARI = exports.IS_SAFARI = exports.IE_VERSION = exports.IS_IE8 = exports.IS_CHROME = exports.IS_EDGE = exports.IS_FIREFOX = exports.IS_NATIVE_ANDROID = exports.IS_OLD_ANDROID = exports.ANDROID_VERSION = exports.IS_ANDROID = exports.IOS_VERSION = exports.IS_IOS = exports.IS_IPOD = exports.IS_IPHONE = exports.IS_IPAD = undefined;
  16875. var _dom = _dereq_(85);
  16876. var Dom = _interopRequireWildcard(_dom);
  16877. var _window = _dereq_(100);
  16878. var _window2 = _interopRequireDefault(_window);
  16879. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  16880. function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
  16881. /**
  16882. * @file browser.js
  16883. * @module browser
  16884. */
  16885. var USER_AGENT = _window2['default'].navigator && _window2['default'].navigator.userAgent || '';
  16886. var webkitVersionMap = /AppleWebKit\/([\d.]+)/i.exec(USER_AGENT);
  16887. var appleWebkitVersion = webkitVersionMap ? parseFloat(webkitVersionMap.pop()) : null;
  16888. /*
  16889. * Device is an iPhone
  16890. *
  16891. * @type {Boolean}
  16892. * @constant
  16893. * @private
  16894. */
  16895. var IS_IPAD = exports.IS_IPAD = /iPad/i.test(USER_AGENT);
  16896. // The Facebook app's UIWebView identifies as both an iPhone and iPad, so
  16897. // to identify iPhones, we need to exclude iPads.
  16898. // http://artsy.github.io/blog/2012/10/18/the-perils-of-ios-user-agent-sniffing/
  16899. var IS_IPHONE = exports.IS_IPHONE = /iPhone/i.test(USER_AGENT) && !IS_IPAD;
  16900. var IS_IPOD = exports.IS_IPOD = /iPod/i.test(USER_AGENT);
  16901. var IS_IOS = exports.IS_IOS = IS_IPHONE || IS_IPAD || IS_IPOD;
  16902. var IOS_VERSION = exports.IOS_VERSION = function () {
  16903. var match = USER_AGENT.match(/OS (\d+)_/i);
  16904. if (match && match[1]) {
  16905. return match[1];
  16906. }
  16907. return null;
  16908. }();
  16909. var IS_ANDROID = exports.IS_ANDROID = /Android/i.test(USER_AGENT);
  16910. var ANDROID_VERSION = exports.ANDROID_VERSION = function () {
  16911. // This matches Android Major.Minor.Patch versions
  16912. // ANDROID_VERSION is Major.Minor as a Number, if Minor isn't available, then only Major is returned
  16913. var match = USER_AGENT.match(/Android (\d+)(?:\.(\d+))?(?:\.(\d+))*/i);
  16914. if (!match) {
  16915. return null;
  16916. }
  16917. var major = match[1] && parseFloat(match[1]);
  16918. var minor = match[2] && parseFloat(match[2]);
  16919. if (major && minor) {
  16920. return parseFloat(match[1] + '.' + match[2]);
  16921. } else if (major) {
  16922. return major;
  16923. }
  16924. return null;
  16925. }();
  16926. // Old Android is defined as Version older than 2.3, and requiring a webkit version of the android browser
  16927. var IS_OLD_ANDROID = exports.IS_OLD_ANDROID = IS_ANDROID && /webkit/i.test(USER_AGENT) && ANDROID_VERSION < 2.3;
  16928. var IS_NATIVE_ANDROID = exports.IS_NATIVE_ANDROID = IS_ANDROID && ANDROID_VERSION < 5 && appleWebkitVersion < 537;
  16929. var IS_FIREFOX = exports.IS_FIREFOX = /Firefox/i.test(USER_AGENT);
  16930. var IS_EDGE = exports.IS_EDGE = /Edge/i.test(USER_AGENT);
  16931. var IS_CHROME = exports.IS_CHROME = !IS_EDGE && /Chrome/i.test(USER_AGENT);
  16932. var IS_IE8 = exports.IS_IE8 = /MSIE\s8\.0/.test(USER_AGENT);
  16933. var IE_VERSION = exports.IE_VERSION = function (result) {
  16934. return result && parseFloat(result[1]);
  16935. }(/MSIE\s(\d+)\.\d/.exec(USER_AGENT));
  16936. var IS_SAFARI = exports.IS_SAFARI = /Safari/i.test(USER_AGENT) && !IS_CHROME && !IS_ANDROID && !IS_EDGE;
  16937. var IS_ANY_SAFARI = exports.IS_ANY_SAFARI = IS_SAFARI || IS_IOS;
  16938. var TOUCH_ENABLED = exports.TOUCH_ENABLED = Dom.isReal() && ('ontouchstart' in _window2['default'] || _window2['default'].DocumentTouch && _window2['default'].document instanceof _window2['default'].DocumentTouch);
  16939. var BACKGROUND_SIZE_SUPPORTED = exports.BACKGROUND_SIZE_SUPPORTED = Dom.isReal() && 'backgroundSize' in _window2['default'].document.createElement('video').style;
  16940. },{"100":100,"85":85}],82:[function(_dereq_,module,exports){
  16941. 'use strict';
  16942. exports.__esModule = true;
  16943. exports.bufferedPercent = bufferedPercent;
  16944. var _timeRanges = _dereq_(95);
  16945. /**
  16946. * Compute the percentage of the media that has been buffered.
  16947. *
  16948. * @param {TimeRange} buffered
  16949. * The current `TimeRange` object representing buffered time ranges
  16950. *
  16951. * @param {number} duration
  16952. * Total duration of the media
  16953. *
  16954. * @return {number}
  16955. * Percent buffered of the total duration in decimal form.
  16956. */
  16957. function bufferedPercent(buffered, duration) {
  16958. var bufferedDuration = 0;
  16959. var start = void 0;
  16960. var end = void 0;
  16961. if (!duration) {
  16962. return 0;
  16963. }
  16964. if (!buffered || !buffered.length) {
  16965. buffered = (0, _timeRanges.createTimeRange)(0, 0);
  16966. }
  16967. for (var i = 0; i < buffered.length; i++) {
  16968. start = buffered.start(i);
  16969. end = buffered.end(i);
  16970. // buffered end can be bigger than duration by a very small fraction
  16971. if (end > duration) {
  16972. end = duration;
  16973. }
  16974. bufferedDuration += end - start;
  16975. }
  16976. return bufferedDuration / duration;
  16977. } /**
  16978. * @file buffer.js
  16979. * @module buffer
  16980. */
  16981. },{"95":95}],83:[function(_dereq_,module,exports){
  16982. 'use strict';
  16983. exports.__esModule = true;
  16984. exports['default'] = computedStyle;
  16985. var _window = _dereq_(100);
  16986. var _window2 = _interopRequireDefault(_window);
  16987. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  16988. /**
  16989. * A safe getComputedStyle with an IE8 fallback.
  16990. *
  16991. * This is needed because in Firefox, if the player is loaded in an iframe with
  16992. * `display:none`, then `getComputedStyle` returns `null`, so, we do a null-check to
  16993. * make sure that the player doesn't break in these cases.
  16994. *
  16995. * @param {Element} el
  16996. * The element you want the computed style of
  16997. *
  16998. * @param {string} prop
  16999. * The property name you want
  17000. *
  17001. * @see https://bugzilla.mozilla.org/show_bug.cgi?id=548397
  17002. *
  17003. * @static
  17004. * @const
  17005. */
  17006. function computedStyle(el, prop) {
  17007. if (!el || !prop) {
  17008. return '';
  17009. }
  17010. if (typeof _window2['default'].getComputedStyle === 'function') {
  17011. var cs = _window2['default'].getComputedStyle(el);
  17012. return cs ? cs[prop] : '';
  17013. }
  17014. return el.currentStyle[prop] || '';
  17015. } /**
  17016. * @file computed-style.js
  17017. * @module computed-style
  17018. */
  17019. },{"100":100}],84:[function(_dereq_,module,exports){
  17020. 'use strict';
  17021. exports.__esModule = true;
  17022. exports.getData = getData;
  17023. exports.hasData = hasData;
  17024. exports.removeData = removeData;
  17025. var _guid = _dereq_(90);
  17026. var Guid = _interopRequireWildcard(_guid);
  17027. function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
  17028. /**
  17029. * Element Data Store.
  17030. *
  17031. * Allows for binding data to an element without putting it directly on the
  17032. * element. Ex. Event listeners are stored here.
  17033. * (also from jsninja.com, slightly modified and updated for closure compiler)
  17034. *
  17035. * @type {Object}
  17036. * @private
  17037. */
  17038. var elData = {};
  17039. /*
  17040. * Unique attribute name to store an element's guid in
  17041. *
  17042. * @type {String}
  17043. * @constant
  17044. * @private
  17045. */
  17046. /**
  17047. * @file dom-data.js
  17048. * @module dom-data
  17049. */
  17050. var elIdAttr = 'vdata' + new Date().getTime();
  17051. /**
  17052. * Returns the cache object where data for an element is stored
  17053. *
  17054. * @param {Element} el
  17055. * Element to store data for.
  17056. *
  17057. * @return {Object}
  17058. * The cache object for that el that was passed in.
  17059. */
  17060. function getData(el) {
  17061. var id = el[elIdAttr];
  17062. if (!id) {
  17063. id = el[elIdAttr] = Guid.newGUID();
  17064. }
  17065. if (!elData[id]) {
  17066. elData[id] = {};
  17067. }
  17068. return elData[id];
  17069. }
  17070. /**
  17071. * Returns whether or not an element has cached data
  17072. *
  17073. * @param {Element} el
  17074. * Check if this element has cached data.
  17075. *
  17076. * @return {boolean}
  17077. * - True if the DOM element has cached data.
  17078. * - False otherwise.
  17079. */
  17080. function hasData(el) {
  17081. var id = el[elIdAttr];
  17082. if (!id) {
  17083. return false;
  17084. }
  17085. return !!Object.getOwnPropertyNames(elData[id]).length;
  17086. }
  17087. /**
  17088. * Delete data for the element from the cache and the guid attr from getElementById
  17089. *
  17090. * @param {Element} el
  17091. * Remove cached data for this element.
  17092. */
  17093. function removeData(el) {
  17094. var id = el[elIdAttr];
  17095. if (!id) {
  17096. return;
  17097. }
  17098. // Remove all stored data
  17099. delete elData[id];
  17100. // Remove the elIdAttr property from the DOM node
  17101. try {
  17102. delete el[elIdAttr];
  17103. } catch (e) {
  17104. if (el.removeAttribute) {
  17105. el.removeAttribute(elIdAttr);
  17106. } else {
  17107. // IE doesn't appear to support removeAttribute on the document element
  17108. el[elIdAttr] = null;
  17109. }
  17110. }
  17111. }
  17112. },{"90":90}],85:[function(_dereq_,module,exports){
  17113. 'use strict';
  17114. exports.__esModule = true;
  17115. exports.$$ = exports.$ = undefined;
  17116. var _templateObject = _taggedTemplateLiteralLoose(['Setting attributes in the second argument of createEl()\n has been deprecated. Use the third argument instead.\n createEl(type, properties, attributes). Attempting to set ', ' to ', '.'], ['Setting attributes in the second argument of createEl()\n has been deprecated. Use the third argument instead.\n createEl(type, properties, attributes). Attempting to set ', ' to ', '.']);
  17117. exports.isReal = isReal;
  17118. exports.isEl = isEl;
  17119. exports.createEl = createEl;
  17120. exports.textContent = textContent;
  17121. exports.prependTo = prependTo;
  17122. exports.hasClass = hasClass;
  17123. exports.addClass = addClass;
  17124. exports.removeClass = removeClass;
  17125. exports.toggleClass = toggleClass;
  17126. exports.setAttributes = setAttributes;
  17127. exports.getAttributes = getAttributes;
  17128. exports.getAttribute = getAttribute;
  17129. exports.setAttribute = setAttribute;
  17130. exports.removeAttribute = removeAttribute;
  17131. exports.blockTextSelection = blockTextSelection;
  17132. exports.unblockTextSelection = unblockTextSelection;
  17133. exports.getBoundingClientRect = getBoundingClientRect;
  17134. exports.findPosition = findPosition;
  17135. exports.getPointerPosition = getPointerPosition;
  17136. exports.isTextNode = isTextNode;
  17137. exports.emptyEl = emptyEl;
  17138. exports.normalizeContent = normalizeContent;
  17139. exports.appendContent = appendContent;
  17140. exports.insertContent = insertContent;
  17141. var _document = _dereq_(99);
  17142. var _document2 = _interopRequireDefault(_document);
  17143. var _window = _dereq_(100);
  17144. var _window2 = _interopRequireDefault(_window);
  17145. var _log = _dereq_(91);
  17146. var _log2 = _interopRequireDefault(_log);
  17147. var _tsml = _dereq_(103);
  17148. var _tsml2 = _interopRequireDefault(_tsml);
  17149. var _obj = _dereq_(93);
  17150. var _computedStyle = _dereq_(83);
  17151. var _computedStyle2 = _interopRequireDefault(_computedStyle);
  17152. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  17153. function _taggedTemplateLiteralLoose(strings, raw) { strings.raw = raw; return strings; } /**
  17154. * @file dom.js
  17155. * @module dom
  17156. */
  17157. /**
  17158. * Detect if a value is a string with any non-whitespace characters.
  17159. *
  17160. * @param {string} str
  17161. * The string to check
  17162. *
  17163. * @return {boolean}
  17164. * - True if the string is non-blank
  17165. * - False otherwise
  17166. *
  17167. */
  17168. function isNonBlankString(str) {
  17169. return typeof str === 'string' && /\S/.test(str);
  17170. }
  17171. /**
  17172. * Throws an error if the passed string has whitespace. This is used by
  17173. * class methods to be relatively consistent with the classList API.
  17174. *
  17175. * @param {string} str
  17176. * The string to check for whitespace.
  17177. *
  17178. * @throws {Error}
  17179. * Throws an error if there is whitespace in the string.
  17180. *
  17181. */
  17182. function throwIfWhitespace(str) {
  17183. if (/\s/.test(str)) {
  17184. throw new Error('class has illegal whitespace characters');
  17185. }
  17186. }
  17187. /**
  17188. * Produce a regular expression for matching a className within an elements className.
  17189. *
  17190. * @param {string} className
  17191. * The className to generate the RegExp for.
  17192. *
  17193. * @return {RegExp}
  17194. * The RegExp that will check for a specific `className` in an elements
  17195. * className.
  17196. */
  17197. function classRegExp(className) {
  17198. return new RegExp('(^|\\s)' + className + '($|\\s)');
  17199. }
  17200. /**
  17201. * Whether the current DOM interface appears to be real.
  17202. *
  17203. * @return {Boolean}
  17204. */
  17205. function isReal() {
  17206. return (
  17207. // Both document and window will never be undefined thanks to `global`.
  17208. _document2['default'] === _window2['default'].document &&
  17209. // In IE < 9, DOM methods return "object" as their type, so all we can
  17210. // confidently check is that it exists.
  17211. typeof _document2['default'].createElement !== 'undefined'
  17212. );
  17213. }
  17214. /**
  17215. * Determines, via duck typing, whether or not a value is a DOM element.
  17216. *
  17217. * @param {Mixed} value
  17218. * The thing to check
  17219. *
  17220. * @return {boolean}
  17221. * - True if it is a DOM element
  17222. * - False otherwise
  17223. */
  17224. function isEl(value) {
  17225. return (0, _obj.isObject)(value) && value.nodeType === 1;
  17226. }
  17227. /**
  17228. * Creates functions to query the DOM using a given method.
  17229. *
  17230. * @param {string} method
  17231. * The method to create the query with.
  17232. *
  17233. * @return {Function}
  17234. * The query method
  17235. */
  17236. function createQuerier(method) {
  17237. return function (selector, context) {
  17238. if (!isNonBlankString(selector)) {
  17239. return _document2['default'][method](null);
  17240. }
  17241. if (isNonBlankString(context)) {
  17242. context = _document2['default'].querySelector(context);
  17243. }
  17244. var ctx = isEl(context) ? context : _document2['default'];
  17245. return ctx[method] && ctx[method](selector);
  17246. };
  17247. }
  17248. /**
  17249. * Creates an element and applies properties.
  17250. *
  17251. * @param {string} [tagName='div']
  17252. * Name of tag to be created.
  17253. *
  17254. * @param {Object} [properties={}]
  17255. * Element properties to be applied.
  17256. *
  17257. * @param {Object} [attributes={}]
  17258. * Element attributes to be applied.
  17259. *
  17260. * @param {String|Element|TextNode|Array|Function} [content]
  17261. * Contents for the element (see: {@link dom:normalizeContent})
  17262. *
  17263. * @return {Element}
  17264. * The element that was created.
  17265. */
  17266. function createEl() {
  17267. var tagName = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'div';
  17268. var properties = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  17269. var attributes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
  17270. var content = arguments[3];
  17271. var el = _document2['default'].createElement(tagName);
  17272. Object.getOwnPropertyNames(properties).forEach(function (propName) {
  17273. var val = properties[propName];
  17274. // See #2176
  17275. // We originally were accepting both properties and attributes in the
  17276. // same object, but that doesn't work so well.
  17277. if (propName.indexOf('aria-') !== -1 || propName === 'role' || propName === 'type') {
  17278. _log2['default'].warn((0, _tsml2['default'])(_templateObject, propName, val));
  17279. el.setAttribute(propName, val);
  17280. // Handle textContent since it's not supported everywhere and we have a
  17281. // method for it.
  17282. } else if (propName === 'textContent') {
  17283. textContent(el, val);
  17284. } else {
  17285. el[propName] = val;
  17286. }
  17287. });
  17288. Object.getOwnPropertyNames(attributes).forEach(function (attrName) {
  17289. el.setAttribute(attrName, attributes[attrName]);
  17290. });
  17291. if (content) {
  17292. appendContent(el, content);
  17293. }
  17294. return el;
  17295. }
  17296. /**
  17297. * Injects text into an element, replacing any existing contents entirely.
  17298. *
  17299. * @param {Element} el
  17300. * The element to add text content into
  17301. *
  17302. * @param {string} text
  17303. * The text content to add.
  17304. *
  17305. * @return {Element}
  17306. * The element with added text content.
  17307. */
  17308. function textContent(el, text) {
  17309. if (typeof el.textContent === 'undefined') {
  17310. el.innerText = text;
  17311. } else {
  17312. el.textContent = text;
  17313. }
  17314. return el;
  17315. }
  17316. /**
  17317. * Insert an element as the first child node of another
  17318. *
  17319. * @param {Element} child
  17320. * Element to insert
  17321. *
  17322. * @param {Element} parent
  17323. * Element to insert child into
  17324. */
  17325. function prependTo(child, parent) {
  17326. if (parent.firstChild) {
  17327. parent.insertBefore(child, parent.firstChild);
  17328. } else {
  17329. parent.appendChild(child);
  17330. }
  17331. }
  17332. /**
  17333. * Check if an element has a CSS class
  17334. *
  17335. * @param {Element} element
  17336. * Element to check
  17337. *
  17338. * @param {string} classToCheck
  17339. * Class name to check for
  17340. *
  17341. * @return {boolean}
  17342. * - True if the element had the class
  17343. * - False otherwise.
  17344. *
  17345. * @throws {Error}
  17346. * Throws an error if `classToCheck` has white space.
  17347. */
  17348. function hasClass(element, classToCheck) {
  17349. throwIfWhitespace(classToCheck);
  17350. if (element.classList) {
  17351. return element.classList.contains(classToCheck);
  17352. }
  17353. return classRegExp(classToCheck).test(element.className);
  17354. }
  17355. /**
  17356. * Add a CSS class name to an element
  17357. *
  17358. * @param {Element} element
  17359. * Element to add class name to.
  17360. *
  17361. * @param {string} classToAdd
  17362. * Class name to add.
  17363. *
  17364. * @return {Element}
  17365. * The dom element with the added class name.
  17366. */
  17367. function addClass(element, classToAdd) {
  17368. if (element.classList) {
  17369. element.classList.add(classToAdd);
  17370. // Don't need to `throwIfWhitespace` here because `hasElClass` will do it
  17371. // in the case of classList not being supported.
  17372. } else if (!hasClass(element, classToAdd)) {
  17373. element.className = (element.className + ' ' + classToAdd).trim();
  17374. }
  17375. return element;
  17376. }
  17377. /**
  17378. * Remove a CSS class name from an element
  17379. *
  17380. * @param {Element} element
  17381. * Element to remove a class name from.
  17382. *
  17383. * @param {string} classToRemove
  17384. * Class name to remove
  17385. *
  17386. * @return {Element}
  17387. * The dom element with class name removed.
  17388. */
  17389. function removeClass(element, classToRemove) {
  17390. if (element.classList) {
  17391. element.classList.remove(classToRemove);
  17392. } else {
  17393. throwIfWhitespace(classToRemove);
  17394. element.className = element.className.split(/\s+/).filter(function (c) {
  17395. return c !== classToRemove;
  17396. }).join(' ');
  17397. }
  17398. return element;
  17399. }
  17400. /**
  17401. * The callback definition for toggleElClass.
  17402. *
  17403. * @callback Dom~PredicateCallback
  17404. * @param {Element} element
  17405. * The DOM element of the Component.
  17406. *
  17407. * @param {string} classToToggle
  17408. * The `className` that wants to be toggled
  17409. *
  17410. * @return {boolean|undefined}
  17411. * - If true the `classToToggle` will get added to `element`.
  17412. * - If false the `classToToggle` will get removed from `element`.
  17413. * - If undefined this callback will be ignored
  17414. */
  17415. /**
  17416. * Adds or removes a CSS class name on an element depending on an optional
  17417. * condition or the presence/absence of the class name.
  17418. *
  17419. * @param {Element} element
  17420. * The element to toggle a class name on.
  17421. *
  17422. * @param {string} classToToggle
  17423. * The class that should be toggled
  17424. *
  17425. * @param {boolean|PredicateCallback} [predicate]
  17426. * See the return value for {@link Dom~PredicateCallback}
  17427. *
  17428. * @return {Element}
  17429. * The element with a class that has been toggled.
  17430. */
  17431. function toggleClass(element, classToToggle, predicate) {
  17432. // This CANNOT use `classList` internally because IE does not support the
  17433. // second parameter to the `classList.toggle()` method! Which is fine because
  17434. // `classList` will be used by the add/remove functions.
  17435. var has = hasClass(element, classToToggle);
  17436. if (typeof predicate === 'function') {
  17437. predicate = predicate(element, classToToggle);
  17438. }
  17439. if (typeof predicate !== 'boolean') {
  17440. predicate = !has;
  17441. }
  17442. // If the necessary class operation matches the current state of the
  17443. // element, no action is required.
  17444. if (predicate === has) {
  17445. return;
  17446. }
  17447. if (predicate) {
  17448. addClass(element, classToToggle);
  17449. } else {
  17450. removeClass(element, classToToggle);
  17451. }
  17452. return element;
  17453. }
  17454. /**
  17455. * Apply attributes to an HTML element.
  17456. *
  17457. * @param {Element} el
  17458. * Element to add attributes to.
  17459. *
  17460. * @param {Object} [attributes]
  17461. * Attributes to be applied.
  17462. */
  17463. function setAttributes(el, attributes) {
  17464. Object.getOwnPropertyNames(attributes).forEach(function (attrName) {
  17465. var attrValue = attributes[attrName];
  17466. if (attrValue === null || typeof attrValue === 'undefined' || attrValue === false) {
  17467. el.removeAttribute(attrName);
  17468. } else {
  17469. el.setAttribute(attrName, attrValue === true ? '' : attrValue);
  17470. }
  17471. });
  17472. }
  17473. /**
  17474. * Get an element's attribute values, as defined on the HTML tag
  17475. * Attributes are not the same as properties. They're defined on the tag
  17476. * or with setAttribute (which shouldn't be used with HTML)
  17477. * This will return true or false for boolean attributes.
  17478. *
  17479. * @param {Element} tag
  17480. * Element from which to get tag attributes.
  17481. *
  17482. * @return {Object}
  17483. * All attributes of the element.
  17484. */
  17485. function getAttributes(tag) {
  17486. var obj = {};
  17487. // known boolean attributes
  17488. // we can check for matching boolean properties, but older browsers
  17489. // won't know about HTML5 boolean attributes that we still read from
  17490. var knownBooleans = ',' + 'autoplay,controls,loop,muted,default' + ',';
  17491. if (tag && tag.attributes && tag.attributes.length > 0) {
  17492. var attrs = tag.attributes;
  17493. for (var i = attrs.length - 1; i >= 0; i--) {
  17494. var attrName = attrs[i].name;
  17495. var attrVal = attrs[i].value;
  17496. // check for known booleans
  17497. // the matching element property will return a value for typeof
  17498. if (typeof tag[attrName] === 'boolean' || knownBooleans.indexOf(',' + attrName + ',') !== -1) {
  17499. // the value of an included boolean attribute is typically an empty
  17500. // string ('') which would equal false if we just check for a false value.
  17501. // we also don't want support bad code like autoplay='false'
  17502. attrVal = attrVal !== null ? true : false;
  17503. }
  17504. obj[attrName] = attrVal;
  17505. }
  17506. }
  17507. return obj;
  17508. }
  17509. /**
  17510. * Get the value of an element's attribute
  17511. *
  17512. * @param {Element} el
  17513. * A DOM element
  17514. *
  17515. * @param {string} attribute
  17516. * Attribute to get the value of
  17517. *
  17518. * @return {string}
  17519. * value of the attribute
  17520. */
  17521. function getAttribute(el, attribute) {
  17522. return el.getAttribute(attribute);
  17523. }
  17524. /**
  17525. * Set the value of an element's attribute
  17526. *
  17527. * @param {Element} el
  17528. * A DOM element
  17529. *
  17530. * @param {string} attribute
  17531. * Attribute to set
  17532. *
  17533. * @param {string} value
  17534. * Value to set the attribute to
  17535. */
  17536. function setAttribute(el, attribute, value) {
  17537. el.setAttribute(attribute, value);
  17538. }
  17539. /**
  17540. * Remove an element's attribute
  17541. *
  17542. * @param {Element} el
  17543. * A DOM element
  17544. *
  17545. * @param {string} attribute
  17546. * Attribute to remove
  17547. */
  17548. function removeAttribute(el, attribute) {
  17549. el.removeAttribute(attribute);
  17550. }
  17551. /**
  17552. * Attempt to block the ability to select text while dragging controls
  17553. */
  17554. function blockTextSelection() {
  17555. _document2['default'].body.focus();
  17556. _document2['default'].onselectstart = function () {
  17557. return false;
  17558. };
  17559. }
  17560. /**
  17561. * Turn off text selection blocking
  17562. */
  17563. function unblockTextSelection() {
  17564. _document2['default'].onselectstart = function () {
  17565. return true;
  17566. };
  17567. }
  17568. /**
  17569. * Identical to the native `getBoundingClientRect` function, but ensures that
  17570. * the method is supported at all (it is in all browsers we claim to support)
  17571. * and that the element is in the DOM before continuing.
  17572. *
  17573. * This wrapper function also shims properties which are not provided by some
  17574. * older browsers (namely, IE8).
  17575. *
  17576. * Additionally, some browsers do not support adding properties to a
  17577. * `ClientRect`/`DOMRect` object; so, we shallow-copy it with the standard
  17578. * properties (except `x` and `y` which are not widely supported). This helps
  17579. * avoid implementations where keys are non-enumerable.
  17580. *
  17581. * @param {Element} el
  17582. * Element whose `ClientRect` we want to calculate.
  17583. *
  17584. * @return {Object|undefined}
  17585. * Always returns a plain
  17586. */
  17587. function getBoundingClientRect(el) {
  17588. if (el && el.getBoundingClientRect && el.parentNode) {
  17589. var rect = el.getBoundingClientRect();
  17590. var result = {};
  17591. ['bottom', 'height', 'left', 'right', 'top', 'width'].forEach(function (k) {
  17592. if (rect[k] !== undefined) {
  17593. result[k] = rect[k];
  17594. }
  17595. });
  17596. if (!result.height) {
  17597. result.height = parseFloat((0, _computedStyle2['default'])(el, 'height'));
  17598. }
  17599. if (!result.width) {
  17600. result.width = parseFloat((0, _computedStyle2['default'])(el, 'width'));
  17601. }
  17602. return result;
  17603. }
  17604. }
  17605. /**
  17606. * The postion of a DOM element on the page.
  17607. *
  17608. * @typedef {Object} Dom~Position
  17609. *
  17610. * @property {number} left
  17611. * Pixels to the left
  17612. *
  17613. * @property {number} top
  17614. * Pixels on top
  17615. */
  17616. /**
  17617. * Offset Left.
  17618. * getBoundingClientRect technique from
  17619. * John Resig
  17620. *
  17621. * @see http://ejohn.org/blog/getboundingclientrect-is-awesome/
  17622. *
  17623. * @param {Element} el
  17624. * Element from which to get offset
  17625. *
  17626. * @return {Dom~Position}
  17627. * The position of the element that was passed in.
  17628. */
  17629. function findPosition(el) {
  17630. var box = void 0;
  17631. if (el.getBoundingClientRect && el.parentNode) {
  17632. box = el.getBoundingClientRect();
  17633. }
  17634. if (!box) {
  17635. return {
  17636. left: 0,
  17637. top: 0
  17638. };
  17639. }
  17640. var docEl = _document2['default'].documentElement;
  17641. var body = _document2['default'].body;
  17642. var clientLeft = docEl.clientLeft || body.clientLeft || 0;
  17643. var scrollLeft = _window2['default'].pageXOffset || body.scrollLeft;
  17644. var left = box.left + scrollLeft - clientLeft;
  17645. var clientTop = docEl.clientTop || body.clientTop || 0;
  17646. var scrollTop = _window2['default'].pageYOffset || body.scrollTop;
  17647. var top = box.top + scrollTop - clientTop;
  17648. // Android sometimes returns slightly off decimal values, so need to round
  17649. return {
  17650. left: Math.round(left),
  17651. top: Math.round(top)
  17652. };
  17653. }
  17654. /**
  17655. * x and y coordinates for a dom element or mouse pointer
  17656. *
  17657. * @typedef {Object} Dom~Coordinates
  17658. *
  17659. * @property {number} x
  17660. * x coordinate in pixels
  17661. *
  17662. * @property {number} y
  17663. * y coordinate in pixels
  17664. */
  17665. /**
  17666. * Get pointer position in element
  17667. * Returns an object with x and y coordinates.
  17668. * The base on the coordinates are the bottom left of the element.
  17669. *
  17670. * @param {Element} el
  17671. * Element on which to get the pointer position on
  17672. *
  17673. * @param {EventTarget~Event} event
  17674. * Event object
  17675. *
  17676. * @return {Dom~Coordinates}
  17677. * A Coordinates object corresponding to the mouse position.
  17678. *
  17679. */
  17680. function getPointerPosition(el, event) {
  17681. var position = {};
  17682. var box = findPosition(el);
  17683. var boxW = el.offsetWidth;
  17684. var boxH = el.offsetHeight;
  17685. var boxY = box.top;
  17686. var boxX = box.left;
  17687. var pageY = event.pageY;
  17688. var pageX = event.pageX;
  17689. if (event.changedTouches) {
  17690. pageX = event.changedTouches[0].pageX;
  17691. pageY = event.changedTouches[0].pageY;
  17692. }
  17693. position.y = Math.max(0, Math.min(1, (boxY - pageY + boxH) / boxH));
  17694. position.x = Math.max(0, Math.min(1, (pageX - boxX) / boxW));
  17695. return position;
  17696. }
  17697. /**
  17698. * Determines, via duck typing, whether or not a value is a text node.
  17699. *
  17700. * @param {Mixed} value
  17701. * Check if this value is a text node.
  17702. *
  17703. * @return {boolean}
  17704. * - True if it is a text node
  17705. * - False otherwise
  17706. */
  17707. function isTextNode(value) {
  17708. return (0, _obj.isObject)(value) && value.nodeType === 3;
  17709. }
  17710. /**
  17711. * Empties the contents of an element.
  17712. *
  17713. * @param {Element} el
  17714. * The element to empty children from
  17715. *
  17716. * @return {Element}
  17717. * The element with no children
  17718. */
  17719. function emptyEl(el) {
  17720. while (el.firstChild) {
  17721. el.removeChild(el.firstChild);
  17722. }
  17723. return el;
  17724. }
  17725. /**
  17726. * Normalizes content for eventual insertion into the DOM.
  17727. *
  17728. * This allows a wide range of content definition methods, but protects
  17729. * from falling into the trap of simply writing to `innerHTML`, which is
  17730. * an XSS concern.
  17731. *
  17732. * The content for an element can be passed in multiple types and
  17733. * combinations, whose behavior is as follows:
  17734. *
  17735. * @param {String|Element|TextNode|Array|Function} content
  17736. * - String: Normalized into a text node.
  17737. * - Element/TextNode: Passed through.
  17738. * - Array: A one-dimensional array of strings, elements, nodes, or functions
  17739. * (which return single strings, elements, or nodes).
  17740. * - Function: If the sole argument, is expected to produce a string, element,
  17741. * node, or array as defined above.
  17742. *
  17743. * @return {Array}
  17744. * All of the content that was passed in normalized.
  17745. */
  17746. function normalizeContent(content) {
  17747. // First, invoke content if it is a function. If it produces an array,
  17748. // that needs to happen before normalization.
  17749. if (typeof content === 'function') {
  17750. content = content();
  17751. }
  17752. // Next up, normalize to an array, so one or many items can be normalized,
  17753. // filtered, and returned.
  17754. return (Array.isArray(content) ? content : [content]).map(function (value) {
  17755. // First, invoke value if it is a function to produce a new value,
  17756. // which will be subsequently normalized to a Node of some kind.
  17757. if (typeof value === 'function') {
  17758. value = value();
  17759. }
  17760. if (isEl(value) || isTextNode(value)) {
  17761. return value;
  17762. }
  17763. if (typeof value === 'string' && /\S/.test(value)) {
  17764. return _document2['default'].createTextNode(value);
  17765. }
  17766. }).filter(function (value) {
  17767. return value;
  17768. });
  17769. }
  17770. /**
  17771. * Normalizes and appends content to an element.
  17772. *
  17773. * @param {Element} el
  17774. * Element to append normalized content to.
  17775. *
  17776. *
  17777. * @param {String|Element|TextNode|Array|Function} content
  17778. * See the `content` argument of {@link dom:normalizeContent}
  17779. *
  17780. * @return {Element}
  17781. * The element with appended normalized content.
  17782. */
  17783. function appendContent(el, content) {
  17784. normalizeContent(content).forEach(function (node) {
  17785. return el.appendChild(node);
  17786. });
  17787. return el;
  17788. }
  17789. /**
  17790. * Normalizes and inserts content into an element; this is identical to
  17791. * `appendContent()`, except it empties the element first.
  17792. *
  17793. * @param {Element} el
  17794. * Element to insert normalized content into.
  17795. *
  17796. * @param {String|Element|TextNode|Array|Function} content
  17797. * See the `content` argument of {@link dom:normalizeContent}
  17798. *
  17799. * @return {Element}
  17800. * The element with inserted normalized content.
  17801. *
  17802. */
  17803. function insertContent(el, content) {
  17804. return appendContent(emptyEl(el), content);
  17805. }
  17806. /**
  17807. * Finds a single DOM element matching `selector` within the optional
  17808. * `context` of another DOM element (defaulting to `document`).
  17809. *
  17810. * @param {string} selector
  17811. * A valid CSS selector, which will be passed to `querySelector`.
  17812. *
  17813. * @param {Element|String} [context=document]
  17814. * A DOM element within which to query. Can also be a selector
  17815. * string in which case the first matching element will be used
  17816. * as context. If missing (or no element matches selector), falls
  17817. * back to `document`.
  17818. *
  17819. * @return {Element|null}
  17820. * The element that was found or null.
  17821. */
  17822. var $ = exports.$ = createQuerier('querySelector');
  17823. /**
  17824. * Finds a all DOM elements matching `selector` within the optional
  17825. * `context` of another DOM element (defaulting to `document`).
  17826. *
  17827. * @param {string} selector
  17828. * A valid CSS selector, which will be passed to `querySelectorAll`.
  17829. *
  17830. * @param {Element|String} [context=document]
  17831. * A DOM element within which to query. Can also be a selector
  17832. * string in which case the first matching element will be used
  17833. * as context. If missing (or no element matches selector), falls
  17834. * back to `document`.
  17835. *
  17836. * @return {NodeList}
  17837. * A element list of elements that were found. Will be empty if none were found.
  17838. *
  17839. */
  17840. var $$ = exports.$$ = createQuerier('querySelectorAll');
  17841. },{"100":100,"103":103,"83":83,"91":91,"93":93,"99":99}],86:[function(_dereq_,module,exports){
  17842. 'use strict';
  17843. exports.__esModule = true;
  17844. exports.fixEvent = fixEvent;
  17845. exports.on = on;
  17846. exports.off = off;
  17847. exports.trigger = trigger;
  17848. exports.one = one;
  17849. var _domData = _dereq_(84);
  17850. var DomData = _interopRequireWildcard(_domData);
  17851. var _guid = _dereq_(90);
  17852. var Guid = _interopRequireWildcard(_guid);
  17853. var _log = _dereq_(91);
  17854. var _log2 = _interopRequireDefault(_log);
  17855. var _window = _dereq_(100);
  17856. var _window2 = _interopRequireDefault(_window);
  17857. var _document = _dereq_(99);
  17858. var _document2 = _interopRequireDefault(_document);
  17859. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  17860. function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
  17861. /**
  17862. * Clean up the listener cache and dispatchers
  17863. *
  17864. * @param {Element|Object} elem
  17865. * Element to clean up
  17866. *
  17867. * @param {string} type
  17868. * Type of event to clean up
  17869. */
  17870. function _cleanUpEvents(elem, type) {
  17871. var data = DomData.getData(elem);
  17872. // Remove the events of a particular type if there are none left
  17873. if (data.handlers[type].length === 0) {
  17874. delete data.handlers[type];
  17875. // data.handlers[type] = null;
  17876. // Setting to null was causing an error with data.handlers
  17877. // Remove the meta-handler from the element
  17878. if (elem.removeEventListener) {
  17879. elem.removeEventListener(type, data.dispatcher, false);
  17880. } else if (elem.detachEvent) {
  17881. elem.detachEvent('on' + type, data.dispatcher);
  17882. }
  17883. }
  17884. // Remove the events object if there are no types left
  17885. if (Object.getOwnPropertyNames(data.handlers).length <= 0) {
  17886. delete data.handlers;
  17887. delete data.dispatcher;
  17888. delete data.disabled;
  17889. }
  17890. // Finally remove the element data if there is no data left
  17891. if (Object.getOwnPropertyNames(data).length === 0) {
  17892. DomData.removeData(elem);
  17893. }
  17894. }
  17895. /**
  17896. * Loops through an array of event types and calls the requested method for each type.
  17897. *
  17898. * @param {Function} fn
  17899. * The event method we want to use.
  17900. *
  17901. * @param {Element|Object} elem
  17902. * Element or object to bind listeners to
  17903. *
  17904. * @param {string} type
  17905. * Type of event to bind to.
  17906. *
  17907. * @param {EventTarget~EventListener} callback
  17908. * Event listener.
  17909. */
  17910. /**
  17911. * @file events.js. An Event System (John Resig - Secrets of a JS Ninja http://jsninja.com/)
  17912. * (Original book version wasn't completely usable, so fixed some things and made Closure Compiler compatible)
  17913. * This should work very similarly to jQuery's events, however it's based off the book version which isn't as
  17914. * robust as jquery's, so there's probably some differences.
  17915. *
  17916. * @module events
  17917. */
  17918. function _handleMultipleEvents(fn, elem, types, callback) {
  17919. types.forEach(function (type) {
  17920. // Call the event method for each one of the types
  17921. fn(elem, type, callback);
  17922. });
  17923. }
  17924. /**
  17925. * Fix a native event to have standard property values
  17926. *
  17927. * @param {Object} event
  17928. * Event object to fix.
  17929. *
  17930. * @return {Object}
  17931. * Fixed event object.
  17932. */
  17933. function fixEvent(event) {
  17934. function returnTrue() {
  17935. return true;
  17936. }
  17937. function returnFalse() {
  17938. return false;
  17939. }
  17940. // Test if fixing up is needed
  17941. // Used to check if !event.stopPropagation instead of isPropagationStopped
  17942. // But native events return true for stopPropagation, but don't have
  17943. // other expected methods like isPropagationStopped. Seems to be a problem
  17944. // with the Javascript Ninja code. So we're just overriding all events now.
  17945. if (!event || !event.isPropagationStopped) {
  17946. var old = event || _window2['default'].event;
  17947. event = {};
  17948. // Clone the old object so that we can modify the values event = {};
  17949. // IE8 Doesn't like when you mess with native event properties
  17950. // Firefox returns false for event.hasOwnProperty('type') and other props
  17951. // which makes copying more difficult.
  17952. // TODO: Probably best to create a whitelist of event props
  17953. for (var key in old) {
  17954. // Safari 6.0.3 warns you if you try to copy deprecated layerX/Y
  17955. // Chrome warns you if you try to copy deprecated keyboardEvent.keyLocation
  17956. // and webkitMovementX/Y
  17957. if (key !== 'layerX' && key !== 'layerY' && key !== 'keyLocation' && key !== 'webkitMovementX' && key !== 'webkitMovementY') {
  17958. // Chrome 32+ warns if you try to copy deprecated returnValue, but
  17959. // we still want to if preventDefault isn't supported (IE8).
  17960. if (!(key === 'returnValue' && old.preventDefault)) {
  17961. event[key] = old[key];
  17962. }
  17963. }
  17964. }
  17965. // The event occurred on this element
  17966. if (!event.target) {
  17967. event.target = event.srcElement || _document2['default'];
  17968. }
  17969. // Handle which other element the event is related to
  17970. if (!event.relatedTarget) {
  17971. event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement;
  17972. }
  17973. // Stop the default browser action
  17974. event.preventDefault = function () {
  17975. if (old.preventDefault) {
  17976. old.preventDefault();
  17977. }
  17978. event.returnValue = false;
  17979. old.returnValue = false;
  17980. event.defaultPrevented = true;
  17981. };
  17982. event.defaultPrevented = false;
  17983. // Stop the event from bubbling
  17984. event.stopPropagation = function () {
  17985. if (old.stopPropagation) {
  17986. old.stopPropagation();
  17987. }
  17988. event.cancelBubble = true;
  17989. old.cancelBubble = true;
  17990. event.isPropagationStopped = returnTrue;
  17991. };
  17992. event.isPropagationStopped = returnFalse;
  17993. // Stop the event from bubbling and executing other handlers
  17994. event.stopImmediatePropagation = function () {
  17995. if (old.stopImmediatePropagation) {
  17996. old.stopImmediatePropagation();
  17997. }
  17998. event.isImmediatePropagationStopped = returnTrue;
  17999. event.stopPropagation();
  18000. };
  18001. event.isImmediatePropagationStopped = returnFalse;
  18002. // Handle mouse position
  18003. if (event.clientX !== null && event.clientX !== undefined) {
  18004. var doc = _document2['default'].documentElement;
  18005. var body = _document2['default'].body;
  18006. event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
  18007. event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0);
  18008. }
  18009. // Handle key presses
  18010. event.which = event.charCode || event.keyCode;
  18011. // Fix button for mouse clicks:
  18012. // 0 == left; 1 == middle; 2 == right
  18013. if (event.button !== null && event.button !== undefined) {
  18014. // The following is disabled because it does not pass videojs-standard
  18015. // and... yikes.
  18016. /* eslint-disable */
  18017. event.button = event.button & 1 ? 0 : event.button & 4 ? 1 : event.button & 2 ? 2 : 0;
  18018. /* eslint-enable */
  18019. }
  18020. }
  18021. // Returns fixed-up instance
  18022. return event;
  18023. }
  18024. /**
  18025. * Add an event listener to element
  18026. * It stores the handler function in a separate cache object
  18027. * and adds a generic handler to the element's event,
  18028. * along with a unique id (guid) to the element.
  18029. *
  18030. * @param {Element|Object} elem
  18031. * Element or object to bind listeners to
  18032. *
  18033. * @param {string|string[]} type
  18034. * Type of event to bind to.
  18035. *
  18036. * @param {EventTarget~EventListener} fn
  18037. * Event listener.
  18038. */
  18039. function on(elem, type, fn) {
  18040. if (Array.isArray(type)) {
  18041. return _handleMultipleEvents(on, elem, type, fn);
  18042. }
  18043. var data = DomData.getData(elem);
  18044. // We need a place to store all our handler data
  18045. if (!data.handlers) {
  18046. data.handlers = {};
  18047. }
  18048. if (!data.handlers[type]) {
  18049. data.handlers[type] = [];
  18050. }
  18051. if (!fn.guid) {
  18052. fn.guid = Guid.newGUID();
  18053. }
  18054. data.handlers[type].push(fn);
  18055. if (!data.dispatcher) {
  18056. data.disabled = false;
  18057. data.dispatcher = function (event, hash) {
  18058. if (data.disabled) {
  18059. return;
  18060. }
  18061. event = fixEvent(event);
  18062. var handlers = data.handlers[event.type];
  18063. if (handlers) {
  18064. // Copy handlers so if handlers are added/removed during the process it doesn't throw everything off.
  18065. var handlersCopy = handlers.slice(0);
  18066. for (var m = 0, n = handlersCopy.length; m < n; m++) {
  18067. if (event.isImmediatePropagationStopped()) {
  18068. break;
  18069. } else {
  18070. try {
  18071. handlersCopy[m].call(elem, event, hash);
  18072. } catch (e) {
  18073. _log2['default'].error(e);
  18074. }
  18075. }
  18076. }
  18077. }
  18078. };
  18079. }
  18080. if (data.handlers[type].length === 1) {
  18081. if (elem.addEventListener) {
  18082. elem.addEventListener(type, data.dispatcher, false);
  18083. } else if (elem.attachEvent) {
  18084. elem.attachEvent('on' + type, data.dispatcher);
  18085. }
  18086. }
  18087. }
  18088. /**
  18089. * Removes event listeners from an element
  18090. *
  18091. * @param {Element|Object} elem
  18092. * Object to remove listeners from.
  18093. *
  18094. * @param {string|string[]} [type]
  18095. * Type of listener to remove. Don't include to remove all events from element.
  18096. *
  18097. * @param {EventTarget~EventListener} [fn]
  18098. * Specific listener to remove. Don't include to remove listeners for an event
  18099. * type.
  18100. */
  18101. function off(elem, type, fn) {
  18102. // Don't want to add a cache object through getElData if not needed
  18103. if (!DomData.hasData(elem)) {
  18104. return;
  18105. }
  18106. var data = DomData.getData(elem);
  18107. // If no events exist, nothing to unbind
  18108. if (!data.handlers) {
  18109. return;
  18110. }
  18111. if (Array.isArray(type)) {
  18112. return _handleMultipleEvents(off, elem, type, fn);
  18113. }
  18114. // Utility function
  18115. var removeType = function removeType(t) {
  18116. data.handlers[t] = [];
  18117. _cleanUpEvents(elem, t);
  18118. };
  18119. // Are we removing all bound events?
  18120. if (!type) {
  18121. for (var t in data.handlers) {
  18122. removeType(t);
  18123. }
  18124. return;
  18125. }
  18126. var handlers = data.handlers[type];
  18127. // If no handlers exist, nothing to unbind
  18128. if (!handlers) {
  18129. return;
  18130. }
  18131. // If no listener was provided, remove all listeners for type
  18132. if (!fn) {
  18133. removeType(type);
  18134. return;
  18135. }
  18136. // We're only removing a single handler
  18137. if (fn.guid) {
  18138. for (var n = 0; n < handlers.length; n++) {
  18139. if (handlers[n].guid === fn.guid) {
  18140. handlers.splice(n--, 1);
  18141. }
  18142. }
  18143. }
  18144. _cleanUpEvents(elem, type);
  18145. }
  18146. /**
  18147. * Trigger an event for an element
  18148. *
  18149. * @param {Element|Object} elem
  18150. * Element to trigger an event on
  18151. *
  18152. * @param {EventTarget~Event|string} event
  18153. * A string (the type) or an event object with a type attribute
  18154. *
  18155. * @param {Object} [hash]
  18156. * data hash to pass along with the event
  18157. *
  18158. * @return {boolean|undefined}
  18159. * - Returns the opposite of `defaultPrevented` if default was prevented
  18160. * - Otherwise returns undefined
  18161. */
  18162. function trigger(elem, event, hash) {
  18163. // Fetches element data and a reference to the parent (for bubbling).
  18164. // Don't want to add a data object to cache for every parent,
  18165. // so checking hasElData first.
  18166. var elemData = DomData.hasData(elem) ? DomData.getData(elem) : {};
  18167. var parent = elem.parentNode || elem.ownerDocument;
  18168. // type = event.type || event,
  18169. // handler;
  18170. // If an event name was passed as a string, creates an event out of it
  18171. if (typeof event === 'string') {
  18172. event = { type: event, target: elem };
  18173. }
  18174. // Normalizes the event properties.
  18175. event = fixEvent(event);
  18176. // If the passed element has a dispatcher, executes the established handlers.
  18177. if (elemData.dispatcher) {
  18178. elemData.dispatcher.call(elem, event, hash);
  18179. }
  18180. // Unless explicitly stopped or the event does not bubble (e.g. media events)
  18181. // recursively calls this function to bubble the event up the DOM.
  18182. if (parent && !event.isPropagationStopped() && event.bubbles === true) {
  18183. trigger.call(null, parent, event, hash);
  18184. // If at the top of the DOM, triggers the default action unless disabled.
  18185. } else if (!parent && !event.defaultPrevented) {
  18186. var targetData = DomData.getData(event.target);
  18187. // Checks if the target has a default action for this event.
  18188. if (event.target[event.type]) {
  18189. // Temporarily disables event dispatching on the target as we have already executed the handler.
  18190. targetData.disabled = true;
  18191. // Executes the default action.
  18192. if (typeof event.target[event.type] === 'function') {
  18193. event.target[event.type]();
  18194. }
  18195. // Re-enables event dispatching.
  18196. targetData.disabled = false;
  18197. }
  18198. }
  18199. // Inform the triggerer if the default was prevented by returning false
  18200. return !event.defaultPrevented;
  18201. }
  18202. /**
  18203. * Trigger a listener only once for an event
  18204. *
  18205. * @param {Element|Object} elem
  18206. * Element or object to bind to.
  18207. *
  18208. * @param {string|string[]} type
  18209. * Name/type of event
  18210. *
  18211. * @param {Event~EventListener} fn
  18212. * Event Listener function
  18213. */
  18214. function one(elem, type, fn) {
  18215. if (Array.isArray(type)) {
  18216. return _handleMultipleEvents(one, elem, type, fn);
  18217. }
  18218. var func = function func() {
  18219. off(elem, type, func);
  18220. fn.apply(this, arguments);
  18221. };
  18222. // copy the guid to the new function so it can removed using the original function's ID
  18223. func.guid = fn.guid = fn.guid || Guid.newGUID();
  18224. on(elem, type, func);
  18225. }
  18226. },{"100":100,"84":84,"90":90,"91":91,"99":99}],87:[function(_dereq_,module,exports){
  18227. 'use strict';
  18228. exports.__esModule = true;
  18229. var _obj = _dereq_(93);
  18230. /**
  18231. * Filter out single bad source objects or multiple source objects in an
  18232. * array. Also flattens nested source object arrays into a 1 dimensional
  18233. * array of source objects.
  18234. *
  18235. * @param {Tech~SourceObject|Tech~SourceObject[]} src
  18236. * The src object to filter
  18237. *
  18238. * @return {Tech~SourceObject[]}
  18239. * An array of sourceobjects containing only valid sources
  18240. *
  18241. * @private
  18242. */
  18243. var filterSource = function filterSource(src) {
  18244. // traverse array
  18245. if (Array.isArray(src)) {
  18246. var newsrc = [];
  18247. src.forEach(function (srcobj) {
  18248. srcobj = filterSource(srcobj);
  18249. if (Array.isArray(srcobj)) {
  18250. newsrc = newsrc.concat(srcobj);
  18251. } else if ((0, _obj.isObject)(srcobj)) {
  18252. newsrc.push(srcobj);
  18253. }
  18254. });
  18255. src = newsrc;
  18256. } else if (typeof src === 'string' && src.trim()) {
  18257. // convert string into object
  18258. src = [{ src: src }];
  18259. } else if ((0, _obj.isObject)(src) && typeof src.src === 'string' && src.src && src.src.trim()) {
  18260. // src is already valid
  18261. src = [src];
  18262. } else {
  18263. // invalid source, turn it into an empty array
  18264. src = [];
  18265. }
  18266. return src;
  18267. }; /**
  18268. * @module filter-source
  18269. */
  18270. exports['default'] = filterSource;
  18271. },{"93":93}],88:[function(_dereq_,module,exports){
  18272. 'use strict';
  18273. exports.__esModule = true;
  18274. exports.throttle = exports.bind = undefined;
  18275. var _guid = _dereq_(90);
  18276. /**
  18277. * Bind (a.k.a proxy or Context). A simple method for changing the context of a function
  18278. * It also stores a unique id on the function so it can be easily removed from events.
  18279. *
  18280. * @param {Mixed} context
  18281. * The object to bind as scope.
  18282. *
  18283. * @param {Function} fn
  18284. * The function to be bound to a scope.
  18285. *
  18286. * @param {number} [uid]
  18287. * An optional unique ID for the function to be set
  18288. *
  18289. * @return {Function}
  18290. * The new function that will be bound into the context given
  18291. */
  18292. var bind = exports.bind = function bind(context, fn, uid) {
  18293. // Make sure the function has a unique ID
  18294. if (!fn.guid) {
  18295. fn.guid = (0, _guid.newGUID)();
  18296. }
  18297. // Create the new function that changes the context
  18298. var bound = function bound() {
  18299. return fn.apply(context, arguments);
  18300. };
  18301. // Allow for the ability to individualize this function
  18302. // Needed in the case where multiple objects might share the same prototype
  18303. // IF both items add an event listener with the same function, then you try to remove just one
  18304. // it will remove both because they both have the same guid.
  18305. // when using this, you need to use the bind method when you remove the listener as well.
  18306. // currently used in text tracks
  18307. bound.guid = uid ? uid + '_' + fn.guid : fn.guid;
  18308. return bound;
  18309. };
  18310. /**
  18311. * Wraps the given function, `fn`, with a new function that only invokes `fn`
  18312. * at most once per every `wait` milliseconds.
  18313. *
  18314. * @param {Function} fn
  18315. * The function to be throttled.
  18316. *
  18317. * @param {Number} wait
  18318. * The number of milliseconds by which to throttle.
  18319. *
  18320. * @return {Function}
  18321. */
  18322. /**
  18323. * @file fn.js
  18324. * @module fn
  18325. */
  18326. var throttle = exports.throttle = function throttle(fn, wait) {
  18327. var last = Date.now();
  18328. var throttled = function throttled() {
  18329. var now = Date.now();
  18330. if (now - last >= wait) {
  18331. fn.apply(undefined, arguments);
  18332. last = now;
  18333. }
  18334. };
  18335. return throttled;
  18336. };
  18337. },{"90":90}],89:[function(_dereq_,module,exports){
  18338. 'use strict';
  18339. exports.__esModule = true;
  18340. /**
  18341. * @file format-time.js
  18342. * @module Format-time
  18343. */
  18344. /**
  18345. * Format seconds as a time string, H:MM:SS or M:SS. Supplying a guide (in seconds)
  18346. * will force a number of leading zeros to cover the length of the guide.
  18347. *
  18348. * @param {number} seconds
  18349. * Number of seconds to be turned into a string
  18350. *
  18351. * @param {number} guide
  18352. * Number (in seconds) to model the string after
  18353. *
  18354. * @return {string}
  18355. * Time formatted as H:MM:SS or M:SS
  18356. */
  18357. function formatTime(seconds) {
  18358. var guide = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : seconds;
  18359. seconds = seconds < 0 ? 0 : seconds;
  18360. var s = Math.floor(seconds % 60);
  18361. var m = Math.floor(seconds / 60 % 60);
  18362. var h = Math.floor(seconds / 3600);
  18363. var gm = Math.floor(guide / 60 % 60);
  18364. var gh = Math.floor(guide / 3600);
  18365. // handle invalid times
  18366. if (isNaN(seconds) || seconds === Infinity) {
  18367. // '-' is false for all relational operators (e.g. <, >=) so this setting
  18368. // will add the minimum number of fields specified by the guide
  18369. h = m = s = '-';
  18370. }
  18371. // Check if we need to show hours
  18372. h = h > 0 || gh > 0 ? h + ':' : '';
  18373. // If hours are showing, we may need to add a leading zero.
  18374. // Always show at least one digit of minutes.
  18375. m = ((h || gm >= 10) && m < 10 ? '0' + m : m) + ':';
  18376. // Check if leading zero is need for seconds
  18377. s = s < 10 ? '0' + s : s;
  18378. return h + m + s;
  18379. }
  18380. exports['default'] = formatTime;
  18381. },{}],90:[function(_dereq_,module,exports){
  18382. "use strict";
  18383. exports.__esModule = true;
  18384. exports.newGUID = newGUID;
  18385. /**
  18386. * @file guid.js
  18387. * @module guid
  18388. */
  18389. /**
  18390. * Unique ID for an element or function
  18391. * @type {Number}
  18392. */
  18393. var _guid = 1;
  18394. /**
  18395. * Get a unique auto-incrementing ID by number that has not been returned before.
  18396. *
  18397. * @return {number}
  18398. * A new unique ID.
  18399. */
  18400. function newGUID() {
  18401. return _guid++;
  18402. }
  18403. },{}],91:[function(_dereq_,module,exports){
  18404. 'use strict';
  18405. exports.__esModule = true;
  18406. exports.logByType = undefined;
  18407. var _window = _dereq_(100);
  18408. var _window2 = _interopRequireDefault(_window);
  18409. var _browser = _dereq_(81);
  18410. var _obj = _dereq_(93);
  18411. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  18412. var log = void 0;
  18413. // This is the private tracking variable for logging level.
  18414. /**
  18415. * @file log.js
  18416. * @module log
  18417. */
  18418. var level = 'all';
  18419. // This is the private tracking variable for the logging history.
  18420. var history = [];
  18421. /**
  18422. * Log messages to the console and history based on the type of message
  18423. *
  18424. * @private
  18425. * @param {string} type
  18426. * The name of the console method to use.
  18427. *
  18428. * @param {Array} args
  18429. * The arguments to be passed to the matching console method.
  18430. *
  18431. * @param {boolean} [stringify]
  18432. * By default, only old IEs should get console argument stringification,
  18433. * but this is exposed as a parameter to facilitate testing.
  18434. */
  18435. var logByType = exports.logByType = function logByType(type, args) {
  18436. var stringify = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : !!_browser.IE_VERSION && _browser.IE_VERSION < 11;
  18437. var lvl = log.levels[level];
  18438. var lvlRegExp = new RegExp('^(' + lvl + ')$');
  18439. if (type !== 'log') {
  18440. // Add the type to the front of the message when it's not "log".
  18441. args.unshift(type.toUpperCase() + ':');
  18442. }
  18443. // Add a clone of the args at this point to history.
  18444. if (history) {
  18445. history.push([].concat(args));
  18446. }
  18447. // Add console prefix after adding to history.
  18448. args.unshift('VIDEOJS:');
  18449. // If there's no console then don't try to output messages, but they will
  18450. // still be stored in history.
  18451. //
  18452. // Was setting these once outside of this function, but containing them
  18453. // in the function makes it easier to test cases where console doesn't exist
  18454. // when the module is executed.
  18455. var fn = _window2['default'].console && _window2['default'].console[type];
  18456. // Bail out if there's no console or if this type is not allowed by the
  18457. // current logging level.
  18458. if (!fn || !lvl || !lvlRegExp.test(type)) {
  18459. return;
  18460. }
  18461. // IEs previous to 11 log objects uselessly as "[object Object]"; so, JSONify
  18462. // objects and arrays for those less-capable browsers.
  18463. if (stringify) {
  18464. args = args.map(function (a) {
  18465. if ((0, _obj.isObject)(a) || Array.isArray(a)) {
  18466. try {
  18467. return JSON.stringify(a);
  18468. } catch (x) {
  18469. return String(a);
  18470. }
  18471. }
  18472. // Cast to string before joining, so we get null and undefined explicitly
  18473. // included in output (as we would in a modern console).
  18474. return String(a);
  18475. }).join(' ');
  18476. }
  18477. // Old IE versions do not allow .apply() for console methods (they are
  18478. // reported as objects rather than functions).
  18479. if (!fn.apply) {
  18480. fn(args);
  18481. } else {
  18482. fn[Array.isArray(args) ? 'apply' : 'call'](_window2['default'].console, args);
  18483. }
  18484. };
  18485. /**
  18486. * Logs plain debug messages. Similar to `console.log`.
  18487. *
  18488. * @class
  18489. * @param {Mixed[]} args
  18490. * One or more messages or objects that should be logged.
  18491. */
  18492. log = function log() {
  18493. for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
  18494. args[_key] = arguments[_key];
  18495. }
  18496. logByType('log', args);
  18497. };
  18498. /**
  18499. * Enumeration of available logging levels, where the keys are the level names
  18500. * and the values are `|`-separated strings containing logging methods allowed
  18501. * in that logging level. These strings are used to create a regular expression
  18502. * matching the function name being called.
  18503. *
  18504. * Levels provided by video.js are:
  18505. *
  18506. * - `off`: Matches no calls. Any value that can be cast to `false` will have
  18507. * this effect. The most restrictive.
  18508. * - `all` (default): Matches only Video.js-provided functions (`log`,
  18509. * `log.warn`, and `log.error`).
  18510. * - `warn`: Matches `log.warn` and `log.error` calls.
  18511. * - `error`: Matches only `log.error` calls.
  18512. *
  18513. * @type {Object}
  18514. */
  18515. log.levels = {
  18516. all: 'log|warn|error',
  18517. error: 'error',
  18518. off: '',
  18519. warn: 'warn|error',
  18520. DEFAULT: level
  18521. };
  18522. /**
  18523. * Get or set the current logging level. If a string matching a key from
  18524. * {@link log.levels} is provided, acts as a setter. Regardless of argument,
  18525. * returns the current logging level.
  18526. *
  18527. * @param {string} [lvl]
  18528. * Pass to set a new logging level.
  18529. *
  18530. * @return {string}
  18531. * The current logging level.
  18532. */
  18533. log.level = function (lvl) {
  18534. if (typeof lvl === 'string') {
  18535. if (!log.levels.hasOwnProperty(lvl)) {
  18536. throw new Error('"' + lvl + '" in not a valid log level');
  18537. }
  18538. level = lvl;
  18539. }
  18540. return level;
  18541. };
  18542. /**
  18543. * Returns an array containing everything that has been logged to the history.
  18544. *
  18545. * This array is a shallow clone of the internal history record. However, its
  18546. * contents are _not_ cloned; so, mutating objects inside this array will
  18547. * mutate them in history.
  18548. *
  18549. * @return {Array}
  18550. */
  18551. log.history = function () {
  18552. return history ? [].concat(history) : [];
  18553. };
  18554. /**
  18555. * Clears the internal history tracking, but does not prevent further history
  18556. * tracking.
  18557. */
  18558. log.history.clear = function () {
  18559. if (history) {
  18560. history.length = 0;
  18561. }
  18562. };
  18563. /**
  18564. * Disable history tracking if it is currently enabled.
  18565. */
  18566. log.history.disable = function () {
  18567. if (history !== null) {
  18568. history.length = 0;
  18569. history = null;
  18570. }
  18571. };
  18572. /**
  18573. * Enable history tracking if it is currently disabled.
  18574. */
  18575. log.history.enable = function () {
  18576. if (history === null) {
  18577. history = [];
  18578. }
  18579. };
  18580. /**
  18581. * Logs error messages. Similar to `console.error`.
  18582. *
  18583. * @param {Mixed[]} args
  18584. * One or more messages or objects that should be logged as an error
  18585. */
  18586. log.error = function () {
  18587. for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
  18588. args[_key2] = arguments[_key2];
  18589. }
  18590. return logByType('error', args);
  18591. };
  18592. /**
  18593. * Logs warning messages. Similar to `console.warn`.
  18594. *
  18595. * @param {Mixed[]} args
  18596. * One or more messages or objects that should be logged as a warning.
  18597. */
  18598. log.warn = function () {
  18599. for (var _len3 = arguments.length, args = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
  18600. args[_key3] = arguments[_key3];
  18601. }
  18602. return logByType('warn', args);
  18603. };
  18604. exports['default'] = log;
  18605. },{"100":100,"81":81,"93":93}],92:[function(_dereq_,module,exports){
  18606. 'use strict';
  18607. exports.__esModule = true;
  18608. exports['default'] = mergeOptions;
  18609. var _obj = _dereq_(93);
  18610. /**
  18611. * Deep-merge one or more options objects, recursively merging **only** plain
  18612. * object properties.
  18613. *
  18614. * @param {Object[]} sources
  18615. * One or more objects to merge into a new object.
  18616. *
  18617. * @returns {Object}
  18618. * A new object that is the merged result of all sources.
  18619. */
  18620. function mergeOptions() {
  18621. var result = {};
  18622. for (var _len = arguments.length, sources = Array(_len), _key = 0; _key < _len; _key++) {
  18623. sources[_key] = arguments[_key];
  18624. }
  18625. sources.forEach(function (source) {
  18626. if (!source) {
  18627. return;
  18628. }
  18629. (0, _obj.each)(source, function (value, key) {
  18630. if (!(0, _obj.isPlain)(value)) {
  18631. result[key] = value;
  18632. return;
  18633. }
  18634. if (!(0, _obj.isPlain)(result[key])) {
  18635. result[key] = {};
  18636. }
  18637. result[key] = mergeOptions(result[key], value);
  18638. });
  18639. });
  18640. return result;
  18641. } /**
  18642. * @file merge-options.js
  18643. * @module merge-options
  18644. */
  18645. },{"93":93}],93:[function(_dereq_,module,exports){
  18646. 'use strict';
  18647. exports.__esModule = true;
  18648. var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
  18649. exports.each = each;
  18650. exports.reduce = reduce;
  18651. exports.assign = assign;
  18652. exports.isObject = isObject;
  18653. exports.isPlain = isPlain;
  18654. /**
  18655. * @file obj.js
  18656. * @module obj
  18657. */
  18658. /**
  18659. * @callback obj:EachCallback
  18660. *
  18661. * @param {Mixed} value
  18662. * The current key for the object that is being iterated over.
  18663. *
  18664. * @param {string} key
  18665. * The current key-value for object that is being iterated over
  18666. */
  18667. /**
  18668. * @callback obj:ReduceCallback
  18669. *
  18670. * @param {Mixed} accum
  18671. * The value that is accumulating over the reduce loop.
  18672. *
  18673. * @param {Mixed} value
  18674. * The current key for the object that is being iterated over.
  18675. *
  18676. * @param {string} key
  18677. * The current key-value for object that is being iterated over
  18678. *
  18679. * @return {Mixed}
  18680. * The new accumulated value.
  18681. */
  18682. var toString = Object.prototype.toString;
  18683. /**
  18684. * Get the keys of an Object
  18685. *
  18686. * @param {Object}
  18687. * The Object to get the keys from
  18688. *
  18689. * @return {string[]}
  18690. * An array of the keys from the object. Returns an empty array if the
  18691. * object passed in was invalid or had no keys.
  18692. *
  18693. * @private
  18694. */
  18695. var keys = function keys(object) {
  18696. return isObject(object) ? Object.keys(object) : [];
  18697. };
  18698. /**
  18699. * Array-like iteration for objects.
  18700. *
  18701. * @param {Object} object
  18702. * The object to iterate over
  18703. *
  18704. * @param {obj:EachCallback} fn
  18705. * The callback function which is called for each key in the object.
  18706. */
  18707. function each(object, fn) {
  18708. keys(object).forEach(function (key) {
  18709. return fn(object[key], key);
  18710. });
  18711. }
  18712. /**
  18713. * Array-like reduce for objects.
  18714. *
  18715. * @param {Object} object
  18716. * The Object that you want to reduce.
  18717. *
  18718. * @param {Function} fn
  18719. * A callback function which is called for each key in the object. It
  18720. * receives the accumulated value and the per-iteration value and key
  18721. * as arguments.
  18722. *
  18723. * @param {Mixed} [initial = 0]
  18724. * Starting value
  18725. *
  18726. * @return {Mixed}
  18727. * The final accumulated value.
  18728. */
  18729. function reduce(object, fn) {
  18730. var initial = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
  18731. return keys(object).reduce(function (accum, key) {
  18732. return fn(accum, object[key], key);
  18733. }, initial);
  18734. }
  18735. /**
  18736. * Object.assign-style object shallow merge/extend.
  18737. *
  18738. * @param {Object} target
  18739. * @param {Object} ...sources
  18740. * @return {Object}
  18741. */
  18742. function assign(target) {
  18743. for (var _len = arguments.length, sources = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
  18744. sources[_key - 1] = arguments[_key];
  18745. }
  18746. if (Object.assign) {
  18747. return Object.assign.apply(Object, [target].concat(sources));
  18748. }
  18749. sources.forEach(function (source) {
  18750. if (!source) {
  18751. return;
  18752. }
  18753. each(source, function (value, key) {
  18754. target[key] = value;
  18755. });
  18756. });
  18757. return target;
  18758. }
  18759. /**
  18760. * Returns whether a value is an object of any kind - including DOM nodes,
  18761. * arrays, regular expressions, etc. Not functions, though.
  18762. *
  18763. * This avoids the gotcha where using `typeof` on a `null` value
  18764. * results in `'object'`.
  18765. *
  18766. * @param {Object} value
  18767. * @return {Boolean}
  18768. */
  18769. function isObject(value) {
  18770. return !!value && (typeof value === 'undefined' ? 'undefined' : _typeof(value)) === 'object';
  18771. }
  18772. /**
  18773. * Returns whether an object appears to be a "plain" object - that is, a
  18774. * direct instance of `Object`.
  18775. *
  18776. * @param {Object} value
  18777. * @return {Boolean}
  18778. */
  18779. function isPlain(value) {
  18780. return isObject(value) && toString.call(value) === '[object Object]' && value.constructor === Object;
  18781. }
  18782. },{}],94:[function(_dereq_,module,exports){
  18783. 'use strict';
  18784. exports.__esModule = true;
  18785. exports.setTextContent = exports.createStyleElement = undefined;
  18786. var _document = _dereq_(99);
  18787. var _document2 = _interopRequireDefault(_document);
  18788. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  18789. /**
  18790. * Create a DOM syle element given a className for it.
  18791. *
  18792. * @param {string} className
  18793. * The className to add to the created style element.
  18794. *
  18795. * @return {Element}
  18796. * The element that was created.
  18797. */
  18798. var createStyleElement = exports.createStyleElement = function createStyleElement(className) {
  18799. var style = _document2['default'].createElement('style');
  18800. style.className = className;
  18801. return style;
  18802. };
  18803. /**
  18804. * Add text to a DOM element.
  18805. *
  18806. * @param {Element} el
  18807. * The Element to add text content to.
  18808. *
  18809. * @param {string} content
  18810. * The text to add to the element.
  18811. */
  18812. /**
  18813. * @file stylesheet.js
  18814. * @module stylesheet
  18815. */
  18816. var setTextContent = exports.setTextContent = function setTextContent(el, content) {
  18817. if (el.styleSheet) {
  18818. el.styleSheet.cssText = content;
  18819. } else {
  18820. el.textContent = content;
  18821. }
  18822. };
  18823. },{"99":99}],95:[function(_dereq_,module,exports){
  18824. 'use strict';
  18825. exports.__esModule = true;
  18826. exports.createTimeRanges = createTimeRanges;
  18827. /**
  18828. * @file time-ranges.js
  18829. * @module time-ranges
  18830. */
  18831. /**
  18832. * Returns the time for the specified index at the start or end
  18833. * of a TimeRange object.
  18834. *
  18835. * @function time-ranges:indexFunction
  18836. *
  18837. * @param {number} [index=0]
  18838. * The range number to return the time for.
  18839. *
  18840. * @return {number}
  18841. * The time that offset at the specified index.
  18842. *
  18843. * @depricated index must be set to a value, in the future this will throw an error.
  18844. */
  18845. /**
  18846. * An object that contains ranges of time for various reasons.
  18847. *
  18848. * @typedef {Object} TimeRange
  18849. *
  18850. * @property {number} length
  18851. * The number of time ranges represented by this Object
  18852. *
  18853. * @property {time-ranges:indexFunction} start
  18854. * Returns the time offset at which a specified time range begins.
  18855. *
  18856. * @property {time-ranges:indexFunction} end
  18857. * Returns the time offset at which a specified time range begins.
  18858. *
  18859. * @see https://developer.mozilla.org/en-US/docs/Web/API/TimeRanges
  18860. */
  18861. /**
  18862. * Check if any of the time ranges are over the maximum index.
  18863. *
  18864. * @param {string} fnName
  18865. * The function name to use for logging
  18866. *
  18867. * @param {number} index
  18868. * The index to check
  18869. *
  18870. * @param {number} maxIndex
  18871. * The maximum possible index
  18872. *
  18873. * @throws {Error} if the timeRanges provided are over the maxIndex
  18874. */
  18875. function rangeCheck(fnName, index, maxIndex) {
  18876. if (typeof index !== 'number' || index < 0 || index > maxIndex) {
  18877. throw new Error('Failed to execute \'' + fnName + '\' on \'TimeRanges\': The index provided (' + index + ') is non-numeric or out of bounds (0-' + maxIndex + ').');
  18878. }
  18879. }
  18880. /**
  18881. * Check if any of the time ranges are over the maximum index.
  18882. *
  18883. * @param {string} fnName
  18884. * The function name to use for logging
  18885. *
  18886. * @param {string} valueIndex
  18887. * The proprety that should be used to get the time. should be 'start' or 'end'
  18888. *
  18889. * @param {Array} ranges
  18890. * An array of time ranges
  18891. *
  18892. * @param {Array} [rangeIndex=0]
  18893. * The index to start the search at
  18894. *
  18895. * @return {number}
  18896. * The time that offset at the specified index.
  18897. *
  18898. *
  18899. * @depricated rangeIndex must be set to a value, in the future this will throw an error.
  18900. * @throws {Error} if rangeIndex is more than the length of ranges
  18901. */
  18902. function getRange(fnName, valueIndex, ranges, rangeIndex) {
  18903. rangeCheck(fnName, rangeIndex, ranges.length - 1);
  18904. return ranges[rangeIndex][valueIndex];
  18905. }
  18906. /**
  18907. * Create a time range object givent ranges of time.
  18908. *
  18909. * @param {Array} [ranges]
  18910. * An array of time ranges.
  18911. */
  18912. function createTimeRangesObj(ranges) {
  18913. if (ranges === undefined || ranges.length === 0) {
  18914. return {
  18915. length: 0,
  18916. start: function start() {
  18917. throw new Error('This TimeRanges object is empty');
  18918. },
  18919. end: function end() {
  18920. throw new Error('This TimeRanges object is empty');
  18921. }
  18922. };
  18923. }
  18924. return {
  18925. length: ranges.length,
  18926. start: getRange.bind(null, 'start', 0, ranges),
  18927. end: getRange.bind(null, 'end', 1, ranges)
  18928. };
  18929. }
  18930. /**
  18931. * Should create a fake `TimeRange` object which mimics an HTML5 time range instance.
  18932. *
  18933. * @param {number|Array} start
  18934. * The start of a single range or an array of ranges
  18935. *
  18936. * @param {number} end
  18937. * The end of a single range.
  18938. *
  18939. * @private
  18940. */
  18941. function createTimeRanges(start, end) {
  18942. if (Array.isArray(start)) {
  18943. return createTimeRangesObj(start);
  18944. } else if (start === undefined || end === undefined) {
  18945. return createTimeRangesObj();
  18946. }
  18947. return createTimeRangesObj([[start, end]]);
  18948. }
  18949. exports.createTimeRange = createTimeRanges;
  18950. },{}],96:[function(_dereq_,module,exports){
  18951. 'use strict';
  18952. exports.__esModule = true;
  18953. /**
  18954. * @file to-title-case.js
  18955. * @module to-title-case
  18956. */
  18957. /**
  18958. * Uppercase the first letter of a string.
  18959. *
  18960. * @param {string} string
  18961. * String to be uppercased
  18962. *
  18963. * @return {string}
  18964. * The string with an uppercased first letter
  18965. */
  18966. function toTitleCase(string) {
  18967. if (typeof string !== 'string') {
  18968. return string;
  18969. }
  18970. return string.charAt(0).toUpperCase() + string.slice(1);
  18971. }
  18972. exports['default'] = toTitleCase;
  18973. },{}],97:[function(_dereq_,module,exports){
  18974. 'use strict';
  18975. exports.__esModule = true;
  18976. exports.isCrossOrigin = exports.getFileExtension = exports.getAbsoluteURL = exports.parseUrl = undefined;
  18977. var _document = _dereq_(99);
  18978. var _document2 = _interopRequireDefault(_document);
  18979. var _window = _dereq_(100);
  18980. var _window2 = _interopRequireDefault(_window);
  18981. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  18982. /**
  18983. * @typedef {Object} url:URLObject
  18984. *
  18985. * @property {string} protocol
  18986. * The protocol of the url that was parsed.
  18987. *
  18988. * @property {string} hostname
  18989. * The hostname of the url that was parsed.
  18990. *
  18991. * @property {string} port
  18992. * The port of the url that was parsed.
  18993. *
  18994. * @property {string} pathname
  18995. * The pathname of the url that was parsed.
  18996. *
  18997. * @property {string} search
  18998. * The search query of the url that was parsed.
  18999. *
  19000. * @property {string} hash
  19001. * The hash of the url that was parsed.
  19002. *
  19003. * @property {string} host
  19004. * The host of the url that was parsed.
  19005. */
  19006. /**
  19007. * Resolve and parse the elements of a URL.
  19008. *
  19009. * @param {String} url
  19010. * The url to parse
  19011. *
  19012. * @return {url:URLObject}
  19013. * An object of url details
  19014. */
  19015. /**
  19016. * @file url.js
  19017. * @module url
  19018. */
  19019. var parseUrl = exports.parseUrl = function parseUrl(url) {
  19020. var props = ['protocol', 'hostname', 'port', 'pathname', 'search', 'hash', 'host'];
  19021. // add the url to an anchor and let the browser parse the URL
  19022. var a = _document2['default'].createElement('a');
  19023. a.href = url;
  19024. // IE8 (and 9?) Fix
  19025. // ie8 doesn't parse the URL correctly until the anchor is actually
  19026. // added to the body, and an innerHTML is needed to trigger the parsing
  19027. var addToBody = a.host === '' && a.protocol !== 'file:';
  19028. var div = void 0;
  19029. if (addToBody) {
  19030. div = _document2['default'].createElement('div');
  19031. div.innerHTML = '<a href="' + url + '"></a>';
  19032. a = div.firstChild;
  19033. // prevent the div from affecting layout
  19034. div.setAttribute('style', 'display:none; position:absolute;');
  19035. _document2['default'].body.appendChild(div);
  19036. }
  19037. // Copy the specific URL properties to a new object
  19038. // This is also needed for IE8 because the anchor loses its
  19039. // properties when it's removed from the dom
  19040. var details = {};
  19041. for (var i = 0; i < props.length; i++) {
  19042. details[props[i]] = a[props[i]];
  19043. }
  19044. // IE9 adds the port to the host property unlike everyone else. If
  19045. // a port identifier is added for standard ports, strip it.
  19046. if (details.protocol === 'http:') {
  19047. details.host = details.host.replace(/:80$/, '');
  19048. }
  19049. if (details.protocol === 'https:') {
  19050. details.host = details.host.replace(/:443$/, '');
  19051. }
  19052. if (addToBody) {
  19053. _document2['default'].body.removeChild(div);
  19054. }
  19055. return details;
  19056. };
  19057. /**
  19058. * Get absolute version of relative URL. Used to tell flash correct URL.
  19059. *
  19060. *
  19061. * @param {string} url
  19062. * URL to make absolute
  19063. *
  19064. * @return {string}
  19065. * Absolute URL
  19066. *
  19067. * @see http://stackoverflow.com/questions/470832/getting-an-absolute-url-from-a-relative-one-ie6-issue
  19068. */
  19069. var getAbsoluteURL = exports.getAbsoluteURL = function getAbsoluteURL(url) {
  19070. // Check if absolute URL
  19071. if (!url.match(/^https?:\/\//)) {
  19072. // Convert to absolute URL. Flash hosted off-site needs an absolute URL.
  19073. var div = _document2['default'].createElement('div');
  19074. div.innerHTML = '<a href="' + url + '">x</a>';
  19075. url = div.firstChild.href;
  19076. }
  19077. return url;
  19078. };
  19079. /**
  19080. * Returns the extension of the passed file name. It will return an empty string
  19081. * if passed an invalid path.
  19082. *
  19083. * @param {string} path
  19084. * The fileName path like '/path/to/file.mp4'
  19085. *
  19086. * @returns {string}
  19087. * The extension in lower case or an empty string if no
  19088. * extension could be found.
  19089. */
  19090. var getFileExtension = exports.getFileExtension = function getFileExtension(path) {
  19091. if (typeof path === 'string') {
  19092. var splitPathRe = /^(\/?)([\s\S]*?)((?:\.{1,2}|[^\/]+?)(\.([^\.\/\?]+)))(?:[\/]*|[\?].*)$/i;
  19093. var pathParts = splitPathRe.exec(path);
  19094. if (pathParts) {
  19095. return pathParts.pop().toLowerCase();
  19096. }
  19097. }
  19098. return '';
  19099. };
  19100. /**
  19101. * Returns whether the url passed is a cross domain request or not.
  19102. *
  19103. * @param {string} url
  19104. * The url to check.
  19105. *
  19106. * @return {boolean}
  19107. * Whether it is a cross domain request or not.
  19108. */
  19109. var isCrossOrigin = exports.isCrossOrigin = function isCrossOrigin(url) {
  19110. var winLoc = _window2['default'].location;
  19111. var urlInfo = parseUrl(url);
  19112. // IE8 protocol relative urls will return ':' for protocol
  19113. var srcProtocol = urlInfo.protocol === ':' ? winLoc.protocol : urlInfo.protocol;
  19114. // Check if url is for another domain/origin
  19115. // IE8 doesn't know location.origin, so we won't rely on it here
  19116. var crossOrigin = srcProtocol + urlInfo.host !== winLoc.protocol + winLoc.host;
  19117. return crossOrigin;
  19118. };
  19119. },{"100":100,"99":99}],98:[function(_dereq_,module,exports){
  19120. 'use strict';
  19121. var _window = _dereq_(100);
  19122. var _window2 = _interopRequireDefault(_window);
  19123. var _document = _dereq_(99);
  19124. var _document2 = _interopRequireDefault(_document);
  19125. var _setup = _dereq_(59);
  19126. var setup = _interopRequireWildcard(_setup);
  19127. var _stylesheet = _dereq_(94);
  19128. var stylesheet = _interopRequireWildcard(_stylesheet);
  19129. var _component = _dereq_(5);
  19130. var _component2 = _interopRequireDefault(_component);
  19131. var _eventTarget = _dereq_(45);
  19132. var _eventTarget2 = _interopRequireDefault(_eventTarget);
  19133. var _events = _dereq_(86);
  19134. var Events = _interopRequireWildcard(_events);
  19135. var _player = _dereq_(56);
  19136. var _player2 = _interopRequireDefault(_player);
  19137. var _plugin = _dereq_(57);
  19138. var _plugin2 = _interopRequireDefault(_plugin);
  19139. var _mergeOptions2 = _dereq_(92);
  19140. var _mergeOptions3 = _interopRequireDefault(_mergeOptions2);
  19141. var _fn = _dereq_(88);
  19142. var Fn = _interopRequireWildcard(_fn);
  19143. var _textTrack = _dereq_(74);
  19144. var _textTrack2 = _interopRequireDefault(_textTrack);
  19145. var _audioTrack = _dereq_(66);
  19146. var _audioTrack2 = _interopRequireDefault(_audioTrack);
  19147. var _videoTrack = _dereq_(80);
  19148. var _videoTrack2 = _interopRequireDefault(_videoTrack);
  19149. var _timeRanges = _dereq_(95);
  19150. var _formatTime = _dereq_(89);
  19151. var _formatTime2 = _interopRequireDefault(_formatTime);
  19152. var _log = _dereq_(91);
  19153. var _log2 = _interopRequireDefault(_log);
  19154. var _dom = _dereq_(85);
  19155. var Dom = _interopRequireWildcard(_dom);
  19156. var _browser = _dereq_(81);
  19157. var browser = _interopRequireWildcard(_browser);
  19158. var _url = _dereq_(97);
  19159. var Url = _interopRequireWildcard(_url);
  19160. var _obj = _dereq_(93);
  19161. var _computedStyle = _dereq_(83);
  19162. var _computedStyle2 = _interopRequireDefault(_computedStyle);
  19163. var _extend = _dereq_(46);
  19164. var _extend2 = _interopRequireDefault(_extend);
  19165. var _xhr = _dereq_(104);
  19166. var _xhr2 = _interopRequireDefault(_xhr);
  19167. var _tech = _dereq_(64);
  19168. var _tech2 = _interopRequireDefault(_tech);
  19169. var _middleware = _dereq_(63);
  19170. function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
  19171. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  19172. // HTML5 Element Shim for IE8
  19173. // Include the built-in techs
  19174. /**
  19175. * @file video.js
  19176. * @module videojs
  19177. */
  19178. if (typeof HTMLVideoElement === 'undefined' && Dom.isReal()) {
  19179. _document2['default'].createElement('video');
  19180. _document2['default'].createElement('audio');
  19181. _document2['default'].createElement('track');
  19182. }
  19183. /**
  19184. * Doubles as the main function for users to create a player instance and also
  19185. * the main library object.
  19186. * The `videojs` function can be used to initialize or retrieve a player.
  19187. *
  19188. * @param {string|Element} id
  19189. * Video element or video element ID
  19190. *
  19191. * @param {Object} [options]
  19192. * Optional options object for config/settings
  19193. *
  19194. * @param {Component~ReadyCallback} [ready]
  19195. * Optional ready callback
  19196. *
  19197. * @return {Player}
  19198. * A player instance
  19199. *
  19200. * @mixes videojs
  19201. */
  19202. function videojs(id, options, ready) {
  19203. var tag = void 0;
  19204. // Allow for element or ID to be passed in
  19205. // String ID
  19206. if (typeof id === 'string') {
  19207. var players = videojs.getPlayers();
  19208. // Adjust for jQuery ID syntax
  19209. if (id.indexOf('#') === 0) {
  19210. id = id.slice(1);
  19211. }
  19212. // If a player instance has already been created for this ID return it.
  19213. if (players[id]) {
  19214. // If options or ready function are passed, warn
  19215. if (options) {
  19216. _log2['default'].warn('Player "' + id + '" is already initialised. Options will not be applied.');
  19217. }
  19218. if (ready) {
  19219. players[id].ready(ready);
  19220. }
  19221. return players[id];
  19222. }
  19223. // Otherwise get element for ID
  19224. tag = Dom.$('#' + id);
  19225. // ID is a media element
  19226. } else {
  19227. tag = id;
  19228. }
  19229. // Check for a useable element
  19230. // re: nodeName, could be a box div also
  19231. if (!tag || !tag.nodeName) {
  19232. throw new TypeError('The element or ID supplied is not valid. (videojs)');
  19233. }
  19234. // Element may have a player attr referring to an already created player instance.
  19235. // If so return that otherwise set up a new player below
  19236. if (tag.player || _player2['default'].players[tag.playerId]) {
  19237. return tag.player || _player2['default'].players[tag.playerId];
  19238. }
  19239. options = options || {};
  19240. videojs.hooks('beforesetup').forEach(function (hookFunction) {
  19241. var opts = hookFunction(tag, (0, _mergeOptions3['default'])(options));
  19242. if (!(0, _obj.isObject)(opts) || Array.isArray(opts)) {
  19243. _log2['default'].error('please return an object in beforesetup hooks');
  19244. return;
  19245. }
  19246. options = (0, _mergeOptions3['default'])(options, opts);
  19247. });
  19248. var PlayerComponent = _component2['default'].getComponent('Player');
  19249. // If not, set up a new player
  19250. var player = new PlayerComponent(tag, options, ready);
  19251. videojs.hooks('setup').forEach(function (hookFunction) {
  19252. return hookFunction(player);
  19253. });
  19254. return player;
  19255. }
  19256. /**
  19257. * An Object that contains lifecycle hooks as keys which point to an array
  19258. * of functions that are run when a lifecycle is triggered
  19259. */
  19260. videojs.hooks_ = {};
  19261. /**
  19262. * Get a list of hooks for a specific lifecycle
  19263. *
  19264. * @param {string} type
  19265. * the lifecyle to get hooks from
  19266. *
  19267. * @param {Function} [fn]
  19268. * Optionally add a hook to the lifecycle that your are getting.
  19269. *
  19270. * @return {Array}
  19271. * an array of hooks, or an empty array if there are none.
  19272. */
  19273. videojs.hooks = function (type, fn) {
  19274. videojs.hooks_[type] = videojs.hooks_[type] || [];
  19275. if (fn) {
  19276. videojs.hooks_[type] = videojs.hooks_[type].concat(fn);
  19277. }
  19278. return videojs.hooks_[type];
  19279. };
  19280. /**
  19281. * Add a function hook to a specific videojs lifecycle.
  19282. *
  19283. * @param {string} type
  19284. * the lifecycle to hook the function to.
  19285. *
  19286. * @param {Function|Function[]}
  19287. * The function or array of functions to attach.
  19288. */
  19289. videojs.hook = function (type, fn) {
  19290. videojs.hooks(type, fn);
  19291. };
  19292. /**
  19293. * Remove a hook from a specific videojs lifecycle.
  19294. *
  19295. * @param {string} type
  19296. * the lifecycle that the function hooked to
  19297. *
  19298. * @param {Function} fn
  19299. * The hooked function to remove
  19300. *
  19301. * @return {boolean}
  19302. * The function that was removed or undef
  19303. */
  19304. videojs.removeHook = function (type, fn) {
  19305. var index = videojs.hooks(type).indexOf(fn);
  19306. if (index <= -1) {
  19307. return false;
  19308. }
  19309. videojs.hooks_[type] = videojs.hooks_[type].slice();
  19310. videojs.hooks_[type].splice(index, 1);
  19311. return true;
  19312. };
  19313. // Add default styles
  19314. if (_window2['default'].VIDEOJS_NO_DYNAMIC_STYLE !== true && Dom.isReal()) {
  19315. var style = Dom.$('.vjs-styles-defaults');
  19316. if (!style) {
  19317. style = stylesheet.createStyleElement('vjs-styles-defaults');
  19318. var head = Dom.$('head');
  19319. if (head) {
  19320. head.insertBefore(style, head.firstChild);
  19321. }
  19322. stylesheet.setTextContent(style, '\n .video-js {\n width: 300px;\n height: 150px;\n }\n\n .vjs-fluid {\n padding-top: 56.25%\n }\n ');
  19323. }
  19324. }
  19325. // Run Auto-load players
  19326. // You have to wait at least once in case this script is loaded after your
  19327. // video in the DOM (weird behavior only with minified version)
  19328. setup.autoSetupTimeout(1, videojs);
  19329. /**
  19330. * Current software version. Follows semver.
  19331. *
  19332. * @type {string}
  19333. */
  19334. videojs.VERSION = '6.0.0-RC.5';
  19335. /**
  19336. * The global options object. These are the settings that take effect
  19337. * if no overrides are specified when the player is created.
  19338. *
  19339. * @type {Object}
  19340. */
  19341. videojs.options = _player2['default'].prototype.options_;
  19342. /**
  19343. * Get an object with the currently created players, keyed by player ID
  19344. *
  19345. * @return {Object}
  19346. * The created players
  19347. */
  19348. videojs.getPlayers = function () {
  19349. return _player2['default'].players;
  19350. };
  19351. /**
  19352. * Expose players object.
  19353. *
  19354. * @memberOf videojs
  19355. * @property {Object} players
  19356. */
  19357. videojs.players = _player2['default'].players;
  19358. /**
  19359. * Get a component class object by name
  19360. *
  19361. * @borrows Component.getComponent as videojs.getComponent
  19362. */
  19363. videojs.getComponent = _component2['default'].getComponent;
  19364. /**
  19365. * Register a component so it can referred to by name. Used when adding to other
  19366. * components, either through addChild `component.addChild('myComponent')` or through
  19367. * default children options `{ children: ['myComponent'] }`.
  19368. *
  19369. * > NOTE: You could also just initialize the component before adding.
  19370. * `component.addChild(new MyComponent());`
  19371. *
  19372. * @param {string} name
  19373. * The class name of the component
  19374. *
  19375. * @param {Component} comp
  19376. * The component class
  19377. *
  19378. * @return {Component}
  19379. * The newly registered component
  19380. */
  19381. videojs.registerComponent = function (name, comp) {
  19382. if (_tech2['default'].isTech(comp)) {
  19383. _log2['default'].warn('The ' + name + ' tech was registered as a component. It should instead be registered using videojs.registerTech(name, tech)');
  19384. }
  19385. _component2['default'].registerComponent.call(_component2['default'], name, comp);
  19386. };
  19387. /**
  19388. * Get a Tech class object by name
  19389. *
  19390. * @borrows Tech.getTech as videojs.getTech
  19391. */
  19392. videojs.getTech = _tech2['default'].getTech;
  19393. /**
  19394. * Register a Tech so it can referred to by name.
  19395. * This is used in the tech order for the player.
  19396. *
  19397. * @borrows Tech.registerTech as videojs.registerTech
  19398. */
  19399. videojs.registerTech = _tech2['default'].registerTech;
  19400. videojs.use = _middleware.use;
  19401. /**
  19402. * A suite of browser and device tests from {@link browser}.
  19403. *
  19404. * @type {Object}
  19405. * @private
  19406. */
  19407. videojs.browser = browser;
  19408. /**
  19409. * Whether or not the browser supports touch events. Included for backward
  19410. * compatibility with 4.x, but deprecated. Use `videojs.browser.TOUCH_ENABLED`
  19411. * instead going forward.
  19412. *
  19413. * @deprecated since version 5.0
  19414. * @type {boolean}
  19415. */
  19416. videojs.TOUCH_ENABLED = browser.TOUCH_ENABLED;
  19417. /**
  19418. * Subclass an existing class
  19419. * Mimics ES6 subclassing with the `extend` keyword
  19420. *
  19421. * @borrows extend:extendFn as videojs.extend
  19422. */
  19423. videojs.extend = _extend2['default'];
  19424. /**
  19425. * Merge two options objects recursively
  19426. * Performs a deep merge like lodash.merge but **only merges plain objects**
  19427. * (not arrays, elements, anything else)
  19428. * Other values will be copied directly from the second object.
  19429. *
  19430. * @borrows merge-options:mergeOptions as videojs.mergeOptions
  19431. */
  19432. videojs.mergeOptions = _mergeOptions3['default'];
  19433. /**
  19434. * Change the context (this) of a function
  19435. *
  19436. * > NOTE: as of v5.0 we require an ES5 shim, so you should use the native
  19437. * `function() {}.bind(newContext);` instead of this.
  19438. *
  19439. * @borrows fn:bind as videojs.bind
  19440. */
  19441. videojs.bind = Fn.bind;
  19442. /**
  19443. * Register a Video.js plugin.
  19444. *
  19445. * @borrows plugin:registerPlugin as videojs.registerPlugin
  19446. * @mixes videojs
  19447. * @method registerPlugin
  19448. *
  19449. * @param {string} name
  19450. * The name of the plugin to be registered. Must be a string and
  19451. * must not match an existing plugin or a method on the `Player`
  19452. * prototype.
  19453. *
  19454. * @param {Function} plugin
  19455. * A sub-class of `Plugin` or a function for basic plugins.
  19456. *
  19457. * @return {Function}
  19458. * For advanced plugins, a factory function for that plugin. For
  19459. * basic plugins, a wrapper function that initializes the plugin.
  19460. */
  19461. videojs.registerPlugin = _plugin2['default'].registerPlugin;
  19462. /**
  19463. * Deprecated method to register a plugin with Video.js
  19464. *
  19465. * @deprecated
  19466. * videojs.plugin() is deprecated; use videojs.registerPlugin() instead
  19467. *
  19468. * @param {string} name
  19469. * The plugin name
  19470. *
  19471. * @param {Plugin|Function} plugin
  19472. * The plugin sub-class or function
  19473. */
  19474. videojs.plugin = function (name, plugin) {
  19475. _log2['default'].warn('videojs.plugin() is deprecated; use videojs.registerPlugin() instead');
  19476. return _plugin2['default'].registerPlugin(name, plugin);
  19477. };
  19478. /**
  19479. * Gets an object containing multiple Video.js plugins.
  19480. *
  19481. * @param {Array} [names]
  19482. * If provided, should be an array of plugin names. Defaults to _all_
  19483. * plugin names.
  19484. *
  19485. * @return {Object|undefined}
  19486. * An object containing plugin(s) associated with their name(s) or
  19487. * `undefined` if no matching plugins exist).
  19488. */
  19489. videojs.getPlugins = _plugin2['default'].getPlugins;
  19490. /**
  19491. * Gets a plugin by name if it exists.
  19492. *
  19493. * @param {string} name
  19494. * The name of a plugin.
  19495. *
  19496. * @return {Function|undefined}
  19497. * The plugin (or `undefined`).
  19498. */
  19499. videojs.getPlugin = _plugin2['default'].getPlugin;
  19500. /**
  19501. * Gets a plugin's version, if available
  19502. *
  19503. * @param {string} name
  19504. * The name of a plugin.
  19505. *
  19506. * @return {string}
  19507. * The plugin's version or an empty string.
  19508. */
  19509. videojs.getPluginVersion = _plugin2['default'].getPluginVersion;
  19510. /**
  19511. * Adding languages so that they're available to all players.
  19512. * Example: `videojs.addLanguage('es', { 'Hello': 'Hola' });`
  19513. *
  19514. * @param {string} code
  19515. * The language code or dictionary property
  19516. *
  19517. * @param {Object} data
  19518. * The data values to be translated
  19519. *
  19520. * @return {Object}
  19521. * The resulting language dictionary object
  19522. */
  19523. videojs.addLanguage = function (code, data) {
  19524. var _mergeOptions;
  19525. code = ('' + code).toLowerCase();
  19526. videojs.options.languages = (0, _mergeOptions3['default'])(videojs.options.languages, (_mergeOptions = {}, _mergeOptions[code] = data, _mergeOptions));
  19527. return videojs.options.languages[code];
  19528. };
  19529. /**
  19530. * Log messages
  19531. *
  19532. * @borrows log:log as videojs.log
  19533. */
  19534. videojs.log = _log2['default'];
  19535. /**
  19536. * Creates an emulated TimeRange object.
  19537. *
  19538. * @borrows time-ranges:createTimeRanges as videojs.createTimeRange
  19539. */
  19540. /**
  19541. * @borrows time-ranges:createTimeRanges as videojs.createTimeRanges
  19542. */
  19543. videojs.createTimeRange = videojs.createTimeRanges = _timeRanges.createTimeRanges;
  19544. /**
  19545. * Format seconds as a time string, H:MM:SS or M:SS
  19546. * Supplying a guide (in seconds) will force a number of leading zeros
  19547. * to cover the length of the guide
  19548. *
  19549. * @borrows format-time:formatTime as videojs.formatTime
  19550. */
  19551. videojs.formatTime = _formatTime2['default'];
  19552. /**
  19553. * Resolve and parse the elements of a URL
  19554. *
  19555. * @borrows url:parseUrl as videojs.parseUrl
  19556. */
  19557. videojs.parseUrl = Url.parseUrl;
  19558. /**
  19559. * Returns whether the url passed is a cross domain request or not.
  19560. *
  19561. * @borrows url:isCrossOrigin as videojs.isCrossOrigin
  19562. */
  19563. videojs.isCrossOrigin = Url.isCrossOrigin;
  19564. /**
  19565. * Event target class.
  19566. *
  19567. * @borrows EventTarget as videojs.EventTarget
  19568. */
  19569. videojs.EventTarget = _eventTarget2['default'];
  19570. /**
  19571. * Add an event listener to element
  19572. * It stores the handler function in a separate cache object
  19573. * and adds a generic handler to the element's event,
  19574. * along with a unique id (guid) to the element.
  19575. *
  19576. * @borrows events:on as videojs.on
  19577. */
  19578. videojs.on = Events.on;
  19579. /**
  19580. * Trigger a listener only once for an event
  19581. *
  19582. * @borrows events:one as videojs.one
  19583. */
  19584. videojs.one = Events.one;
  19585. /**
  19586. * Removes event listeners from an element
  19587. *
  19588. * @borrows events:off as videojs.off
  19589. */
  19590. videojs.off = Events.off;
  19591. /**
  19592. * Trigger an event for an element
  19593. *
  19594. * @borrows events:trigger as videojs.trigger
  19595. */
  19596. videojs.trigger = Events.trigger;
  19597. /**
  19598. * A cross-browser XMLHttpRequest wrapper. Here's a simple example:
  19599. *
  19600. * @param {Object} options
  19601. * settings for the request.
  19602. *
  19603. * @return {XMLHttpRequest|XDomainRequest}
  19604. * The request object.
  19605. *
  19606. * @see https://github.com/Raynos/xhr
  19607. */
  19608. videojs.xhr = _xhr2['default'];
  19609. /**
  19610. * TextTrack class
  19611. *
  19612. * @borrows TextTrack as videojs.TextTrack
  19613. */
  19614. videojs.TextTrack = _textTrack2['default'];
  19615. /**
  19616. * export the AudioTrack class so that source handlers can create
  19617. * AudioTracks and then add them to the players AudioTrackList
  19618. *
  19619. * @borrows AudioTrack as videojs.AudioTrack
  19620. */
  19621. videojs.AudioTrack = _audioTrack2['default'];
  19622. /**
  19623. * export the VideoTrack class so that source handlers can create
  19624. * VideoTracks and then add them to the players VideoTrackList
  19625. *
  19626. * @borrows VideoTrack as videojs.VideoTrack
  19627. */
  19628. videojs.VideoTrack = _videoTrack2['default'];
  19629. /**
  19630. * Determines, via duck typing, whether or not a value is a DOM element.
  19631. *
  19632. * @borrows dom:isEl as videojs.isEl
  19633. * @deprecated Use videojs.dom.isEl() instead
  19634. */
  19635. /**
  19636. * Determines, via duck typing, whether or not a value is a text node.
  19637. *
  19638. * @borrows dom:isTextNode as videojs.isTextNode
  19639. * @deprecated Use videojs.dom.isTextNode() instead
  19640. */
  19641. /**
  19642. * Creates an element and applies properties.
  19643. *
  19644. * @borrows dom:createEl as videojs.createEl
  19645. * @deprecated Use videojs.dom.createEl() instead
  19646. */
  19647. /**
  19648. * Check if an element has a CSS class
  19649. *
  19650. * @borrows dom:hasElClass as videojs.hasClass
  19651. * @deprecated Use videojs.dom.hasClass() instead
  19652. */
  19653. /**
  19654. * Add a CSS class name to an element
  19655. *
  19656. * @borrows dom:addElClass as videojs.addClass
  19657. * @deprecated Use videojs.dom.addClass() instead
  19658. */
  19659. /**
  19660. * Remove a CSS class name from an element
  19661. *
  19662. * @borrows dom:removeElClass as videojs.removeClass
  19663. * @deprecated Use videojs.dom.removeClass() instead
  19664. */
  19665. /**
  19666. * Adds or removes a CSS class name on an element depending on an optional
  19667. * condition or the presence/absence of the class name.
  19668. *
  19669. * @borrows dom:toggleElClass as videojs.toggleClass
  19670. * @deprecated Use videojs.dom.toggleClass() instead
  19671. */
  19672. /**
  19673. * Apply attributes to an HTML element.
  19674. *
  19675. * @borrows dom:setElAttributes as videojs.setAttribute
  19676. * @deprecated Use videojs.dom.setAttributes() instead
  19677. */
  19678. /**
  19679. * Get an element's attribute values, as defined on the HTML tag
  19680. * Attributes are not the same as properties. They're defined on the tag
  19681. * or with setAttribute (which shouldn't be used with HTML)
  19682. * This will return true or false for boolean attributes.
  19683. *
  19684. * @borrows dom:getElAttributes as videojs.getAttributes
  19685. * @deprecated Use videojs.dom.getAttributes() instead
  19686. */
  19687. /**
  19688. * Empties the contents of an element.
  19689. *
  19690. * @borrows dom:emptyEl as videojs.emptyEl
  19691. * @deprecated Use videojs.dom.emptyEl() instead
  19692. */
  19693. /**
  19694. * Normalizes and appends content to an element.
  19695. *
  19696. * The content for an element can be passed in multiple types and
  19697. * combinations, whose behavior is as follows:
  19698. *
  19699. * - String
  19700. * Normalized into a text node.
  19701. *
  19702. * - Element, TextNode
  19703. * Passed through.
  19704. *
  19705. * - Array
  19706. * A one-dimensional array of strings, elements, nodes, or functions (which
  19707. * return single strings, elements, or nodes).
  19708. *
  19709. * - Function
  19710. * If the sole argument, is expected to produce a string, element,
  19711. * node, or array.
  19712. *
  19713. * @borrows dom:appendContents as videojs.appendContet
  19714. * @deprecated Use videojs.dom.appendContent() instead
  19715. */
  19716. /**
  19717. * Normalizes and inserts content into an element; this is identical to
  19718. * `appendContent()`, except it empties the element first.
  19719. *
  19720. * The content for an element can be passed in multiple types and
  19721. * combinations, whose behavior is as follows:
  19722. *
  19723. * - String
  19724. * Normalized into a text node.
  19725. *
  19726. * - Element, TextNode
  19727. * Passed through.
  19728. *
  19729. * - Array
  19730. * A one-dimensional array of strings, elements, nodes, or functions (which
  19731. * return single strings, elements, or nodes).
  19732. *
  19733. * - Function
  19734. * If the sole argument, is expected to produce a string, element,
  19735. * node, or array.
  19736. *
  19737. * @borrows dom:insertContent as videojs.insertContent
  19738. * @deprecated Use videojs.dom.insertContent() instead
  19739. */
  19740. ['isEl', 'isTextNode', 'createEl', 'hasClass', 'addClass', 'removeClass', 'toggleClass', 'setAttributes', 'getAttributes', 'emptyEl', 'appendContent', 'insertContent'].forEach(function (k) {
  19741. videojs[k] = function () {
  19742. _log2['default'].warn('videojs.' + k + '() is deprecated; use videojs.dom.' + k + '() instead');
  19743. return Dom[k].apply(null, arguments);
  19744. };
  19745. });
  19746. /**
  19747. * A safe getComputedStyle with an IE8 fallback.
  19748. *
  19749. * This is because in Firefox, if the player is loaded in an iframe with `display:none`,
  19750. * then `getComputedStyle` returns `null`, so, we do a null-check to make sure
  19751. * that the player doesn't break in these cases.
  19752. * See https://bugzilla.mozilla.org/show_bug.cgi?id=548397 for more details.
  19753. *
  19754. * @borrows computed-style:computedStyle as videojs.computedStyle
  19755. */
  19756. videojs.computedStyle = _computedStyle2['default'];
  19757. /**
  19758. * Export the Dom utilities for use in external plugins
  19759. * and Tech's
  19760. */
  19761. videojs.dom = Dom;
  19762. /**
  19763. * Export the Url utilities for use in external plugins
  19764. * and Tech's
  19765. */
  19766. videojs.url = Url;
  19767. // We use Node-style module.exports here instead of ES6 because it is more
  19768. // compatible with different module systems.
  19769. module.exports = videojs;
  19770. },{"100":100,"104":104,"45":45,"46":46,"5":5,"56":56,"57":57,"59":59,"63":63,"64":64,"66":66,"74":74,"80":80,"81":81,"83":83,"85":85,"86":86,"88":88,"89":89,"91":91,"92":92,"93":93,"94":94,"95":95,"97":97,"99":99}],99:[function(_dereq_,module,exports){
  19771. (function (global){
  19772. var topLevel = typeof global !== 'undefined' ? global :
  19773. typeof window !== 'undefined' ? window : {}
  19774. var minDoc = _dereq_(101);
  19775. if (typeof document !== 'undefined') {
  19776. module.exports = document;
  19777. } else {
  19778. var doccy = topLevel['__GLOBAL_DOCUMENT_CACHE@4'];
  19779. if (!doccy) {
  19780. doccy = topLevel['__GLOBAL_DOCUMENT_CACHE@4'] = minDoc;
  19781. }
  19782. module.exports = doccy;
  19783. }
  19784. }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
  19785. },{"101":101}],100:[function(_dereq_,module,exports){
  19786. (function (global){
  19787. if (typeof window !== "undefined") {
  19788. module.exports = window;
  19789. } else if (typeof global !== "undefined") {
  19790. module.exports = global;
  19791. } else if (typeof self !== "undefined"){
  19792. module.exports = self;
  19793. } else {
  19794. module.exports = {};
  19795. }
  19796. }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
  19797. },{}],101:[function(_dereq_,module,exports){
  19798. },{}],102:[function(_dereq_,module,exports){
  19799. module.exports = SafeParseTuple
  19800. function SafeParseTuple(obj, reviver) {
  19801. var json
  19802. var error = null
  19803. try {
  19804. json = JSON.parse(obj, reviver)
  19805. } catch (err) {
  19806. error = err
  19807. }
  19808. return [error, json]
  19809. }
  19810. },{}],103:[function(_dereq_,module,exports){
  19811. function clean (s) {
  19812. return s.replace(/\n\r?\s*/g, '')
  19813. }
  19814. module.exports = function tsml (sa) {
  19815. var s = ''
  19816. , i = 0
  19817. for (; i < arguments.length; i++)
  19818. s += clean(sa[i]) + (arguments[i + 1] || '')
  19819. return s
  19820. }
  19821. },{}],104:[function(_dereq_,module,exports){
  19822. "use strict";
  19823. var window = _dereq_(100)
  19824. var isFunction = _dereq_(105)
  19825. var parseHeaders = _dereq_(108)
  19826. var xtend = _dereq_(109)
  19827. module.exports = createXHR
  19828. createXHR.XMLHttpRequest = window.XMLHttpRequest || noop
  19829. createXHR.XDomainRequest = "withCredentials" in (new createXHR.XMLHttpRequest()) ? createXHR.XMLHttpRequest : window.XDomainRequest
  19830. forEachArray(["get", "put", "post", "patch", "head", "delete"], function(method) {
  19831. createXHR[method === "delete" ? "del" : method] = function(uri, options, callback) {
  19832. options = initParams(uri, options, callback)
  19833. options.method = method.toUpperCase()
  19834. return _createXHR(options)
  19835. }
  19836. })
  19837. function forEachArray(array, iterator) {
  19838. for (var i = 0; i < array.length; i++) {
  19839. iterator(array[i])
  19840. }
  19841. }
  19842. function isEmpty(obj){
  19843. for(var i in obj){
  19844. if(obj.hasOwnProperty(i)) return false
  19845. }
  19846. return true
  19847. }
  19848. function initParams(uri, options, callback) {
  19849. var params = uri
  19850. if (isFunction(options)) {
  19851. callback = options
  19852. if (typeof uri === "string") {
  19853. params = {uri:uri}
  19854. }
  19855. } else {
  19856. params = xtend(options, {uri: uri})
  19857. }
  19858. params.callback = callback
  19859. return params
  19860. }
  19861. function createXHR(uri, options, callback) {
  19862. options = initParams(uri, options, callback)
  19863. return _createXHR(options)
  19864. }
  19865. function _createXHR(options) {
  19866. if(typeof options.callback === "undefined"){
  19867. throw new Error("callback argument missing")
  19868. }
  19869. var called = false
  19870. var callback = function cbOnce(err, response, body){
  19871. if(!called){
  19872. called = true
  19873. options.callback(err, response, body)
  19874. }
  19875. }
  19876. function readystatechange() {
  19877. if (xhr.readyState === 4) {
  19878. setTimeout(loadFunc, 0)
  19879. }
  19880. }
  19881. function getBody() {
  19882. // Chrome with requestType=blob throws errors arround when even testing access to responseText
  19883. var body = undefined
  19884. if (xhr.response) {
  19885. body = xhr.response
  19886. } else {
  19887. body = xhr.responseText || getXml(xhr)
  19888. }
  19889. if (isJson) {
  19890. try {
  19891. body = JSON.parse(body)
  19892. } catch (e) {}
  19893. }
  19894. return body
  19895. }
  19896. function errorFunc(evt) {
  19897. clearTimeout(timeoutTimer)
  19898. if(!(evt instanceof Error)){
  19899. evt = new Error("" + (evt || "Unknown XMLHttpRequest Error") )
  19900. }
  19901. evt.statusCode = 0
  19902. return callback(evt, failureResponse)
  19903. }
  19904. // will load the data & process the response in a special response object
  19905. function loadFunc() {
  19906. if (aborted) return
  19907. var status
  19908. clearTimeout(timeoutTimer)
  19909. if(options.useXDR && xhr.status===undefined) {
  19910. //IE8 CORS GET successful response doesn't have a status field, but body is fine
  19911. status = 200
  19912. } else {
  19913. status = (xhr.status === 1223 ? 204 : xhr.status)
  19914. }
  19915. var response = failureResponse
  19916. var err = null
  19917. if (status !== 0){
  19918. response = {
  19919. body: getBody(),
  19920. statusCode: status,
  19921. method: method,
  19922. headers: {},
  19923. url: uri,
  19924. rawRequest: xhr
  19925. }
  19926. if(xhr.getAllResponseHeaders){ //remember xhr can in fact be XDR for CORS in IE
  19927. response.headers = parseHeaders(xhr.getAllResponseHeaders())
  19928. }
  19929. } else {
  19930. err = new Error("Internal XMLHttpRequest Error")
  19931. }
  19932. return callback(err, response, response.body)
  19933. }
  19934. var xhr = options.xhr || null
  19935. if (!xhr) {
  19936. if (options.cors || options.useXDR) {
  19937. xhr = new createXHR.XDomainRequest()
  19938. }else{
  19939. xhr = new createXHR.XMLHttpRequest()
  19940. }
  19941. }
  19942. var key
  19943. var aborted
  19944. var uri = xhr.url = options.uri || options.url
  19945. var method = xhr.method = options.method || "GET"
  19946. var body = options.body || options.data
  19947. var headers = xhr.headers = options.headers || {}
  19948. var sync = !!options.sync
  19949. var isJson = false
  19950. var timeoutTimer
  19951. var failureResponse = {
  19952. body: undefined,
  19953. headers: {},
  19954. statusCode: 0,
  19955. method: method,
  19956. url: uri,
  19957. rawRequest: xhr
  19958. }
  19959. if ("json" in options && options.json !== false) {
  19960. isJson = true
  19961. headers["accept"] || headers["Accept"] || (headers["Accept"] = "application/json") //Don't override existing accept header declared by user
  19962. if (method !== "GET" && method !== "HEAD") {
  19963. headers["content-type"] || headers["Content-Type"] || (headers["Content-Type"] = "application/json") //Don't override existing accept header declared by user
  19964. body = JSON.stringify(options.json === true ? body : options.json)
  19965. }
  19966. }
  19967. xhr.onreadystatechange = readystatechange
  19968. xhr.onload = loadFunc
  19969. xhr.onerror = errorFunc
  19970. // IE9 must have onprogress be set to a unique function.
  19971. xhr.onprogress = function () {
  19972. // IE must die
  19973. }
  19974. xhr.onabort = function(){
  19975. aborted = true;
  19976. }
  19977. xhr.ontimeout = errorFunc
  19978. xhr.open(method, uri, !sync, options.username, options.password)
  19979. //has to be after open
  19980. if(!sync) {
  19981. xhr.withCredentials = !!options.withCredentials
  19982. }
  19983. // Cannot set timeout with sync request
  19984. // not setting timeout on the xhr object, because of old webkits etc. not handling that correctly
  19985. // both npm's request and jquery 1.x use this kind of timeout, so this is being consistent
  19986. if (!sync && options.timeout > 0 ) {
  19987. timeoutTimer = setTimeout(function(){
  19988. if (aborted) return
  19989. aborted = true//IE9 may still call readystatechange
  19990. xhr.abort("timeout")
  19991. var e = new Error("XMLHttpRequest timeout")
  19992. e.code = "ETIMEDOUT"
  19993. errorFunc(e)
  19994. }, options.timeout )
  19995. }
  19996. if (xhr.setRequestHeader) {
  19997. for(key in headers){
  19998. if(headers.hasOwnProperty(key)){
  19999. xhr.setRequestHeader(key, headers[key])
  20000. }
  20001. }
  20002. } else if (options.headers && !isEmpty(options.headers)) {
  20003. throw new Error("Headers cannot be set on an XDomainRequest object")
  20004. }
  20005. if ("responseType" in options) {
  20006. xhr.responseType = options.responseType
  20007. }
  20008. if ("beforeSend" in options &&
  20009. typeof options.beforeSend === "function"
  20010. ) {
  20011. options.beforeSend(xhr)
  20012. }
  20013. // Microsoft Edge browser sends "undefined" when send is called with undefined value.
  20014. // XMLHttpRequest spec says to pass null as body to indicate no body
  20015. // See https://github.com/naugtur/xhr/issues/100.
  20016. xhr.send(body || null)
  20017. return xhr
  20018. }
  20019. function getXml(xhr) {
  20020. if (xhr.responseType === "document") {
  20021. return xhr.responseXML
  20022. }
  20023. var firefoxBugTakenEffect = xhr.responseXML && xhr.responseXML.documentElement.nodeName === "parsererror"
  20024. if (xhr.responseType === "" && !firefoxBugTakenEffect) {
  20025. return xhr.responseXML
  20026. }
  20027. return null
  20028. }
  20029. function noop() {}
  20030. },{"100":100,"105":105,"108":108,"109":109}],105:[function(_dereq_,module,exports){
  20031. module.exports = isFunction
  20032. var toString = Object.prototype.toString
  20033. function isFunction (fn) {
  20034. var string = toString.call(fn)
  20035. return string === '[object Function]' ||
  20036. (typeof fn === 'function' && string !== '[object RegExp]') ||
  20037. (typeof window !== 'undefined' &&
  20038. // IE8 and below
  20039. (fn === window.setTimeout ||
  20040. fn === window.alert ||
  20041. fn === window.confirm ||
  20042. fn === window.prompt))
  20043. };
  20044. },{}],106:[function(_dereq_,module,exports){
  20045. var isFunction = _dereq_(105)
  20046. module.exports = forEach
  20047. var toString = Object.prototype.toString
  20048. var hasOwnProperty = Object.prototype.hasOwnProperty
  20049. function forEach(list, iterator, context) {
  20050. if (!isFunction(iterator)) {
  20051. throw new TypeError('iterator must be a function')
  20052. }
  20053. if (arguments.length < 3) {
  20054. context = this
  20055. }
  20056. if (toString.call(list) === '[object Array]')
  20057. forEachArray(list, iterator, context)
  20058. else if (typeof list === 'string')
  20059. forEachString(list, iterator, context)
  20060. else
  20061. forEachObject(list, iterator, context)
  20062. }
  20063. function forEachArray(array, iterator, context) {
  20064. for (var i = 0, len = array.length; i < len; i++) {
  20065. if (hasOwnProperty.call(array, i)) {
  20066. iterator.call(context, array[i], i, array)
  20067. }
  20068. }
  20069. }
  20070. function forEachString(string, iterator, context) {
  20071. for (var i = 0, len = string.length; i < len; i++) {
  20072. // no such thing as a sparse string.
  20073. iterator.call(context, string.charAt(i), i, string)
  20074. }
  20075. }
  20076. function forEachObject(object, iterator, context) {
  20077. for (var k in object) {
  20078. if (hasOwnProperty.call(object, k)) {
  20079. iterator.call(context, object[k], k, object)
  20080. }
  20081. }
  20082. }
  20083. },{"105":105}],107:[function(_dereq_,module,exports){
  20084. exports = module.exports = trim;
  20085. function trim(str){
  20086. return str.replace(/^\s*|\s*$/g, '');
  20087. }
  20088. exports.left = function(str){
  20089. return str.replace(/^\s*/, '');
  20090. };
  20091. exports.right = function(str){
  20092. return str.replace(/\s*$/, '');
  20093. };
  20094. },{}],108:[function(_dereq_,module,exports){
  20095. var trim = _dereq_(107)
  20096. , forEach = _dereq_(106)
  20097. , isArray = function(arg) {
  20098. return Object.prototype.toString.call(arg) === '[object Array]';
  20099. }
  20100. module.exports = function (headers) {
  20101. if (!headers)
  20102. return {}
  20103. var result = {}
  20104. forEach(
  20105. trim(headers).split('\n')
  20106. , function (row) {
  20107. var index = row.indexOf(':')
  20108. , key = trim(row.slice(0, index)).toLowerCase()
  20109. , value = trim(row.slice(index + 1))
  20110. if (typeof(result[key]) === 'undefined') {
  20111. result[key] = value
  20112. } else if (isArray(result[key])) {
  20113. result[key].push(value)
  20114. } else {
  20115. result[key] = [ result[key], value ]
  20116. }
  20117. }
  20118. )
  20119. return result
  20120. }
  20121. },{"106":106,"107":107}],109:[function(_dereq_,module,exports){
  20122. module.exports = extend
  20123. var hasOwnProperty = Object.prototype.hasOwnProperty;
  20124. function extend() {
  20125. var target = {}
  20126. for (var i = 0; i < arguments.length; i++) {
  20127. var source = arguments[i]
  20128. for (var key in source) {
  20129. if (hasOwnProperty.call(source, key)) {
  20130. target[key] = source[key]
  20131. }
  20132. }
  20133. }
  20134. return target
  20135. }
  20136. },{}],110:[function(_dereq_,module,exports){
  20137. /**
  20138. * Copyright 2013 vtt.js Contributors
  20139. *
  20140. * Licensed under the Apache License, Version 2.0 (the "License");
  20141. * you may not use this file except in compliance with the License.
  20142. * You may obtain a copy of the License at
  20143. *
  20144. * http://www.apache.org/licenses/LICENSE-2.0
  20145. *
  20146. * Unless required by applicable law or agreed to in writing, software
  20147. * distributed under the License is distributed on an "AS IS" BASIS,
  20148. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  20149. * See the License for the specific language governing permissions and
  20150. * limitations under the License.
  20151. */
  20152. // Default exports for Node. Export the extended versions of VTTCue and
  20153. // VTTRegion in Node since we likely want the capability to convert back and
  20154. // forth between JSON. If we don't then it's not that big of a deal since we're
  20155. // off browser.
  20156. var vttjs = module.exports = {
  20157. WebVTT: _dereq_(111).WebVTT,
  20158. VTTCue: _dereq_(112).VTTCue,
  20159. VTTRegion: _dereq_(114).VTTRegion
  20160. };
  20161. window.vttjs = vttjs;
  20162. window.WebVTT = vttjs.WebVTT;
  20163. var cueShim = vttjs.VTTCue;
  20164. var regionShim = vttjs.VTTRegion;
  20165. var oldVTTCue = window.VTTCue;
  20166. var oldVTTRegion = window.VTTRegion;
  20167. vttjs.shim = function() {
  20168. window.VTTCue = cueShim;
  20169. window.VTTRegion = regionShim;
  20170. };
  20171. vttjs.restore = function() {
  20172. window.VTTCue = oldVTTCue;
  20173. window.VTTRegion = oldVTTRegion;
  20174. };
  20175. if (!window.VTTCue) {
  20176. vttjs.shim();
  20177. }
  20178. },{"111":111,"112":112,"114":114}],111:[function(_dereq_,module,exports){
  20179. /**
  20180. * Copyright 2013 vtt.js Contributors
  20181. *
  20182. * Licensed under the Apache License, Version 2.0 (the "License");
  20183. * you may not use this file except in compliance with the License.
  20184. * You may obtain a copy of the License at
  20185. *
  20186. * http://www.apache.org/licenses/LICENSE-2.0
  20187. *
  20188. * Unless required by applicable law or agreed to in writing, software
  20189. * distributed under the License is distributed on an "AS IS" BASIS,
  20190. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  20191. * See the License for the specific language governing permissions and
  20192. * limitations under the License.
  20193. */
  20194. /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  20195. /* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
  20196. (function(global) {
  20197. var _objCreate = Object.create || (function() {
  20198. function F() {}
  20199. return function(o) {
  20200. if (arguments.length !== 1) {
  20201. throw new Error('Object.create shim only accepts one parameter.');
  20202. }
  20203. F.prototype = o;
  20204. return new F();
  20205. };
  20206. })();
  20207. // Creates a new ParserError object from an errorData object. The errorData
  20208. // object should have default code and message properties. The default message
  20209. // property can be overriden by passing in a message parameter.
  20210. // See ParsingError.Errors below for acceptable errors.
  20211. function ParsingError(errorData, message) {
  20212. this.name = "ParsingError";
  20213. this.code = errorData.code;
  20214. this.message = message || errorData.message;
  20215. }
  20216. ParsingError.prototype = _objCreate(Error.prototype);
  20217. ParsingError.prototype.constructor = ParsingError;
  20218. // ParsingError metadata for acceptable ParsingErrors.
  20219. ParsingError.Errors = {
  20220. BadSignature: {
  20221. code: 0,
  20222. message: "Malformed WebVTT signature."
  20223. },
  20224. BadTimeStamp: {
  20225. code: 1,
  20226. message: "Malformed time stamp."
  20227. }
  20228. };
  20229. // Try to parse input as a time stamp.
  20230. function parseTimeStamp(input) {
  20231. function computeSeconds(h, m, s, f) {
  20232. return (h | 0) * 3600 + (m | 0) * 60 + (s | 0) + (f | 0) / 1000;
  20233. }
  20234. var m = input.match(/^(\d+):(\d{2})(:\d{2})?\.(\d{3})/);
  20235. if (!m) {
  20236. return null;
  20237. }
  20238. if (m[3]) {
  20239. // Timestamp takes the form of [hours]:[minutes]:[seconds].[milliseconds]
  20240. return computeSeconds(m[1], m[2], m[3].replace(":", ""), m[4]);
  20241. } else if (m[1] > 59) {
  20242. // Timestamp takes the form of [hours]:[minutes].[milliseconds]
  20243. // First position is hours as it's over 59.
  20244. return computeSeconds(m[1], m[2], 0, m[4]);
  20245. } else {
  20246. // Timestamp takes the form of [minutes]:[seconds].[milliseconds]
  20247. return computeSeconds(0, m[1], m[2], m[4]);
  20248. }
  20249. }
  20250. // A settings object holds key/value pairs and will ignore anything but the first
  20251. // assignment to a specific key.
  20252. function Settings() {
  20253. this.values = _objCreate(null);
  20254. }
  20255. Settings.prototype = {
  20256. // Only accept the first assignment to any key.
  20257. set: function(k, v) {
  20258. if (!this.get(k) && v !== "") {
  20259. this.values[k] = v;
  20260. }
  20261. },
  20262. // Return the value for a key, or a default value.
  20263. // If 'defaultKey' is passed then 'dflt' is assumed to be an object with
  20264. // a number of possible default values as properties where 'defaultKey' is
  20265. // the key of the property that will be chosen; otherwise it's assumed to be
  20266. // a single value.
  20267. get: function(k, dflt, defaultKey) {
  20268. if (defaultKey) {
  20269. return this.has(k) ? this.values[k] : dflt[defaultKey];
  20270. }
  20271. return this.has(k) ? this.values[k] : dflt;
  20272. },
  20273. // Check whether we have a value for a key.
  20274. has: function(k) {
  20275. return k in this.values;
  20276. },
  20277. // Accept a setting if its one of the given alternatives.
  20278. alt: function(k, v, a) {
  20279. for (var n = 0; n < a.length; ++n) {
  20280. if (v === a[n]) {
  20281. this.set(k, v);
  20282. break;
  20283. }
  20284. }
  20285. },
  20286. // Accept a setting if its a valid (signed) integer.
  20287. integer: function(k, v) {
  20288. if (/^-?\d+$/.test(v)) { // integer
  20289. this.set(k, parseInt(v, 10));
  20290. }
  20291. },
  20292. // Accept a setting if its a valid percentage.
  20293. percent: function(k, v) {
  20294. var m;
  20295. if ((m = v.match(/^([\d]{1,3})(\.[\d]*)?%$/))) {
  20296. v = parseFloat(v);
  20297. if (v >= 0 && v <= 100) {
  20298. this.set(k, v);
  20299. return true;
  20300. }
  20301. }
  20302. return false;
  20303. }
  20304. };
  20305. // Helper function to parse input into groups separated by 'groupDelim', and
  20306. // interprete each group as a key/value pair separated by 'keyValueDelim'.
  20307. function parseOptions(input, callback, keyValueDelim, groupDelim) {
  20308. var groups = groupDelim ? input.split(groupDelim) : [input];
  20309. for (var i in groups) {
  20310. if (typeof groups[i] !== "string") {
  20311. continue;
  20312. }
  20313. var kv = groups[i].split(keyValueDelim);
  20314. if (kv.length !== 2) {
  20315. continue;
  20316. }
  20317. var k = kv[0];
  20318. var v = kv[1];
  20319. callback(k, v);
  20320. }
  20321. }
  20322. function parseCue(input, cue, regionList) {
  20323. // Remember the original input if we need to throw an error.
  20324. var oInput = input;
  20325. // 4.1 WebVTT timestamp
  20326. function consumeTimeStamp() {
  20327. var ts = parseTimeStamp(input);
  20328. if (ts === null) {
  20329. throw new ParsingError(ParsingError.Errors.BadTimeStamp,
  20330. "Malformed timestamp: " + oInput);
  20331. }
  20332. // Remove time stamp from input.
  20333. input = input.replace(/^[^\sa-zA-Z-]+/, "");
  20334. return ts;
  20335. }
  20336. // 4.4.2 WebVTT cue settings
  20337. function consumeCueSettings(input, cue) {
  20338. var settings = new Settings();
  20339. parseOptions(input, function (k, v) {
  20340. switch (k) {
  20341. case "region":
  20342. // Find the last region we parsed with the same region id.
  20343. for (var i = regionList.length - 1; i >= 0; i--) {
  20344. if (regionList[i].id === v) {
  20345. settings.set(k, regionList[i].region);
  20346. break;
  20347. }
  20348. }
  20349. break;
  20350. case "vertical":
  20351. settings.alt(k, v, ["rl", "lr"]);
  20352. break;
  20353. case "line":
  20354. var vals = v.split(","),
  20355. vals0 = vals[0];
  20356. settings.integer(k, vals0);
  20357. settings.percent(k, vals0) ? settings.set("snapToLines", false) : null;
  20358. settings.alt(k, vals0, ["auto"]);
  20359. if (vals.length === 2) {
  20360. settings.alt("lineAlign", vals[1], ["start", "middle", "end"]);
  20361. }
  20362. break;
  20363. case "position":
  20364. vals = v.split(",");
  20365. settings.percent(k, vals[0]);
  20366. if (vals.length === 2) {
  20367. settings.alt("positionAlign", vals[1], ["start", "middle", "end"]);
  20368. }
  20369. break;
  20370. case "size":
  20371. settings.percent(k, v);
  20372. break;
  20373. case "align":
  20374. settings.alt(k, v, ["start", "middle", "end", "left", "right"]);
  20375. break;
  20376. }
  20377. }, /:/, /\s/);
  20378. // Apply default values for any missing fields.
  20379. cue.region = settings.get("region", null);
  20380. cue.vertical = settings.get("vertical", "");
  20381. cue.line = settings.get("line", "auto");
  20382. cue.lineAlign = settings.get("lineAlign", "start");
  20383. cue.snapToLines = settings.get("snapToLines", true);
  20384. cue.size = settings.get("size", 100);
  20385. cue.align = settings.get("align", "middle");
  20386. cue.position = settings.get("position", {
  20387. start: 0,
  20388. left: 0,
  20389. middle: 50,
  20390. end: 100,
  20391. right: 100
  20392. }, cue.align);
  20393. cue.positionAlign = settings.get("positionAlign", {
  20394. start: "start",
  20395. left: "start",
  20396. middle: "middle",
  20397. end: "end",
  20398. right: "end"
  20399. }, cue.align);
  20400. }
  20401. function skipWhitespace() {
  20402. input = input.replace(/^\s+/, "");
  20403. }
  20404. // 4.1 WebVTT cue timings.
  20405. skipWhitespace();
  20406. cue.startTime = consumeTimeStamp(); // (1) collect cue start time
  20407. skipWhitespace();
  20408. if (input.substr(0, 3) !== "-->") { // (3) next characters must match "-->"
  20409. throw new ParsingError(ParsingError.Errors.BadTimeStamp,
  20410. "Malformed time stamp (time stamps must be separated by '-->'): " +
  20411. oInput);
  20412. }
  20413. input = input.substr(3);
  20414. skipWhitespace();
  20415. cue.endTime = consumeTimeStamp(); // (5) collect cue end time
  20416. // 4.1 WebVTT cue settings list.
  20417. skipWhitespace();
  20418. consumeCueSettings(input, cue);
  20419. }
  20420. var ESCAPE = {
  20421. "&amp;": "&",
  20422. "&lt;": "<",
  20423. "&gt;": ">",
  20424. "&lrm;": "\u200e",
  20425. "&rlm;": "\u200f",
  20426. "&nbsp;": "\u00a0"
  20427. };
  20428. var TAG_NAME = {
  20429. c: "span",
  20430. i: "i",
  20431. b: "b",
  20432. u: "u",
  20433. ruby: "ruby",
  20434. rt: "rt",
  20435. v: "span",
  20436. lang: "span"
  20437. };
  20438. var TAG_ANNOTATION = {
  20439. v: "title",
  20440. lang: "lang"
  20441. };
  20442. var NEEDS_PARENT = {
  20443. rt: "ruby"
  20444. };
  20445. // Parse content into a document fragment.
  20446. function parseContent(window, input) {
  20447. function nextToken() {
  20448. // Check for end-of-string.
  20449. if (!input) {
  20450. return null;
  20451. }
  20452. // Consume 'n' characters from the input.
  20453. function consume(result) {
  20454. input = input.substr(result.length);
  20455. return result;
  20456. }
  20457. var m = input.match(/^([^<]*)(<[^>]+>?)?/);
  20458. // If there is some text before the next tag, return it, otherwise return
  20459. // the tag.
  20460. return consume(m[1] ? m[1] : m[2]);
  20461. }
  20462. // Unescape a string 's'.
  20463. function unescape1(e) {
  20464. return ESCAPE[e];
  20465. }
  20466. function unescape(s) {
  20467. while ((m = s.match(/&(amp|lt|gt|lrm|rlm|nbsp);/))) {
  20468. s = s.replace(m[0], unescape1);
  20469. }
  20470. return s;
  20471. }
  20472. function shouldAdd(current, element) {
  20473. return !NEEDS_PARENT[element.localName] ||
  20474. NEEDS_PARENT[element.localName] === current.localName;
  20475. }
  20476. // Create an element for this tag.
  20477. function createElement(type, annotation) {
  20478. var tagName = TAG_NAME[type];
  20479. if (!tagName) {
  20480. return null;
  20481. }
  20482. var element = window.document.createElement(tagName);
  20483. element.localName = tagName;
  20484. var name = TAG_ANNOTATION[type];
  20485. if (name && annotation) {
  20486. element[name] = annotation.trim();
  20487. }
  20488. return element;
  20489. }
  20490. var rootDiv = window.document.createElement("div"),
  20491. current = rootDiv,
  20492. t,
  20493. tagStack = [];
  20494. while ((t = nextToken()) !== null) {
  20495. if (t[0] === '<') {
  20496. if (t[1] === "/") {
  20497. // If the closing tag matches, move back up to the parent node.
  20498. if (tagStack.length &&
  20499. tagStack[tagStack.length - 1] === t.substr(2).replace(">", "")) {
  20500. tagStack.pop();
  20501. current = current.parentNode;
  20502. }
  20503. // Otherwise just ignore the end tag.
  20504. continue;
  20505. }
  20506. var ts = parseTimeStamp(t.substr(1, t.length - 2));
  20507. var node;
  20508. if (ts) {
  20509. // Timestamps are lead nodes as well.
  20510. node = window.document.createProcessingInstruction("timestamp", ts);
  20511. current.appendChild(node);
  20512. continue;
  20513. }
  20514. var m = t.match(/^<([^.\s/0-9>]+)(\.[^\s\\>]+)?([^>\\]+)?(\\?)>?$/);
  20515. // If we can't parse the tag, skip to the next tag.
  20516. if (!m) {
  20517. continue;
  20518. }
  20519. // Try to construct an element, and ignore the tag if we couldn't.
  20520. node = createElement(m[1], m[3]);
  20521. if (!node) {
  20522. continue;
  20523. }
  20524. // Determine if the tag should be added based on the context of where it
  20525. // is placed in the cuetext.
  20526. if (!shouldAdd(current, node)) {
  20527. continue;
  20528. }
  20529. // Set the class list (as a list of classes, separated by space).
  20530. if (m[2]) {
  20531. node.className = m[2].substr(1).replace('.', ' ');
  20532. }
  20533. // Append the node to the current node, and enter the scope of the new
  20534. // node.
  20535. tagStack.push(m[1]);
  20536. current.appendChild(node);
  20537. current = node;
  20538. continue;
  20539. }
  20540. // Text nodes are leaf nodes.
  20541. current.appendChild(window.document.createTextNode(unescape(t)));
  20542. }
  20543. return rootDiv;
  20544. }
  20545. // This is a list of all the Unicode characters that have a strong
  20546. // right-to-left category. What this means is that these characters are
  20547. // written right-to-left for sure. It was generated by pulling all the strong
  20548. // right-to-left characters out of the Unicode data table. That table can
  20549. // found at: http://www.unicode.org/Public/UNIDATA/UnicodeData.txt
  20550. var strongRTLRanges = [[0x5be, 0x5be], [0x5c0, 0x5c0], [0x5c3, 0x5c3], [0x5c6, 0x5c6],
  20551. [0x5d0, 0x5ea], [0x5f0, 0x5f4], [0x608, 0x608], [0x60b, 0x60b], [0x60d, 0x60d],
  20552. [0x61b, 0x61b], [0x61e, 0x64a], [0x66d, 0x66f], [0x671, 0x6d5], [0x6e5, 0x6e6],
  20553. [0x6ee, 0x6ef], [0x6fa, 0x70d], [0x70f, 0x710], [0x712, 0x72f], [0x74d, 0x7a5],
  20554. [0x7b1, 0x7b1], [0x7c0, 0x7ea], [0x7f4, 0x7f5], [0x7fa, 0x7fa], [0x800, 0x815],
  20555. [0x81a, 0x81a], [0x824, 0x824], [0x828, 0x828], [0x830, 0x83e], [0x840, 0x858],
  20556. [0x85e, 0x85e], [0x8a0, 0x8a0], [0x8a2, 0x8ac], [0x200f, 0x200f],
  20557. [0xfb1d, 0xfb1d], [0xfb1f, 0xfb28], [0xfb2a, 0xfb36], [0xfb38, 0xfb3c],
  20558. [0xfb3e, 0xfb3e], [0xfb40, 0xfb41], [0xfb43, 0xfb44], [0xfb46, 0xfbc1],
  20559. [0xfbd3, 0xfd3d], [0xfd50, 0xfd8f], [0xfd92, 0xfdc7], [0xfdf0, 0xfdfc],
  20560. [0xfe70, 0xfe74], [0xfe76, 0xfefc], [0x10800, 0x10805], [0x10808, 0x10808],
  20561. [0x1080a, 0x10835], [0x10837, 0x10838], [0x1083c, 0x1083c], [0x1083f, 0x10855],
  20562. [0x10857, 0x1085f], [0x10900, 0x1091b], [0x10920, 0x10939], [0x1093f, 0x1093f],
  20563. [0x10980, 0x109b7], [0x109be, 0x109bf], [0x10a00, 0x10a00], [0x10a10, 0x10a13],
  20564. [0x10a15, 0x10a17], [0x10a19, 0x10a33], [0x10a40, 0x10a47], [0x10a50, 0x10a58],
  20565. [0x10a60, 0x10a7f], [0x10b00, 0x10b35], [0x10b40, 0x10b55], [0x10b58, 0x10b72],
  20566. [0x10b78, 0x10b7f], [0x10c00, 0x10c48], [0x1ee00, 0x1ee03], [0x1ee05, 0x1ee1f],
  20567. [0x1ee21, 0x1ee22], [0x1ee24, 0x1ee24], [0x1ee27, 0x1ee27], [0x1ee29, 0x1ee32],
  20568. [0x1ee34, 0x1ee37], [0x1ee39, 0x1ee39], [0x1ee3b, 0x1ee3b], [0x1ee42, 0x1ee42],
  20569. [0x1ee47, 0x1ee47], [0x1ee49, 0x1ee49], [0x1ee4b, 0x1ee4b], [0x1ee4d, 0x1ee4f],
  20570. [0x1ee51, 0x1ee52], [0x1ee54, 0x1ee54], [0x1ee57, 0x1ee57], [0x1ee59, 0x1ee59],
  20571. [0x1ee5b, 0x1ee5b], [0x1ee5d, 0x1ee5d], [0x1ee5f, 0x1ee5f], [0x1ee61, 0x1ee62],
  20572. [0x1ee64, 0x1ee64], [0x1ee67, 0x1ee6a], [0x1ee6c, 0x1ee72], [0x1ee74, 0x1ee77],
  20573. [0x1ee79, 0x1ee7c], [0x1ee7e, 0x1ee7e], [0x1ee80, 0x1ee89], [0x1ee8b, 0x1ee9b],
  20574. [0x1eea1, 0x1eea3], [0x1eea5, 0x1eea9], [0x1eeab, 0x1eebb], [0x10fffd, 0x10fffd]];
  20575. function isStrongRTLChar(charCode) {
  20576. for (var i = 0; i < strongRTLRanges.length; i++) {
  20577. var currentRange = strongRTLRanges[i];
  20578. if (charCode >= currentRange[0] && charCode <= currentRange[1]) {
  20579. return true;
  20580. }
  20581. }
  20582. return false;
  20583. }
  20584. function determineBidi(cueDiv) {
  20585. var nodeStack = [],
  20586. text = "",
  20587. charCode;
  20588. if (!cueDiv || !cueDiv.childNodes) {
  20589. return "ltr";
  20590. }
  20591. function pushNodes(nodeStack, node) {
  20592. for (var i = node.childNodes.length - 1; i >= 0; i--) {
  20593. nodeStack.push(node.childNodes[i]);
  20594. }
  20595. }
  20596. function nextTextNode(nodeStack) {
  20597. if (!nodeStack || !nodeStack.length) {
  20598. return null;
  20599. }
  20600. var node = nodeStack.pop(),
  20601. text = node.textContent || node.innerText;
  20602. if (text) {
  20603. // TODO: This should match all unicode type B characters (paragraph
  20604. // separator characters). See issue #115.
  20605. var m = text.match(/^.*(\n|\r)/);
  20606. if (m) {
  20607. nodeStack.length = 0;
  20608. return m[0];
  20609. }
  20610. return text;
  20611. }
  20612. if (node.tagName === "ruby") {
  20613. return nextTextNode(nodeStack);
  20614. }
  20615. if (node.childNodes) {
  20616. pushNodes(nodeStack, node);
  20617. return nextTextNode(nodeStack);
  20618. }
  20619. }
  20620. pushNodes(nodeStack, cueDiv);
  20621. while ((text = nextTextNode(nodeStack))) {
  20622. for (var i = 0; i < text.length; i++) {
  20623. charCode = text.charCodeAt(i);
  20624. if (isStrongRTLChar(charCode)) {
  20625. return "rtl";
  20626. }
  20627. }
  20628. }
  20629. return "ltr";
  20630. }
  20631. function computeLinePos(cue) {
  20632. if (typeof cue.line === "number" &&
  20633. (cue.snapToLines || (cue.line >= 0 && cue.line <= 100))) {
  20634. return cue.line;
  20635. }
  20636. if (!cue.track || !cue.track.textTrackList ||
  20637. !cue.track.textTrackList.mediaElement) {
  20638. return -1;
  20639. }
  20640. var track = cue.track,
  20641. trackList = track.textTrackList,
  20642. count = 0;
  20643. for (var i = 0; i < trackList.length && trackList[i] !== track; i++) {
  20644. if (trackList[i].mode === "showing") {
  20645. count++;
  20646. }
  20647. }
  20648. return ++count * -1;
  20649. }
  20650. function StyleBox() {
  20651. }
  20652. // Apply styles to a div. If there is no div passed then it defaults to the
  20653. // div on 'this'.
  20654. StyleBox.prototype.applyStyles = function(styles, div) {
  20655. div = div || this.div;
  20656. for (var prop in styles) {
  20657. if (styles.hasOwnProperty(prop)) {
  20658. div.style[prop] = styles[prop];
  20659. }
  20660. }
  20661. };
  20662. StyleBox.prototype.formatStyle = function(val, unit) {
  20663. return val === 0 ? 0 : val + unit;
  20664. };
  20665. // Constructs the computed display state of the cue (a div). Places the div
  20666. // into the overlay which should be a block level element (usually a div).
  20667. function CueStyleBox(window, cue, styleOptions) {
  20668. var isIE8 = (/MSIE\s8\.0/).test(navigator.userAgent);
  20669. var color = "rgba(255, 255, 255, 1)";
  20670. var backgroundColor = "rgba(0, 0, 0, 0.8)";
  20671. if (isIE8) {
  20672. color = "rgb(255, 255, 255)";
  20673. backgroundColor = "rgb(0, 0, 0)";
  20674. }
  20675. StyleBox.call(this);
  20676. this.cue = cue;
  20677. // Parse our cue's text into a DOM tree rooted at 'cueDiv'. This div will
  20678. // have inline positioning and will function as the cue background box.
  20679. this.cueDiv = parseContent(window, cue.text);
  20680. var styles = {
  20681. color: color,
  20682. backgroundColor: backgroundColor,
  20683. position: "relative",
  20684. left: 0,
  20685. right: 0,
  20686. top: 0,
  20687. bottom: 0,
  20688. display: "inline"
  20689. };
  20690. if (!isIE8) {
  20691. styles.writingMode = cue.vertical === "" ? "horizontal-tb"
  20692. : cue.vertical === "lr" ? "vertical-lr"
  20693. : "vertical-rl";
  20694. styles.unicodeBidi = "plaintext";
  20695. }
  20696. this.applyStyles(styles, this.cueDiv);
  20697. // Create an absolutely positioned div that will be used to position the cue
  20698. // div. Note, all WebVTT cue-setting alignments are equivalent to the CSS
  20699. // mirrors of them except "middle" which is "center" in CSS.
  20700. this.div = window.document.createElement("div");
  20701. styles = {
  20702. textAlign: cue.align === "middle" ? "center" : cue.align,
  20703. font: styleOptions.font,
  20704. whiteSpace: "pre-line",
  20705. position: "absolute"
  20706. };
  20707. if (!isIE8) {
  20708. styles.direction = determineBidi(this.cueDiv);
  20709. styles.writingMode = cue.vertical === "" ? "horizontal-tb"
  20710. : cue.vertical === "lr" ? "vertical-lr"
  20711. : "vertical-rl".
  20712. stylesunicodeBidi = "plaintext";
  20713. }
  20714. this.applyStyles(styles);
  20715. this.div.appendChild(this.cueDiv);
  20716. // Calculate the distance from the reference edge of the viewport to the text
  20717. // position of the cue box. The reference edge will be resolved later when
  20718. // the box orientation styles are applied.
  20719. var textPos = 0;
  20720. switch (cue.positionAlign) {
  20721. case "start":
  20722. textPos = cue.position;
  20723. break;
  20724. case "middle":
  20725. textPos = cue.position - (cue.size / 2);
  20726. break;
  20727. case "end":
  20728. textPos = cue.position - cue.size;
  20729. break;
  20730. }
  20731. // Horizontal box orientation; textPos is the distance from the left edge of the
  20732. // area to the left edge of the box and cue.size is the distance extending to
  20733. // the right from there.
  20734. if (cue.vertical === "") {
  20735. this.applyStyles({
  20736. left: this.formatStyle(textPos, "%"),
  20737. width: this.formatStyle(cue.size, "%")
  20738. });
  20739. // Vertical box orientation; textPos is the distance from the top edge of the
  20740. // area to the top edge of the box and cue.size is the height extending
  20741. // downwards from there.
  20742. } else {
  20743. this.applyStyles({
  20744. top: this.formatStyle(textPos, "%"),
  20745. height: this.formatStyle(cue.size, "%")
  20746. });
  20747. }
  20748. this.move = function(box) {
  20749. this.applyStyles({
  20750. top: this.formatStyle(box.top, "px"),
  20751. bottom: this.formatStyle(box.bottom, "px"),
  20752. left: this.formatStyle(box.left, "px"),
  20753. right: this.formatStyle(box.right, "px"),
  20754. height: this.formatStyle(box.height, "px"),
  20755. width: this.formatStyle(box.width, "px")
  20756. });
  20757. };
  20758. }
  20759. CueStyleBox.prototype = _objCreate(StyleBox.prototype);
  20760. CueStyleBox.prototype.constructor = CueStyleBox;
  20761. // Represents the co-ordinates of an Element in a way that we can easily
  20762. // compute things with such as if it overlaps or intersects with another Element.
  20763. // Can initialize it with either a StyleBox or another BoxPosition.
  20764. function BoxPosition(obj) {
  20765. var isIE8 = (/MSIE\s8\.0/).test(navigator.userAgent);
  20766. // Either a BoxPosition was passed in and we need to copy it, or a StyleBox
  20767. // was passed in and we need to copy the results of 'getBoundingClientRect'
  20768. // as the object returned is readonly. All co-ordinate values are in reference
  20769. // to the viewport origin (top left).
  20770. var lh, height, width, top;
  20771. if (obj.div) {
  20772. height = obj.div.offsetHeight;
  20773. width = obj.div.offsetWidth;
  20774. top = obj.div.offsetTop;
  20775. var rects = (rects = obj.div.childNodes) && (rects = rects[0]) &&
  20776. rects.getClientRects && rects.getClientRects();
  20777. obj = obj.div.getBoundingClientRect();
  20778. // In certain cases the outter div will be slightly larger then the sum of
  20779. // the inner div's lines. This could be due to bold text, etc, on some platforms.
  20780. // In this case we should get the average line height and use that. This will
  20781. // result in the desired behaviour.
  20782. lh = rects ? Math.max((rects[0] && rects[0].height) || 0, obj.height / rects.length)
  20783. : 0;
  20784. }
  20785. this.left = obj.left;
  20786. this.right = obj.right;
  20787. this.top = obj.top || top;
  20788. this.height = obj.height || height;
  20789. this.bottom = obj.bottom || (top + (obj.height || height));
  20790. this.width = obj.width || width;
  20791. this.lineHeight = lh !== undefined ? lh : obj.lineHeight;
  20792. if (isIE8 && !this.lineHeight) {
  20793. this.lineHeight = 13;
  20794. }
  20795. }
  20796. // Move the box along a particular axis. Optionally pass in an amount to move
  20797. // the box. If no amount is passed then the default is the line height of the
  20798. // box.
  20799. BoxPosition.prototype.move = function(axis, toMove) {
  20800. toMove = toMove !== undefined ? toMove : this.lineHeight;
  20801. switch (axis) {
  20802. case "+x":
  20803. this.left += toMove;
  20804. this.right += toMove;
  20805. break;
  20806. case "-x":
  20807. this.left -= toMove;
  20808. this.right -= toMove;
  20809. break;
  20810. case "+y":
  20811. this.top += toMove;
  20812. this.bottom += toMove;
  20813. break;
  20814. case "-y":
  20815. this.top -= toMove;
  20816. this.bottom -= toMove;
  20817. break;
  20818. }
  20819. };
  20820. // Check if this box overlaps another box, b2.
  20821. BoxPosition.prototype.overlaps = function(b2) {
  20822. return this.left < b2.right &&
  20823. this.right > b2.left &&
  20824. this.top < b2.bottom &&
  20825. this.bottom > b2.top;
  20826. };
  20827. // Check if this box overlaps any other boxes in boxes.
  20828. BoxPosition.prototype.overlapsAny = function(boxes) {
  20829. for (var i = 0; i < boxes.length; i++) {
  20830. if (this.overlaps(boxes[i])) {
  20831. return true;
  20832. }
  20833. }
  20834. return false;
  20835. };
  20836. // Check if this box is within another box.
  20837. BoxPosition.prototype.within = function(container) {
  20838. return this.top >= container.top &&
  20839. this.bottom <= container.bottom &&
  20840. this.left >= container.left &&
  20841. this.right <= container.right;
  20842. };
  20843. // Check if this box is entirely within the container or it is overlapping
  20844. // on the edge opposite of the axis direction passed. For example, if "+x" is
  20845. // passed and the box is overlapping on the left edge of the container, then
  20846. // return true.
  20847. BoxPosition.prototype.overlapsOppositeAxis = function(container, axis) {
  20848. switch (axis) {
  20849. case "+x":
  20850. return this.left < container.left;
  20851. case "-x":
  20852. return this.right > container.right;
  20853. case "+y":
  20854. return this.top < container.top;
  20855. case "-y":
  20856. return this.bottom > container.bottom;
  20857. }
  20858. };
  20859. // Find the percentage of the area that this box is overlapping with another
  20860. // box.
  20861. BoxPosition.prototype.intersectPercentage = function(b2) {
  20862. var x = Math.max(0, Math.min(this.right, b2.right) - Math.max(this.left, b2.left)),
  20863. y = Math.max(0, Math.min(this.bottom, b2.bottom) - Math.max(this.top, b2.top)),
  20864. intersectArea = x * y;
  20865. return intersectArea / (this.height * this.width);
  20866. };
  20867. // Convert the positions from this box to CSS compatible positions using
  20868. // the reference container's positions. This has to be done because this
  20869. // box's positions are in reference to the viewport origin, whereas, CSS
  20870. // values are in referecne to their respective edges.
  20871. BoxPosition.prototype.toCSSCompatValues = function(reference) {
  20872. return {
  20873. top: this.top - reference.top,
  20874. bottom: reference.bottom - this.bottom,
  20875. left: this.left - reference.left,
  20876. right: reference.right - this.right,
  20877. height: this.height,
  20878. width: this.width
  20879. };
  20880. };
  20881. // Get an object that represents the box's position without anything extra.
  20882. // Can pass a StyleBox, HTMLElement, or another BoxPositon.
  20883. BoxPosition.getSimpleBoxPosition = function(obj) {
  20884. var height = obj.div ? obj.div.offsetHeight : obj.tagName ? obj.offsetHeight : 0;
  20885. var width = obj.div ? obj.div.offsetWidth : obj.tagName ? obj.offsetWidth : 0;
  20886. var top = obj.div ? obj.div.offsetTop : obj.tagName ? obj.offsetTop : 0;
  20887. obj = obj.div ? obj.div.getBoundingClientRect() :
  20888. obj.tagName ? obj.getBoundingClientRect() : obj;
  20889. var ret = {
  20890. left: obj.left,
  20891. right: obj.right,
  20892. top: obj.top || top,
  20893. height: obj.height || height,
  20894. bottom: obj.bottom || (top + (obj.height || height)),
  20895. width: obj.width || width
  20896. };
  20897. return ret;
  20898. };
  20899. // Move a StyleBox to its specified, or next best, position. The containerBox
  20900. // is the box that contains the StyleBox, such as a div. boxPositions are
  20901. // a list of other boxes that the styleBox can't overlap with.
  20902. function moveBoxToLinePosition(window, styleBox, containerBox, boxPositions) {
  20903. // Find the best position for a cue box, b, on the video. The axis parameter
  20904. // is a list of axis, the order of which, it will move the box along. For example:
  20905. // Passing ["+x", "-x"] will move the box first along the x axis in the positive
  20906. // direction. If it doesn't find a good position for it there it will then move
  20907. // it along the x axis in the negative direction.
  20908. function findBestPosition(b, axis) {
  20909. var bestPosition,
  20910. specifiedPosition = new BoxPosition(b),
  20911. percentage = 1; // Highest possible so the first thing we get is better.
  20912. for (var i = 0; i < axis.length; i++) {
  20913. while (b.overlapsOppositeAxis(containerBox, axis[i]) ||
  20914. (b.within(containerBox) && b.overlapsAny(boxPositions))) {
  20915. b.move(axis[i]);
  20916. }
  20917. // We found a spot where we aren't overlapping anything. This is our
  20918. // best position.
  20919. if (b.within(containerBox)) {
  20920. return b;
  20921. }
  20922. var p = b.intersectPercentage(containerBox);
  20923. // If we're outside the container box less then we were on our last try
  20924. // then remember this position as the best position.
  20925. if (percentage > p) {
  20926. bestPosition = new BoxPosition(b);
  20927. percentage = p;
  20928. }
  20929. // Reset the box position to the specified position.
  20930. b = new BoxPosition(specifiedPosition);
  20931. }
  20932. return bestPosition || specifiedPosition;
  20933. }
  20934. var boxPosition = new BoxPosition(styleBox),
  20935. cue = styleBox.cue,
  20936. linePos = computeLinePos(cue),
  20937. axis = [];
  20938. // If we have a line number to align the cue to.
  20939. if (cue.snapToLines) {
  20940. var size;
  20941. switch (cue.vertical) {
  20942. case "":
  20943. axis = [ "+y", "-y" ];
  20944. size = "height";
  20945. break;
  20946. case "rl":
  20947. axis = [ "+x", "-x" ];
  20948. size = "width";
  20949. break;
  20950. case "lr":
  20951. axis = [ "-x", "+x" ];
  20952. size = "width";
  20953. break;
  20954. }
  20955. var step = boxPosition.lineHeight,
  20956. position = step * Math.round(linePos),
  20957. maxPosition = containerBox[size] + step,
  20958. initialAxis = axis[0];
  20959. // If the specified intial position is greater then the max position then
  20960. // clamp the box to the amount of steps it would take for the box to
  20961. // reach the max position.
  20962. if (Math.abs(position) > maxPosition) {
  20963. position = position < 0 ? -1 : 1;
  20964. position *= Math.ceil(maxPosition / step) * step;
  20965. }
  20966. // If computed line position returns negative then line numbers are
  20967. // relative to the bottom of the video instead of the top. Therefore, we
  20968. // need to increase our initial position by the length or width of the
  20969. // video, depending on the writing direction, and reverse our axis directions.
  20970. if (linePos < 0) {
  20971. position += cue.vertical === "" ? containerBox.height : containerBox.width;
  20972. axis = axis.reverse();
  20973. }
  20974. // Move the box to the specified position. This may not be its best
  20975. // position.
  20976. boxPosition.move(initialAxis, position);
  20977. } else {
  20978. // If we have a percentage line value for the cue.
  20979. var calculatedPercentage = (boxPosition.lineHeight / containerBox.height) * 100;
  20980. switch (cue.lineAlign) {
  20981. case "middle":
  20982. linePos -= (calculatedPercentage / 2);
  20983. break;
  20984. case "end":
  20985. linePos -= calculatedPercentage;
  20986. break;
  20987. }
  20988. // Apply initial line position to the cue box.
  20989. switch (cue.vertical) {
  20990. case "":
  20991. styleBox.applyStyles({
  20992. top: styleBox.formatStyle(linePos, "%")
  20993. });
  20994. break;
  20995. case "rl":
  20996. styleBox.applyStyles({
  20997. left: styleBox.formatStyle(linePos, "%")
  20998. });
  20999. break;
  21000. case "lr":
  21001. styleBox.applyStyles({
  21002. right: styleBox.formatStyle(linePos, "%")
  21003. });
  21004. break;
  21005. }
  21006. axis = [ "+y", "-x", "+x", "-y" ];
  21007. // Get the box position again after we've applied the specified positioning
  21008. // to it.
  21009. boxPosition = new BoxPosition(styleBox);
  21010. }
  21011. var bestPosition = findBestPosition(boxPosition, axis);
  21012. styleBox.move(bestPosition.toCSSCompatValues(containerBox));
  21013. }
  21014. function WebVTT() {
  21015. // Nothing
  21016. }
  21017. // Helper to allow strings to be decoded instead of the default binary utf8 data.
  21018. WebVTT.StringDecoder = function() {
  21019. return {
  21020. decode: function(data) {
  21021. if (!data) {
  21022. return "";
  21023. }
  21024. if (typeof data !== "string") {
  21025. throw new Error("Error - expected string data.");
  21026. }
  21027. return decodeURIComponent(encodeURIComponent(data));
  21028. }
  21029. };
  21030. };
  21031. WebVTT.convertCueToDOMTree = function(window, cuetext) {
  21032. if (!window || !cuetext) {
  21033. return null;
  21034. }
  21035. return parseContent(window, cuetext);
  21036. };
  21037. var FONT_SIZE_PERCENT = 0.05;
  21038. var FONT_STYLE = "sans-serif";
  21039. var CUE_BACKGROUND_PADDING = "1.5%";
  21040. // Runs the processing model over the cues and regions passed to it.
  21041. // @param overlay A block level element (usually a div) that the computed cues
  21042. // and regions will be placed into.
  21043. WebVTT.processCues = function(window, cues, overlay) {
  21044. if (!window || !cues || !overlay) {
  21045. return null;
  21046. }
  21047. // Remove all previous children.
  21048. while (overlay.firstChild) {
  21049. overlay.removeChild(overlay.firstChild);
  21050. }
  21051. var paddedOverlay = window.document.createElement("div");
  21052. paddedOverlay.style.position = "absolute";
  21053. paddedOverlay.style.left = "0";
  21054. paddedOverlay.style.right = "0";
  21055. paddedOverlay.style.top = "0";
  21056. paddedOverlay.style.bottom = "0";
  21057. paddedOverlay.style.margin = CUE_BACKGROUND_PADDING;
  21058. overlay.appendChild(paddedOverlay);
  21059. // Determine if we need to compute the display states of the cues. This could
  21060. // be the case if a cue's state has been changed since the last computation or
  21061. // if it has not been computed yet.
  21062. function shouldCompute(cues) {
  21063. for (var i = 0; i < cues.length; i++) {
  21064. if (cues[i].hasBeenReset || !cues[i].displayState) {
  21065. return true;
  21066. }
  21067. }
  21068. return false;
  21069. }
  21070. // We don't need to recompute the cues' display states. Just reuse them.
  21071. if (!shouldCompute(cues)) {
  21072. for (var i = 0; i < cues.length; i++) {
  21073. paddedOverlay.appendChild(cues[i].displayState);
  21074. }
  21075. return;
  21076. }
  21077. var boxPositions = [],
  21078. containerBox = BoxPosition.getSimpleBoxPosition(paddedOverlay),
  21079. fontSize = Math.round(containerBox.height * FONT_SIZE_PERCENT * 100) / 100;
  21080. var styleOptions = {
  21081. font: fontSize + "px " + FONT_STYLE
  21082. };
  21083. (function() {
  21084. var styleBox, cue;
  21085. for (var i = 0; i < cues.length; i++) {
  21086. cue = cues[i];
  21087. // Compute the intial position and styles of the cue div.
  21088. styleBox = new CueStyleBox(window, cue, styleOptions);
  21089. paddedOverlay.appendChild(styleBox.div);
  21090. // Move the cue div to it's correct line position.
  21091. moveBoxToLinePosition(window, styleBox, containerBox, boxPositions);
  21092. // Remember the computed div so that we don't have to recompute it later
  21093. // if we don't have too.
  21094. cue.displayState = styleBox.div;
  21095. boxPositions.push(BoxPosition.getSimpleBoxPosition(styleBox));
  21096. }
  21097. })();
  21098. };
  21099. WebVTT.Parser = function(window, vttjs, decoder) {
  21100. if (!decoder) {
  21101. decoder = vttjs;
  21102. vttjs = {};
  21103. }
  21104. if (!vttjs) {
  21105. vttjs = {};
  21106. }
  21107. this.window = window;
  21108. this.vttjs = vttjs;
  21109. this.state = "INITIAL";
  21110. this.buffer = "";
  21111. this.decoder = decoder || new TextDecoder("utf8");
  21112. this.regionList = [];
  21113. };
  21114. WebVTT.Parser.prototype = {
  21115. // If the error is a ParsingError then report it to the consumer if
  21116. // possible. If it's not a ParsingError then throw it like normal.
  21117. reportOrThrowError: function(e) {
  21118. if (e instanceof ParsingError) {
  21119. this.onparsingerror && this.onparsingerror(e);
  21120. } else {
  21121. throw e;
  21122. }
  21123. },
  21124. parse: function (data) {
  21125. var self = this;
  21126. // If there is no data then we won't decode it, but will just try to parse
  21127. // whatever is in buffer already. This may occur in circumstances, for
  21128. // example when flush() is called.
  21129. if (data) {
  21130. // Try to decode the data that we received.
  21131. self.buffer += self.decoder.decode(data, {stream: true});
  21132. }
  21133. function collectNextLine() {
  21134. var buffer = self.buffer;
  21135. var pos = 0;
  21136. while (pos < buffer.length && buffer[pos] !== '\r' && buffer[pos] !== '\n') {
  21137. ++pos;
  21138. }
  21139. var line = buffer.substr(0, pos);
  21140. // Advance the buffer early in case we fail below.
  21141. if (buffer[pos] === '\r') {
  21142. ++pos;
  21143. }
  21144. if (buffer[pos] === '\n') {
  21145. ++pos;
  21146. }
  21147. self.buffer = buffer.substr(pos);
  21148. return line;
  21149. }
  21150. // 3.4 WebVTT region and WebVTT region settings syntax
  21151. function parseRegion(input) {
  21152. var settings = new Settings();
  21153. parseOptions(input, function (k, v) {
  21154. switch (k) {
  21155. case "id":
  21156. settings.set(k, v);
  21157. break;
  21158. case "width":
  21159. settings.percent(k, v);
  21160. break;
  21161. case "lines":
  21162. settings.integer(k, v);
  21163. break;
  21164. case "regionanchor":
  21165. case "viewportanchor":
  21166. var xy = v.split(',');
  21167. if (xy.length !== 2) {
  21168. break;
  21169. }
  21170. // We have to make sure both x and y parse, so use a temporary
  21171. // settings object here.
  21172. var anchor = new Settings();
  21173. anchor.percent("x", xy[0]);
  21174. anchor.percent("y", xy[1]);
  21175. if (!anchor.has("x") || !anchor.has("y")) {
  21176. break;
  21177. }
  21178. settings.set(k + "X", anchor.get("x"));
  21179. settings.set(k + "Y", anchor.get("y"));
  21180. break;
  21181. case "scroll":
  21182. settings.alt(k, v, ["up"]);
  21183. break;
  21184. }
  21185. }, /=/, /\s/);
  21186. // Create the region, using default values for any values that were not
  21187. // specified.
  21188. if (settings.has("id")) {
  21189. var region = new (self.vttjs.VTTRegion || self.window.VTTRegion)();
  21190. region.width = settings.get("width", 100);
  21191. region.lines = settings.get("lines", 3);
  21192. region.regionAnchorX = settings.get("regionanchorX", 0);
  21193. region.regionAnchorY = settings.get("regionanchorY", 100);
  21194. region.viewportAnchorX = settings.get("viewportanchorX", 0);
  21195. region.viewportAnchorY = settings.get("viewportanchorY", 100);
  21196. region.scroll = settings.get("scroll", "");
  21197. // Register the region.
  21198. self.onregion && self.onregion(region);
  21199. // Remember the VTTRegion for later in case we parse any VTTCues that
  21200. // reference it.
  21201. self.regionList.push({
  21202. id: settings.get("id"),
  21203. region: region
  21204. });
  21205. }
  21206. }
  21207. // 3.2 WebVTT metadata header syntax
  21208. function parseHeader(input) {
  21209. parseOptions(input, function (k, v) {
  21210. switch (k) {
  21211. case "Region":
  21212. // 3.3 WebVTT region metadata header syntax
  21213. parseRegion(v);
  21214. break;
  21215. }
  21216. }, /:/);
  21217. }
  21218. // 5.1 WebVTT file parsing.
  21219. try {
  21220. var line;
  21221. if (self.state === "INITIAL") {
  21222. // We can't start parsing until we have the first line.
  21223. if (!/\r\n|\n/.test(self.buffer)) {
  21224. return this;
  21225. }
  21226. line = collectNextLine();
  21227. var m = line.match(/^WEBVTT([ \t].*)?$/);
  21228. if (!m || !m[0]) {
  21229. throw new ParsingError(ParsingError.Errors.BadSignature);
  21230. }
  21231. self.state = "HEADER";
  21232. }
  21233. var alreadyCollectedLine = false;
  21234. while (self.buffer) {
  21235. // We can't parse a line until we have the full line.
  21236. if (!/\r\n|\n/.test(self.buffer)) {
  21237. return this;
  21238. }
  21239. if (!alreadyCollectedLine) {
  21240. line = collectNextLine();
  21241. } else {
  21242. alreadyCollectedLine = false;
  21243. }
  21244. switch (self.state) {
  21245. case "HEADER":
  21246. // 13-18 - Allow a header (metadata) under the WEBVTT line.
  21247. if (/:/.test(line)) {
  21248. parseHeader(line);
  21249. } else if (!line) {
  21250. // An empty line terminates the header and starts the body (cues).
  21251. self.state = "ID";
  21252. }
  21253. continue;
  21254. case "NOTE":
  21255. // Ignore NOTE blocks.
  21256. if (!line) {
  21257. self.state = "ID";
  21258. }
  21259. continue;
  21260. case "ID":
  21261. // Check for the start of NOTE blocks.
  21262. if (/^NOTE($|[ \t])/.test(line)) {
  21263. self.state = "NOTE";
  21264. break;
  21265. }
  21266. // 19-29 - Allow any number of line terminators, then initialize new cue values.
  21267. if (!line) {
  21268. continue;
  21269. }
  21270. self.cue = new (self.vttjs.VTTCue || self.window.VTTCue)(0, 0, "");
  21271. self.state = "CUE";
  21272. // 30-39 - Check if self line contains an optional identifier or timing data.
  21273. if (line.indexOf("-->") === -1) {
  21274. self.cue.id = line;
  21275. continue;
  21276. }
  21277. // Process line as start of a cue.
  21278. /*falls through*/
  21279. case "CUE":
  21280. // 40 - Collect cue timings and settings.
  21281. try {
  21282. parseCue(line, self.cue, self.regionList);
  21283. } catch (e) {
  21284. self.reportOrThrowError(e);
  21285. // In case of an error ignore rest of the cue.
  21286. self.cue = null;
  21287. self.state = "BADCUE";
  21288. continue;
  21289. }
  21290. self.state = "CUETEXT";
  21291. continue;
  21292. case "CUETEXT":
  21293. var hasSubstring = line.indexOf("-->") !== -1;
  21294. // 34 - If we have an empty line then report the cue.
  21295. // 35 - If we have the special substring '-->' then report the cue,
  21296. // but do not collect the line as we need to process the current
  21297. // one as a new cue.
  21298. if (!line || hasSubstring && (alreadyCollectedLine = true)) {
  21299. // We are done parsing self cue.
  21300. self.oncue && self.oncue(self.cue);
  21301. self.cue = null;
  21302. self.state = "ID";
  21303. continue;
  21304. }
  21305. if (self.cue.text) {
  21306. self.cue.text += "\n";
  21307. }
  21308. self.cue.text += line;
  21309. continue;
  21310. case "BADCUE": // BADCUE
  21311. // 54-62 - Collect and discard the remaining cue.
  21312. if (!line) {
  21313. self.state = "ID";
  21314. }
  21315. continue;
  21316. }
  21317. }
  21318. } catch (e) {
  21319. self.reportOrThrowError(e);
  21320. // If we are currently parsing a cue, report what we have.
  21321. if (self.state === "CUETEXT" && self.cue && self.oncue) {
  21322. self.oncue(self.cue);
  21323. }
  21324. self.cue = null;
  21325. // Enter BADWEBVTT state if header was not parsed correctly otherwise
  21326. // another exception occurred so enter BADCUE state.
  21327. self.state = self.state === "INITIAL" ? "BADWEBVTT" : "BADCUE";
  21328. }
  21329. return this;
  21330. },
  21331. flush: function () {
  21332. var self = this;
  21333. try {
  21334. // Finish decoding the stream.
  21335. self.buffer += self.decoder.decode();
  21336. // Synthesize the end of the current cue or region.
  21337. if (self.cue || self.state === "HEADER") {
  21338. self.buffer += "\n\n";
  21339. self.parse();
  21340. }
  21341. // If we've flushed, parsed, and we're still on the INITIAL state then
  21342. // that means we don't have enough of the stream to parse the first
  21343. // line.
  21344. if (self.state === "INITIAL") {
  21345. throw new ParsingError(ParsingError.Errors.BadSignature);
  21346. }
  21347. } catch(e) {
  21348. self.reportOrThrowError(e);
  21349. }
  21350. self.onflush && self.onflush();
  21351. return this;
  21352. }
  21353. };
  21354. global.WebVTT = WebVTT;
  21355. }(this, (this.vttjs || {})));
  21356. },{}],112:[function(_dereq_,module,exports){
  21357. /**
  21358. * Copyright 2013 vtt.js Contributors
  21359. *
  21360. * Licensed under the Apache License, Version 2.0 (the "License");
  21361. * you may not use this file except in compliance with the License.
  21362. * You may obtain a copy of the License at
  21363. *
  21364. * http://www.apache.org/licenses/LICENSE-2.0
  21365. *
  21366. * Unless required by applicable law or agreed to in writing, software
  21367. * distributed under the License is distributed on an "AS IS" BASIS,
  21368. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  21369. * See the License for the specific language governing permissions and
  21370. * limitations under the License.
  21371. */
  21372. // If we're in Node.js then require VTTCue so we can extend it, otherwise assume
  21373. // VTTCue is on the global.
  21374. if (typeof module !== "undefined" && module.exports) {
  21375. this.VTTCue = this.VTTCue || _dereq_(113).VTTCue;
  21376. }
  21377. // Extend VTTCue with methods to convert to JSON, from JSON, and construct a
  21378. // VTTCue from an options object. The primary purpose of this is for use in the
  21379. // vtt.js test suite (for testing only properties that we care about). It's also
  21380. // useful if you need to work with VTTCues in JSON format.
  21381. (function(root) {
  21382. root.VTTCue.prototype.toJSON = function() {
  21383. var cue = {},
  21384. self = this;
  21385. // Filter out getCueAsHTML as it's a function and hasBeenReset and displayState as
  21386. // they're only used when running the processing model algorithm.
  21387. Object.keys(this).forEach(function(key) {
  21388. if (key !== "getCueAsHTML" && key !== "hasBeenReset" && key !== "displayState") {
  21389. cue[key] = self[key];
  21390. }
  21391. });
  21392. return cue;
  21393. };
  21394. root.VTTCue.create = function(options) {
  21395. if (!options.hasOwnProperty("startTime") || !options.hasOwnProperty("endTime") ||
  21396. !options.hasOwnProperty("text")) {
  21397. throw new Error("You must at least have start time, end time, and text.");
  21398. }
  21399. var cue = new root.VTTCue(options.startTime, options.endTime, options.text);
  21400. for (var key in options) {
  21401. if (cue.hasOwnProperty(key)) {
  21402. cue[key] = options[key];
  21403. }
  21404. }
  21405. return cue;
  21406. };
  21407. root.VTTCue.fromJSON = function(json) {
  21408. return this.create(JSON.parse(json));
  21409. };
  21410. }(this));
  21411. },{"113":113}],113:[function(_dereq_,module,exports){
  21412. /**
  21413. * Copyright 2013 vtt.js Contributors
  21414. *
  21415. * Licensed under the Apache License, Version 2.0 (the "License");
  21416. * you may not use this file except in compliance with the License.
  21417. * You may obtain a copy of the License at
  21418. *
  21419. * http://www.apache.org/licenses/LICENSE-2.0
  21420. *
  21421. * Unless required by applicable law or agreed to in writing, software
  21422. * distributed under the License is distributed on an "AS IS" BASIS,
  21423. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  21424. * See the License for the specific language governing permissions and
  21425. * limitations under the License.
  21426. */
  21427. (function(root, vttjs) {
  21428. var autoKeyword = "auto";
  21429. var directionSetting = {
  21430. "": true,
  21431. "lr": true,
  21432. "rl": true
  21433. };
  21434. var alignSetting = {
  21435. "start": true,
  21436. "middle": true,
  21437. "end": true,
  21438. "left": true,
  21439. "right": true
  21440. };
  21441. function findDirectionSetting(value) {
  21442. if (typeof value !== "string") {
  21443. return false;
  21444. }
  21445. var dir = directionSetting[value.toLowerCase()];
  21446. return dir ? value.toLowerCase() : false;
  21447. }
  21448. function findAlignSetting(value) {
  21449. if (typeof value !== "string") {
  21450. return false;
  21451. }
  21452. var align = alignSetting[value.toLowerCase()];
  21453. return align ? value.toLowerCase() : false;
  21454. }
  21455. function extend(obj) {
  21456. var i = 1;
  21457. for (; i < arguments.length; i++) {
  21458. var cobj = arguments[i];
  21459. for (var p in cobj) {
  21460. obj[p] = cobj[p];
  21461. }
  21462. }
  21463. return obj;
  21464. }
  21465. function VTTCue(startTime, endTime, text) {
  21466. var cue = this;
  21467. var isIE8 = (/MSIE\s8\.0/).test(navigator.userAgent);
  21468. var baseObj = {};
  21469. if (isIE8) {
  21470. cue = document.createElement('custom');
  21471. } else {
  21472. baseObj.enumerable = true;
  21473. }
  21474. /**
  21475. * Shim implementation specific properties. These properties are not in
  21476. * the spec.
  21477. */
  21478. // Lets us know when the VTTCue's data has changed in such a way that we need
  21479. // to recompute its display state. This lets us compute its display state
  21480. // lazily.
  21481. cue.hasBeenReset = false;
  21482. /**
  21483. * VTTCue and TextTrackCue properties
  21484. * http://dev.w3.org/html5/webvtt/#vttcue-interface
  21485. */
  21486. var _id = "";
  21487. var _pauseOnExit = false;
  21488. var _startTime = startTime;
  21489. var _endTime = endTime;
  21490. var _text = text;
  21491. var _region = null;
  21492. var _vertical = "";
  21493. var _snapToLines = true;
  21494. var _line = "auto";
  21495. var _lineAlign = "start";
  21496. var _position = 50;
  21497. var _positionAlign = "middle";
  21498. var _size = 50;
  21499. var _align = "middle";
  21500. Object.defineProperty(cue,
  21501. "id", extend({}, baseObj, {
  21502. get: function() {
  21503. return _id;
  21504. },
  21505. set: function(value) {
  21506. _id = "" + value;
  21507. }
  21508. }));
  21509. Object.defineProperty(cue,
  21510. "pauseOnExit", extend({}, baseObj, {
  21511. get: function() {
  21512. return _pauseOnExit;
  21513. },
  21514. set: function(value) {
  21515. _pauseOnExit = !!value;
  21516. }
  21517. }));
  21518. Object.defineProperty(cue,
  21519. "startTime", extend({}, baseObj, {
  21520. get: function() {
  21521. return _startTime;
  21522. },
  21523. set: function(value) {
  21524. if (typeof value !== "number") {
  21525. throw new TypeError("Start time must be set to a number.");
  21526. }
  21527. _startTime = value;
  21528. this.hasBeenReset = true;
  21529. }
  21530. }));
  21531. Object.defineProperty(cue,
  21532. "endTime", extend({}, baseObj, {
  21533. get: function() {
  21534. return _endTime;
  21535. },
  21536. set: function(value) {
  21537. if (typeof value !== "number") {
  21538. throw new TypeError("End time must be set to a number.");
  21539. }
  21540. _endTime = value;
  21541. this.hasBeenReset = true;
  21542. }
  21543. }));
  21544. Object.defineProperty(cue,
  21545. "text", extend({}, baseObj, {
  21546. get: function() {
  21547. return _text;
  21548. },
  21549. set: function(value) {
  21550. _text = "" + value;
  21551. this.hasBeenReset = true;
  21552. }
  21553. }));
  21554. Object.defineProperty(cue,
  21555. "region", extend({}, baseObj, {
  21556. get: function() {
  21557. return _region;
  21558. },
  21559. set: function(value) {
  21560. _region = value;
  21561. this.hasBeenReset = true;
  21562. }
  21563. }));
  21564. Object.defineProperty(cue,
  21565. "vertical", extend({}, baseObj, {
  21566. get: function() {
  21567. return _vertical;
  21568. },
  21569. set: function(value) {
  21570. var setting = findDirectionSetting(value);
  21571. // Have to check for false because the setting an be an empty string.
  21572. if (setting === false) {
  21573. throw new SyntaxError("An invalid or illegal string was specified.");
  21574. }
  21575. _vertical = setting;
  21576. this.hasBeenReset = true;
  21577. }
  21578. }));
  21579. Object.defineProperty(cue,
  21580. "snapToLines", extend({}, baseObj, {
  21581. get: function() {
  21582. return _snapToLines;
  21583. },
  21584. set: function(value) {
  21585. _snapToLines = !!value;
  21586. this.hasBeenReset = true;
  21587. }
  21588. }));
  21589. Object.defineProperty(cue,
  21590. "line", extend({}, baseObj, {
  21591. get: function() {
  21592. return _line;
  21593. },
  21594. set: function(value) {
  21595. if (typeof value !== "number" && value !== autoKeyword) {
  21596. throw new SyntaxError("An invalid number or illegal string was specified.");
  21597. }
  21598. _line = value;
  21599. this.hasBeenReset = true;
  21600. }
  21601. }));
  21602. Object.defineProperty(cue,
  21603. "lineAlign", extend({}, baseObj, {
  21604. get: function() {
  21605. return _lineAlign;
  21606. },
  21607. set: function(value) {
  21608. var setting = findAlignSetting(value);
  21609. if (!setting) {
  21610. throw new SyntaxError("An invalid or illegal string was specified.");
  21611. }
  21612. _lineAlign = setting;
  21613. this.hasBeenReset = true;
  21614. }
  21615. }));
  21616. Object.defineProperty(cue,
  21617. "position", extend({}, baseObj, {
  21618. get: function() {
  21619. return _position;
  21620. },
  21621. set: function(value) {
  21622. if (value < 0 || value > 100) {
  21623. throw new Error("Position must be between 0 and 100.");
  21624. }
  21625. _position = value;
  21626. this.hasBeenReset = true;
  21627. }
  21628. }));
  21629. Object.defineProperty(cue,
  21630. "positionAlign", extend({}, baseObj, {
  21631. get: function() {
  21632. return _positionAlign;
  21633. },
  21634. set: function(value) {
  21635. var setting = findAlignSetting(value);
  21636. if (!setting) {
  21637. throw new SyntaxError("An invalid or illegal string was specified.");
  21638. }
  21639. _positionAlign = setting;
  21640. this.hasBeenReset = true;
  21641. }
  21642. }));
  21643. Object.defineProperty(cue,
  21644. "size", extend({}, baseObj, {
  21645. get: function() {
  21646. return _size;
  21647. },
  21648. set: function(value) {
  21649. if (value < 0 || value > 100) {
  21650. throw new Error("Size must be between 0 and 100.");
  21651. }
  21652. _size = value;
  21653. this.hasBeenReset = true;
  21654. }
  21655. }));
  21656. Object.defineProperty(cue,
  21657. "align", extend({}, baseObj, {
  21658. get: function() {
  21659. return _align;
  21660. },
  21661. set: function(value) {
  21662. var setting = findAlignSetting(value);
  21663. if (!setting) {
  21664. throw new SyntaxError("An invalid or illegal string was specified.");
  21665. }
  21666. _align = setting;
  21667. this.hasBeenReset = true;
  21668. }
  21669. }));
  21670. /**
  21671. * Other <track> spec defined properties
  21672. */
  21673. // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#text-track-cue-display-state
  21674. cue.displayState = undefined;
  21675. if (isIE8) {
  21676. return cue;
  21677. }
  21678. }
  21679. /**
  21680. * VTTCue methods
  21681. */
  21682. VTTCue.prototype.getCueAsHTML = function() {
  21683. // Assume WebVTT.convertCueToDOMTree is on the global.
  21684. return WebVTT.convertCueToDOMTree(window, this.text);
  21685. };
  21686. root.VTTCue = root.VTTCue || VTTCue;
  21687. vttjs.VTTCue = VTTCue;
  21688. }(this, (this.vttjs || {})));
  21689. },{}],114:[function(_dereq_,module,exports){
  21690. /**
  21691. * Copyright 2013 vtt.js Contributors
  21692. *
  21693. * Licensed under the Apache License, Version 2.0 (the "License");
  21694. * you may not use this file except in compliance with the License.
  21695. * You may obtain a copy of the License at
  21696. *
  21697. * http://www.apache.org/licenses/LICENSE-2.0
  21698. *
  21699. * Unless required by applicable law or agreed to in writing, software
  21700. * distributed under the License is distributed on an "AS IS" BASIS,
  21701. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  21702. * See the License for the specific language governing permissions and
  21703. * limitations under the License.
  21704. */
  21705. // If we're in Node.js then require VTTRegion so we can extend it, otherwise assume
  21706. // VTTRegion is on the global.
  21707. if (typeof module !== "undefined" && module.exports) {
  21708. this.VTTRegion = _dereq_(115).VTTRegion;
  21709. }
  21710. // Extend VTTRegion with methods to convert to JSON, from JSON, and construct a
  21711. // VTTRegion from an options object. The primary purpose of this is for use in the
  21712. // vtt.js test suite. It's also useful if you need to work with VTTRegions in
  21713. // JSON format.
  21714. (function(root) {
  21715. root.VTTRegion.create = function(options) {
  21716. var region = new root.VTTRegion();
  21717. for (var key in options) {
  21718. if (region.hasOwnProperty(key)) {
  21719. region[key] = options[key];
  21720. }
  21721. }
  21722. return region;
  21723. };
  21724. root.VTTRegion.fromJSON = function(json) {
  21725. return this.create(JSON.parse(json));
  21726. };
  21727. }(this));
  21728. },{"115":115}],115:[function(_dereq_,module,exports){
  21729. /**
  21730. * Copyright 2013 vtt.js Contributors
  21731. *
  21732. * Licensed under the Apache License, Version 2.0 (the "License");
  21733. * you may not use this file except in compliance with the License.
  21734. * You may obtain a copy of the License at
  21735. *
  21736. * http://www.apache.org/licenses/LICENSE-2.0
  21737. *
  21738. * Unless required by applicable law or agreed to in writing, software
  21739. * distributed under the License is distributed on an "AS IS" BASIS,
  21740. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  21741. * See the License for the specific language governing permissions and
  21742. * limitations under the License.
  21743. */
  21744. (function(root, vttjs) {
  21745. var scrollSetting = {
  21746. "": true,
  21747. "up": true
  21748. };
  21749. function findScrollSetting(value) {
  21750. if (typeof value !== "string") {
  21751. return false;
  21752. }
  21753. var scroll = scrollSetting[value.toLowerCase()];
  21754. return scroll ? value.toLowerCase() : false;
  21755. }
  21756. function isValidPercentValue(value) {
  21757. return typeof value === "number" && (value >= 0 && value <= 100);
  21758. }
  21759. // VTTRegion shim http://dev.w3.org/html5/webvtt/#vttregion-interface
  21760. function VTTRegion() {
  21761. var _width = 100;
  21762. var _lines = 3;
  21763. var _regionAnchorX = 0;
  21764. var _regionAnchorY = 100;
  21765. var _viewportAnchorX = 0;
  21766. var _viewportAnchorY = 100;
  21767. var _scroll = "";
  21768. Object.defineProperties(this, {
  21769. "width": {
  21770. enumerable: true,
  21771. get: function() {
  21772. return _width;
  21773. },
  21774. set: function(value) {
  21775. if (!isValidPercentValue(value)) {
  21776. throw new Error("Width must be between 0 and 100.");
  21777. }
  21778. _width = value;
  21779. }
  21780. },
  21781. "lines": {
  21782. enumerable: true,
  21783. get: function() {
  21784. return _lines;
  21785. },
  21786. set: function(value) {
  21787. if (typeof value !== "number") {
  21788. throw new TypeError("Lines must be set to a number.");
  21789. }
  21790. _lines = value;
  21791. }
  21792. },
  21793. "regionAnchorY": {
  21794. enumerable: true,
  21795. get: function() {
  21796. return _regionAnchorY;
  21797. },
  21798. set: function(value) {
  21799. if (!isValidPercentValue(value)) {
  21800. throw new Error("RegionAnchorX must be between 0 and 100.");
  21801. }
  21802. _regionAnchorY = value;
  21803. }
  21804. },
  21805. "regionAnchorX": {
  21806. enumerable: true,
  21807. get: function() {
  21808. return _regionAnchorX;
  21809. },
  21810. set: function(value) {
  21811. if(!isValidPercentValue(value)) {
  21812. throw new Error("RegionAnchorY must be between 0 and 100.");
  21813. }
  21814. _regionAnchorX = value;
  21815. }
  21816. },
  21817. "viewportAnchorY": {
  21818. enumerable: true,
  21819. get: function() {
  21820. return _viewportAnchorY;
  21821. },
  21822. set: function(value) {
  21823. if (!isValidPercentValue(value)) {
  21824. throw new Error("ViewportAnchorY must be between 0 and 100.");
  21825. }
  21826. _viewportAnchorY = value;
  21827. }
  21828. },
  21829. "viewportAnchorX": {
  21830. enumerable: true,
  21831. get: function() {
  21832. return _viewportAnchorX;
  21833. },
  21834. set: function(value) {
  21835. if (!isValidPercentValue(value)) {
  21836. throw new Error("ViewportAnchorX must be between 0 and 100.");
  21837. }
  21838. _viewportAnchorX = value;
  21839. }
  21840. },
  21841. "scroll": {
  21842. enumerable: true,
  21843. get: function() {
  21844. return _scroll;
  21845. },
  21846. set: function(value) {
  21847. var setting = findScrollSetting(value);
  21848. // Have to check for false as an empty string is a legal value.
  21849. if (setting === false) {
  21850. throw new SyntaxError("An invalid or illegal string was specified.");
  21851. }
  21852. _scroll = setting;
  21853. }
  21854. }
  21855. });
  21856. }
  21857. root.VTTRegion = root.VTTRegion || VTTRegion;
  21858. vttjs.VTTRegion = VTTRegion;
  21859. }(this, (this.vttjs || {})));
  21860. },{}]},{},[98])(98)
  21861. });