video.js 858 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595959695979598959996009601960296039604960596069607960896099610961196129613961496159616961796189619962096219622962396249625962696279628962996309631963296339634963596369637963896399640964196429643964496459646964796489649965096519652965396549655965696579658965996609661966296639664966596669667966896699670967196729673967496759676967796789679968096819682968396849685968696879688968996909691969296939694969596969697969896999700970197029703970497059706970797089709971097119712971397149715971697179718971997209721972297239724972597269727972897299730973197329733973497359736973797389739974097419742974397449745974697479748974997509751975297539754975597569757975897599760976197629763976497659766976797689769977097719772977397749775977697779778977997809781978297839784978597869787978897899790979197929793979497959796979797989799980098019802980398049805980698079808980998109811981298139814981598169817981898199820982198229823982498259826982798289829983098319832983398349835983698379838983998409841984298439844984598469847984898499850985198529853985498559856985798589859986098619862986398649865986698679868986998709871987298739874987598769877987898799880988198829883988498859886988798889889989098919892989398949895989698979898989999009901990299039904990599069907990899099910991199129913991499159916991799189919992099219922992399249925992699279928992999309931993299339934993599369937993899399940994199429943994499459946994799489949995099519952995399549955995699579958995999609961996299639964996599669967996899699970997199729973997499759976997799789979998099819982998399849985998699879988998999909991999299939994999599969997999899991000010001100021000310004100051000610007100081000910010100111001210013100141001510016100171001810019100201002110022100231002410025100261002710028100291003010031100321003310034100351003610037100381003910040100411004210043100441004510046100471004810049100501005110052100531005410055100561005710058100591006010061100621006310064100651006610067100681006910070100711007210073100741007510076100771007810079100801008110082100831008410085100861008710088100891009010091100921009310094100951009610097100981009910100101011010210103101041010510106101071010810109101101011110112101131011410115101161011710118101191012010121101221012310124101251012610127101281012910130101311013210133101341013510136101371013810139101401014110142101431014410145101461014710148101491015010151101521015310154101551015610157101581015910160101611016210163101641016510166101671016810169101701017110172101731017410175101761017710178101791018010181101821018310184101851018610187101881018910190101911019210193101941019510196101971019810199102001020110202102031020410205102061020710208102091021010211102121021310214102151021610217102181021910220102211022210223102241022510226102271022810229102301023110232102331023410235102361023710238102391024010241102421024310244102451024610247102481024910250102511025210253102541025510256102571025810259102601026110262102631026410265102661026710268102691027010271102721027310274102751027610277102781027910280102811028210283102841028510286102871028810289102901029110292102931029410295102961029710298102991030010301103021030310304103051030610307103081030910310103111031210313103141031510316103171031810319103201032110322103231032410325103261032710328103291033010331103321033310334103351033610337103381033910340103411034210343103441034510346103471034810349103501035110352103531035410355103561035710358103591036010361103621036310364103651036610367103681036910370103711037210373103741037510376103771037810379103801038110382103831038410385103861038710388103891039010391103921039310394103951039610397103981039910400104011040210403104041040510406104071040810409104101041110412104131041410415104161041710418104191042010421104221042310424104251042610427104281042910430104311043210433104341043510436104371043810439104401044110442104431044410445104461044710448104491045010451104521045310454104551045610457104581045910460104611046210463104641046510466104671046810469104701047110472104731047410475104761047710478104791048010481104821048310484104851048610487104881048910490104911049210493104941049510496104971049810499105001050110502105031050410505105061050710508105091051010511105121051310514105151051610517105181051910520105211052210523105241052510526105271052810529105301053110532105331053410535105361053710538105391054010541105421054310544105451054610547105481054910550105511055210553105541055510556105571055810559105601056110562105631056410565105661056710568105691057010571105721057310574105751057610577105781057910580105811058210583105841058510586105871058810589105901059110592105931059410595105961059710598105991060010601106021060310604106051060610607106081060910610106111061210613106141061510616106171061810619106201062110622106231062410625106261062710628106291063010631106321063310634106351063610637106381063910640106411064210643106441064510646106471064810649106501065110652106531065410655106561065710658106591066010661106621066310664106651066610667106681066910670106711067210673106741067510676106771067810679106801068110682106831068410685106861068710688106891069010691106921069310694106951069610697106981069910700107011070210703107041070510706107071070810709107101071110712107131071410715107161071710718107191072010721107221072310724107251072610727107281072910730107311073210733107341073510736107371073810739107401074110742107431074410745107461074710748107491075010751107521075310754107551075610757107581075910760107611076210763107641076510766107671076810769107701077110772107731077410775107761077710778107791078010781107821078310784107851078610787107881078910790107911079210793107941079510796107971079810799108001080110802108031080410805108061080710808108091081010811108121081310814108151081610817108181081910820108211082210823108241082510826108271082810829108301083110832108331083410835108361083710838108391084010841108421084310844108451084610847108481084910850108511085210853108541085510856108571085810859108601086110862108631086410865108661086710868108691087010871108721087310874108751087610877108781087910880108811088210883108841088510886108871088810889108901089110892108931089410895108961089710898108991090010901109021090310904109051090610907109081090910910109111091210913109141091510916109171091810919109201092110922109231092410925109261092710928109291093010931109321093310934109351093610937109381093910940109411094210943109441094510946109471094810949109501095110952109531095410955109561095710958109591096010961109621096310964109651096610967109681096910970109711097210973109741097510976109771097810979109801098110982109831098410985109861098710988109891099010991109921099310994109951099610997109981099911000110011100211003110041100511006110071100811009110101101111012110131101411015110161101711018110191102011021110221102311024110251102611027110281102911030110311103211033110341103511036110371103811039110401104111042110431104411045110461104711048110491105011051110521105311054110551105611057110581105911060110611106211063110641106511066110671106811069110701107111072110731107411075110761107711078110791108011081110821108311084110851108611087110881108911090110911109211093110941109511096110971109811099111001110111102111031110411105111061110711108111091111011111111121111311114111151111611117111181111911120111211112211123111241112511126111271112811129111301113111132111331113411135111361113711138111391114011141111421114311144111451114611147111481114911150111511115211153111541115511156111571115811159111601116111162111631116411165111661116711168111691117011171111721117311174111751117611177111781117911180111811118211183111841118511186111871118811189111901119111192111931119411195111961119711198111991120011201112021120311204112051120611207112081120911210112111121211213112141121511216112171121811219112201122111222112231122411225112261122711228112291123011231112321123311234112351123611237112381123911240112411124211243112441124511246112471124811249112501125111252112531125411255112561125711258112591126011261112621126311264112651126611267112681126911270112711127211273112741127511276112771127811279112801128111282112831128411285112861128711288112891129011291112921129311294112951129611297112981129911300113011130211303113041130511306113071130811309113101131111312113131131411315113161131711318113191132011321113221132311324113251132611327113281132911330113311133211333113341133511336113371133811339113401134111342113431134411345113461134711348113491135011351113521135311354113551135611357113581135911360113611136211363113641136511366113671136811369113701137111372113731137411375113761137711378113791138011381113821138311384113851138611387113881138911390113911139211393113941139511396113971139811399114001140111402114031140411405114061140711408114091141011411114121141311414114151141611417114181141911420114211142211423114241142511426114271142811429114301143111432114331143411435114361143711438114391144011441114421144311444114451144611447114481144911450114511145211453114541145511456114571145811459114601146111462114631146411465114661146711468114691147011471114721147311474114751147611477114781147911480114811148211483114841148511486114871148811489114901149111492114931149411495114961149711498114991150011501115021150311504115051150611507115081150911510115111151211513115141151511516115171151811519115201152111522115231152411525115261152711528115291153011531115321153311534115351153611537115381153911540115411154211543115441154511546115471154811549115501155111552115531155411555115561155711558115591156011561115621156311564115651156611567115681156911570115711157211573115741157511576115771157811579115801158111582115831158411585115861158711588115891159011591115921159311594115951159611597115981159911600116011160211603116041160511606116071160811609116101161111612116131161411615116161161711618116191162011621116221162311624116251162611627116281162911630116311163211633116341163511636116371163811639116401164111642116431164411645116461164711648116491165011651116521165311654116551165611657116581165911660116611166211663116641166511666116671166811669116701167111672116731167411675116761167711678116791168011681116821168311684116851168611687116881168911690116911169211693116941169511696116971169811699117001170111702117031170411705117061170711708117091171011711117121171311714117151171611717117181171911720117211172211723117241172511726117271172811729117301173111732117331173411735117361173711738117391174011741117421174311744117451174611747117481174911750117511175211753117541175511756117571175811759117601176111762117631176411765117661176711768117691177011771117721177311774117751177611777117781177911780117811178211783117841178511786117871178811789117901179111792117931179411795117961179711798117991180011801118021180311804118051180611807118081180911810118111181211813118141181511816118171181811819118201182111822118231182411825118261182711828118291183011831118321183311834118351183611837118381183911840118411184211843118441184511846118471184811849118501185111852118531185411855118561185711858118591186011861118621186311864118651186611867118681186911870118711187211873118741187511876118771187811879118801188111882118831188411885118861188711888118891189011891118921189311894118951189611897118981189911900119011190211903119041190511906119071190811909119101191111912119131191411915119161191711918119191192011921119221192311924119251192611927119281192911930119311193211933119341193511936119371193811939119401194111942119431194411945119461194711948119491195011951119521195311954119551195611957119581195911960119611196211963119641196511966119671196811969119701197111972119731197411975119761197711978119791198011981119821198311984119851198611987119881198911990119911199211993119941199511996119971199811999120001200112002120031200412005120061200712008120091201012011120121201312014120151201612017120181201912020120211202212023120241202512026120271202812029120301203112032120331203412035120361203712038120391204012041120421204312044120451204612047120481204912050120511205212053120541205512056120571205812059120601206112062120631206412065120661206712068120691207012071120721207312074120751207612077120781207912080120811208212083120841208512086120871208812089120901209112092120931209412095120961209712098120991210012101121021210312104121051210612107121081210912110121111211212113121141211512116121171211812119121201212112122121231212412125121261212712128121291213012131121321213312134121351213612137121381213912140121411214212143121441214512146121471214812149121501215112152121531215412155121561215712158121591216012161121621216312164121651216612167121681216912170121711217212173121741217512176121771217812179121801218112182121831218412185121861218712188121891219012191121921219312194121951219612197121981219912200122011220212203122041220512206122071220812209122101221112212122131221412215122161221712218122191222012221122221222312224122251222612227122281222912230122311223212233122341223512236122371223812239122401224112242122431224412245122461224712248122491225012251122521225312254122551225612257122581225912260122611226212263122641226512266122671226812269122701227112272122731227412275122761227712278122791228012281122821228312284122851228612287122881228912290122911229212293122941229512296122971229812299123001230112302123031230412305123061230712308123091231012311123121231312314123151231612317123181231912320123211232212323123241232512326123271232812329123301233112332123331233412335123361233712338123391234012341123421234312344123451234612347123481234912350123511235212353123541235512356123571235812359123601236112362123631236412365123661236712368123691237012371123721237312374123751237612377123781237912380123811238212383123841238512386123871238812389123901239112392123931239412395123961239712398123991240012401124021240312404124051240612407124081240912410124111241212413124141241512416124171241812419124201242112422124231242412425124261242712428124291243012431124321243312434124351243612437124381243912440124411244212443124441244512446124471244812449124501245112452124531245412455124561245712458124591246012461124621246312464124651246612467124681246912470124711247212473124741247512476124771247812479124801248112482124831248412485124861248712488124891249012491124921249312494124951249612497124981249912500125011250212503125041250512506125071250812509125101251112512125131251412515125161251712518125191252012521125221252312524125251252612527125281252912530125311253212533125341253512536125371253812539125401254112542125431254412545125461254712548125491255012551125521255312554125551255612557125581255912560125611256212563125641256512566125671256812569125701257112572125731257412575125761257712578125791258012581125821258312584125851258612587125881258912590125911259212593125941259512596125971259812599126001260112602126031260412605126061260712608126091261012611126121261312614126151261612617126181261912620126211262212623126241262512626126271262812629126301263112632126331263412635126361263712638126391264012641126421264312644126451264612647126481264912650126511265212653126541265512656126571265812659126601266112662126631266412665126661266712668126691267012671126721267312674126751267612677126781267912680126811268212683126841268512686126871268812689126901269112692126931269412695126961269712698126991270012701127021270312704127051270612707127081270912710127111271212713127141271512716127171271812719127201272112722127231272412725127261272712728127291273012731127321273312734127351273612737127381273912740127411274212743127441274512746127471274812749127501275112752127531275412755127561275712758127591276012761127621276312764127651276612767127681276912770127711277212773127741277512776127771277812779127801278112782127831278412785127861278712788127891279012791127921279312794127951279612797127981279912800128011280212803128041280512806128071280812809128101281112812128131281412815128161281712818128191282012821128221282312824128251282612827128281282912830128311283212833128341283512836128371283812839128401284112842128431284412845128461284712848128491285012851128521285312854128551285612857128581285912860128611286212863128641286512866128671286812869128701287112872128731287412875128761287712878128791288012881128821288312884128851288612887128881288912890128911289212893128941289512896128971289812899129001290112902129031290412905129061290712908129091291012911129121291312914129151291612917129181291912920129211292212923129241292512926129271292812929129301293112932129331293412935129361293712938129391294012941129421294312944129451294612947129481294912950129511295212953129541295512956129571295812959129601296112962129631296412965129661296712968129691297012971129721297312974129751297612977129781297912980129811298212983129841298512986129871298812989129901299112992129931299412995129961299712998129991300013001130021300313004130051300613007130081300913010130111301213013130141301513016130171301813019130201302113022130231302413025130261302713028130291303013031130321303313034130351303613037130381303913040130411304213043130441304513046130471304813049130501305113052130531305413055130561305713058130591306013061130621306313064130651306613067130681306913070130711307213073130741307513076130771307813079130801308113082130831308413085130861308713088130891309013091130921309313094130951309613097130981309913100131011310213103131041310513106131071310813109131101311113112131131311413115131161311713118131191312013121131221312313124131251312613127131281312913130131311313213133131341313513136131371313813139131401314113142131431314413145131461314713148131491315013151131521315313154131551315613157131581315913160131611316213163131641316513166131671316813169131701317113172131731317413175131761317713178131791318013181131821318313184131851318613187131881318913190131911319213193131941319513196131971319813199132001320113202132031320413205132061320713208132091321013211132121321313214132151321613217132181321913220132211322213223132241322513226132271322813229132301323113232132331323413235132361323713238132391324013241132421324313244132451324613247132481324913250132511325213253132541325513256132571325813259132601326113262132631326413265132661326713268132691327013271132721327313274132751327613277132781327913280132811328213283132841328513286132871328813289132901329113292132931329413295132961329713298132991330013301133021330313304133051330613307133081330913310133111331213313133141331513316133171331813319133201332113322133231332413325133261332713328133291333013331133321333313334133351333613337133381333913340133411334213343133441334513346133471334813349133501335113352133531335413355133561335713358133591336013361133621336313364133651336613367133681336913370133711337213373133741337513376133771337813379133801338113382133831338413385133861338713388133891339013391133921339313394133951339613397133981339913400134011340213403134041340513406134071340813409134101341113412134131341413415134161341713418134191342013421134221342313424134251342613427134281342913430134311343213433134341343513436134371343813439134401344113442134431344413445134461344713448134491345013451134521345313454134551345613457134581345913460134611346213463134641346513466134671346813469134701347113472134731347413475134761347713478134791348013481134821348313484134851348613487134881348913490134911349213493134941349513496134971349813499135001350113502135031350413505135061350713508135091351013511135121351313514135151351613517135181351913520135211352213523135241352513526135271352813529135301353113532135331353413535135361353713538135391354013541135421354313544135451354613547135481354913550135511355213553135541355513556135571355813559135601356113562135631356413565135661356713568135691357013571135721357313574135751357613577135781357913580135811358213583135841358513586135871358813589135901359113592135931359413595135961359713598135991360013601136021360313604136051360613607136081360913610136111361213613136141361513616136171361813619136201362113622136231362413625136261362713628136291363013631136321363313634136351363613637136381363913640136411364213643136441364513646136471364813649136501365113652136531365413655136561365713658136591366013661136621366313664136651366613667136681366913670136711367213673136741367513676136771367813679136801368113682136831368413685136861368713688136891369013691136921369313694136951369613697136981369913700137011370213703137041370513706137071370813709137101371113712137131371413715137161371713718137191372013721137221372313724137251372613727137281372913730137311373213733137341373513736137371373813739137401374113742137431374413745137461374713748137491375013751137521375313754137551375613757137581375913760137611376213763137641376513766137671376813769137701377113772137731377413775137761377713778137791378013781137821378313784137851378613787137881378913790137911379213793137941379513796137971379813799138001380113802138031380413805138061380713808138091381013811138121381313814138151381613817138181381913820138211382213823138241382513826138271382813829138301383113832138331383413835138361383713838138391384013841138421384313844138451384613847138481384913850138511385213853138541385513856138571385813859138601386113862138631386413865138661386713868138691387013871138721387313874138751387613877138781387913880138811388213883138841388513886138871388813889138901389113892138931389413895138961389713898138991390013901139021390313904139051390613907139081390913910139111391213913139141391513916139171391813919139201392113922139231392413925139261392713928139291393013931139321393313934139351393613937139381393913940139411394213943139441394513946139471394813949139501395113952139531395413955139561395713958139591396013961139621396313964139651396613967139681396913970139711397213973139741397513976139771397813979139801398113982139831398413985139861398713988139891399013991139921399313994139951399613997139981399914000140011400214003140041400514006140071400814009140101401114012140131401414015140161401714018140191402014021140221402314024140251402614027140281402914030140311403214033140341403514036140371403814039140401404114042140431404414045140461404714048140491405014051140521405314054140551405614057140581405914060140611406214063140641406514066140671406814069140701407114072140731407414075140761407714078140791408014081140821408314084140851408614087140881408914090140911409214093140941409514096140971409814099141001410114102141031410414105141061410714108141091411014111141121411314114141151411614117141181411914120141211412214123141241412514126141271412814129141301413114132141331413414135141361413714138141391414014141141421414314144141451414614147141481414914150141511415214153141541415514156141571415814159141601416114162141631416414165141661416714168141691417014171141721417314174141751417614177141781417914180141811418214183141841418514186141871418814189141901419114192141931419414195141961419714198141991420014201142021420314204142051420614207142081420914210142111421214213142141421514216142171421814219142201422114222142231422414225142261422714228142291423014231142321423314234142351423614237142381423914240142411424214243142441424514246142471424814249142501425114252142531425414255142561425714258142591426014261142621426314264142651426614267142681426914270142711427214273142741427514276142771427814279142801428114282142831428414285142861428714288142891429014291142921429314294142951429614297142981429914300143011430214303143041430514306143071430814309143101431114312143131431414315143161431714318143191432014321143221432314324143251432614327143281432914330143311433214333143341433514336143371433814339143401434114342143431434414345143461434714348143491435014351143521435314354143551435614357143581435914360143611436214363143641436514366143671436814369143701437114372143731437414375143761437714378143791438014381143821438314384143851438614387143881438914390143911439214393143941439514396143971439814399144001440114402144031440414405144061440714408144091441014411144121441314414144151441614417144181441914420144211442214423144241442514426144271442814429144301443114432144331443414435144361443714438144391444014441144421444314444144451444614447144481444914450144511445214453144541445514456144571445814459144601446114462144631446414465144661446714468144691447014471144721447314474144751447614477144781447914480144811448214483144841448514486144871448814489144901449114492144931449414495144961449714498144991450014501145021450314504145051450614507145081450914510145111451214513145141451514516145171451814519145201452114522145231452414525145261452714528145291453014531145321453314534145351453614537145381453914540145411454214543145441454514546145471454814549145501455114552145531455414555145561455714558145591456014561145621456314564145651456614567145681456914570145711457214573145741457514576145771457814579145801458114582145831458414585145861458714588145891459014591145921459314594145951459614597145981459914600146011460214603146041460514606146071460814609146101461114612146131461414615146161461714618146191462014621146221462314624146251462614627146281462914630146311463214633146341463514636146371463814639146401464114642146431464414645146461464714648146491465014651146521465314654146551465614657146581465914660146611466214663146641466514666146671466814669146701467114672146731467414675146761467714678146791468014681146821468314684146851468614687146881468914690146911469214693146941469514696146971469814699147001470114702147031470414705147061470714708147091471014711147121471314714147151471614717147181471914720147211472214723147241472514726147271472814729147301473114732147331473414735147361473714738147391474014741147421474314744147451474614747147481474914750147511475214753147541475514756147571475814759147601476114762147631476414765147661476714768147691477014771147721477314774147751477614777147781477914780147811478214783147841478514786147871478814789147901479114792147931479414795147961479714798147991480014801148021480314804148051480614807148081480914810148111481214813148141481514816148171481814819148201482114822148231482414825148261482714828148291483014831148321483314834148351483614837148381483914840148411484214843148441484514846148471484814849148501485114852148531485414855148561485714858148591486014861148621486314864148651486614867148681486914870148711487214873148741487514876148771487814879148801488114882148831488414885148861488714888148891489014891148921489314894148951489614897148981489914900149011490214903149041490514906149071490814909149101491114912149131491414915149161491714918149191492014921149221492314924149251492614927149281492914930149311493214933149341493514936149371493814939149401494114942149431494414945149461494714948149491495014951149521495314954149551495614957149581495914960149611496214963149641496514966149671496814969149701497114972149731497414975149761497714978149791498014981149821498314984149851498614987149881498914990149911499214993149941499514996149971499814999150001500115002150031500415005150061500715008150091501015011150121501315014150151501615017150181501915020150211502215023150241502515026150271502815029150301503115032150331503415035150361503715038150391504015041150421504315044150451504615047150481504915050150511505215053150541505515056150571505815059150601506115062150631506415065150661506715068150691507015071150721507315074150751507615077150781507915080150811508215083150841508515086150871508815089150901509115092150931509415095150961509715098150991510015101151021510315104151051510615107151081510915110151111511215113151141511515116151171511815119151201512115122151231512415125151261512715128151291513015131151321513315134151351513615137151381513915140151411514215143151441514515146151471514815149151501515115152151531515415155151561515715158151591516015161151621516315164151651516615167151681516915170151711517215173151741517515176151771517815179151801518115182151831518415185151861518715188151891519015191151921519315194151951519615197151981519915200152011520215203152041520515206152071520815209152101521115212152131521415215152161521715218152191522015221152221522315224152251522615227152281522915230152311523215233152341523515236152371523815239152401524115242152431524415245152461524715248152491525015251152521525315254152551525615257152581525915260152611526215263152641526515266152671526815269152701527115272152731527415275152761527715278152791528015281152821528315284152851528615287152881528915290152911529215293152941529515296152971529815299153001530115302153031530415305153061530715308153091531015311153121531315314153151531615317153181531915320153211532215323153241532515326153271532815329153301533115332153331533415335153361533715338153391534015341153421534315344153451534615347153481534915350153511535215353153541535515356153571535815359153601536115362153631536415365153661536715368153691537015371153721537315374153751537615377153781537915380153811538215383153841538515386153871538815389153901539115392153931539415395153961539715398153991540015401154021540315404154051540615407154081540915410154111541215413154141541515416154171541815419154201542115422154231542415425154261542715428154291543015431154321543315434154351543615437154381543915440154411544215443154441544515446154471544815449154501545115452154531545415455154561545715458154591546015461154621546315464154651546615467154681546915470154711547215473154741547515476154771547815479154801548115482154831548415485154861548715488154891549015491154921549315494154951549615497154981549915500155011550215503155041550515506155071550815509155101551115512155131551415515155161551715518155191552015521155221552315524155251552615527155281552915530155311553215533155341553515536155371553815539155401554115542155431554415545155461554715548155491555015551155521555315554155551555615557155581555915560155611556215563155641556515566155671556815569155701557115572155731557415575155761557715578155791558015581155821558315584155851558615587155881558915590155911559215593155941559515596155971559815599156001560115602156031560415605156061560715608156091561015611156121561315614156151561615617156181561915620156211562215623156241562515626156271562815629156301563115632156331563415635156361563715638156391564015641156421564315644156451564615647156481564915650156511565215653156541565515656156571565815659156601566115662156631566415665156661566715668156691567015671156721567315674156751567615677156781567915680156811568215683156841568515686156871568815689156901569115692156931569415695156961569715698156991570015701157021570315704157051570615707157081570915710157111571215713157141571515716157171571815719157201572115722157231572415725157261572715728157291573015731157321573315734157351573615737157381573915740157411574215743157441574515746157471574815749157501575115752157531575415755157561575715758157591576015761157621576315764157651576615767157681576915770157711577215773157741577515776157771577815779157801578115782157831578415785157861578715788157891579015791157921579315794157951579615797157981579915800158011580215803158041580515806158071580815809158101581115812158131581415815158161581715818158191582015821158221582315824158251582615827158281582915830158311583215833158341583515836158371583815839158401584115842158431584415845158461584715848158491585015851158521585315854158551585615857158581585915860158611586215863158641586515866158671586815869158701587115872158731587415875158761587715878158791588015881158821588315884158851588615887158881588915890158911589215893158941589515896158971589815899159001590115902159031590415905159061590715908159091591015911159121591315914159151591615917159181591915920159211592215923159241592515926159271592815929159301593115932159331593415935159361593715938159391594015941159421594315944159451594615947159481594915950159511595215953159541595515956159571595815959159601596115962159631596415965159661596715968159691597015971159721597315974159751597615977159781597915980159811598215983159841598515986159871598815989159901599115992159931599415995159961599715998159991600016001160021600316004160051600616007160081600916010160111601216013160141601516016160171601816019160201602116022160231602416025160261602716028160291603016031160321603316034160351603616037160381603916040160411604216043160441604516046160471604816049160501605116052160531605416055160561605716058160591606016061160621606316064160651606616067160681606916070160711607216073160741607516076160771607816079160801608116082160831608416085160861608716088160891609016091160921609316094160951609616097160981609916100161011610216103161041610516106161071610816109161101611116112161131611416115161161611716118161191612016121161221612316124161251612616127161281612916130161311613216133161341613516136161371613816139161401614116142161431614416145161461614716148161491615016151161521615316154161551615616157161581615916160161611616216163161641616516166161671616816169161701617116172161731617416175161761617716178161791618016181161821618316184161851618616187161881618916190161911619216193161941619516196161971619816199162001620116202162031620416205162061620716208162091621016211162121621316214162151621616217162181621916220162211622216223162241622516226162271622816229162301623116232162331623416235162361623716238162391624016241162421624316244162451624616247162481624916250162511625216253162541625516256162571625816259162601626116262162631626416265162661626716268162691627016271162721627316274162751627616277162781627916280162811628216283162841628516286162871628816289162901629116292162931629416295162961629716298162991630016301163021630316304163051630616307163081630916310163111631216313163141631516316163171631816319163201632116322163231632416325163261632716328163291633016331163321633316334163351633616337163381633916340163411634216343163441634516346163471634816349163501635116352163531635416355163561635716358163591636016361163621636316364163651636616367163681636916370163711637216373163741637516376163771637816379163801638116382163831638416385163861638716388163891639016391163921639316394163951639616397163981639916400164011640216403164041640516406164071640816409164101641116412164131641416415164161641716418164191642016421164221642316424164251642616427164281642916430164311643216433164341643516436164371643816439164401644116442164431644416445164461644716448164491645016451164521645316454164551645616457164581645916460164611646216463164641646516466164671646816469164701647116472164731647416475164761647716478164791648016481164821648316484164851648616487164881648916490164911649216493164941649516496164971649816499165001650116502165031650416505165061650716508165091651016511165121651316514165151651616517165181651916520165211652216523165241652516526165271652816529165301653116532165331653416535165361653716538165391654016541165421654316544165451654616547165481654916550165511655216553165541655516556165571655816559165601656116562165631656416565165661656716568165691657016571165721657316574165751657616577165781657916580165811658216583165841658516586165871658816589165901659116592165931659416595165961659716598165991660016601166021660316604166051660616607166081660916610166111661216613166141661516616166171661816619166201662116622166231662416625166261662716628166291663016631166321663316634166351663616637166381663916640166411664216643166441664516646166471664816649166501665116652166531665416655166561665716658166591666016661166621666316664166651666616667166681666916670166711667216673166741667516676166771667816679166801668116682166831668416685166861668716688166891669016691166921669316694166951669616697166981669916700167011670216703167041670516706167071670816709167101671116712167131671416715167161671716718167191672016721167221672316724167251672616727167281672916730167311673216733167341673516736167371673816739167401674116742167431674416745167461674716748167491675016751167521675316754167551675616757167581675916760167611676216763167641676516766167671676816769167701677116772167731677416775167761677716778167791678016781167821678316784167851678616787167881678916790167911679216793167941679516796167971679816799168001680116802168031680416805168061680716808168091681016811168121681316814168151681616817168181681916820168211682216823168241682516826168271682816829168301683116832168331683416835168361683716838168391684016841168421684316844168451684616847168481684916850168511685216853168541685516856168571685816859168601686116862168631686416865168661686716868168691687016871168721687316874168751687616877168781687916880168811688216883168841688516886168871688816889168901689116892168931689416895168961689716898168991690016901169021690316904169051690616907169081690916910169111691216913169141691516916169171691816919169201692116922169231692416925169261692716928169291693016931169321693316934169351693616937169381693916940169411694216943169441694516946169471694816949169501695116952169531695416955169561695716958169591696016961169621696316964169651696616967169681696916970169711697216973169741697516976169771697816979169801698116982169831698416985169861698716988169891699016991169921699316994169951699616997169981699917000170011700217003170041700517006170071700817009170101701117012170131701417015170161701717018170191702017021170221702317024170251702617027170281702917030170311703217033170341703517036170371703817039170401704117042170431704417045170461704717048170491705017051170521705317054170551705617057170581705917060170611706217063170641706517066170671706817069170701707117072170731707417075170761707717078170791708017081170821708317084170851708617087170881708917090170911709217093170941709517096170971709817099171001710117102171031710417105171061710717108171091711017111171121711317114171151711617117171181711917120171211712217123171241712517126171271712817129171301713117132171331713417135171361713717138171391714017141171421714317144171451714617147171481714917150171511715217153171541715517156171571715817159171601716117162171631716417165171661716717168171691717017171171721717317174171751717617177171781717917180171811718217183171841718517186171871718817189171901719117192171931719417195171961719717198171991720017201172021720317204172051720617207172081720917210172111721217213172141721517216172171721817219172201722117222172231722417225172261722717228172291723017231172321723317234172351723617237172381723917240172411724217243172441724517246172471724817249172501725117252172531725417255172561725717258172591726017261172621726317264172651726617267172681726917270172711727217273172741727517276172771727817279172801728117282172831728417285172861728717288172891729017291172921729317294172951729617297172981729917300173011730217303173041730517306173071730817309173101731117312173131731417315173161731717318173191732017321173221732317324173251732617327173281732917330173311733217333173341733517336173371733817339173401734117342173431734417345173461734717348173491735017351173521735317354173551735617357173581735917360173611736217363173641736517366173671736817369173701737117372173731737417375173761737717378173791738017381173821738317384173851738617387173881738917390173911739217393173941739517396173971739817399174001740117402174031740417405174061740717408174091741017411174121741317414174151741617417174181741917420174211742217423174241742517426174271742817429174301743117432174331743417435174361743717438174391744017441174421744317444174451744617447174481744917450174511745217453174541745517456174571745817459174601746117462174631746417465174661746717468174691747017471174721747317474174751747617477174781747917480174811748217483174841748517486174871748817489174901749117492174931749417495174961749717498174991750017501175021750317504175051750617507175081750917510175111751217513175141751517516175171751817519175201752117522175231752417525175261752717528175291753017531175321753317534175351753617537175381753917540175411754217543175441754517546175471754817549175501755117552175531755417555175561755717558175591756017561175621756317564175651756617567175681756917570175711757217573175741757517576175771757817579175801758117582175831758417585175861758717588175891759017591175921759317594175951759617597175981759917600176011760217603176041760517606176071760817609176101761117612176131761417615176161761717618176191762017621176221762317624176251762617627176281762917630176311763217633176341763517636176371763817639176401764117642176431764417645176461764717648176491765017651176521765317654176551765617657176581765917660176611766217663176641766517666176671766817669176701767117672176731767417675176761767717678176791768017681176821768317684176851768617687176881768917690176911769217693176941769517696176971769817699177001770117702177031770417705177061770717708177091771017711177121771317714177151771617717177181771917720177211772217723177241772517726177271772817729177301773117732177331773417735177361773717738177391774017741177421774317744177451774617747177481774917750177511775217753177541775517756177571775817759177601776117762177631776417765177661776717768177691777017771177721777317774177751777617777177781777917780177811778217783177841778517786177871778817789177901779117792177931779417795177961779717798177991780017801178021780317804178051780617807178081780917810178111781217813178141781517816178171781817819178201782117822178231782417825178261782717828178291783017831178321783317834178351783617837178381783917840178411784217843178441784517846178471784817849178501785117852178531785417855178561785717858178591786017861178621786317864178651786617867178681786917870178711787217873178741787517876178771787817879178801788117882178831788417885178861788717888178891789017891178921789317894178951789617897178981789917900179011790217903179041790517906179071790817909179101791117912179131791417915179161791717918179191792017921179221792317924179251792617927179281792917930179311793217933179341793517936179371793817939179401794117942179431794417945179461794717948179491795017951179521795317954179551795617957179581795917960179611796217963179641796517966179671796817969179701797117972179731797417975179761797717978179791798017981179821798317984179851798617987179881798917990179911799217993179941799517996179971799817999180001800118002180031800418005180061800718008180091801018011180121801318014180151801618017180181801918020180211802218023180241802518026180271802818029180301803118032180331803418035180361803718038180391804018041180421804318044180451804618047180481804918050180511805218053180541805518056180571805818059180601806118062180631806418065180661806718068180691807018071180721807318074180751807618077180781807918080180811808218083180841808518086180871808818089180901809118092180931809418095180961809718098180991810018101181021810318104181051810618107181081810918110181111811218113181141811518116181171811818119181201812118122181231812418125181261812718128181291813018131181321813318134181351813618137181381813918140181411814218143181441814518146181471814818149181501815118152181531815418155181561815718158181591816018161181621816318164181651816618167181681816918170181711817218173181741817518176181771817818179181801818118182181831818418185181861818718188181891819018191181921819318194181951819618197181981819918200182011820218203182041820518206182071820818209182101821118212182131821418215182161821718218182191822018221182221822318224182251822618227182281822918230182311823218233182341823518236182371823818239182401824118242182431824418245182461824718248182491825018251182521825318254182551825618257182581825918260182611826218263182641826518266182671826818269182701827118272182731827418275182761827718278182791828018281182821828318284182851828618287182881828918290182911829218293182941829518296182971829818299183001830118302183031830418305183061830718308183091831018311183121831318314183151831618317183181831918320183211832218323183241832518326183271832818329183301833118332183331833418335183361833718338183391834018341183421834318344183451834618347183481834918350183511835218353183541835518356183571835818359183601836118362183631836418365183661836718368183691837018371183721837318374183751837618377183781837918380183811838218383183841838518386183871838818389183901839118392183931839418395183961839718398183991840018401184021840318404184051840618407184081840918410184111841218413184141841518416184171841818419184201842118422184231842418425184261842718428184291843018431184321843318434184351843618437184381843918440184411844218443184441844518446184471844818449184501845118452184531845418455184561845718458184591846018461184621846318464184651846618467184681846918470184711847218473184741847518476184771847818479184801848118482184831848418485184861848718488184891849018491184921849318494184951849618497184981849918500185011850218503185041850518506185071850818509185101851118512185131851418515185161851718518185191852018521185221852318524185251852618527185281852918530185311853218533185341853518536185371853818539185401854118542185431854418545185461854718548185491855018551185521855318554185551855618557185581855918560185611856218563185641856518566185671856818569185701857118572185731857418575185761857718578185791858018581185821858318584185851858618587185881858918590185911859218593185941859518596185971859818599186001860118602186031860418605186061860718608186091861018611186121861318614186151861618617186181861918620186211862218623186241862518626186271862818629186301863118632186331863418635186361863718638186391864018641186421864318644186451864618647186481864918650186511865218653186541865518656186571865818659186601866118662186631866418665186661866718668186691867018671186721867318674186751867618677186781867918680186811868218683186841868518686186871868818689186901869118692186931869418695186961869718698186991870018701187021870318704187051870618707187081870918710187111871218713187141871518716187171871818719187201872118722187231872418725187261872718728187291873018731187321873318734187351873618737187381873918740187411874218743187441874518746187471874818749187501875118752187531875418755187561875718758187591876018761187621876318764187651876618767187681876918770187711877218773187741877518776187771877818779187801878118782187831878418785187861878718788187891879018791187921879318794187951879618797187981879918800188011880218803188041880518806188071880818809188101881118812188131881418815188161881718818188191882018821188221882318824188251882618827188281882918830188311883218833188341883518836188371883818839188401884118842188431884418845188461884718848188491885018851188521885318854188551885618857188581885918860188611886218863188641886518866188671886818869188701887118872188731887418875188761887718878188791888018881188821888318884188851888618887188881888918890188911889218893188941889518896188971889818899189001890118902189031890418905189061890718908189091891018911189121891318914189151891618917189181891918920189211892218923189241892518926189271892818929189301893118932189331893418935189361893718938189391894018941189421894318944189451894618947189481894918950189511895218953189541895518956189571895818959189601896118962189631896418965189661896718968189691897018971189721897318974189751897618977189781897918980189811898218983189841898518986189871898818989189901899118992189931899418995189961899718998189991900019001190021900319004190051900619007190081900919010190111901219013190141901519016190171901819019190201902119022190231902419025190261902719028190291903019031190321903319034190351903619037190381903919040190411904219043190441904519046190471904819049190501905119052190531905419055190561905719058190591906019061190621906319064190651906619067190681906919070190711907219073190741907519076190771907819079190801908119082190831908419085190861908719088190891909019091190921909319094190951909619097190981909919100191011910219103191041910519106191071910819109191101911119112191131911419115191161911719118191191912019121191221912319124191251912619127191281912919130191311913219133191341913519136191371913819139191401914119142191431914419145191461914719148191491915019151191521915319154191551915619157191581915919160191611916219163191641916519166191671916819169191701917119172191731917419175191761917719178191791918019181191821918319184191851918619187191881918919190191911919219193191941919519196191971919819199192001920119202192031920419205192061920719208192091921019211192121921319214192151921619217192181921919220192211922219223192241922519226192271922819229192301923119232192331923419235192361923719238192391924019241192421924319244192451924619247192481924919250192511925219253192541925519256192571925819259192601926119262192631926419265192661926719268192691927019271192721927319274192751927619277192781927919280192811928219283192841928519286192871928819289192901929119292192931929419295192961929719298192991930019301193021930319304193051930619307193081930919310193111931219313193141931519316193171931819319193201932119322193231932419325193261932719328193291933019331193321933319334193351933619337193381933919340193411934219343193441934519346193471934819349193501935119352193531935419355193561935719358193591936019361193621936319364193651936619367193681936919370193711937219373193741937519376193771937819379193801938119382193831938419385193861938719388193891939019391193921939319394193951939619397193981939919400194011940219403194041940519406194071940819409194101941119412194131941419415194161941719418194191942019421194221942319424194251942619427194281942919430194311943219433194341943519436194371943819439194401944119442194431944419445194461944719448194491945019451194521945319454194551945619457194581945919460194611946219463194641946519466194671946819469194701947119472194731947419475194761947719478194791948019481194821948319484194851948619487194881948919490194911949219493194941949519496194971949819499195001950119502195031950419505195061950719508195091951019511195121951319514195151951619517195181951919520195211952219523195241952519526195271952819529195301953119532195331953419535195361953719538195391954019541195421954319544195451954619547195481954919550195511955219553195541955519556195571955819559195601956119562195631956419565195661956719568195691957019571195721957319574195751957619577195781957919580195811958219583195841958519586195871958819589195901959119592195931959419595195961959719598195991960019601196021960319604196051960619607196081960919610196111961219613196141961519616196171961819619196201962119622196231962419625196261962719628196291963019631196321963319634196351963619637196381963919640196411964219643196441964519646196471964819649196501965119652196531965419655196561965719658196591966019661196621966319664196651966619667196681966919670196711967219673196741967519676196771967819679196801968119682196831968419685196861968719688196891969019691196921969319694196951969619697196981969919700197011970219703197041970519706197071970819709197101971119712197131971419715197161971719718197191972019721197221972319724197251972619727197281972919730197311973219733197341973519736197371973819739197401974119742197431974419745197461974719748197491975019751197521975319754197551975619757197581975919760197611976219763197641976519766197671976819769197701977119772197731977419775197761977719778197791978019781197821978319784197851978619787197881978919790197911979219793197941979519796197971979819799198001980119802198031980419805198061980719808198091981019811198121981319814198151981619817198181981919820198211982219823198241982519826198271982819829198301983119832198331983419835198361983719838198391984019841198421984319844198451984619847198481984919850198511985219853198541985519856198571985819859198601986119862198631986419865198661986719868198691987019871198721987319874198751987619877198781987919880198811988219883198841988519886198871988819889198901989119892198931989419895198961989719898198991990019901199021990319904199051990619907199081990919910199111991219913199141991519916199171991819919199201992119922199231992419925199261992719928199291993019931199321993319934199351993619937199381993919940199411994219943199441994519946199471994819949199501995119952199531995419955199561995719958199591996019961199621996319964199651996619967199681996919970199711997219973199741997519976199771997819979199801998119982199831998419985199861998719988199891999019991199921999319994199951999619997199981999920000200012000220003200042000520006200072000820009200102001120012200132001420015200162001720018200192002020021200222002320024200252002620027200282002920030200312003220033200342003520036200372003820039200402004120042200432004420045200462004720048200492005020051200522005320054200552005620057200582005920060200612006220063200642006520066200672006820069200702007120072200732007420075200762007720078200792008020081200822008320084200852008620087200882008920090200912009220093200942009520096200972009820099201002010120102201032010420105201062010720108201092011020111201122011320114201152011620117201182011920120201212012220123201242012520126201272012820129201302013120132201332013420135201362013720138201392014020141201422014320144201452014620147201482014920150201512015220153201542015520156201572015820159201602016120162201632016420165201662016720168201692017020171201722017320174201752017620177201782017920180201812018220183201842018520186201872018820189201902019120192201932019420195201962019720198201992020020201202022020320204202052020620207202082020920210202112021220213202142021520216202172021820219202202022120222202232022420225202262022720228202292023020231202322023320234202352023620237202382023920240202412024220243202442024520246202472024820249202502025120252202532025420255202562025720258202592026020261202622026320264202652026620267202682026920270202712027220273202742027520276202772027820279202802028120282202832028420285202862028720288202892029020291202922029320294202952029620297202982029920300203012030220303203042030520306203072030820309203102031120312203132031420315203162031720318203192032020321203222032320324203252032620327203282032920330203312033220333203342033520336203372033820339203402034120342203432034420345203462034720348203492035020351203522035320354203552035620357203582035920360203612036220363203642036520366203672036820369203702037120372203732037420375203762037720378203792038020381203822038320384203852038620387203882038920390203912039220393203942039520396203972039820399204002040120402204032040420405204062040720408204092041020411204122041320414204152041620417204182041920420204212042220423204242042520426204272042820429204302043120432204332043420435204362043720438204392044020441204422044320444204452044620447204482044920450204512045220453204542045520456204572045820459204602046120462204632046420465204662046720468204692047020471204722047320474204752047620477204782047920480204812048220483204842048520486204872048820489204902049120492204932049420495204962049720498204992050020501205022050320504205052050620507205082050920510205112051220513205142051520516205172051820519205202052120522205232052420525205262052720528205292053020531205322053320534205352053620537205382053920540205412054220543205442054520546205472054820549205502055120552205532055420555205562055720558205592056020561205622056320564205652056620567205682056920570205712057220573205742057520576205772057820579205802058120582205832058420585205862058720588205892059020591205922059320594205952059620597205982059920600206012060220603206042060520606206072060820609206102061120612206132061420615206162061720618206192062020621206222062320624206252062620627206282062920630206312063220633206342063520636206372063820639206402064120642206432064420645206462064720648206492065020651206522065320654206552065620657206582065920660206612066220663206642066520666206672066820669206702067120672206732067420675206762067720678206792068020681206822068320684206852068620687206882068920690206912069220693206942069520696206972069820699207002070120702207032070420705207062070720708207092071020711207122071320714207152071620717207182071920720207212072220723207242072520726207272072820729207302073120732207332073420735207362073720738207392074020741207422074320744207452074620747207482074920750207512075220753207542075520756207572075820759207602076120762207632076420765207662076720768207692077020771207722077320774207752077620777207782077920780207812078220783207842078520786207872078820789207902079120792207932079420795207962079720798207992080020801208022080320804208052080620807208082080920810208112081220813208142081520816208172081820819208202082120822208232082420825208262082720828208292083020831208322083320834208352083620837208382083920840208412084220843208442084520846208472084820849208502085120852208532085420855208562085720858208592086020861208622086320864208652086620867208682086920870208712087220873208742087520876208772087820879208802088120882208832088420885208862088720888208892089020891208922089320894208952089620897208982089920900209012090220903209042090520906209072090820909209102091120912209132091420915209162091720918209192092020921209222092320924209252092620927209282092920930209312093220933209342093520936209372093820939209402094120942209432094420945209462094720948209492095020951209522095320954209552095620957209582095920960209612096220963209642096520966209672096820969209702097120972209732097420975209762097720978209792098020981209822098320984209852098620987209882098920990209912099220993209942099520996209972099820999210002100121002210032100421005210062100721008210092101021011210122101321014210152101621017210182101921020210212102221023210242102521026210272102821029210302103121032210332103421035210362103721038210392104021041210422104321044210452104621047210482104921050210512105221053210542105521056210572105821059210602106121062210632106421065210662106721068210692107021071210722107321074210752107621077210782107921080210812108221083210842108521086210872108821089210902109121092210932109421095210962109721098210992110021101211022110321104211052110621107211082110921110211112111221113211142111521116211172111821119211202112121122211232112421125211262112721128211292113021131211322113321134211352113621137211382113921140211412114221143211442114521146211472114821149211502115121152211532115421155211562115721158211592116021161211622116321164211652116621167211682116921170211712117221173211742117521176211772117821179211802118121182211832118421185211862118721188211892119021191211922119321194211952119621197211982119921200212012120221203212042120521206212072120821209212102121121212212132121421215212162121721218212192122021221212222122321224212252122621227212282122921230212312123221233212342123521236212372123821239212402124121242212432124421245212462124721248212492125021251212522125321254212552125621257212582125921260212612126221263212642126521266212672126821269212702127121272212732127421275212762127721278212792128021281212822128321284212852128621287212882128921290212912129221293212942129521296212972129821299213002130121302213032130421305213062130721308213092131021311213122131321314213152131621317213182131921320213212132221323213242132521326213272132821329213302133121332213332133421335213362133721338213392134021341213422134321344213452134621347213482134921350213512135221353213542135521356213572135821359213602136121362213632136421365213662136721368213692137021371213722137321374213752137621377213782137921380213812138221383213842138521386213872138821389213902139121392213932139421395213962139721398213992140021401214022140321404214052140621407214082140921410214112141221413214142141521416214172141821419214202142121422214232142421425214262142721428214292143021431214322143321434214352143621437214382143921440214412144221443214442144521446214472144821449214502145121452214532145421455214562145721458214592146021461214622146321464214652146621467214682146921470214712147221473214742147521476214772147821479214802148121482214832148421485214862148721488214892149021491214922149321494214952149621497214982149921500215012150221503215042150521506215072150821509215102151121512215132151421515215162151721518215192152021521215222152321524215252152621527215282152921530215312153221533215342153521536215372153821539215402154121542215432154421545215462154721548215492155021551215522155321554215552155621557215582155921560215612156221563215642156521566215672156821569215702157121572215732157421575215762157721578215792158021581215822158321584215852158621587215882158921590215912159221593215942159521596215972159821599216002160121602216032160421605216062160721608216092161021611216122161321614216152161621617216182161921620216212162221623216242162521626216272162821629216302163121632216332163421635216362163721638216392164021641216422164321644216452164621647216482164921650216512165221653216542165521656216572165821659216602166121662216632166421665216662166721668216692167021671216722167321674216752167621677216782167921680216812168221683216842168521686216872168821689216902169121692216932169421695216962169721698216992170021701217022170321704217052170621707217082170921710217112171221713217142171521716217172171821719217202172121722217232172421725217262172721728217292173021731217322173321734217352173621737217382173921740217412174221743217442174521746217472174821749217502175121752217532175421755217562175721758217592176021761217622176321764217652176621767217682176921770217712177221773217742177521776217772177821779217802178121782217832178421785217862178721788217892179021791217922179321794217952179621797217982179921800218012180221803218042180521806218072180821809218102181121812218132181421815218162181721818218192182021821218222182321824218252182621827218282182921830218312183221833218342183521836218372183821839218402184121842218432184421845218462184721848218492185021851218522185321854218552185621857218582185921860218612186221863218642186521866218672186821869218702187121872218732187421875218762187721878218792188021881218822188321884218852188621887218882188921890218912189221893218942189521896218972189821899219002190121902219032190421905219062190721908219092191021911219122191321914219152191621917219182191921920219212192221923219242192521926219272192821929219302193121932219332193421935219362193721938219392194021941219422194321944219452194621947219482194921950219512195221953219542195521956219572195821959219602196121962219632196421965219662196721968219692197021971219722197321974219752197621977219782197921980219812198221983219842198521986219872198821989219902199121992219932199421995219962199721998219992200022001220022200322004220052200622007220082200922010220112201222013220142201522016220172201822019220202202122022220232202422025220262202722028220292203022031220322203322034220352203622037220382203922040220412204222043220442204522046220472204822049220502205122052220532205422055220562205722058220592206022061220622206322064220652206622067220682206922070220712207222073220742207522076220772207822079220802208122082220832208422085220862208722088220892209022091220922209322094220952209622097220982209922100221012210222103221042210522106221072210822109221102211122112221132211422115221162211722118221192212022121221222212322124221252212622127221282212922130221312213222133221342213522136221372213822139221402214122142221432214422145221462214722148221492215022151221522215322154221552215622157221582215922160221612216222163221642216522166221672216822169221702217122172221732217422175221762217722178221792218022181221822218322184221852218622187221882218922190221912219222193221942219522196221972219822199222002220122202222032220422205222062220722208222092221022211222122221322214222152221622217222182221922220222212222222223222242222522226222272222822229222302223122232222332223422235222362223722238222392224022241222422224322244222452224622247222482224922250222512225222253222542225522256222572225822259222602226122262222632226422265222662226722268222692227022271222722227322274222752227622277222782227922280222812228222283222842228522286222872228822289222902229122292222932229422295222962229722298222992230022301223022230322304223052230622307223082230922310223112231222313223142231522316223172231822319223202232122322223232232422325223262232722328223292233022331223322233322334223352233622337223382233922340223412234222343223442234522346223472234822349223502235122352223532235422355223562235722358223592236022361223622236322364223652236622367223682236922370223712237222373223742237522376223772237822379223802238122382223832238422385223862238722388223892239022391223922239322394223952239622397223982239922400224012240222403224042240522406224072240822409224102241122412224132241422415224162241722418224192242022421224222242322424224252242622427224282242922430224312243222433224342243522436224372243822439224402244122442224432244422445224462244722448224492245022451224522245322454224552245622457224582245922460224612246222463224642246522466224672246822469224702247122472224732247422475224762247722478224792248022481224822248322484224852248622487224882248922490224912249222493224942249522496224972249822499225002250122502225032250422505225062250722508225092251022511225122251322514225152251622517225182251922520225212252222523225242252522526225272252822529225302253122532225332253422535225362253722538225392254022541225422254322544225452254622547225482254922550225512255222553225542255522556225572255822559225602256122562225632256422565225662256722568225692257022571225722257322574225752257622577225782257922580225812258222583225842258522586225872258822589225902259122592225932259422595225962259722598225992260022601226022260322604226052260622607226082260922610226112261222613226142261522616226172261822619226202262122622226232262422625226262262722628226292263022631226322263322634226352263622637226382263922640226412264222643226442264522646226472264822649226502265122652226532265422655226562265722658226592266022661226622266322664226652266622667226682266922670226712267222673226742267522676226772267822679226802268122682226832268422685226862268722688226892269022691226922269322694226952269622697226982269922700227012270222703227042270522706227072270822709227102271122712227132271422715227162271722718227192272022721227222272322724227252272622727227282272922730227312273222733227342273522736227372273822739227402274122742227432274422745227462274722748227492275022751227522275322754227552275622757227582275922760227612276222763227642276522766227672276822769227702277122772227732277422775227762277722778227792278022781227822278322784227852278622787227882278922790227912279222793227942279522796227972279822799228002280122802228032280422805228062280722808228092281022811228122281322814228152281622817228182281922820228212282222823228242282522826228272282822829228302283122832228332283422835228362283722838228392284022841228422284322844228452284622847228482284922850228512285222853228542285522856228572285822859228602286122862228632286422865228662286722868228692287022871228722287322874228752287622877228782287922880228812288222883228842288522886228872288822889228902289122892228932289422895228962289722898228992290022901229022290322904229052290622907229082290922910229112291222913229142291522916229172291822919229202292122922229232292422925229262292722928229292293022931229322293322934229352293622937229382293922940229412294222943229442294522946229472294822949229502295122952229532295422955229562295722958229592296022961229622296322964229652296622967229682296922970229712297222973229742297522976229772297822979229802298122982229832298422985229862298722988229892299022991229922299322994229952299622997229982299923000230012300223003230042300523006230072300823009230102301123012230132301423015230162301723018230192302023021230222302323024230252302623027230282302923030230312303223033230342303523036230372303823039230402304123042230432304423045230462304723048230492305023051230522305323054230552305623057230582305923060230612306223063230642306523066230672306823069230702307123072230732307423075230762307723078230792308023081230822308323084230852308623087230882308923090230912309223093230942309523096230972309823099231002310123102231032310423105231062310723108231092311023111231122311323114231152311623117231182311923120231212312223123231242312523126231272312823129231302313123132231332313423135231362313723138231392314023141231422314323144231452314623147231482314923150231512315223153231542315523156231572315823159231602316123162231632316423165231662316723168231692317023171231722317323174231752317623177231782317923180231812318223183231842318523186231872318823189231902319123192231932319423195231962319723198231992320023201232022320323204232052320623207232082320923210232112321223213232142321523216232172321823219232202322123222232232322423225232262322723228232292323023231232322323323234232352323623237232382323923240232412324223243232442324523246232472324823249232502325123252232532325423255232562325723258232592326023261232622326323264232652326623267232682326923270232712327223273232742327523276232772327823279232802328123282232832328423285232862328723288232892329023291232922329323294232952329623297232982329923300233012330223303233042330523306233072330823309233102331123312233132331423315233162331723318233192332023321233222332323324233252332623327233282332923330233312333223333233342333523336233372333823339233402334123342233432334423345233462334723348233492335023351233522335323354233552335623357233582335923360233612336223363233642336523366233672336823369233702337123372233732337423375233762337723378233792338023381233822338323384233852338623387233882338923390233912339223393233942339523396233972339823399234002340123402234032340423405234062340723408234092341023411234122341323414234152341623417234182341923420234212342223423234242342523426234272342823429234302343123432234332343423435234362343723438234392344023441234422344323444234452344623447234482344923450234512345223453234542345523456234572345823459234602346123462234632346423465234662346723468234692347023471234722347323474234752347623477234782347923480234812348223483234842348523486234872348823489234902349123492234932349423495234962349723498234992350023501235022350323504235052350623507235082350923510235112351223513235142351523516235172351823519235202352123522235232352423525235262352723528235292353023531235322353323534235352353623537235382353923540235412354223543235442354523546235472354823549235502355123552235532355423555235562355723558235592356023561235622356323564235652356623567235682356923570235712357223573235742357523576235772357823579235802358123582235832358423585235862358723588235892359023591235922359323594235952359623597235982359923600236012360223603236042360523606236072360823609236102361123612236132361423615236162361723618236192362023621236222362323624236252362623627236282362923630236312363223633236342363523636236372363823639236402364123642236432364423645236462364723648236492365023651236522365323654236552365623657236582365923660236612366223663236642366523666236672366823669236702367123672236732367423675236762367723678236792368023681236822368323684236852368623687236882368923690236912369223693236942369523696236972369823699237002370123702237032370423705237062370723708237092371023711237122371323714237152371623717237182371923720237212372223723237242372523726237272372823729237302373123732237332373423735237362373723738237392374023741237422374323744237452374623747237482374923750237512375223753237542375523756237572375823759237602376123762237632376423765237662376723768237692377023771237722377323774237752377623777237782377923780237812378223783237842378523786237872378823789237902379123792237932379423795237962379723798237992380023801238022380323804238052380623807238082380923810238112381223813238142381523816238172381823819238202382123822238232382423825238262382723828238292383023831238322383323834238352383623837238382383923840238412384223843238442384523846238472384823849238502385123852238532385423855238562385723858238592386023861238622386323864238652386623867238682386923870238712387223873238742387523876238772387823879238802388123882238832388423885238862388723888238892389023891238922389323894238952389623897238982389923900239012390223903239042390523906239072390823909239102391123912239132391423915239162391723918239192392023921239222392323924239252392623927239282392923930239312393223933239342393523936239372393823939239402394123942239432394423945239462394723948239492395023951239522395323954239552395623957239582395923960239612396223963239642396523966239672396823969239702397123972239732397423975239762397723978239792398023981239822398323984239852398623987239882398923990239912399223993239942399523996239972399823999240002400124002240032400424005240062400724008240092401024011240122401324014240152401624017240182401924020240212402224023240242402524026240272402824029240302403124032240332403424035240362403724038240392404024041240422404324044240452404624047240482404924050240512405224053240542405524056240572405824059240602406124062240632406424065240662406724068240692407024071240722407324074240752407624077240782407924080240812408224083240842408524086240872408824089240902409124092240932409424095240962409724098240992410024101241022410324104241052410624107241082410924110241112411224113241142411524116241172411824119241202412124122241232412424125241262412724128241292413024131241322413324134241352413624137241382413924140241412414224143241442414524146241472414824149241502415124152241532415424155241562415724158241592416024161241622416324164241652416624167241682416924170241712417224173241742417524176241772417824179241802418124182241832418424185241862418724188241892419024191241922419324194241952419624197241982419924200242012420224203242042420524206242072420824209242102421124212242132421424215242162421724218242192422024221242222422324224242252422624227242282422924230242312423224233242342423524236242372423824239242402424124242242432424424245242462424724248242492425024251242522425324254242552425624257242582425924260242612426224263242642426524266242672426824269242702427124272242732427424275242762427724278242792428024281242822428324284242852428624287242882428924290242912429224293242942429524296242972429824299243002430124302243032430424305243062430724308243092431024311243122431324314243152431624317243182431924320243212432224323243242432524326243272432824329243302433124332243332433424335243362433724338243392434024341243422434324344243452434624347243482434924350243512435224353243542435524356243572435824359243602436124362243632436424365243662436724368243692437024371243722437324374243752437624377243782437924380243812438224383243842438524386243872438824389243902439124392243932439424395243962439724398243992440024401244022440324404244052440624407244082440924410244112441224413244142441524416244172441824419244202442124422244232442424425244262442724428244292443024431244322443324434244352443624437244382443924440244412444224443244442444524446244472444824449244502445124452244532445424455244562445724458244592446024461244622446324464244652446624467244682446924470244712447224473244742447524476244772447824479244802448124482244832448424485244862448724488244892449024491244922449324494244952449624497244982449924500245012450224503245042450524506245072450824509245102451124512245132451424515245162451724518245192452024521245222452324524245252452624527245282452924530245312453224533245342453524536245372453824539245402454124542245432454424545245462454724548245492455024551245522455324554245552455624557245582455924560245612456224563245642456524566245672456824569245702457124572245732457424575245762457724578245792458024581245822458324584245852458624587245882458924590245912459224593245942459524596245972459824599246002460124602246032460424605246062460724608246092461024611246122461324614246152461624617246182461924620246212462224623246242462524626246272462824629246302463124632246332463424635246362463724638246392464024641246422464324644246452464624647246482464924650246512465224653246542465524656246572465824659246602466124662246632466424665246662466724668246692467024671246722467324674246752467624677246782467924680246812468224683246842468524686246872468824689246902469124692246932469424695246962469724698246992470024701247022470324704247052470624707247082470924710247112471224713247142471524716247172471824719247202472124722247232472424725247262472724728247292473024731247322473324734247352473624737247382473924740247412474224743247442474524746247472474824749247502475124752247532475424755247562475724758247592476024761247622476324764247652476624767247682476924770247712477224773247742477524776247772477824779247802478124782247832478424785247862478724788247892479024791247922479324794247952479624797247982479924800248012480224803248042480524806248072480824809248102481124812248132481424815248162481724818248192482024821248222482324824248252482624827248282482924830248312483224833248342483524836248372483824839248402484124842248432484424845248462484724848248492485024851248522485324854248552485624857248582485924860248612486224863248642486524866248672486824869248702487124872248732487424875248762487724878248792488024881248822488324884248852488624887248882488924890248912489224893248942489524896248972489824899249002490124902249032490424905249062490724908249092491024911249122491324914249152491624917249182491924920249212492224923249242492524926249272492824929249302493124932249332493424935249362493724938249392494024941249422494324944249452494624947249482494924950249512495224953249542495524956249572495824959249602496124962249632496424965249662496724968249692497024971249722497324974249752497624977249782497924980249812498224983249842498524986249872498824989249902499124992249932499424995249962499724998249992500025001250022500325004250052500625007250082500925010250112501225013250142501525016250172501825019250202502125022250232502425025250262502725028250292503025031250322503325034250352503625037250382503925040250412504225043250442504525046250472504825049250502505125052250532505425055250562505725058250592506025061250622506325064250652506625067250682506925070250712507225073250742507525076250772507825079250802508125082250832508425085250862508725088250892509025091250922509325094250952509625097250982509925100251012510225103251042510525106251072510825109251102511125112251132511425115251162511725118251192512025121251222512325124251252512625127251282512925130251312513225133251342513525136251372513825139251402514125142251432514425145251462514725148251492515025151251522515325154251552515625157251582515925160251612516225163251642516525166251672516825169251702517125172251732517425175251762517725178251792518025181251822518325184251852518625187251882518925190251912519225193251942519525196251972519825199252002520125202252032520425205252062520725208252092521025211252122521325214252152521625217252182521925220252212522225223252242522525226252272522825229252302523125232252332523425235252362523725238252392524025241252422524325244252452524625247252482524925250252512525225253252542525525256252572525825259252602526125262252632526425265252662526725268252692527025271252722527325274252752527625277252782527925280252812528225283252842528525286252872528825289252902529125292252932529425295252962529725298252992530025301253022530325304253052530625307253082530925310253112531225313253142531525316253172531825319253202532125322253232532425325253262532725328253292533025331253322533325334253352533625337253382533925340253412534225343253442534525346253472534825349253502535125352253532535425355253562535725358253592536025361253622536325364253652536625367253682536925370253712537225373253742537525376253772537825379253802538125382253832538425385253862538725388253892539025391253922539325394253952539625397253982539925400254012540225403254042540525406254072540825409254102541125412254132541425415254162541725418254192542025421254222542325424254252542625427254282542925430254312543225433254342543525436254372543825439254402544125442254432544425445254462544725448254492545025451254522545325454254552545625457254582545925460254612546225463254642546525466254672546825469254702547125472254732547425475254762547725478254792548025481254822548325484254852548625487254882548925490254912549225493254942549525496254972549825499255002550125502255032550425505255062550725508255092551025511255122551325514255152551625517255182551925520255212552225523255242552525526255272552825529255302553125532255332553425535255362553725538255392554025541255422554325544255452554625547255482554925550255512555225553255542555525556255572555825559255602556125562255632556425565255662556725568255692557025571255722557325574255752557625577255782557925580255812558225583255842558525586255872558825589255902559125592255932559425595255962559725598255992560025601256022560325604256052560625607256082560925610256112561225613256142561525616256172561825619256202562125622256232562425625256262562725628256292563025631256322563325634256352563625637256382563925640256412564225643256442564525646256472564825649256502565125652256532565425655256562565725658256592566025661256622566325664256652566625667256682566925670256712567225673256742567525676256772567825679256802568125682256832568425685256862568725688256892569025691256922569325694256952569625697256982569925700257012570225703257042570525706257072570825709257102571125712257132571425715257162571725718257192572025721257222572325724257252572625727257282572925730257312573225733257342573525736257372573825739257402574125742257432574425745257462574725748257492575025751257522575325754257552575625757257582575925760257612576225763257642576525766257672576825769257702577125772257732577425775257762577725778257792578025781257822578325784257852578625787257882578925790257912579225793257942579525796257972579825799258002580125802258032580425805258062580725808258092581025811258122581325814258152581625817258182581925820258212582225823258242582525826258272582825829258302583125832258332583425835258362583725838258392584025841258422584325844258452584625847258482584925850258512585225853258542585525856258572585825859258602586125862258632586425865258662586725868258692587025871258722587325874258752587625877258782587925880258812588225883258842588525886258872588825889258902589125892258932589425895258962589725898258992590025901259022590325904259052590625907259082590925910259112591225913259142591525916259172591825919259202592125922259232592425925259262592725928259292593025931259322593325934259352593625937259382593925940259412594225943259442594525946259472594825949259502595125952259532595425955259562595725958259592596025961259622596325964259652596625967259682596925970259712597225973259742597525976259772597825979259802598125982259832598425985259862598725988259892599025991259922599325994259952599625997259982599926000260012600226003260042600526006260072600826009260102601126012260132601426015260162601726018260192602026021260222602326024260252602626027260282602926030260312603226033260342603526036260372603826039260402604126042260432604426045260462604726048260492605026051260522605326054260552605626057260582605926060260612606226063260642606526066260672606826069260702607126072260732607426075260762607726078260792608026081260822608326084260852608626087260882608926090260912609226093260942609526096260972609826099261002610126102261032610426105261062610726108261092611026111261122611326114261152611626117261182611926120261212612226123261242612526126261272612826129261302613126132261332613426135261362613726138261392614026141261422614326144261452614626147261482614926150261512615226153261542615526156261572615826159261602616126162261632616426165261662616726168261692617026171261722617326174261752617626177261782617926180261812618226183261842618526186261872618826189261902619126192261932619426195261962619726198261992620026201262022620326204262052620626207262082620926210262112621226213262142621526216262172621826219262202622126222262232622426225262262622726228262292623026231262322623326234262352623626237262382623926240262412624226243262442624526246262472624826249262502625126252262532625426255262562625726258262592626026261262622626326264262652626626267262682626926270262712627226273262742627526276262772627826279262802628126282262832628426285262862628726288262892629026291262922629326294262952629626297262982629926300263012630226303263042630526306263072630826309263102631126312263132631426315263162631726318263192632026321263222632326324263252632626327263282632926330263312633226333263342633526336263372633826339263402634126342263432634426345263462634726348263492635026351263522635326354263552635626357263582635926360263612636226363263642636526366263672636826369263702637126372263732637426375263762637726378263792638026381263822638326384263852638626387263882638926390263912639226393263942639526396263972639826399264002640126402264032640426405264062640726408264092641026411264122641326414264152641626417264182641926420264212642226423264242642526426264272642826429264302643126432264332643426435264362643726438264392644026441264422644326444264452644626447264482644926450264512645226453264542645526456264572645826459264602646126462264632646426465264662646726468264692647026471264722647326474264752647626477264782647926480264812648226483264842648526486264872648826489264902649126492264932649426495264962649726498264992650026501265022650326504265052650626507265082650926510265112651226513265142651526516265172651826519265202652126522265232652426525265262652726528265292653026531265322653326534265352653626537265382653926540265412654226543265442654526546265472654826549265502655126552265532655426555265562655726558265592656026561265622656326564265652656626567265682656926570265712657226573265742657526576265772657826579265802658126582265832658426585265862658726588265892659026591265922659326594265952659626597265982659926600266012660226603266042660526606266072660826609266102661126612266132661426615266162661726618266192662026621266222662326624266252662626627266282662926630266312663226633266342663526636266372663826639266402664126642266432664426645266462664726648266492665026651266522665326654266552665626657266582665926660266612666226663266642666526666266672666826669266702667126672266732667426675266762667726678266792668026681266822668326684266852668626687266882668926690266912669226693266942669526696266972669826699267002670126702267032670426705267062670726708267092671026711267122671326714267152671626717267182671926720267212672226723267242672526726267272672826729267302673126732267332673426735267362673726738267392674026741267422674326744267452674626747267482674926750267512675226753267542675526756267572675826759267602676126762267632676426765267662676726768267692677026771267722677326774267752677626777267782677926780267812678226783267842678526786267872678826789267902679126792267932679426795267962679726798267992680026801268022680326804
  1. /**
  2. * @license
  3. * Video.js 5.16.0 <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. this.player_.play();
  59. };
  60. return BigPlayButton;
  61. }(_button2['default']);
  62. /**
  63. * The text that should display over the `BigPlayButton`s controls. Added to for localization.
  64. *
  65. * @type {string}
  66. * @private
  67. */
  68. BigPlayButton.prototype.controlText_ = 'Play Video';
  69. _component2['default'].registerComponent('BigPlayButton', BigPlayButton);
  70. exports['default'] = BigPlayButton;
  71. },{"2":2,"5":5}],2:[function(_dereq_,module,exports){
  72. 'use strict';
  73. exports.__esModule = true;
  74. var _clickableComponent = _dereq_(3);
  75. var _clickableComponent2 = _interopRequireDefault(_clickableComponent);
  76. var _component = _dereq_(5);
  77. var _component2 = _interopRequireDefault(_component);
  78. var _log = _dereq_(86);
  79. var _log2 = _interopRequireDefault(_log);
  80. var _obj = _dereq_(88);
  81. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  82. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  83. 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; }
  84. 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; } /**
  85. * @file button.js
  86. */
  87. /**
  88. * Base class for all buttons.
  89. *
  90. * @extends ClickableComponent
  91. */
  92. var Button = function (_ClickableComponent) {
  93. _inherits(Button, _ClickableComponent);
  94. function Button() {
  95. _classCallCheck(this, Button);
  96. return _possibleConstructorReturn(this, _ClickableComponent.apply(this, arguments));
  97. }
  98. /**
  99. * Create the `Button`s DOM element.
  100. *
  101. * @param {string} [tag=button]
  102. * Element's node type. e.g. 'button'
  103. *
  104. * @param {Object} [props={}]
  105. * An object of properties that should be set on the element.
  106. *
  107. * @param {Object} [attributes={}]
  108. * An object of attributes that should be set on the element.
  109. *
  110. * @return {Element}
  111. * The element that gets created.
  112. */
  113. Button.prototype.createEl = function createEl() {
  114. var tag = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'button';
  115. var props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  116. var attributes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
  117. props = (0, _obj.assign)({
  118. className: this.buildCSSClass()
  119. }, props);
  120. if (tag !== 'button') {
  121. _log2['default'].warn('Creating a Button with an HTML element of ' + tag + ' is deprecated; use ClickableComponent instead.');
  122. // Add properties for clickable element which is not a native HTML button
  123. props = (0, _obj.assign)({
  124. tabIndex: 0
  125. }, props);
  126. // Add ARIA attributes for clickable element which is not a native HTML button
  127. attributes = (0, _obj.assign)({
  128. role: 'button'
  129. }, attributes);
  130. }
  131. // Add attributes for button element
  132. attributes = (0, _obj.assign)({
  133. // Necessary since the default button type is "submit"
  134. 'type': 'button',
  135. // let the screen reader user know that the text of the button may change
  136. 'aria-live': 'polite'
  137. }, attributes);
  138. var el = _component2['default'].prototype.createEl.call(this, tag, props, attributes);
  139. this.createControlTextEl(el);
  140. return el;
  141. };
  142. /**
  143. * Add a child `Component` inside of this `Button`.
  144. *
  145. * @param {string|Component} child
  146. * The name or instance of a child to add.
  147. *
  148. * @param {Object} [options={}]
  149. * The key/value store of options that will get passed to children of
  150. * the child.
  151. *
  152. * @return {Component}
  153. * The `Component` that gets added as a child. When using a string the
  154. * `Component` will get created by this process.
  155. *
  156. * @deprecated since version 5
  157. */
  158. Button.prototype.addChild = function addChild(child) {
  159. var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  160. var className = this.constructor.name;
  161. _log2['default'].warn('Adding an actionable (user controllable) child to a Button (' + className + ') is not supported; use a ClickableComponent instead.');
  162. // Avoid the error message generated by ClickableComponent's addChild method
  163. return _component2['default'].prototype.addChild.call(this, child, options);
  164. };
  165. /**
  166. * Enable the `Button` element so that it can be activated or clicked. Use this with
  167. * {@link Button#disable}.
  168. */
  169. Button.prototype.enable = function enable() {
  170. _ClickableComponent.prototype.enable.call(this);
  171. this.el_.removeAttribute('disabled');
  172. };
  173. /**
  174. * Enable the `Button` element so that it cannot be activated or clicked. Use this with
  175. * {@link Button#enable}.
  176. */
  177. Button.prototype.disable = function disable() {
  178. _ClickableComponent.prototype.disable.call(this);
  179. this.el_.setAttribute('disabled', 'disabled');
  180. };
  181. /**
  182. * This gets called when a `Button` has focus and `keydown` is triggered via a key
  183. * press.
  184. *
  185. * @param {EventTarget~Event} event
  186. * The event that caused this function to get called.
  187. *
  188. * @listens keydown
  189. */
  190. Button.prototype.handleKeyPress = function handleKeyPress(event) {
  191. // Ignore Space (32) or Enter (13) key operation, which is handled by the browser for a button.
  192. if (event.which === 32 || event.which === 13) {
  193. return;
  194. }
  195. // Pass keypress handling up for unsupported keys
  196. _ClickableComponent.prototype.handleKeyPress.call(this, event);
  197. };
  198. return Button;
  199. }(_clickableComponent2['default']);
  200. _component2['default'].registerComponent('Button', Button);
  201. exports['default'] = Button;
  202. },{"3":3,"5":5,"86":86,"88":88}],3:[function(_dereq_,module,exports){
  203. 'use strict';
  204. exports.__esModule = true;
  205. var _component = _dereq_(5);
  206. var _component2 = _interopRequireDefault(_component);
  207. var _dom = _dereq_(81);
  208. var Dom = _interopRequireWildcard(_dom);
  209. var _events = _dereq_(82);
  210. var Events = _interopRequireWildcard(_events);
  211. var _fn = _dereq_(83);
  212. var Fn = _interopRequireWildcard(_fn);
  213. var _log = _dereq_(86);
  214. var _log2 = _interopRequireDefault(_log);
  215. var _document = _dereq_(94);
  216. var _document2 = _interopRequireDefault(_document);
  217. var _obj = _dereq_(88);
  218. 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; } }
  219. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  220. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  221. 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; }
  222. 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; } /**
  223. * @file button.js
  224. */
  225. /**
  226. * Clickable Component which is clickable or keyboard actionable,
  227. * but is not a native HTML button.
  228. *
  229. * @extends Component
  230. */
  231. var ClickableComponent = function (_Component) {
  232. _inherits(ClickableComponent, _Component);
  233. /**
  234. * Creates an instance of this class.
  235. *
  236. * @param {Player} player
  237. * The `Player` that this class should be attached to.
  238. *
  239. * @param {Object} [options]
  240. * The key/value store of player options.
  241. */
  242. function ClickableComponent(player, options) {
  243. _classCallCheck(this, ClickableComponent);
  244. var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
  245. _this.emitTapEvents();
  246. _this.enable();
  247. return _this;
  248. }
  249. /**
  250. * Create the `Component`s DOM element.
  251. *
  252. * @param {string} [tag=div]
  253. * The element's node type.
  254. *
  255. * @param {Object} [props={}]
  256. * An object of properties that should be set on the element.
  257. *
  258. * @param {Object} [attributes={}]
  259. * An object of attributes that should be set on the element.
  260. *
  261. * @return {Element}
  262. * The element that gets created.
  263. */
  264. ClickableComponent.prototype.createEl = function createEl() {
  265. var tag = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'div';
  266. var props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  267. var attributes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
  268. props = (0, _obj.assign)({
  269. className: this.buildCSSClass(),
  270. tabIndex: 0
  271. }, props);
  272. if (tag === 'button') {
  273. _log2['default'].error('Creating a ClickableComponent with an HTML element of ' + tag + ' is not supported; use a Button instead.');
  274. }
  275. // Add ARIA attributes for clickable element which is not a native HTML button
  276. attributes = (0, _obj.assign)({
  277. 'role': 'button',
  278. // let the screen reader user know that the text of the element may change
  279. 'aria-live': 'polite'
  280. }, attributes);
  281. this.tabIndex_ = props.tabIndex;
  282. var el = _Component.prototype.createEl.call(this, tag, props, attributes);
  283. this.createControlTextEl(el);
  284. return el;
  285. };
  286. /**
  287. * Create a control text element on this `Component`
  288. *
  289. * @param {Element} [el]
  290. * Parent element for the control text.
  291. *
  292. * @return {Element}
  293. * The control text element that gets created.
  294. */
  295. ClickableComponent.prototype.createControlTextEl = function createControlTextEl(el) {
  296. this.controlTextEl_ = Dom.createEl('span', {
  297. className: 'vjs-control-text'
  298. });
  299. if (el) {
  300. el.appendChild(this.controlTextEl_);
  301. }
  302. this.controlText(this.controlText_, el);
  303. return this.controlTextEl_;
  304. };
  305. /**
  306. * Get or set the localize text to use for the controls on the `Component`.
  307. *
  308. * @param {string} [text]
  309. * Control text for element.
  310. *
  311. * @param {Element} [el=this.el()]
  312. * Element to set the title on.
  313. *
  314. * @return {string|ClickableComponent}
  315. * - The control text when getting
  316. * - Returns itself when setting; method can be chained.
  317. */
  318. ClickableComponent.prototype.controlText = function controlText(text) {
  319. var el = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.el();
  320. if (!text) {
  321. return this.controlText_ || 'Need Text';
  322. }
  323. var localizedText = this.localize(text);
  324. this.controlText_ = text;
  325. this.controlTextEl_.innerHTML = localizedText;
  326. el.setAttribute('title', localizedText);
  327. return this;
  328. };
  329. /**
  330. * Builds the default DOM `className`.
  331. *
  332. * @return {string}
  333. * The DOM `className` for this object.
  334. */
  335. ClickableComponent.prototype.buildCSSClass = function buildCSSClass() {
  336. return 'vjs-control vjs-button ' + _Component.prototype.buildCSSClass.call(this);
  337. };
  338. /**
  339. * Enable this `Component`s element.
  340. *
  341. * @return {ClickableComponent}
  342. * Returns itself; method can be chained.
  343. */
  344. ClickableComponent.prototype.enable = function enable() {
  345. this.removeClass('vjs-disabled');
  346. this.el_.setAttribute('aria-disabled', 'false');
  347. if (typeof this.tabIndex_ !== 'undefined') {
  348. this.el_.setAttribute('tabIndex', this.tabIndex_);
  349. }
  350. this.on('tap', this.handleClick);
  351. this.on('click', this.handleClick);
  352. this.on('focus', this.handleFocus);
  353. this.on('blur', this.handleBlur);
  354. return this;
  355. };
  356. /**
  357. * Disable this `Component`s element.
  358. *
  359. * @return {ClickableComponent}
  360. * Returns itself; method can be chained.
  361. */
  362. ClickableComponent.prototype.disable = function disable() {
  363. this.addClass('vjs-disabled');
  364. this.el_.setAttribute('aria-disabled', 'true');
  365. if (typeof this.tabIndex_ !== 'undefined') {
  366. this.el_.removeAttribute('tabIndex');
  367. }
  368. this.off('tap', this.handleClick);
  369. this.off('click', this.handleClick);
  370. this.off('focus', this.handleFocus);
  371. this.off('blur', this.handleBlur);
  372. return this;
  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.handleClick(event);
  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,"81":81,"82":82,"83":83,"86":86,"88":88,"94":94}],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_(95);
  524. var _window2 = _interopRequireDefault(_window);
  525. var _dom = _dereq_(81);
  526. var Dom = _interopRequireWildcard(_dom);
  527. var _fn = _dereq_(83);
  528. var Fn = _interopRequireWildcard(_fn);
  529. var _guid = _dereq_(85);
  530. var Guid = _interopRequireWildcard(_guid);
  531. var _events = _dereq_(82);
  532. var Events = _interopRequireWildcard(_events);
  533. var _log = _dereq_(86);
  534. var _log2 = _interopRequireDefault(_log);
  535. var _toTitleCase = _dereq_(91);
  536. var _toTitleCase2 = _interopRequireDefault(_toTitleCase);
  537. var _mergeOptions = _dereq_(87);
  538. var _mergeOptions2 = _interopRequireDefault(_mergeOptions);
  539. 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; } }
  540. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  541. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } /**
  542. * Player Component - Base class for all UI objects
  543. *
  544. * @file component.js
  545. */
  546. /**
  547. * Base class for all UI Components.
  548. * Components are UI objects which represent both a javascript object and an element
  549. * in the DOM. They can be children of other components, and can have
  550. * children themselves.
  551. *
  552. * Components can also use methods from {@link EventTarget}
  553. */
  554. var Component = function () {
  555. /**
  556. * A callback that is called when a component is ready. Does not have any
  557. * paramters and any callback value will be ignored.
  558. *
  559. * @callback Component~ReadyCallback
  560. * @this Component
  561. */
  562. /**
  563. * Creates an instance of this class.
  564. *
  565. * @param {Player} player
  566. * The `Player` that this class should be attached to.
  567. *
  568. * @param {Object} [options]
  569. * The key/value store of player options.
  570. #
  571. * @param {Object[]} [options.children]
  572. * An array of children objects to intialize this component with. Children objects have
  573. * a name property that will be used if more than one component of the same type needs to be
  574. * added.
  575. *
  576. * @param {Component~ReadyCallback} [ready]
  577. * Function that gets called when the `Component` is ready.
  578. */
  579. function Component(player, options, ready) {
  580. _classCallCheck(this, Component);
  581. // The component might be the player itself and we can't pass `this` to super
  582. if (!player && this.play) {
  583. this.player_ = player = this; // eslint-disable-line
  584. } else {
  585. this.player_ = player;
  586. }
  587. // Make a copy of prototype.options_ to protect against overriding defaults
  588. this.options_ = (0, _mergeOptions2['default'])({}, this.options_);
  589. // Updated options with supplied options
  590. options = this.options_ = (0, _mergeOptions2['default'])(this.options_, options);
  591. // Get ID from options or options element if one is supplied
  592. this.id_ = options.id || options.el && options.el.id;
  593. // If there was no ID from the options, generate one
  594. if (!this.id_) {
  595. // Don't require the player ID function in the case of mock players
  596. var id = player && player.id && player.id() || 'no_player';
  597. this.id_ = id + '_component_' + Guid.newGUID();
  598. }
  599. this.name_ = options.name || null;
  600. // Create element if one wasn't provided in options
  601. if (options.el) {
  602. this.el_ = options.el;
  603. } else if (options.createEl !== false) {
  604. this.el_ = this.createEl();
  605. }
  606. this.children_ = [];
  607. this.childIndex_ = {};
  608. this.childNameIndex_ = {};
  609. // Add any child components in options
  610. if (options.initChildren !== false) {
  611. this.initChildren();
  612. }
  613. this.ready(ready);
  614. // Don't want to trigger ready here or it will before init is actually
  615. // finished for all children that run this constructor
  616. if (options.reportTouchActivity !== false) {
  617. this.enableTouchActivity();
  618. }
  619. }
  620. /**
  621. * Dispose of the `Component` and all child components.
  622. *
  623. * @fires Component#dispose
  624. */
  625. Component.prototype.dispose = function dispose() {
  626. /**
  627. * Triggered when a `Component` is disposed.
  628. *
  629. * @event Component#dispose
  630. * @type {EventTarget~Event}
  631. *
  632. * @property {boolean} [bubbles=false]
  633. * set to false so that the close event does not
  634. * bubble up
  635. */
  636. this.trigger({ type: 'dispose', bubbles: false });
  637. // Dispose all children.
  638. if (this.children_) {
  639. for (var i = this.children_.length - 1; i >= 0; i--) {
  640. if (this.children_[i].dispose) {
  641. this.children_[i].dispose();
  642. }
  643. }
  644. }
  645. // Delete child references
  646. this.children_ = null;
  647. this.childIndex_ = null;
  648. this.childNameIndex_ = null;
  649. // Remove all event listeners.
  650. this.off();
  651. // Remove element from DOM
  652. if (this.el_.parentNode) {
  653. this.el_.parentNode.removeChild(this.el_);
  654. }
  655. Dom.removeElData(this.el_);
  656. this.el_ = null;
  657. };
  658. /**
  659. * Return the {@link Player} that the `Component` has attached to.
  660. *
  661. * @return {Player}
  662. * The player that this `Component` has attached to.
  663. */
  664. Component.prototype.player = function player() {
  665. return this.player_;
  666. };
  667. /**
  668. * Deep merge of options objects with new options.
  669. * > Note: When both `obj` and `options` contain properties whose values are objects.
  670. * The two properties get merged using {@link module:mergeOptions}
  671. *
  672. * @param {Object} obj
  673. * The object that contains new options.
  674. *
  675. * @return {Object}
  676. * A new object of `this.options_` and `obj` merged together.
  677. *
  678. * @deprecated since version 5
  679. */
  680. Component.prototype.options = function options(obj) {
  681. _log2['default'].warn('this.options() has been deprecated and will be moved to the constructor in 6.0');
  682. if (!obj) {
  683. return this.options_;
  684. }
  685. this.options_ = (0, _mergeOptions2['default'])(this.options_, obj);
  686. return this.options_;
  687. };
  688. /**
  689. * Get the `Component`s DOM element
  690. *
  691. * @return {Element}
  692. * The DOM element for this `Component`.
  693. */
  694. Component.prototype.el = function el() {
  695. return this.el_;
  696. };
  697. /**
  698. * Create the `Component`s DOM element.
  699. *
  700. * @param {string} [tagName]
  701. * Element's DOM node type. e.g. 'div'
  702. *
  703. * @param {Object} [properties]
  704. * An object of properties that should be set.
  705. *
  706. * @param {Object} [attributes]
  707. * An object of attributes that should be set.
  708. *
  709. * @return {Element}
  710. * The element that gets created.
  711. */
  712. Component.prototype.createEl = function createEl(tagName, properties, attributes) {
  713. return Dom.createEl(tagName, properties, attributes);
  714. };
  715. /**
  716. * Localize a string given the string in english.
  717. *
  718. * @param {string} string
  719. * The string to localize.
  720. *
  721. * @return {string}
  722. * The localized string or if no localization exists the english string.
  723. */
  724. Component.prototype.localize = function localize(string) {
  725. var code = this.player_.language && this.player_.language();
  726. var languages = this.player_.languages && this.player_.languages();
  727. if (!code || !languages) {
  728. return string;
  729. }
  730. var language = languages[code];
  731. if (language && language[string]) {
  732. return language[string];
  733. }
  734. var primaryCode = code.split('-')[0];
  735. var primaryLang = languages[primaryCode];
  736. if (primaryLang && primaryLang[string]) {
  737. return primaryLang[string];
  738. }
  739. return string;
  740. };
  741. /**
  742. * Return the `Component`s DOM element. This is where children get inserted.
  743. * This will usually be the the same as the element returned in {@link Component#el}.
  744. *
  745. * @return {Element}
  746. * The content element for this `Component`.
  747. */
  748. Component.prototype.contentEl = function contentEl() {
  749. return this.contentEl_ || this.el_;
  750. };
  751. /**
  752. * Get this `Component`s ID
  753. *
  754. * @return {string}
  755. * The id of this `Component`
  756. */
  757. Component.prototype.id = function id() {
  758. return this.id_;
  759. };
  760. /**
  761. * Get the `Component`s name. The name gets used to reference the `Component`
  762. * and is set during registration.
  763. *
  764. * @return {string}
  765. * The name of this `Component`.
  766. */
  767. Component.prototype.name = function name() {
  768. return this.name_;
  769. };
  770. /**
  771. * Get an array of all child components
  772. *
  773. * @return {Array}
  774. * The children
  775. */
  776. Component.prototype.children = function children() {
  777. return this.children_;
  778. };
  779. /**
  780. * Returns the child `Component` with the given `id`.
  781. *
  782. * @param {string} id
  783. * The id of the child `Component` to get.
  784. *
  785. * @return {Component|undefined}
  786. * The child `Component` with the given `id` or undefined.
  787. */
  788. Component.prototype.getChildById = function getChildById(id) {
  789. return this.childIndex_[id];
  790. };
  791. /**
  792. * Returns the child `Component` with the given `name`.
  793. *
  794. * @param {string} name
  795. * The name of the child `Component` to get.
  796. *
  797. * @return {Component|undefined}
  798. * The child `Component` with the given `name` or undefined.
  799. */
  800. Component.prototype.getChild = function getChild(name) {
  801. if (!name) {
  802. return;
  803. }
  804. name = (0, _toTitleCase2['default'])(name);
  805. return this.childNameIndex_[name];
  806. };
  807. /**
  808. * Add a child `Component` inside the current `Component`.
  809. *
  810. *
  811. * @param {string|Component} child
  812. * The name or instance of a child to add.
  813. *
  814. * @param {Object} [options={}]
  815. * The key/value store of options that will get passed to children of
  816. * the child.
  817. *
  818. * @param {number} [index=this.children_.length]
  819. * The index to attempt to add a child into.
  820. *
  821. * @return {Component}
  822. * The `Component` that gets added as a child. When using a string the
  823. * `Component` will get created by this process.
  824. */
  825. Component.prototype.addChild = function addChild(child) {
  826. var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  827. var index = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.children_.length;
  828. var component = void 0;
  829. var componentName = void 0;
  830. // If child is a string, create component with options
  831. if (typeof child === 'string') {
  832. componentName = (0, _toTitleCase2['default'])(child);
  833. // Options can also be specified as a boolean,
  834. // so convert to an empty object if false.
  835. if (!options) {
  836. options = {};
  837. }
  838. // Same as above, but true is deprecated so show a warning.
  839. if (options === true) {
  840. _log2['default'].warn('Initializing a child component with `true` is deprecated.' + 'Children should be defined in an array when possible, ' + 'but if necessary use an object instead of `true`.');
  841. options = {};
  842. }
  843. var componentClassName = options.componentClass || componentName;
  844. // Set name through options
  845. options.name = componentName;
  846. // Create a new object & element for this controls set
  847. // If there's no .player_, this is a player
  848. var ComponentClass = Component.getComponent(componentClassName);
  849. if (!ComponentClass) {
  850. throw new Error('Component ' + componentClassName + ' does not exist');
  851. }
  852. // data stored directly on the videojs object may be
  853. // misidentified as a component to retain
  854. // backwards-compatibility with 4.x. check to make sure the
  855. // component class can be instantiated.
  856. if (typeof ComponentClass !== 'function') {
  857. return null;
  858. }
  859. component = new ComponentClass(this.player_ || this, options);
  860. // child is a component instance
  861. } else {
  862. component = child;
  863. }
  864. this.children_.splice(index, 0, component);
  865. if (typeof component.id === 'function') {
  866. this.childIndex_[component.id()] = component;
  867. }
  868. // If a name wasn't used to create the component, check if we can use the
  869. // name function of the component
  870. componentName = componentName || component.name && component.name();
  871. if (componentName) {
  872. this.childNameIndex_[componentName] = component;
  873. }
  874. // Add the UI object's element to the container div (box)
  875. // Having an element is not required
  876. if (typeof component.el === 'function' && component.el()) {
  877. var childNodes = this.contentEl().children;
  878. var refNode = childNodes[index] || null;
  879. this.contentEl().insertBefore(component.el(), refNode);
  880. }
  881. // Return so it can stored on parent object if desired.
  882. return component;
  883. };
  884. /**
  885. * Remove a child `Component` from this `Component`s list of children. Also removes
  886. * the child `Component`s element from this `Component`s element.
  887. *
  888. * @param {Component} component
  889. * The child `Component` to remove.
  890. */
  891. Component.prototype.removeChild = function removeChild(component) {
  892. if (typeof component === 'string') {
  893. component = this.getChild(component);
  894. }
  895. if (!component || !this.children_) {
  896. return;
  897. }
  898. var childFound = false;
  899. for (var i = this.children_.length - 1; i >= 0; i--) {
  900. if (this.children_[i] === component) {
  901. childFound = true;
  902. this.children_.splice(i, 1);
  903. break;
  904. }
  905. }
  906. if (!childFound) {
  907. return;
  908. }
  909. this.childIndex_[component.id()] = null;
  910. this.childNameIndex_[component.name()] = null;
  911. var compEl = component.el();
  912. if (compEl && compEl.parentNode === this.contentEl()) {
  913. this.contentEl().removeChild(component.el());
  914. }
  915. };
  916. /**
  917. * Add and initialize default child `Component`s based upon options.
  918. */
  919. Component.prototype.initChildren = function initChildren() {
  920. var _this = this;
  921. var children = this.options_.children;
  922. if (children) {
  923. (function () {
  924. // `this` is `parent`
  925. var parentOptions = _this.options_;
  926. var handleAdd = function handleAdd(child) {
  927. var name = child.name;
  928. var opts = child.opts;
  929. // Allow options for children to be set at the parent options
  930. // e.g. videojs(id, { controlBar: false });
  931. // instead of videojs(id, { children: { controlBar: false });
  932. if (parentOptions[name] !== undefined) {
  933. opts = parentOptions[name];
  934. }
  935. // Allow for disabling default components
  936. // e.g. options['children']['posterImage'] = false
  937. if (opts === false) {
  938. return;
  939. }
  940. // Allow options to be passed as a simple boolean if no configuration
  941. // is necessary.
  942. if (opts === true) {
  943. opts = {};
  944. }
  945. // We also want to pass the original player options
  946. // to each component as well so they don't need to
  947. // reach back into the player for options later.
  948. opts.playerOptions = _this.options_.playerOptions;
  949. // Create and add the child component.
  950. // Add a direct reference to the child by name on the parent instance.
  951. // If two of the same component are used, different names should be supplied
  952. // for each
  953. var newChild = _this.addChild(name, opts);
  954. if (newChild) {
  955. _this[name] = newChild;
  956. }
  957. };
  958. // Allow for an array of children details to passed in the options
  959. var workingChildren = void 0;
  960. var Tech = Component.getComponent('Tech');
  961. if (Array.isArray(children)) {
  962. workingChildren = children;
  963. } else {
  964. workingChildren = Object.keys(children);
  965. }
  966. workingChildren
  967. // children that are in this.options_ but also in workingChildren would
  968. // give us extra children we do not want. So, we want to filter them out.
  969. .concat(Object.keys(_this.options_).filter(function (child) {
  970. return !workingChildren.some(function (wchild) {
  971. if (typeof wchild === 'string') {
  972. return child === wchild;
  973. }
  974. return child === wchild.name;
  975. });
  976. })).map(function (child) {
  977. var name = void 0;
  978. var opts = void 0;
  979. if (typeof child === 'string') {
  980. name = child;
  981. opts = children[name] || _this.options_[name] || {};
  982. } else {
  983. name = child.name;
  984. opts = child;
  985. }
  986. return { name: name, opts: opts };
  987. }).filter(function (child) {
  988. // we have to make sure that child.name isn't in the techOrder since
  989. // techs are registerd as Components but can't aren't compatible
  990. // See https://github.com/videojs/video.js/issues/2772
  991. var c = Component.getComponent(child.opts.componentClass || (0, _toTitleCase2['default'])(child.name));
  992. return c && !Tech.isTech(c);
  993. }).forEach(handleAdd);
  994. })();
  995. }
  996. };
  997. /**
  998. * Builds the default DOM class name. Should be overriden by sub-components.
  999. *
  1000. * @return {string}
  1001. * The DOM class name for this object.
  1002. *
  1003. * @abstract
  1004. */
  1005. Component.prototype.buildCSSClass = function buildCSSClass() {
  1006. // Child classes can include a function that does:
  1007. // return 'CLASS NAME' + this._super();
  1008. return '';
  1009. };
  1010. /**
  1011. * Add an `event listener` to this `Component`s element.
  1012. *
  1013. * The benefit of using this over the following:
  1014. * - `VjsEvents.on(otherElement, 'eventName', myFunc)`
  1015. * - `otherComponent.on('eventName', myFunc)`
  1016. *
  1017. * 1. Is that the listeners will get cleaned up when either component gets disposed.
  1018. * 1. It will also bind `myComponent` as the context of `myFunc`.
  1019. * > NOTE: If you remove the element from the DOM that has used `on` you need to
  1020. * clean up references using: `myComponent.trigger(el, 'dispose')`
  1021. * This will also allow the browser to garbage collect it. In special
  1022. * cases such as with `window` and `document`, which are both permanent,
  1023. * this is not necessary.
  1024. *
  1025. * @param {string|Component|string[]} [first]
  1026. * The event name, and array of event names, or another `Component`.
  1027. *
  1028. * @param {EventTarget~EventListener|string|string[]} [second]
  1029. * The listener function, an event name, or an Array of events names.
  1030. *
  1031. * @param {EventTarget~EventListener} [third]
  1032. * The event handler if `first` is a `Component` and `second` is an event name
  1033. * or an Array of event names.
  1034. *
  1035. * @return {Component}
  1036. * Returns itself; method can be chained.
  1037. *
  1038. * @listens Component#dispose
  1039. */
  1040. Component.prototype.on = function on(first, second, third) {
  1041. var _this2 = this;
  1042. if (typeof first === 'string' || Array.isArray(first)) {
  1043. Events.on(this.el_, first, Fn.bind(this, second));
  1044. // Targeting another component or element
  1045. } else {
  1046. (function () {
  1047. var target = first;
  1048. var type = second;
  1049. var fn = Fn.bind(_this2, third);
  1050. // When this component is disposed, remove the listener from the other component
  1051. var removeOnDispose = function removeOnDispose() {
  1052. return _this2.off(target, type, fn);
  1053. };
  1054. // Use the same function ID so we can remove it later it using the ID
  1055. // of the original listener
  1056. removeOnDispose.guid = fn.guid;
  1057. _this2.on('dispose', removeOnDispose);
  1058. // If the other component is disposed first we need to clean the reference
  1059. // to the other component in this component's removeOnDispose listener
  1060. // Otherwise we create a memory leak.
  1061. var cleanRemover = function cleanRemover() {
  1062. return _this2.off('dispose', removeOnDispose);
  1063. };
  1064. // Add the same function ID so we can easily remove it later
  1065. cleanRemover.guid = fn.guid;
  1066. // Check if this is a DOM node
  1067. if (first.nodeName) {
  1068. // Add the listener to the other element
  1069. Events.on(target, type, fn);
  1070. Events.on(target, 'dispose', cleanRemover);
  1071. // Should be a component
  1072. // Not using `instanceof Component` because it makes mock players difficult
  1073. } else if (typeof first.on === 'function') {
  1074. // Add the listener to the other component
  1075. target.on(type, fn);
  1076. target.on('dispose', cleanRemover);
  1077. }
  1078. })();
  1079. }
  1080. return this;
  1081. };
  1082. /**
  1083. * Remove an event listener from this `Component`s element. If the second argument is
  1084. * exluded all listeners for the type passed in as the first argument will be removed.
  1085. *
  1086. * @param {string|Component|string[]} [first]
  1087. * The event name, and array of event names, or another `Component`.
  1088. *
  1089. * @param {EventTarget~EventListener|string|string[]} [second]
  1090. * The listener function, an event name, or an Array of events names.
  1091. *
  1092. * @param {EventTarget~EventListener} [third]
  1093. * The event handler if `first` is a `Component` and `second` is an event name
  1094. * or an Array of event names.
  1095. *
  1096. * @return {Component}
  1097. * Returns itself; method can be chained.
  1098. */
  1099. Component.prototype.off = function off(first, second, third) {
  1100. if (!first || typeof first === 'string' || Array.isArray(first)) {
  1101. Events.off(this.el_, first, second);
  1102. } else {
  1103. var target = first;
  1104. var type = second;
  1105. // Ensure there's at least a guid, even if the function hasn't been used
  1106. var fn = Fn.bind(this, third);
  1107. // Remove the dispose listener on this component,
  1108. // which was given the same guid as the event listener
  1109. this.off('dispose', fn);
  1110. if (first.nodeName) {
  1111. // Remove the listener
  1112. Events.off(target, type, fn);
  1113. // Remove the listener for cleaning the dispose listener
  1114. Events.off(target, 'dispose', fn);
  1115. } else {
  1116. target.off(type, fn);
  1117. target.off('dispose', fn);
  1118. }
  1119. }
  1120. return this;
  1121. };
  1122. /**
  1123. * Add an event listener that gets triggered only once and then gets removed.
  1124. *
  1125. * @param {string|Component|string[]} [first]
  1126. * The event name, and array of event names, or another `Component`.
  1127. *
  1128. * @param {EventTarget~EventListener|string|string[]} [second]
  1129. * The listener function, an event name, or an Array of events names.
  1130. *
  1131. * @param {EventTarget~EventListener} [third]
  1132. * The event handler if `first` is a `Component` and `second` is an event name
  1133. * or an Array of event names.
  1134. *
  1135. * @return {Component}
  1136. * Returns itself; method can be chained.
  1137. */
  1138. Component.prototype.one = function one(first, second, third) {
  1139. var _this3 = this,
  1140. _arguments = arguments;
  1141. if (typeof first === 'string' || Array.isArray(first)) {
  1142. Events.one(this.el_, first, Fn.bind(this, second));
  1143. } else {
  1144. (function () {
  1145. var target = first;
  1146. var type = second;
  1147. var fn = Fn.bind(_this3, third);
  1148. var newFunc = function newFunc() {
  1149. _this3.off(target, type, newFunc);
  1150. fn.apply(null, _arguments);
  1151. };
  1152. // Keep the same function ID so we can remove it later
  1153. newFunc.guid = fn.guid;
  1154. _this3.on(target, type, newFunc);
  1155. })();
  1156. }
  1157. return this;
  1158. };
  1159. /**
  1160. * Trigger an event on an element.
  1161. *
  1162. * @param {EventTarget~Event|Object|string} event
  1163. * The event name, and Event, or an event-like object with a type attribute
  1164. * set to the event name.
  1165. *
  1166. * @param {Object} [hash]
  1167. * Data hash to pass along with the event
  1168. *
  1169. * @return {Component}
  1170. * Returns itself; method can be chained.
  1171. */
  1172. Component.prototype.trigger = function trigger(event, hash) {
  1173. Events.trigger(this.el_, event, hash);
  1174. return this;
  1175. };
  1176. /**
  1177. * Bind a listener to the component's ready state. If the ready event has already
  1178. * happened it will trigger the function immediately.
  1179. *
  1180. * @param {Component~ReadyCallback} fn
  1181. * A function to call when ready is triggered.
  1182. *
  1183. * @param {boolean} [sync=false]
  1184. * Execute the listener synchronously if `Component` is ready.
  1185. *
  1186. * @return {Component}
  1187. * Returns itself; method can be chained.
  1188. */
  1189. Component.prototype.ready = function ready(fn) {
  1190. var sync = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
  1191. if (fn) {
  1192. if (this.isReady_) {
  1193. if (sync) {
  1194. fn.call(this);
  1195. } else {
  1196. // Call the function asynchronously by default for consistency
  1197. this.setTimeout(fn, 1);
  1198. }
  1199. } else {
  1200. this.readyQueue_ = this.readyQueue_ || [];
  1201. this.readyQueue_.push(fn);
  1202. }
  1203. }
  1204. return this;
  1205. };
  1206. /**
  1207. * Trigger all the ready listeners for this `Component`.
  1208. *
  1209. * @fires Component#ready
  1210. */
  1211. Component.prototype.triggerReady = function triggerReady() {
  1212. this.isReady_ = true;
  1213. // Ensure ready is triggerd asynchronously
  1214. this.setTimeout(function () {
  1215. var readyQueue = this.readyQueue_;
  1216. // Reset Ready Queue
  1217. this.readyQueue_ = [];
  1218. if (readyQueue && readyQueue.length > 0) {
  1219. readyQueue.forEach(function (fn) {
  1220. fn.call(this);
  1221. }, this);
  1222. }
  1223. // Allow for using event listeners also
  1224. /**
  1225. * Triggered when a `Component` is ready.
  1226. *
  1227. * @event Component#ready
  1228. * @type {EventTarget~Event}
  1229. */
  1230. this.trigger('ready');
  1231. }, 1);
  1232. };
  1233. /**
  1234. * Find a single DOM element matching a `selector`. This can be within the `Component`s
  1235. * `contentEl()` or another custom context.
  1236. *
  1237. * @param {string} selector
  1238. * A valid CSS selector, which will be passed to `querySelector`.
  1239. *
  1240. * @param {Element|string} [context=this.contentEl()]
  1241. * A DOM element within which to query. Can also be a selector string in
  1242. * which case the first matching element will get used as context. If
  1243. * missing `this.contentEl()` gets used. If `this.contentEl()` returns
  1244. * nothing it falls back to `document`.
  1245. *
  1246. * @return {Element|null}
  1247. * the dom element that was found, or null
  1248. *
  1249. * @see [Information on CSS Selectors](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Getting_Started/Selectors)
  1250. */
  1251. Component.prototype.$ = function $(selector, context) {
  1252. return Dom.$(selector, context || this.contentEl());
  1253. };
  1254. /**
  1255. * Finds all DOM element matching a `selector`. This can be within the `Component`s
  1256. * `contentEl()` or another custom context.
  1257. *
  1258. * @param {string} selector
  1259. * A valid CSS selector, which will be passed to `querySelectorAll`.
  1260. *
  1261. * @param {Element|string} [context=this.contentEl()]
  1262. * A DOM element within which to query. Can also be a selector string in
  1263. * which case the first matching element will get used as context. If
  1264. * missing `this.contentEl()` gets used. If `this.contentEl()` returns
  1265. * nothing it falls back to `document`.
  1266. *
  1267. * @return {NodeList}
  1268. * a list of dom elements that were found
  1269. *
  1270. * @see [Information on CSS Selectors](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Getting_Started/Selectors)
  1271. */
  1272. Component.prototype.$$ = function $$(selector, context) {
  1273. return Dom.$$(selector, context || this.contentEl());
  1274. };
  1275. /**
  1276. * Check if a component's element has a CSS class name.
  1277. *
  1278. * @param {string} classToCheck
  1279. * CSS class name to check.
  1280. *
  1281. * @return {boolean}
  1282. * - True if the `Component` has the class.
  1283. * - False if the `Component` does not have the class`
  1284. */
  1285. Component.prototype.hasClass = function hasClass(classToCheck) {
  1286. return Dom.hasElClass(this.el_, classToCheck);
  1287. };
  1288. /**
  1289. * Add a CSS class name to the `Component`s element.
  1290. *
  1291. * @param {string} classToAdd
  1292. * CSS class name to add
  1293. *
  1294. * @return {Component}
  1295. * Returns itself; method can be chained.
  1296. */
  1297. Component.prototype.addClass = function addClass(classToAdd) {
  1298. Dom.addElClass(this.el_, classToAdd);
  1299. return this;
  1300. };
  1301. /**
  1302. * Remove a CSS class name from the `Component`s element.
  1303. *
  1304. * @param {string} classToRemove
  1305. * CSS class name to remove
  1306. *
  1307. * @return {Component}
  1308. * Returns itself; method can be chained.
  1309. */
  1310. Component.prototype.removeClass = function removeClass(classToRemove) {
  1311. Dom.removeElClass(this.el_, classToRemove);
  1312. return this;
  1313. };
  1314. /**
  1315. * Add or remove a CSS class name from the component's element.
  1316. * - `classToToggle` gets added when {@link Component#hasClass} would return false.
  1317. * - `classToToggle` gets removed when {@link Component#hasClass} would return true.
  1318. *
  1319. * @param {string} classToToggle
  1320. * The class to add or remove based on (@link Component#hasClass}
  1321. *
  1322. * @param {boolean|Dom~predicate} [predicate]
  1323. * An {@link Dom~predicate} function or a boolean
  1324. *
  1325. * @return {Component}
  1326. * Returns itself; method can be chained.
  1327. */
  1328. Component.prototype.toggleClass = function toggleClass(classToToggle, predicate) {
  1329. Dom.toggleElClass(this.el_, classToToggle, predicate);
  1330. return this;
  1331. };
  1332. /**
  1333. * Show the `Component`s element if it is hidden by removing the
  1334. * 'vjs-hidden' class name from it.
  1335. *
  1336. * @return {Component}
  1337. * Returns itself; method can be chained.
  1338. */
  1339. Component.prototype.show = function show() {
  1340. this.removeClass('vjs-hidden');
  1341. return this;
  1342. };
  1343. /**
  1344. * Hide the `Component`s element if it is currently showing by adding the
  1345. * 'vjs-hidden` class name to it.
  1346. *
  1347. * @return {Component}
  1348. * Returns itself; method can be chained.
  1349. */
  1350. Component.prototype.hide = function hide() {
  1351. this.addClass('vjs-hidden');
  1352. return this;
  1353. };
  1354. /**
  1355. * Lock a `Component`s element in its visible state by adding the 'vjs-lock-showing'
  1356. * class name to it. Used during fadeIn/fadeOut.
  1357. *
  1358. * @return {Component}
  1359. * Returns itself; method can be chained.
  1360. *
  1361. * @private
  1362. */
  1363. Component.prototype.lockShowing = function lockShowing() {
  1364. this.addClass('vjs-lock-showing');
  1365. return this;
  1366. };
  1367. /**
  1368. * Unlock a `Component`s element from its visible state by removing the 'vjs-lock-showing'
  1369. * class name from it. Used during fadeIn/fadeOut.
  1370. *
  1371. * @return {Component}
  1372. * Returns itself; method can be chained.
  1373. *
  1374. * @private
  1375. */
  1376. Component.prototype.unlockShowing = function unlockShowing() {
  1377. this.removeClass('vjs-lock-showing');
  1378. return this;
  1379. };
  1380. /**
  1381. * Get the value of an attribute on the `Component`s element.
  1382. *
  1383. * @param {string} attribute
  1384. * Name of the attribute to get the value from.
  1385. *
  1386. * @return {string|null}
  1387. * - The value of the attribute that was asked for.
  1388. * - Can be an empty string on some browsers if the attribute does not exist
  1389. * or has no value
  1390. * - Most browsers will return null if the attibute does not exist or has
  1391. * no value.
  1392. *
  1393. * @see [DOM API]{@link https://developer.mozilla.org/en-US/docs/Web/API/Element/getAttribute}
  1394. */
  1395. Component.prototype.getAttribute = function getAttribute(attribute) {
  1396. return Dom.getAttribute(this.el_, attribute);
  1397. };
  1398. /**
  1399. * Set the value of an attribute on the `Component`'s element
  1400. *
  1401. * @param {string} attribute
  1402. * Name of the attribute to set.
  1403. *
  1404. * @param {string} value
  1405. * Value to set the attribute to.
  1406. *
  1407. * @return {Component}
  1408. * Returns itself; method can be chained.
  1409. *
  1410. * @see [DOM API]{@link https://developer.mozilla.org/en-US/docs/Web/API/Element/setAttribute}
  1411. */
  1412. Component.prototype.setAttribute = function setAttribute(attribute, value) {
  1413. Dom.setAttribute(this.el_, attribute, value);
  1414. return this;
  1415. };
  1416. /**
  1417. * Remove an attribute from the `Component`s element.
  1418. *
  1419. * @param {string} attribute
  1420. * Name of the attribute to remove.
  1421. *
  1422. * @return {Component}
  1423. * Returns itself; method can be chained.
  1424. *
  1425. * @see [DOM API]{@link https://developer.mozilla.org/en-US/docs/Web/API/Element/removeAttribute}
  1426. */
  1427. Component.prototype.removeAttribute = function removeAttribute(attribute) {
  1428. Dom.removeAttribute(this.el_, attribute);
  1429. return this;
  1430. };
  1431. /**
  1432. * Get or set the width of the component based upon the CSS styles.
  1433. * See {@link Component#dimension} for more detailed information.
  1434. *
  1435. * @param {number|string} [num]
  1436. * The width that you want to set postfixed with '%', 'px' or nothing.
  1437. *
  1438. * @param {boolean} [skipListeners]
  1439. * Skip the resize event trigger
  1440. *
  1441. * @return {Component|number|string}
  1442. * - The width when getting, zero if there is no width. Can be a string
  1443. * postpixed with '%' or 'px'.
  1444. * - Returns itself when setting; method can be chained.
  1445. */
  1446. Component.prototype.width = function width(num, skipListeners) {
  1447. return this.dimension('width', num, skipListeners);
  1448. };
  1449. /**
  1450. * Get or set the height of the component based upon the CSS styles.
  1451. * See {@link Component#dimension} for more detailed information.
  1452. *
  1453. * @param {number|string} [num]
  1454. * The height that you want to set postfixed with '%', 'px' or nothing.
  1455. *
  1456. * @param {boolean} [skipListeners]
  1457. * Skip the resize event trigger
  1458. *
  1459. * @return {Component|number|string}
  1460. * - The width when getting, zero if there is no width. Can be a string
  1461. * postpixed with '%' or 'px'.
  1462. * - Returns itself when setting; method can be chained.
  1463. */
  1464. Component.prototype.height = function height(num, skipListeners) {
  1465. return this.dimension('height', num, skipListeners);
  1466. };
  1467. /**
  1468. * Set both the width and height of the `Component` element at the same time.
  1469. *
  1470. * @param {number|string} width
  1471. * Width to set the `Component`s element to.
  1472. *
  1473. * @param {number|string} height
  1474. * Height to set the `Component`s element to.
  1475. *
  1476. * @return {Component}
  1477. * Returns itself; method can be chained.
  1478. */
  1479. Component.prototype.dimensions = function dimensions(width, height) {
  1480. // Skip resize listeners on width for optimization
  1481. return this.width(width, true).height(height);
  1482. };
  1483. /**
  1484. * Get or set width or height of the `Component` element. This is the shared code
  1485. * for the {@link Component#width} and {@link Component#height}.
  1486. *
  1487. * Things to know:
  1488. * - If the width or height in an number this will return the number postfixed with 'px'.
  1489. * - If the width/height is a percent this will return the percent postfixed with '%'
  1490. * - Hidden elements have a width of 0 with `window.getComputedStyle`. This function
  1491. * defaults to the `Component`s `style.width` and falls back to `window.getComputedStyle`.
  1492. * See [this]{@link http://www.foliotek.com/devblog/getting-the-width-of-a-hidden-element-with-jquery-using-width/}
  1493. * for more information
  1494. * - If you want the computed style of the component, use {@link Component#currentWidth}
  1495. * and {@link {Component#currentHeight}
  1496. *
  1497. * @fires Component#resize
  1498. *
  1499. * @param {string} widthOrHeight
  1500. 8 'width' or 'height'
  1501. *
  1502. * @param {number|string} [num]
  1503. 8 New dimension
  1504. *
  1505. * @param {boolean} [skipListeners]
  1506. * Skip resize event trigger
  1507. *
  1508. * @return {Component}
  1509. * - the dimension when getting or 0 if unset
  1510. * - Returns itself when setting; method can be chained.
  1511. */
  1512. Component.prototype.dimension = function dimension(widthOrHeight, num, skipListeners) {
  1513. if (num !== undefined) {
  1514. // Set to zero if null or literally NaN (NaN !== NaN)
  1515. if (num === null || num !== num) {
  1516. num = 0;
  1517. }
  1518. // Check if using css width/height (% or px) and adjust
  1519. if (('' + num).indexOf('%') !== -1 || ('' + num).indexOf('px') !== -1) {
  1520. this.el_.style[widthOrHeight] = num;
  1521. } else if (num === 'auto') {
  1522. this.el_.style[widthOrHeight] = '';
  1523. } else {
  1524. this.el_.style[widthOrHeight] = num + 'px';
  1525. }
  1526. // skipListeners allows us to avoid triggering the resize event when setting both width and height
  1527. if (!skipListeners) {
  1528. /**
  1529. * Triggered when a component is resized.
  1530. *
  1531. * @event Component#resize
  1532. * @type {EventTarget~Event}
  1533. */
  1534. this.trigger('resize');
  1535. }
  1536. // Return component
  1537. return this;
  1538. }
  1539. // Not setting a value, so getting it
  1540. // Make sure element exists
  1541. if (!this.el_) {
  1542. return 0;
  1543. }
  1544. // Get dimension value from style
  1545. var val = this.el_.style[widthOrHeight];
  1546. var pxIndex = val.indexOf('px');
  1547. if (pxIndex !== -1) {
  1548. // Return the pixel value with no 'px'
  1549. return parseInt(val.slice(0, pxIndex), 10);
  1550. }
  1551. // No px so using % or no style was set, so falling back to offsetWidth/height
  1552. // If component has display:none, offset will return 0
  1553. // TODO: handle display:none and no dimension style using px
  1554. return parseInt(this.el_['offset' + (0, _toTitleCase2['default'])(widthOrHeight)], 10);
  1555. };
  1556. /**
  1557. * Get the width or the height of the `Component` elements computed style. Uses
  1558. * `window.getComputedStyle`.
  1559. *
  1560. * @param {string} widthOrHeight
  1561. * A string containing 'width' or 'height'. Whichever one you want to get.
  1562. *
  1563. * @return {number}
  1564. * The dimension that gets asked for or 0 if nothing was set
  1565. * for that dimension.
  1566. */
  1567. Component.prototype.currentDimension = function currentDimension(widthOrHeight) {
  1568. var computedWidthOrHeight = 0;
  1569. if (widthOrHeight !== 'width' && widthOrHeight !== 'height') {
  1570. throw new Error('currentDimension only accepts width or height value');
  1571. }
  1572. if (typeof _window2['default'].getComputedStyle === 'function') {
  1573. var computedStyle = _window2['default'].getComputedStyle(this.el_);
  1574. computedWidthOrHeight = computedStyle.getPropertyValue(widthOrHeight) || computedStyle[widthOrHeight];
  1575. }
  1576. // remove 'px' from variable and parse as integer
  1577. computedWidthOrHeight = parseFloat(computedWidthOrHeight);
  1578. // if the computed value is still 0, it's possible that the browser is lying
  1579. // and we want to check the offset values.
  1580. // This code also runs on IE8 and wherever getComputedStyle doesn't exist.
  1581. if (computedWidthOrHeight === 0) {
  1582. var rule = 'offset' + (0, _toTitleCase2['default'])(widthOrHeight);
  1583. computedWidthOrHeight = this.el_[rule];
  1584. }
  1585. return computedWidthOrHeight;
  1586. };
  1587. /**
  1588. * An object that contains width and height values of the `Component`s
  1589. * computed style. Uses `window.getComputedStyle`.
  1590. *
  1591. * @typedef {Object} Component~DimensionObject
  1592. *
  1593. * @property {number} width
  1594. * The width of the `Component`s computed style.
  1595. *
  1596. * @property {number} height
  1597. * The height of the `Component`s computed style.
  1598. */
  1599. /**
  1600. * Get an object that contains width and height values of the `Component`s
  1601. * computed style.
  1602. *
  1603. * @return {Component~DimensionObject}
  1604. * The dimensions of the components element
  1605. */
  1606. Component.prototype.currentDimensions = function currentDimensions() {
  1607. return {
  1608. width: this.currentDimension('width'),
  1609. height: this.currentDimension('height')
  1610. };
  1611. };
  1612. /**
  1613. * Get the width of the `Component`s computed style. Uses `window.getComputedStyle`.
  1614. *
  1615. * @return {number} width
  1616. * The width of the `Component`s computed style.
  1617. */
  1618. Component.prototype.currentWidth = function currentWidth() {
  1619. return this.currentDimension('width');
  1620. };
  1621. /**
  1622. * Get the height of the `Component`s computed style. Uses `window.getComputedStyle`.
  1623. *
  1624. * @return {number} height
  1625. * The height of the `Component`s computed style.
  1626. */
  1627. Component.prototype.currentHeight = function currentHeight() {
  1628. return this.currentDimension('height');
  1629. };
  1630. /**
  1631. * Emit a 'tap' events when touch event support gets detected. This gets used to
  1632. * support toggling the controls through a tap on the video. They get enabled
  1633. * because every sub-component would have extra overhead otherwise.
  1634. *
  1635. * @private
  1636. * @fires Component#tap
  1637. * @listens Component#touchstart
  1638. * @listens Component#touchmove
  1639. * @listens Component#touchleave
  1640. * @listens Component#touchcancel
  1641. * @listens Component#touchend
  1642. */
  1643. Component.prototype.emitTapEvents = function emitTapEvents() {
  1644. // Track the start time so we can determine how long the touch lasted
  1645. var touchStart = 0;
  1646. var firstTouch = null;
  1647. // Maximum movement allowed during a touch event to still be considered a tap
  1648. // Other popular libs use anywhere from 2 (hammer.js) to 15,
  1649. // so 10 seems like a nice, round number.
  1650. var tapMovementThreshold = 10;
  1651. // The maximum length a touch can be while still being considered a tap
  1652. var touchTimeThreshold = 200;
  1653. var couldBeTap = void 0;
  1654. this.on('touchstart', function (event) {
  1655. // If more than one finger, don't consider treating this as a click
  1656. if (event.touches.length === 1) {
  1657. // Copy pageX/pageY from the object
  1658. firstTouch = {
  1659. pageX: event.touches[0].pageX,
  1660. pageY: event.touches[0].pageY
  1661. };
  1662. // Record start time so we can detect a tap vs. "touch and hold"
  1663. touchStart = new Date().getTime();
  1664. // Reset couldBeTap tracking
  1665. couldBeTap = true;
  1666. }
  1667. });
  1668. this.on('touchmove', function (event) {
  1669. // If more than one finger, don't consider treating this as a click
  1670. if (event.touches.length > 1) {
  1671. couldBeTap = false;
  1672. } else if (firstTouch) {
  1673. // Some devices will throw touchmoves for all but the slightest of taps.
  1674. // So, if we moved only a small distance, this could still be a tap
  1675. var xdiff = event.touches[0].pageX - firstTouch.pageX;
  1676. var ydiff = event.touches[0].pageY - firstTouch.pageY;
  1677. var touchDistance = Math.sqrt(xdiff * xdiff + ydiff * ydiff);
  1678. if (touchDistance > tapMovementThreshold) {
  1679. couldBeTap = false;
  1680. }
  1681. }
  1682. });
  1683. var noTap = function noTap() {
  1684. couldBeTap = false;
  1685. };
  1686. // TODO: Listen to the original target. http://youtu.be/DujfpXOKUp8?t=13m8s
  1687. this.on('touchleave', noTap);
  1688. this.on('touchcancel', noTap);
  1689. // When the touch ends, measure how long it took and trigger the appropriate
  1690. // event
  1691. this.on('touchend', function (event) {
  1692. firstTouch = null;
  1693. // Proceed only if the touchmove/leave/cancel event didn't happen
  1694. if (couldBeTap === true) {
  1695. // Measure how long the touch lasted
  1696. var touchTime = new Date().getTime() - touchStart;
  1697. // Make sure the touch was less than the threshold to be considered a tap
  1698. if (touchTime < touchTimeThreshold) {
  1699. // Don't let browser turn this into a click
  1700. event.preventDefault();
  1701. /**
  1702. * Triggered when a `Component` is tapped.
  1703. *
  1704. * @event Component#tap
  1705. * @type {EventTarget~Event}
  1706. */
  1707. this.trigger('tap');
  1708. // It may be good to copy the touchend event object and change the
  1709. // type to tap, if the other event properties aren't exact after
  1710. // Events.fixEvent runs (e.g. event.target)
  1711. }
  1712. }
  1713. });
  1714. };
  1715. /**
  1716. * This function reports user activity whenever touch events happen. This can get
  1717. * turned off by any sub-components that wants touch events to act another way.
  1718. *
  1719. * Report user touch activity when touch events occur. User activity gets used to
  1720. * determine when controls should show/hide. It is simple when it comes to mouse
  1721. * events, because any mouse event should show the controls. So we capture mouse
  1722. * events that bubble up to the player and report activity when that happens.
  1723. * With touch events it isn't as easy as `touchstart` and `touchend` toggle player
  1724. * controls. So touch events can't help us at the player level either.
  1725. *
  1726. * User activity gets checked asynchronously. So what could happen is a tap event
  1727. * on the video turns the controls off. Then the `touchend` event bubbles up to
  1728. * the player. Which, if it reported user activity, would turn the controls right
  1729. * back on. We also don't want to completely block touch events from bubbling up.
  1730. * Furthermore a `touchmove` event and anything other than a tap, should not turn
  1731. * controls back on.
  1732. *
  1733. * @listens Component#touchstart
  1734. * @listens Component#touchmove
  1735. * @listens Component#touchend
  1736. * @listens Component#touchcancel
  1737. */
  1738. Component.prototype.enableTouchActivity = function enableTouchActivity() {
  1739. // Don't continue if the root player doesn't support reporting user activity
  1740. if (!this.player() || !this.player().reportUserActivity) {
  1741. return;
  1742. }
  1743. // listener for reporting that the user is active
  1744. var report = Fn.bind(this.player(), this.player().reportUserActivity);
  1745. var touchHolding = void 0;
  1746. this.on('touchstart', function () {
  1747. report();
  1748. // For as long as the they are touching the device or have their mouse down,
  1749. // we consider them active even if they're not moving their finger or mouse.
  1750. // So we want to continue to update that they are active
  1751. this.clearInterval(touchHolding);
  1752. // report at the same interval as activityCheck
  1753. touchHolding = this.setInterval(report, 250);
  1754. });
  1755. var touchEnd = function touchEnd(event) {
  1756. report();
  1757. // stop the interval that maintains activity if the touch is holding
  1758. this.clearInterval(touchHolding);
  1759. };
  1760. this.on('touchmove', report);
  1761. this.on('touchend', touchEnd);
  1762. this.on('touchcancel', touchEnd);
  1763. };
  1764. /**
  1765. * A callback that has no parameters and is bound into `Component`s context.
  1766. *
  1767. * @callback Component~GenericCallback
  1768. * @this Component
  1769. */
  1770. /**
  1771. * Creates a function that runs after an `x` millisecond timeout. This function is a
  1772. * wrapper around `window.setTimeout`. There are a few reasons to use this one
  1773. * instead though:
  1774. * 1. It gets cleared via {@link Component#clearTimeout} when
  1775. * {@link Component#dispose} gets called.
  1776. * 2. The function callback will gets turned into a {@link Component~GenericCallback}
  1777. *
  1778. * > Note: You can use `window.clearTimeout` on the id returned by this function. This
  1779. * will cause its dispose listener not to get cleaned up! Please use
  1780. * {@link Component#clearTimeout} or {@link Component#dispose}.
  1781. *
  1782. * @param {Component~GenericCallback} fn
  1783. * The function that will be run after `timeout`.
  1784. *
  1785. * @param {number} timeout
  1786. * Timeout in milliseconds to delay before executing the specified function.
  1787. *
  1788. * @return {number}
  1789. * Returns a timeout ID that gets used to identify the timeout. It can also
  1790. * get used in {@link Component#clearTimeout} to clear the timeout that
  1791. * was set.
  1792. *
  1793. * @listens Component#dispose
  1794. * @see [Similar to]{@link https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setTimeout}
  1795. */
  1796. Component.prototype.setTimeout = function setTimeout(fn, timeout) {
  1797. fn = Fn.bind(this, fn);
  1798. var timeoutId = _window2['default'].setTimeout(fn, timeout);
  1799. var disposeFn = function disposeFn() {
  1800. this.clearTimeout(timeoutId);
  1801. };
  1802. disposeFn.guid = 'vjs-timeout-' + timeoutId;
  1803. this.on('dispose', disposeFn);
  1804. return timeoutId;
  1805. };
  1806. /**
  1807. * Clears a timeout that gets created via `window.setTimeout` or
  1808. * {@link Component#setTimeout}. If you set a timeout via {@link Component#setTimeout}
  1809. * use this function instead of `window.clearTimout`. If you don't your dispose
  1810. * listener will not get cleaned up until {@link Component#dispose}!
  1811. *
  1812. * @param {number} timeoutId
  1813. * The id of the timeout to clear. The return value of
  1814. * {@link Component#setTimeout} or `window.setTimeout`.
  1815. *
  1816. * @return {number}
  1817. * Returns the timeout id that was cleared.
  1818. *
  1819. * @see [Similar to]{@link https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/clearTimeout}
  1820. */
  1821. Component.prototype.clearTimeout = function clearTimeout(timeoutId) {
  1822. _window2['default'].clearTimeout(timeoutId);
  1823. var disposeFn = function disposeFn() {};
  1824. disposeFn.guid = 'vjs-timeout-' + timeoutId;
  1825. this.off('dispose', disposeFn);
  1826. return timeoutId;
  1827. };
  1828. /**
  1829. * Creates a function that gets run every `x` milliseconds. This function is a wrapper
  1830. * around `window.setInterval`. There are a few reasons to use this one instead though.
  1831. * 1. It gets cleared via {@link Component#clearInterval} when
  1832. * {@link Component#dispose} gets called.
  1833. * 2. The function callback will be a {@link Component~GenericCallback}
  1834. *
  1835. * @param {Component~GenericCallback} fn
  1836. * The function to run every `x` seconds.
  1837. *
  1838. * @param {number} interval
  1839. * Execute the specified function every `x` milliseconds.
  1840. *
  1841. * @return {number}
  1842. * Returns an id that can be used to identify the interval. It can also be be used in
  1843. * {@link Component#clearInterval} to clear the interval.
  1844. *
  1845. * @listens Component#dispose
  1846. * @see [Similar to]{@link https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setInterval}
  1847. */
  1848. Component.prototype.setInterval = function setInterval(fn, interval) {
  1849. fn = Fn.bind(this, fn);
  1850. var intervalId = _window2['default'].setInterval(fn, interval);
  1851. var disposeFn = function disposeFn() {
  1852. this.clearInterval(intervalId);
  1853. };
  1854. disposeFn.guid = 'vjs-interval-' + intervalId;
  1855. this.on('dispose', disposeFn);
  1856. return intervalId;
  1857. };
  1858. /**
  1859. * Clears an interval that gets created via `window.setInterval` or
  1860. * {@link Component#setInterval}. If you set an inteval via {@link Component#setInterval}
  1861. * use this function instead of `window.clearInterval`. If you don't your dispose
  1862. * listener will not get cleaned up until {@link Component#dispose}!
  1863. *
  1864. * @param {number} intervalId
  1865. * The id of the interval to clear. The return value of
  1866. * {@link Component#setInterval} or `window.setInterval`.
  1867. *
  1868. * @return {number}
  1869. * Returns the interval id that was cleared.
  1870. *
  1871. * @see [Similar to]{@link https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/clearInterval}
  1872. */
  1873. Component.prototype.clearInterval = function clearInterval(intervalId) {
  1874. _window2['default'].clearInterval(intervalId);
  1875. var disposeFn = function disposeFn() {};
  1876. disposeFn.guid = 'vjs-interval-' + intervalId;
  1877. this.off('dispose', disposeFn);
  1878. return intervalId;
  1879. };
  1880. /**
  1881. * Register a `Component` with `videojs` given the name and the component.
  1882. *
  1883. * > NOTE: {@link Tech}s should not be registered as a `Component`. {@link Tech}s
  1884. * should be registered using {@link Tech.registerTech} or
  1885. * {@link videojs:videojs.registerTech}.
  1886. *
  1887. * > NOTE: This function can also be seen on videojs as
  1888. * {@link videojs:videojs.registerComponent}.
  1889. *
  1890. * @param {string} name
  1891. * The name of the `Component` to register.
  1892. *
  1893. * @param {Component} comp
  1894. * The `Component` class to register.
  1895. *
  1896. * @return {Component}
  1897. * The `Component` that was registered.
  1898. */
  1899. Component.registerComponent = function registerComponent(name, comp) {
  1900. if (!name) {
  1901. return;
  1902. }
  1903. name = (0, _toTitleCase2['default'])(name);
  1904. if (!Component.components_) {
  1905. Component.components_ = {};
  1906. }
  1907. if (name === 'Player' && Component.components_[name]) {
  1908. (function () {
  1909. var Player = Component.components_[name];
  1910. // If we have players that were disposed, then their name will still be
  1911. // in Players.players. So, we must loop through and verify that the value
  1912. // for each item is not null. This allows registration of the Player component
  1913. // after all players have been disposed or before any were created.
  1914. if (Player.players && Object.keys(Player.players).length > 0 && Object.keys(Player.players).map(function (playerName) {
  1915. return Player.players[playerName];
  1916. }).every(Boolean)) {
  1917. throw new Error('Can not register Player component after player has been created');
  1918. }
  1919. })();
  1920. }
  1921. Component.components_[name] = comp;
  1922. return comp;
  1923. };
  1924. /**
  1925. * Get a `Component` based on the name it was registered with.
  1926. *
  1927. * @param {string} name
  1928. * The Name of the component to get.
  1929. *
  1930. * @return {Component}
  1931. * The `Component` that got registered under the given name.
  1932. *
  1933. * @deprecated In `videojs` 6 this will not return `Component`s that were not
  1934. * registered using {@link Component.registerComponent}. Currently we
  1935. * check the global `videojs` object for a `Component` name and
  1936. * return that if it exists.
  1937. */
  1938. Component.getComponent = function getComponent(name) {
  1939. if (!name) {
  1940. return;
  1941. }
  1942. name = (0, _toTitleCase2['default'])(name);
  1943. if (Component.components_ && Component.components_[name]) {
  1944. return Component.components_[name];
  1945. }
  1946. if (_window2['default'] && _window2['default'].videojs && _window2['default'].videojs[name]) {
  1947. _log2['default'].warn('The ' + name + ' component was added to the videojs object when it should be registered using videojs.registerComponent(name, component)');
  1948. return _window2['default'].videojs[name];
  1949. }
  1950. };
  1951. /**
  1952. * Sets up the constructor using the supplied init method or uses the init of the
  1953. * parent object.
  1954. *
  1955. * @param {Object} [props={}]
  1956. * An object of properties.
  1957. *
  1958. * @return {Object}
  1959. * the extended object.
  1960. *
  1961. * @deprecated since version 5
  1962. */
  1963. Component.extend = function extend(props) {
  1964. props = props || {};
  1965. _log2['default'].warn('Component.extend({}) has been deprecated, ' + ' use videojs.extend(Component, {}) instead');
  1966. // Set up the constructor using the supplied init method
  1967. // or using the init of the parent object
  1968. // Make sure to check the unobfuscated version for external libs
  1969. var init = props.init || props.init || this.prototype.init || this.prototype.init || function () {};
  1970. // In Resig's simple class inheritance (previously used) the constructor
  1971. // is a function that calls `this.init.apply(arguments)`
  1972. // However that would prevent us from using `ParentObject.call(this);`
  1973. // in a Child constructor because the `this` in `this.init`
  1974. // would still refer to the Child and cause an infinite loop.
  1975. // We would instead have to do
  1976. // `ParentObject.prototype.init.apply(this, arguments);`
  1977. // Bleh. We're not creating a _super() function, so it's good to keep
  1978. // the parent constructor reference simple.
  1979. var subObj = function subObj() {
  1980. init.apply(this, arguments);
  1981. };
  1982. // Inherit from this object's prototype
  1983. subObj.prototype = Object.create(this.prototype);
  1984. // Reset the constructor property for subObj otherwise
  1985. // instances of subObj would have the constructor of the parent Object
  1986. subObj.prototype.constructor = subObj;
  1987. // Make the class extendable
  1988. subObj.extend = Component.extend;
  1989. // Extend subObj's prototype with functions and other properties from props
  1990. for (var name in props) {
  1991. if (props.hasOwnProperty(name)) {
  1992. subObj.prototype[name] = props[name];
  1993. }
  1994. }
  1995. return subObj;
  1996. };
  1997. return Component;
  1998. }();
  1999. Component.registerComponent('Component', Component);
  2000. exports['default'] = Component;
  2001. },{"81":81,"82":82,"83":83,"85":85,"86":86,"87":87,"91":91,"95":95}],6:[function(_dereq_,module,exports){
  2002. 'use strict';
  2003. exports.__esModule = true;
  2004. var _trackButton = _dereq_(36);
  2005. var _trackButton2 = _interopRequireDefault(_trackButton);
  2006. var _component = _dereq_(5);
  2007. var _component2 = _interopRequireDefault(_component);
  2008. var _audioTrackMenuItem = _dereq_(7);
  2009. var _audioTrackMenuItem2 = _interopRequireDefault(_audioTrackMenuItem);
  2010. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  2011. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  2012. 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; }
  2013. 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; } /**
  2014. * @file audio-track-button.js
  2015. */
  2016. /**
  2017. * The base class for buttons that toggle specific {@link AudioTrack} types.
  2018. *
  2019. * @extends TrackButton
  2020. */
  2021. var AudioTrackButton = function (_TrackButton) {
  2022. _inherits(AudioTrackButton, _TrackButton);
  2023. /**
  2024. * Creates an instance of this class.
  2025. *
  2026. * @param {Player} player
  2027. * The `Player` that this class should be attached to.
  2028. *
  2029. * @param {Object} [options={}]
  2030. * The key/value store of player options.
  2031. */
  2032. function AudioTrackButton(player) {
  2033. var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  2034. _classCallCheck(this, AudioTrackButton);
  2035. options.tracks = player.audioTracks && player.audioTracks();
  2036. var _this = _possibleConstructorReturn(this, _TrackButton.call(this, player, options));
  2037. _this.el_.setAttribute('aria-label', 'Audio Menu');
  2038. return _this;
  2039. }
  2040. /**
  2041. * Builds the default DOM `className`.
  2042. *
  2043. * @return {string}
  2044. * The DOM `className` for this object.
  2045. */
  2046. AudioTrackButton.prototype.buildCSSClass = function buildCSSClass() {
  2047. return 'vjs-audio-button ' + _TrackButton.prototype.buildCSSClass.call(this);
  2048. };
  2049. /**
  2050. * Create a menu item for each audio track
  2051. *
  2052. * @param {AudioTrackMenuItem[]} [items=[]]
  2053. * An array of existing menu items to use.
  2054. *
  2055. * @return {AudioTrackMenuItem[]}
  2056. * An array of menu items
  2057. */
  2058. AudioTrackButton.prototype.createItems = function createItems() {
  2059. var items = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
  2060. var tracks = this.player_.audioTracks && this.player_.audioTracks();
  2061. if (!tracks) {
  2062. return items;
  2063. }
  2064. for (var i = 0; i < tracks.length; i++) {
  2065. var track = tracks[i];
  2066. items.push(new _audioTrackMenuItem2['default'](this.player_, {
  2067. track: track,
  2068. // MenuItem is selectable
  2069. selectable: true
  2070. }));
  2071. }
  2072. return items;
  2073. };
  2074. return AudioTrackButton;
  2075. }(_trackButton2['default']);
  2076. /**
  2077. * The text that should display over the `AudioTrackButton`s controls. Added for localization.
  2078. *
  2079. * @type {string}
  2080. * @private
  2081. */
  2082. AudioTrackButton.prototype.controlText_ = 'Audio Track';
  2083. _component2['default'].registerComponent('AudioTrackButton', AudioTrackButton);
  2084. exports['default'] = AudioTrackButton;
  2085. },{"36":36,"5":5,"7":7}],7:[function(_dereq_,module,exports){
  2086. 'use strict';
  2087. exports.__esModule = true;
  2088. var _menuItem = _dereq_(48);
  2089. var _menuItem2 = _interopRequireDefault(_menuItem);
  2090. var _component = _dereq_(5);
  2091. var _component2 = _interopRequireDefault(_component);
  2092. var _fn = _dereq_(83);
  2093. var Fn = _interopRequireWildcard(_fn);
  2094. 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; } }
  2095. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  2096. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  2097. 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; }
  2098. 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; } /**
  2099. * @file audio-track-menu-item.js
  2100. */
  2101. /**
  2102. * An {@link AudioTrack} {@link MenuItem}
  2103. *
  2104. * @extends MenuItem
  2105. */
  2106. var AudioTrackMenuItem = function (_MenuItem) {
  2107. _inherits(AudioTrackMenuItem, _MenuItem);
  2108. /**
  2109. * Creates an instance of this class.
  2110. *
  2111. * @param {Player} player
  2112. * The `Player` that this class should be attached to.
  2113. *
  2114. * @param {Object} [options]
  2115. * The key/value store of player options.
  2116. */
  2117. function AudioTrackMenuItem(player, options) {
  2118. _classCallCheck(this, AudioTrackMenuItem);
  2119. var track = options.track;
  2120. var tracks = player.audioTracks();
  2121. // Modify options for parent MenuItem class's init.
  2122. options.label = track.label || track.language || 'Unknown';
  2123. options.selected = track.enabled;
  2124. var _this = _possibleConstructorReturn(this, _MenuItem.call(this, player, options));
  2125. _this.track = track;
  2126. if (tracks) {
  2127. (function () {
  2128. var changeHandler = Fn.bind(_this, _this.handleTracksChange);
  2129. tracks.addEventListener('change', changeHandler);
  2130. _this.on('dispose', function () {
  2131. tracks.removeEventListener('change', changeHandler);
  2132. });
  2133. })();
  2134. }
  2135. return _this;
  2136. }
  2137. /**
  2138. * This gets called when an `AudioTrackMenuItem is "clicked". See {@link ClickableComponent}
  2139. * for more detailed information on what a click can be.
  2140. *
  2141. * @param {EventTarget~Event} [event]
  2142. * The `keydown`, `tap`, or `click` event that caused this function to be
  2143. * called.
  2144. *
  2145. * @listens tap
  2146. * @listens click
  2147. */
  2148. AudioTrackMenuItem.prototype.handleClick = function handleClick(event) {
  2149. var tracks = this.player_.audioTracks();
  2150. _MenuItem.prototype.handleClick.call(this, event);
  2151. if (!tracks) {
  2152. return;
  2153. }
  2154. for (var i = 0; i < tracks.length; i++) {
  2155. var track = tracks[i];
  2156. track.enabled = track === this.track;
  2157. }
  2158. };
  2159. /**
  2160. * Handle any {@link AudioTrack} change.
  2161. *
  2162. * @param {EventTarget~Event} [event]
  2163. * The {@link AudioTrackList#change} event that caused this to run.
  2164. *
  2165. * @listens AudioTrackList#change
  2166. */
  2167. AudioTrackMenuItem.prototype.handleTracksChange = function handleTracksChange(event) {
  2168. this.selected(this.track.enabled);
  2169. };
  2170. return AudioTrackMenuItem;
  2171. }(_menuItem2['default']);
  2172. _component2['default'].registerComponent('AudioTrackMenuItem', AudioTrackMenuItem);
  2173. exports['default'] = AudioTrackMenuItem;
  2174. },{"48":48,"5":5,"83":83}],8:[function(_dereq_,module,exports){
  2175. 'use strict';
  2176. exports.__esModule = true;
  2177. var _component = _dereq_(5);
  2178. var _component2 = _interopRequireDefault(_component);
  2179. _dereq_(12);
  2180. _dereq_(32);
  2181. _dereq_(33);
  2182. _dereq_(35);
  2183. _dereq_(34);
  2184. _dereq_(10);
  2185. _dereq_(18);
  2186. _dereq_(9);
  2187. _dereq_(38);
  2188. _dereq_(40);
  2189. _dereq_(11);
  2190. _dereq_(25);
  2191. _dereq_(27);
  2192. _dereq_(29);
  2193. _dereq_(24);
  2194. _dereq_(6);
  2195. _dereq_(13);
  2196. _dereq_(21);
  2197. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  2198. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  2199. 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; }
  2200. 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; } /**
  2201. * @file control-bar.js
  2202. */
  2203. // Required children
  2204. /**
  2205. * Container of main controls.
  2206. *
  2207. * @extends Component
  2208. */
  2209. var ControlBar = function (_Component) {
  2210. _inherits(ControlBar, _Component);
  2211. function ControlBar() {
  2212. _classCallCheck(this, ControlBar);
  2213. return _possibleConstructorReturn(this, _Component.apply(this, arguments));
  2214. }
  2215. /**
  2216. * Create the `Component`'s DOM element
  2217. *
  2218. * @return {Element}
  2219. * The element that was created.
  2220. */
  2221. ControlBar.prototype.createEl = function createEl() {
  2222. return _Component.prototype.createEl.call(this, 'div', {
  2223. className: 'vjs-control-bar',
  2224. dir: 'ltr'
  2225. }, {
  2226. // The control bar is a group, so it can contain menuitems
  2227. role: 'group'
  2228. });
  2229. };
  2230. return ControlBar;
  2231. }(_component2['default']);
  2232. /**
  2233. * Default options for `ControlBar`
  2234. *
  2235. * @type {Object}
  2236. * @private
  2237. */
  2238. ControlBar.prototype.options_ = {
  2239. children: ['playToggle', 'volumeMenuButton', 'currentTimeDisplay', 'timeDivider', 'durationDisplay', 'progressControl', 'liveDisplay', 'remainingTimeDisplay', 'customControlSpacer', 'playbackRateMenuButton', 'chaptersButton', 'descriptionsButton', 'subtitlesButton', 'captionsButton', 'audioTrackButton', 'fullscreenToggle']
  2240. };
  2241. _component2['default'].registerComponent('ControlBar', ControlBar);
  2242. exports['default'] = ControlBar;
  2243. },{"10":10,"11":11,"12":12,"13":13,"18":18,"21":21,"24":24,"25":25,"27":27,"29":29,"32":32,"33":33,"34":34,"35":35,"38":38,"40":40,"5":5,"6":6,"9":9}],9:[function(_dereq_,module,exports){
  2244. 'use strict';
  2245. exports.__esModule = true;
  2246. var _button = _dereq_(2);
  2247. var _button2 = _interopRequireDefault(_button);
  2248. var _component = _dereq_(5);
  2249. var _component2 = _interopRequireDefault(_component);
  2250. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  2251. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  2252. 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; }
  2253. 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; } /**
  2254. * @file fullscreen-toggle.js
  2255. */
  2256. /**
  2257. * Toggle fullscreen video
  2258. *
  2259. * @extends Button
  2260. */
  2261. var FullscreenToggle = function (_Button) {
  2262. _inherits(FullscreenToggle, _Button);
  2263. /**
  2264. * Creates an instance of this class.
  2265. *
  2266. * @param {Player} player
  2267. * The `Player` that this class should be attached to.
  2268. *
  2269. * @param {Object} [options]
  2270. * The key/value store of player options.
  2271. */
  2272. function FullscreenToggle(player, options) {
  2273. _classCallCheck(this, FullscreenToggle);
  2274. var _this = _possibleConstructorReturn(this, _Button.call(this, player, options));
  2275. _this.on(player, 'fullscreenchange', _this.handleFullscreenChange);
  2276. return _this;
  2277. }
  2278. /**
  2279. * Builds the default DOM `className`.
  2280. *
  2281. * @return {string}
  2282. * The DOM `className` for this object.
  2283. */
  2284. FullscreenToggle.prototype.buildCSSClass = function buildCSSClass() {
  2285. return 'vjs-fullscreen-control ' + _Button.prototype.buildCSSClass.call(this);
  2286. };
  2287. /**
  2288. * Handles fullscreenchange on the player and change control text accordingly.
  2289. *
  2290. * @param {EventTarget~Event} [event]
  2291. * The {@link Player#fullscreenchange} event that caused this function to be
  2292. * called.
  2293. *
  2294. * @listens Player#fullscreenchange
  2295. */
  2296. FullscreenToggle.prototype.handleFullscreenChange = function handleFullscreenChange(event) {
  2297. if (this.player_.isFullscreen()) {
  2298. this.controlText('Non-Fullscreen');
  2299. } else {
  2300. this.controlText('Fullscreen');
  2301. }
  2302. };
  2303. /**
  2304. * This gets called when an `FullscreenToggle` is "clicked". See
  2305. * {@link ClickableComponent} for more detailed information on what a click can be.
  2306. *
  2307. * @param {EventTarget~Event} [event]
  2308. * The `keydown`, `tap`, or `click` event that caused this function to be
  2309. * called.
  2310. *
  2311. * @listens tap
  2312. * @listens click
  2313. */
  2314. FullscreenToggle.prototype.handleClick = function handleClick(event) {
  2315. if (!this.player_.isFullscreen()) {
  2316. this.player_.requestFullscreen();
  2317. } else {
  2318. this.player_.exitFullscreen();
  2319. }
  2320. };
  2321. return FullscreenToggle;
  2322. }(_button2['default']);
  2323. /**
  2324. * The text that should display over the `FullscreenToggle`s controls. Added for localization.
  2325. *
  2326. * @type {string}
  2327. * @private
  2328. */
  2329. FullscreenToggle.prototype.controlText_ = 'Fullscreen';
  2330. _component2['default'].registerComponent('FullscreenToggle', FullscreenToggle);
  2331. exports['default'] = FullscreenToggle;
  2332. },{"2":2,"5":5}],10:[function(_dereq_,module,exports){
  2333. 'use strict';
  2334. exports.__esModule = true;
  2335. var _component = _dereq_(5);
  2336. var _component2 = _interopRequireDefault(_component);
  2337. var _dom = _dereq_(81);
  2338. var Dom = _interopRequireWildcard(_dom);
  2339. 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; } }
  2340. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  2341. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  2342. 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; }
  2343. 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; } /**
  2344. * @file live-display.js
  2345. */
  2346. // TODO - Future make it click to snap to live
  2347. /**
  2348. * Displays the live indicator when duration is Infinity.
  2349. *
  2350. * @extends Component
  2351. */
  2352. var LiveDisplay = function (_Component) {
  2353. _inherits(LiveDisplay, _Component);
  2354. /**
  2355. * Creates an instance of this class.
  2356. *
  2357. * @param {Player} player
  2358. * The `Player` that this class should be attached to.
  2359. *
  2360. * @param {Object} [options]
  2361. * The key/value store of player options.
  2362. */
  2363. function LiveDisplay(player, options) {
  2364. _classCallCheck(this, LiveDisplay);
  2365. var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
  2366. _this.updateShowing();
  2367. _this.on(_this.player(), 'durationchange', _this.updateShowing);
  2368. return _this;
  2369. }
  2370. /**
  2371. * Create the `Component`'s DOM element
  2372. *
  2373. * @return {Element}
  2374. * The element that was created.
  2375. */
  2376. LiveDisplay.prototype.createEl = function createEl() {
  2377. var el = _Component.prototype.createEl.call(this, 'div', {
  2378. className: 'vjs-live-control vjs-control'
  2379. });
  2380. this.contentEl_ = Dom.createEl('div', {
  2381. className: 'vjs-live-display',
  2382. innerHTML: '<span class="vjs-control-text">' + this.localize('Stream Type') + '</span>' + this.localize('LIVE')
  2383. }, {
  2384. 'aria-live': 'off'
  2385. });
  2386. el.appendChild(this.contentEl_);
  2387. return el;
  2388. };
  2389. /**
  2390. * Check the duration to see if the LiveDisplay should be showing or not. Then show/hide
  2391. * it accordingly
  2392. *
  2393. * @param {EventTarget~Event} [event]
  2394. * The {@link Player#durationchange} event that caused this function to run.
  2395. *
  2396. * @listens Player#durationchange
  2397. */
  2398. LiveDisplay.prototype.updateShowing = function updateShowing(event) {
  2399. if (this.player().duration() === Infinity) {
  2400. this.show();
  2401. } else {
  2402. this.hide();
  2403. }
  2404. };
  2405. return LiveDisplay;
  2406. }(_component2['default']);
  2407. _component2['default'].registerComponent('LiveDisplay', LiveDisplay);
  2408. exports['default'] = LiveDisplay;
  2409. },{"5":5,"81":81}],11:[function(_dereq_,module,exports){
  2410. 'use strict';
  2411. exports.__esModule = true;
  2412. var _button = _dereq_(2);
  2413. var _button2 = _interopRequireDefault(_button);
  2414. var _component = _dereq_(5);
  2415. var _component2 = _interopRequireDefault(_component);
  2416. var _dom = _dereq_(81);
  2417. var Dom = _interopRequireWildcard(_dom);
  2418. 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; } }
  2419. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  2420. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  2421. 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; }
  2422. 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; } /**
  2423. * @file mute-toggle.js
  2424. */
  2425. /**
  2426. * A button component for muting the audio.
  2427. *
  2428. * @extends Button
  2429. */
  2430. var MuteToggle = function (_Button) {
  2431. _inherits(MuteToggle, _Button);
  2432. /**
  2433. * Creates an instance of this class.
  2434. *
  2435. * @param {Player} player
  2436. * The `Player` that this class should be attached to.
  2437. *
  2438. * @param {Object} [options]
  2439. * The key/value store of player options.
  2440. */
  2441. function MuteToggle(player, options) {
  2442. _classCallCheck(this, MuteToggle);
  2443. var _this = _possibleConstructorReturn(this, _Button.call(this, player, options));
  2444. _this.on(player, 'volumechange', _this.update);
  2445. // hide mute toggle if the current tech doesn't support volume control
  2446. if (player.tech_ && player.tech_.featuresVolumeControl === false) {
  2447. _this.addClass('vjs-hidden');
  2448. }
  2449. _this.on(player, 'loadstart', function () {
  2450. // We need to update the button to account for a default muted state.
  2451. this.update();
  2452. if (player.tech_.featuresVolumeControl === false) {
  2453. this.addClass('vjs-hidden');
  2454. } else {
  2455. this.removeClass('vjs-hidden');
  2456. }
  2457. });
  2458. return _this;
  2459. }
  2460. /**
  2461. * Builds the default DOM `className`.
  2462. *
  2463. * @return {string}
  2464. * The DOM `className` for this object.
  2465. */
  2466. MuteToggle.prototype.buildCSSClass = function buildCSSClass() {
  2467. return 'vjs-mute-control ' + _Button.prototype.buildCSSClass.call(this);
  2468. };
  2469. /**
  2470. * This gets called when an `MuteToggle` is "clicked". See
  2471. * {@link ClickableComponent} for more detailed information on what a click can be.
  2472. *
  2473. * @param {EventTarget~Event} [event]
  2474. * The `keydown`, `tap`, or `click` event that caused this function to be
  2475. * called.
  2476. *
  2477. * @listens tap
  2478. * @listens click
  2479. */
  2480. MuteToggle.prototype.handleClick = function handleClick(event) {
  2481. this.player_.muted(this.player_.muted() ? false : true);
  2482. };
  2483. /**
  2484. * Update the state of volume.
  2485. *
  2486. * @param {EventTarget~Event} [event]
  2487. * The {@link Player#loadstart} event if this function was called through an
  2488. * event.
  2489. *
  2490. * @listens Player#loadstart
  2491. */
  2492. MuteToggle.prototype.update = function update(event) {
  2493. var vol = this.player_.volume();
  2494. var level = 3;
  2495. if (vol === 0 || this.player_.muted()) {
  2496. level = 0;
  2497. } else if (vol < 0.33) {
  2498. level = 1;
  2499. } else if (vol < 0.67) {
  2500. level = 2;
  2501. }
  2502. // Don't rewrite the button text if the actual text doesn't change.
  2503. // This causes unnecessary and confusing information for screen reader users.
  2504. // This check is needed because this function gets called every time the volume level is changed.
  2505. var toMute = this.player_.muted() ? 'Unmute' : 'Mute';
  2506. if (this.controlText() !== toMute) {
  2507. this.controlText(toMute);
  2508. }
  2509. // TODO improve muted icon classes
  2510. for (var i = 0; i < 4; i++) {
  2511. Dom.removeElClass(this.el_, 'vjs-vol-' + i);
  2512. }
  2513. Dom.addElClass(this.el_, 'vjs-vol-' + level);
  2514. };
  2515. return MuteToggle;
  2516. }(_button2['default']);
  2517. /**
  2518. * The text that should display over the `MuteToggle`s controls. Added for localization.
  2519. *
  2520. * @type {string}
  2521. * @private
  2522. */
  2523. MuteToggle.prototype.controlText_ = 'Mute';
  2524. _component2['default'].registerComponent('MuteToggle', MuteToggle);
  2525. exports['default'] = MuteToggle;
  2526. },{"2":2,"5":5,"81":81}],12:[function(_dereq_,module,exports){
  2527. 'use strict';
  2528. exports.__esModule = true;
  2529. var _button = _dereq_(2);
  2530. var _button2 = _interopRequireDefault(_button);
  2531. var _component = _dereq_(5);
  2532. var _component2 = _interopRequireDefault(_component);
  2533. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  2534. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  2535. 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; }
  2536. 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; } /**
  2537. * @file play-toggle.js
  2538. */
  2539. /**
  2540. * Button to toggle between play and pause.
  2541. *
  2542. * @extends Button
  2543. */
  2544. var PlayToggle = function (_Button) {
  2545. _inherits(PlayToggle, _Button);
  2546. /**
  2547. * Creates an instance of this class.
  2548. *
  2549. * @param {Player} player
  2550. * The `Player` that this class should be attached to.
  2551. *
  2552. * @param {Object} [options]
  2553. * The key/value store of player options.
  2554. */
  2555. function PlayToggle(player, options) {
  2556. _classCallCheck(this, PlayToggle);
  2557. var _this = _possibleConstructorReturn(this, _Button.call(this, player, options));
  2558. _this.on(player, 'play', _this.handlePlay);
  2559. _this.on(player, 'pause', _this.handlePause);
  2560. return _this;
  2561. }
  2562. /**
  2563. * Builds the default DOM `className`.
  2564. *
  2565. * @return {string}
  2566. * The DOM `className` for this object.
  2567. */
  2568. PlayToggle.prototype.buildCSSClass = function buildCSSClass() {
  2569. return 'vjs-play-control ' + _Button.prototype.buildCSSClass.call(this);
  2570. };
  2571. /**
  2572. * This gets called when an `PlayToggle` is "clicked". See
  2573. * {@link ClickableComponent} for more detailed information on what a click can be.
  2574. *
  2575. * @param {EventTarget~Event} [event]
  2576. * The `keydown`, `tap`, or `click` event that caused this function to be
  2577. * called.
  2578. *
  2579. * @listens tap
  2580. * @listens click
  2581. */
  2582. PlayToggle.prototype.handleClick = function handleClick(event) {
  2583. if (this.player_.paused()) {
  2584. this.player_.play();
  2585. } else {
  2586. this.player_.pause();
  2587. }
  2588. };
  2589. /**
  2590. * Add the vjs-playing class to the element so it can change appearance.
  2591. *
  2592. * @param {EventTarget~Event} [event]
  2593. * The event that caused this function to run.
  2594. *
  2595. * @listens Player#play
  2596. */
  2597. PlayToggle.prototype.handlePlay = function handlePlay(event) {
  2598. this.removeClass('vjs-paused');
  2599. this.addClass('vjs-playing');
  2600. // change the button text to "Pause"
  2601. this.controlText('Pause');
  2602. };
  2603. /**
  2604. * Add the vjs-paused class to the element so it can change appearance.
  2605. *
  2606. * @param {EventTarget~Event} [event]
  2607. * The event that caused this function to run.
  2608. *
  2609. * @listens Player#pause
  2610. */
  2611. PlayToggle.prototype.handlePause = function handlePause(event) {
  2612. this.removeClass('vjs-playing');
  2613. this.addClass('vjs-paused');
  2614. // change the button text to "Play"
  2615. this.controlText('Play');
  2616. };
  2617. return PlayToggle;
  2618. }(_button2['default']);
  2619. /**
  2620. * The text that should display over the `PlayToggle`s controls. Added for localization.
  2621. *
  2622. * @type {string}
  2623. * @private
  2624. */
  2625. PlayToggle.prototype.controlText_ = 'Play';
  2626. _component2['default'].registerComponent('PlayToggle', PlayToggle);
  2627. exports['default'] = PlayToggle;
  2628. },{"2":2,"5":5}],13:[function(_dereq_,module,exports){
  2629. 'use strict';
  2630. exports.__esModule = true;
  2631. var _menuButton = _dereq_(47);
  2632. var _menuButton2 = _interopRequireDefault(_menuButton);
  2633. var _menu = _dereq_(49);
  2634. var _menu2 = _interopRequireDefault(_menu);
  2635. var _playbackRateMenuItem = _dereq_(14);
  2636. var _playbackRateMenuItem2 = _interopRequireDefault(_playbackRateMenuItem);
  2637. var _component = _dereq_(5);
  2638. var _component2 = _interopRequireDefault(_component);
  2639. var _dom = _dereq_(81);
  2640. var Dom = _interopRequireWildcard(_dom);
  2641. 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; } }
  2642. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  2643. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  2644. 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; }
  2645. 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; } /**
  2646. * @file playback-rate-menu-button.js
  2647. */
  2648. /**
  2649. * The component for controlling the playback rate.
  2650. *
  2651. * @extends MenuButton
  2652. */
  2653. var PlaybackRateMenuButton = function (_MenuButton) {
  2654. _inherits(PlaybackRateMenuButton, _MenuButton);
  2655. /**
  2656. * Creates an instance of this class.
  2657. *
  2658. * @param {Player} player
  2659. * The `Player` that this class should be attached to.
  2660. *
  2661. * @param {Object} [options]
  2662. * The key/value store of player options.
  2663. */
  2664. function PlaybackRateMenuButton(player, options) {
  2665. _classCallCheck(this, PlaybackRateMenuButton);
  2666. var _this = _possibleConstructorReturn(this, _MenuButton.call(this, player, options));
  2667. _this.updateVisibility();
  2668. _this.updateLabel();
  2669. _this.on(player, 'loadstart', _this.updateVisibility);
  2670. _this.on(player, 'ratechange', _this.updateLabel);
  2671. return _this;
  2672. }
  2673. /**
  2674. * Create the `Component`'s DOM element
  2675. *
  2676. * @return {Element}
  2677. * The element that was created.
  2678. */
  2679. PlaybackRateMenuButton.prototype.createEl = function createEl() {
  2680. var el = _MenuButton.prototype.createEl.call(this);
  2681. this.labelEl_ = Dom.createEl('div', {
  2682. className: 'vjs-playback-rate-value',
  2683. innerHTML: 1.0
  2684. });
  2685. el.appendChild(this.labelEl_);
  2686. return el;
  2687. };
  2688. /**
  2689. * Builds the default DOM `className`.
  2690. *
  2691. * @return {string}
  2692. * The DOM `className` for this object.
  2693. */
  2694. PlaybackRateMenuButton.prototype.buildCSSClass = function buildCSSClass() {
  2695. return 'vjs-playback-rate ' + _MenuButton.prototype.buildCSSClass.call(this);
  2696. };
  2697. /**
  2698. * Create the playback rate menu
  2699. *
  2700. * @return {Menu}
  2701. * Menu object populated with {@link PlaybackRateMenuItem}s
  2702. */
  2703. PlaybackRateMenuButton.prototype.createMenu = function createMenu() {
  2704. var menu = new _menu2['default'](this.player());
  2705. var rates = this.playbackRates();
  2706. if (rates) {
  2707. for (var i = rates.length - 1; i >= 0; i--) {
  2708. menu.addChild(new _playbackRateMenuItem2['default'](this.player(), { rate: rates[i] + 'x' }));
  2709. }
  2710. }
  2711. return menu;
  2712. };
  2713. /**
  2714. * Updates ARIA accessibility attributes
  2715. */
  2716. PlaybackRateMenuButton.prototype.updateARIAAttributes = function updateARIAAttributes() {
  2717. // Current playback rate
  2718. this.el().setAttribute('aria-valuenow', this.player().playbackRate());
  2719. };
  2720. /**
  2721. * This gets called when an `PlaybackRateMenuButton` is "clicked". See
  2722. * {@link ClickableComponent} for more detailed information on what a click can be.
  2723. *
  2724. * @param {EventTarget~Event} [event]
  2725. * The `keydown`, `tap`, or `click` event that caused this function to be
  2726. * called.
  2727. *
  2728. * @listens tap
  2729. * @listens click
  2730. */
  2731. PlaybackRateMenuButton.prototype.handleClick = function handleClick(event) {
  2732. // select next rate option
  2733. var currentRate = this.player().playbackRate();
  2734. var rates = this.playbackRates();
  2735. // this will select first one if the last one currently selected
  2736. var newRate = rates[0];
  2737. for (var i = 0; i < rates.length; i++) {
  2738. if (rates[i] > currentRate) {
  2739. newRate = rates[i];
  2740. break;
  2741. }
  2742. }
  2743. this.player().playbackRate(newRate);
  2744. };
  2745. /**
  2746. * Get possible playback rates
  2747. *
  2748. * @return {Array}
  2749. * All possible playback rates
  2750. */
  2751. PlaybackRateMenuButton.prototype.playbackRates = function playbackRates() {
  2752. return this.options_.playbackRates || this.options_.playerOptions && this.options_.playerOptions.playbackRates;
  2753. };
  2754. /**
  2755. * Get whether playback rates is supported by the tech
  2756. * and an array of playback rates exists
  2757. *
  2758. * @return {boolean}
  2759. * Whether changing playback rate is supported
  2760. */
  2761. PlaybackRateMenuButton.prototype.playbackRateSupported = function playbackRateSupported() {
  2762. return this.player().tech_ && this.player().tech_.featuresPlaybackRate && this.playbackRates() && this.playbackRates().length > 0;
  2763. };
  2764. /**
  2765. * Hide playback rate controls when they're no playback rate options to select
  2766. *
  2767. * @param {EventTarget~Event} [event]
  2768. * The event that caused this function to run.
  2769. *
  2770. * @listens Player#loadstart
  2771. */
  2772. PlaybackRateMenuButton.prototype.updateVisibility = function updateVisibility(event) {
  2773. if (this.playbackRateSupported()) {
  2774. this.removeClass('vjs-hidden');
  2775. } else {
  2776. this.addClass('vjs-hidden');
  2777. }
  2778. };
  2779. /**
  2780. * Update button label when rate changed
  2781. *
  2782. * @param {EventTarget~Event} [event]
  2783. * The event that caused this function to run.
  2784. *
  2785. * @listens Player#ratechange
  2786. */
  2787. PlaybackRateMenuButton.prototype.updateLabel = function updateLabel(event) {
  2788. if (this.playbackRateSupported()) {
  2789. this.labelEl_.innerHTML = this.player().playbackRate() + 'x';
  2790. }
  2791. };
  2792. return PlaybackRateMenuButton;
  2793. }(_menuButton2['default']);
  2794. /**
  2795. * The text that should display over the `FullscreenToggle`s controls. Added for localization.
  2796. *
  2797. * @type {string}
  2798. * @private
  2799. */
  2800. PlaybackRateMenuButton.prototype.controlText_ = 'Playback Rate';
  2801. _component2['default'].registerComponent('PlaybackRateMenuButton', PlaybackRateMenuButton);
  2802. exports['default'] = PlaybackRateMenuButton;
  2803. },{"14":14,"47":47,"49":49,"5":5,"81":81}],14:[function(_dereq_,module,exports){
  2804. 'use strict';
  2805. exports.__esModule = true;
  2806. var _menuItem = _dereq_(48);
  2807. var _menuItem2 = _interopRequireDefault(_menuItem);
  2808. var _component = _dereq_(5);
  2809. var _component2 = _interopRequireDefault(_component);
  2810. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  2811. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  2812. 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; }
  2813. 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; } /**
  2814. * @file playback-rate-menu-item.js
  2815. */
  2816. /**
  2817. * The specific menu item type for selecting a playback rate.
  2818. *
  2819. * @extends MenuItem
  2820. */
  2821. var PlaybackRateMenuItem = function (_MenuItem) {
  2822. _inherits(PlaybackRateMenuItem, _MenuItem);
  2823. /**
  2824. * Creates an instance of this class.
  2825. *
  2826. * @param {Player} player
  2827. * The `Player` that this class should be attached to.
  2828. *
  2829. * @param {Object} [options]
  2830. * The key/value store of player options.
  2831. */
  2832. function PlaybackRateMenuItem(player, options) {
  2833. _classCallCheck(this, PlaybackRateMenuItem);
  2834. var label = options.rate;
  2835. var rate = parseFloat(label, 10);
  2836. // Modify options for parent MenuItem class's init.
  2837. options.label = label;
  2838. options.selected = rate === 1;
  2839. var _this = _possibleConstructorReturn(this, _MenuItem.call(this, player, options));
  2840. _this.label = label;
  2841. _this.rate = rate;
  2842. _this.on(player, 'ratechange', _this.update);
  2843. return _this;
  2844. }
  2845. /**
  2846. * This gets called when an `PlaybackRateMenuItem` is "clicked". See
  2847. * {@link ClickableComponent} for more detailed information on what a click can be.
  2848. *
  2849. * @param {EventTarget~Event} [event]
  2850. * The `keydown`, `tap`, or `click` event that caused this function to be
  2851. * called.
  2852. *
  2853. * @listens tap
  2854. * @listens click
  2855. */
  2856. PlaybackRateMenuItem.prototype.handleClick = function handleClick(event) {
  2857. _MenuItem.prototype.handleClick.call(this);
  2858. this.player().playbackRate(this.rate);
  2859. };
  2860. /**
  2861. * Update the PlaybackRateMenuItem when the playbackrate changes.
  2862. *
  2863. * @param {EventTarget~Event} [event]
  2864. * The `ratechange` event that caused this function to run.
  2865. *
  2866. * @listens Player#ratechange
  2867. */
  2868. PlaybackRateMenuItem.prototype.update = function update(event) {
  2869. this.selected(this.player().playbackRate() === this.rate);
  2870. };
  2871. return PlaybackRateMenuItem;
  2872. }(_menuItem2['default']);
  2873. /**
  2874. * The text that should display over the `PlaybackRateMenuItem`s controls. Added for localization.
  2875. *
  2876. * @type {string}
  2877. * @private
  2878. */
  2879. PlaybackRateMenuItem.prototype.contentElType = 'button';
  2880. _component2['default'].registerComponent('PlaybackRateMenuItem', PlaybackRateMenuItem);
  2881. exports['default'] = PlaybackRateMenuItem;
  2882. },{"48":48,"5":5}],15:[function(_dereq_,module,exports){
  2883. 'use strict';
  2884. exports.__esModule = true;
  2885. var _component = _dereq_(5);
  2886. var _component2 = _interopRequireDefault(_component);
  2887. var _dom = _dereq_(81);
  2888. var Dom = _interopRequireWildcard(_dom);
  2889. 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; } }
  2890. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  2891. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  2892. 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; }
  2893. 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; } /**
  2894. * @file load-progress-bar.js
  2895. */
  2896. /**
  2897. * Shows loading progress
  2898. *
  2899. * @extends Component
  2900. */
  2901. var LoadProgressBar = function (_Component) {
  2902. _inherits(LoadProgressBar, _Component);
  2903. /**
  2904. * Creates an instance of this class.
  2905. *
  2906. * @param {Player} player
  2907. * The `Player` that this class should be attached to.
  2908. *
  2909. * @param {Object} [options]
  2910. * The key/value store of player options.
  2911. */
  2912. function LoadProgressBar(player, options) {
  2913. _classCallCheck(this, LoadProgressBar);
  2914. var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
  2915. _this.partEls_ = [];
  2916. _this.on(player, 'progress', _this.update);
  2917. return _this;
  2918. }
  2919. /**
  2920. * Create the `Component`'s DOM element
  2921. *
  2922. * @return {Element}
  2923. * The element that was created.
  2924. */
  2925. LoadProgressBar.prototype.createEl = function createEl() {
  2926. return _Component.prototype.createEl.call(this, 'div', {
  2927. className: 'vjs-load-progress',
  2928. innerHTML: '<span class="vjs-control-text"><span>' + this.localize('Loaded') + '</span>: 0%</span>'
  2929. });
  2930. };
  2931. /**
  2932. * Update progress bar
  2933. *
  2934. * @param {EventTarget~Event} [event]
  2935. * The `progress` event that caused this function to run.
  2936. *
  2937. * @listens Player#progress
  2938. */
  2939. LoadProgressBar.prototype.update = function update(event) {
  2940. var buffered = this.player_.buffered();
  2941. var duration = this.player_.duration();
  2942. var bufferedEnd = this.player_.bufferedEnd();
  2943. var children = this.partEls_;
  2944. // get the percent width of a time compared to the total end
  2945. var percentify = function percentify(time, end) {
  2946. // no NaN
  2947. var percent = time / end || 0;
  2948. return (percent >= 1 ? 1 : percent) * 100 + '%';
  2949. };
  2950. // update the width of the progress bar
  2951. this.el_.style.width = percentify(bufferedEnd, duration);
  2952. // add child elements to represent the individual buffered time ranges
  2953. for (var i = 0; i < buffered.length; i++) {
  2954. var start = buffered.start(i);
  2955. var end = buffered.end(i);
  2956. var part = children[i];
  2957. if (!part) {
  2958. part = this.el_.appendChild(Dom.createEl());
  2959. children[i] = part;
  2960. }
  2961. // set the percent based on the width of the progress bar (bufferedEnd)
  2962. part.style.left = percentify(start, bufferedEnd);
  2963. part.style.width = percentify(end - start, bufferedEnd);
  2964. }
  2965. // remove unused buffered range elements
  2966. for (var _i = children.length; _i > buffered.length; _i--) {
  2967. this.el_.removeChild(children[_i - 1]);
  2968. }
  2969. children.length = buffered.length;
  2970. };
  2971. return LoadProgressBar;
  2972. }(_component2['default']);
  2973. _component2['default'].registerComponent('LoadProgressBar', LoadProgressBar);
  2974. exports['default'] = LoadProgressBar;
  2975. },{"5":5,"81":81}],16:[function(_dereq_,module,exports){
  2976. 'use strict';
  2977. exports.__esModule = true;
  2978. var _component = _dereq_(5);
  2979. var _component2 = _interopRequireDefault(_component);
  2980. var _dom = _dereq_(81);
  2981. var Dom = _interopRequireWildcard(_dom);
  2982. var _fn = _dereq_(83);
  2983. var Fn = _interopRequireWildcard(_fn);
  2984. var _formatTime = _dereq_(84);
  2985. var _formatTime2 = _interopRequireDefault(_formatTime);
  2986. var _computedStyle = _dereq_(80);
  2987. var _computedStyle2 = _interopRequireDefault(_computedStyle);
  2988. 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; } }
  2989. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  2990. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  2991. 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; }
  2992. 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; } /**
  2993. * @file mouse-time-display.js
  2994. */
  2995. /**
  2996. * The Mouse Time Display component shows the time you will seek to
  2997. * when hovering over the progress bar
  2998. *
  2999. * @extends Component
  3000. */
  3001. var MouseTimeDisplay = function (_Component) {
  3002. _inherits(MouseTimeDisplay, _Component);
  3003. /**
  3004. * Creates an instance of this class.
  3005. *
  3006. * @param {Player} player
  3007. * The `Player` that this class should be attached to.
  3008. *
  3009. * @param {Object} [options]
  3010. * The key/value store of player options.
  3011. */
  3012. function MouseTimeDisplay(player, options) {
  3013. _classCallCheck(this, MouseTimeDisplay);
  3014. var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
  3015. if (options.playerOptions && options.playerOptions.controlBar && options.playerOptions.controlBar.progressControl && options.playerOptions.controlBar.progressControl.keepTooltipsInside) {
  3016. _this.keepTooltipsInside = options.playerOptions.controlBar.progressControl.keepTooltipsInside;
  3017. }
  3018. if (_this.keepTooltipsInside) {
  3019. _this.tooltip = Dom.createEl('div', { className: 'vjs-time-tooltip' });
  3020. _this.el().appendChild(_this.tooltip);
  3021. _this.addClass('vjs-keep-tooltips-inside');
  3022. }
  3023. _this.update(0, 0);
  3024. player.on('ready', function () {
  3025. _this.on(player.controlBar.progressControl.el(), 'mousemove', Fn.throttle(Fn.bind(_this, _this.handleMouseMove), 25));
  3026. });
  3027. return _this;
  3028. }
  3029. /**
  3030. * Create the `Component`'s DOM element
  3031. *
  3032. * @return {Element}
  3033. * The element that was created.
  3034. */
  3035. MouseTimeDisplay.prototype.createEl = function createEl() {
  3036. return _Component.prototype.createEl.call(this, 'div', {
  3037. className: 'vjs-mouse-display'
  3038. });
  3039. };
  3040. /**
  3041. * Handle the mouse move event on the `MouseTimeDisplay`.
  3042. *
  3043. * @param {EventTarget~Event} event
  3044. * The `mousemove` event that caused this to event to run.
  3045. *
  3046. * @listen mousemove
  3047. */
  3048. MouseTimeDisplay.prototype.handleMouseMove = function handleMouseMove(event) {
  3049. var duration = this.player_.duration();
  3050. var newTime = this.calculateDistance(event) * duration;
  3051. var position = event.pageX - Dom.findElPosition(this.el().parentNode).left;
  3052. this.update(newTime, position);
  3053. };
  3054. /**
  3055. * Update the time and posistion of the `MouseTimeDisplay`.
  3056. *
  3057. * @param {number} newTime
  3058. * Time to change the `MouseTimeDisplay` to.
  3059. *
  3060. * @param {nubmer} position
  3061. * Postion from the left of the in pixels.
  3062. */
  3063. MouseTimeDisplay.prototype.update = function update(newTime, position) {
  3064. var time = (0, _formatTime2['default'])(newTime, this.player_.duration());
  3065. this.el().style.left = position + 'px';
  3066. this.el().setAttribute('data-current-time', time);
  3067. if (this.keepTooltipsInside) {
  3068. var clampedPosition = this.clampPosition_(position);
  3069. var difference = position - clampedPosition + 1;
  3070. var tooltipWidth = parseFloat((0, _computedStyle2['default'])(this.tooltip, 'width'));
  3071. var tooltipWidthHalf = tooltipWidth / 2;
  3072. this.tooltip.innerHTML = time;
  3073. this.tooltip.style.right = '-' + (tooltipWidthHalf - difference) + 'px';
  3074. }
  3075. };
  3076. /**
  3077. * Get the mouse pointers x coordinate in pixels.
  3078. *
  3079. * @param {EventTarget~Event} [event]
  3080. * The `mousemove` event that was passed to this function by
  3081. * {@link MouseTimeDisplay#handleMouseMove}
  3082. *
  3083. * @return {number}
  3084. * THe x position in pixels of the mouse pointer.
  3085. */
  3086. MouseTimeDisplay.prototype.calculateDistance = function calculateDistance(event) {
  3087. return Dom.getPointerPosition(this.el().parentNode, event).x;
  3088. };
  3089. /**
  3090. * This takes in a horizontal position for the bar and returns a clamped position.
  3091. * Clamped position means that it will keep the position greater than half the width
  3092. * of the tooltip and smaller than the player width minus half the width o the tooltip.
  3093. * It will only clamp the position if `keepTooltipsInside` option is set.
  3094. *
  3095. * @param {number} position
  3096. * The position the bar wants to be
  3097. *
  3098. * @return {number}
  3099. * The (potentially) new clamped position.
  3100. *
  3101. * @private
  3102. */
  3103. MouseTimeDisplay.prototype.clampPosition_ = function clampPosition_(position) {
  3104. if (!this.keepTooltipsInside) {
  3105. return position;
  3106. }
  3107. var playerWidth = parseFloat((0, _computedStyle2['default'])(this.player().el(), 'width'));
  3108. var tooltipWidth = parseFloat((0, _computedStyle2['default'])(this.tooltip, 'width'));
  3109. var tooltipWidthHalf = tooltipWidth / 2;
  3110. var actualPosition = position;
  3111. if (position < tooltipWidthHalf) {
  3112. actualPosition = Math.ceil(tooltipWidthHalf);
  3113. } else if (position > playerWidth - tooltipWidthHalf) {
  3114. actualPosition = Math.floor(playerWidth - tooltipWidthHalf);
  3115. }
  3116. return actualPosition;
  3117. };
  3118. return MouseTimeDisplay;
  3119. }(_component2['default']);
  3120. _component2['default'].registerComponent('MouseTimeDisplay', MouseTimeDisplay);
  3121. exports['default'] = MouseTimeDisplay;
  3122. },{"5":5,"80":80,"81":81,"83":83,"84":84}],17:[function(_dereq_,module,exports){
  3123. 'use strict';
  3124. exports.__esModule = true;
  3125. var _component = _dereq_(5);
  3126. var _component2 = _interopRequireDefault(_component);
  3127. var _fn = _dereq_(83);
  3128. var Fn = _interopRequireWildcard(_fn);
  3129. var _formatTime = _dereq_(84);
  3130. var _formatTime2 = _interopRequireDefault(_formatTime);
  3131. 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; } }
  3132. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  3133. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  3134. 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; }
  3135. 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; } /**
  3136. * @file play-progress-bar.js
  3137. */
  3138. /**
  3139. * Shows play progress
  3140. *
  3141. * @extends Component
  3142. */
  3143. var PlayProgressBar = function (_Component) {
  3144. _inherits(PlayProgressBar, _Component);
  3145. /**
  3146. * Creates an instance of this class.
  3147. *
  3148. * @param {Player} player
  3149. * The `Player` that this class should be attached to.
  3150. *
  3151. * @param {Object} [options]
  3152. * The key/value store of player options.
  3153. */
  3154. function PlayProgressBar(player, options) {
  3155. _classCallCheck(this, PlayProgressBar);
  3156. var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
  3157. _this.updateDataAttr();
  3158. _this.on(player, 'timeupdate', _this.updateDataAttr);
  3159. player.ready(Fn.bind(_this, _this.updateDataAttr));
  3160. if (options.playerOptions && options.playerOptions.controlBar && options.playerOptions.controlBar.progressControl && options.playerOptions.controlBar.progressControl.keepTooltipsInside) {
  3161. _this.keepTooltipsInside = options.playerOptions.controlBar.progressControl.keepTooltipsInside;
  3162. }
  3163. if (_this.keepTooltipsInside) {
  3164. _this.addClass('vjs-keep-tooltips-inside');
  3165. }
  3166. return _this;
  3167. }
  3168. /**
  3169. * Create the `Component`'s DOM element
  3170. *
  3171. * @return {Element}
  3172. * The element that was created.
  3173. */
  3174. PlayProgressBar.prototype.createEl = function createEl() {
  3175. return _Component.prototype.createEl.call(this, 'div', {
  3176. className: 'vjs-play-progress vjs-slider-bar',
  3177. innerHTML: '<span class="vjs-control-text"><span>' + this.localize('Progress') + '</span>: 0%</span>'
  3178. });
  3179. };
  3180. /**
  3181. * Update the data-current-time attribute on the `PlayProgressBar`.
  3182. *
  3183. * @param {EventTarget~Event} [event]
  3184. * The `timeupdate` event that caused this to run.
  3185. *
  3186. * @listens Player#timeupdate
  3187. */
  3188. PlayProgressBar.prototype.updateDataAttr = function updateDataAttr(event) {
  3189. var time = this.player_.scrubbing() ? this.player_.getCache().currentTime : this.player_.currentTime();
  3190. this.el_.setAttribute('data-current-time', (0, _formatTime2['default'])(time, this.player_.duration()));
  3191. };
  3192. return PlayProgressBar;
  3193. }(_component2['default']);
  3194. _component2['default'].registerComponent('PlayProgressBar', PlayProgressBar);
  3195. exports['default'] = PlayProgressBar;
  3196. },{"5":5,"83":83,"84":84}],18:[function(_dereq_,module,exports){
  3197. 'use strict';
  3198. exports.__esModule = true;
  3199. var _component = _dereq_(5);
  3200. var _component2 = _interopRequireDefault(_component);
  3201. _dereq_(19);
  3202. _dereq_(16);
  3203. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  3204. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  3205. 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; }
  3206. 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; } /**
  3207. * @file progress-control.js
  3208. */
  3209. /**
  3210. * The Progress Control component contains the seek bar, load progress,
  3211. * and play progress.
  3212. *
  3213. * @extends Component
  3214. */
  3215. var ProgressControl = function (_Component) {
  3216. _inherits(ProgressControl, _Component);
  3217. function ProgressControl() {
  3218. _classCallCheck(this, ProgressControl);
  3219. return _possibleConstructorReturn(this, _Component.apply(this, arguments));
  3220. }
  3221. /**
  3222. * Create the `Component`'s DOM element
  3223. *
  3224. * @return {Element}
  3225. * The element that was created.
  3226. */
  3227. ProgressControl.prototype.createEl = function createEl() {
  3228. return _Component.prototype.createEl.call(this, 'div', {
  3229. className: 'vjs-progress-control vjs-control'
  3230. });
  3231. };
  3232. return ProgressControl;
  3233. }(_component2['default']);
  3234. /**
  3235. * Default options for `ProgressControl`
  3236. *
  3237. * @type {Object}
  3238. * @private
  3239. */
  3240. ProgressControl.prototype.options_ = {
  3241. children: ['seekBar']
  3242. };
  3243. _component2['default'].registerComponent('ProgressControl', ProgressControl);
  3244. exports['default'] = ProgressControl;
  3245. },{"16":16,"19":19,"5":5}],19:[function(_dereq_,module,exports){
  3246. 'use strict';
  3247. exports.__esModule = true;
  3248. var _slider = _dereq_(57);
  3249. var _slider2 = _interopRequireDefault(_slider);
  3250. var _component = _dereq_(5);
  3251. var _component2 = _interopRequireDefault(_component);
  3252. var _fn = _dereq_(83);
  3253. var Fn = _interopRequireWildcard(_fn);
  3254. var _formatTime = _dereq_(84);
  3255. var _formatTime2 = _interopRequireDefault(_formatTime);
  3256. var _computedStyle = _dereq_(80);
  3257. var _computedStyle2 = _interopRequireDefault(_computedStyle);
  3258. _dereq_(15);
  3259. _dereq_(17);
  3260. _dereq_(20);
  3261. 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; } }
  3262. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  3263. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  3264. 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; }
  3265. 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; } /**
  3266. * @file seek-bar.js
  3267. */
  3268. /**
  3269. * Seek Bar and holder for the progress bars
  3270. *
  3271. * @extends Slider
  3272. */
  3273. var SeekBar = function (_Slider) {
  3274. _inherits(SeekBar, _Slider);
  3275. /**
  3276. * Creates an instance of this class.
  3277. *
  3278. * @param {Player} player
  3279. * The `Player` that this class should be attached to.
  3280. *
  3281. * @param {Object} [options]
  3282. * The key/value store of player options.
  3283. */
  3284. function SeekBar(player, options) {
  3285. _classCallCheck(this, SeekBar);
  3286. var _this = _possibleConstructorReturn(this, _Slider.call(this, player, options));
  3287. _this.on(player, 'timeupdate', _this.updateProgress);
  3288. _this.on(player, 'ended', _this.updateProgress);
  3289. player.ready(Fn.bind(_this, _this.updateProgress));
  3290. if (options.playerOptions && options.playerOptions.controlBar && options.playerOptions.controlBar.progressControl && options.playerOptions.controlBar.progressControl.keepTooltipsInside) {
  3291. _this.keepTooltipsInside = options.playerOptions.controlBar.progressControl.keepTooltipsInside;
  3292. }
  3293. if (_this.keepTooltipsInside) {
  3294. _this.tooltipProgressBar = _this.addChild('TooltipProgressBar');
  3295. }
  3296. return _this;
  3297. }
  3298. /**
  3299. * Create the `Component`'s DOM element
  3300. *
  3301. * @return {Element}
  3302. * The element that was created.
  3303. */
  3304. SeekBar.prototype.createEl = function createEl() {
  3305. return _Slider.prototype.createEl.call(this, 'div', {
  3306. className: 'vjs-progress-holder'
  3307. }, {
  3308. 'aria-label': 'progress bar'
  3309. });
  3310. };
  3311. /**
  3312. * Update the seek bars tooltip and width.
  3313. *
  3314. * @param {EventTarget~Event} [event]
  3315. * The `timeupdate` or `ended` event that caused this to run.
  3316. *
  3317. * @listens Player#timeupdate
  3318. * @listens Player#ended
  3319. */
  3320. SeekBar.prototype.updateProgress = function updateProgress(event) {
  3321. this.updateAriaAttributes(this.el_);
  3322. if (this.keepTooltipsInside) {
  3323. this.updateAriaAttributes(this.tooltipProgressBar.el_);
  3324. this.tooltipProgressBar.el_.style.width = this.bar.el_.style.width;
  3325. var playerWidth = parseFloat((0, _computedStyle2['default'])(this.player().el(), 'width'));
  3326. var tooltipWidth = parseFloat((0, _computedStyle2['default'])(this.tooltipProgressBar.tooltip, 'width'));
  3327. var tooltipStyle = this.tooltipProgressBar.el().style;
  3328. tooltipStyle.maxWidth = Math.floor(playerWidth - tooltipWidth / 2) + 'px';
  3329. tooltipStyle.minWidth = Math.ceil(tooltipWidth / 2) + 'px';
  3330. tooltipStyle.right = '-' + tooltipWidth / 2 + 'px';
  3331. }
  3332. };
  3333. /**
  3334. * Update ARIA accessibility attributes
  3335. *
  3336. * @param {Element} el
  3337. * The element to update with aria accessibility attributes.
  3338. */
  3339. SeekBar.prototype.updateAriaAttributes = function updateAriaAttributes(el) {
  3340. // Allows for smooth scrubbing, when player can't keep up.
  3341. var time = this.player_.scrubbing() ? this.player_.getCache().currentTime : this.player_.currentTime();
  3342. // machine readable value of progress bar (percentage complete)
  3343. el.setAttribute('aria-valuenow', (this.getPercent() * 100).toFixed(2));
  3344. // human readable value of progress bar (time complete)
  3345. el.setAttribute('aria-valuetext', (0, _formatTime2['default'])(time, this.player_.duration()));
  3346. };
  3347. /**
  3348. * Get percentage of video played
  3349. *
  3350. * @return {number}
  3351. * The percentage played
  3352. */
  3353. SeekBar.prototype.getPercent = function getPercent() {
  3354. var percent = this.player_.currentTime() / this.player_.duration();
  3355. return percent >= 1 ? 1 : percent;
  3356. };
  3357. /**
  3358. * Handle mouse down on seek bar
  3359. *
  3360. * @param {EventTarget~Event} event
  3361. * The `mousedown` event that caused this to run.
  3362. *
  3363. * @listens mousedown
  3364. */
  3365. SeekBar.prototype.handleMouseDown = function handleMouseDown(event) {
  3366. this.player_.scrubbing(true);
  3367. this.videoWasPlaying = !this.player_.paused();
  3368. this.player_.pause();
  3369. _Slider.prototype.handleMouseDown.call(this, event);
  3370. };
  3371. /**
  3372. * Handle mouse move on seek bar
  3373. *
  3374. * @param {EventTarget~Event} event
  3375. * The `mousemove` event that caused this to run.
  3376. *
  3377. * @listens mousemove
  3378. */
  3379. SeekBar.prototype.handleMouseMove = function handleMouseMove(event) {
  3380. var newTime = this.calculateDistance(event) * this.player_.duration();
  3381. // Don't let video end while scrubbing.
  3382. if (newTime === this.player_.duration()) {
  3383. newTime = newTime - 0.1;
  3384. }
  3385. // Set new time (tell player to seek to new time)
  3386. this.player_.currentTime(newTime);
  3387. };
  3388. /**
  3389. * Handle mouse up on seek bar
  3390. *
  3391. * @param {EventTarget~Event} event
  3392. * The `mouseup` event that caused this to run.
  3393. *
  3394. * @listens mouseup
  3395. */
  3396. SeekBar.prototype.handleMouseUp = function handleMouseUp(event) {
  3397. _Slider.prototype.handleMouseUp.call(this, event);
  3398. this.player_.scrubbing(false);
  3399. if (this.videoWasPlaying) {
  3400. this.player_.play();
  3401. }
  3402. };
  3403. /**
  3404. * Move more quickly fast forward for keyboard-only users
  3405. */
  3406. SeekBar.prototype.stepForward = function stepForward() {
  3407. // more quickly fast forward for keyboard-only users
  3408. this.player_.currentTime(this.player_.currentTime() + 5);
  3409. };
  3410. /**
  3411. * Move more quickly rewind for keyboard-only users
  3412. */
  3413. SeekBar.prototype.stepBack = function stepBack() {
  3414. // more quickly rewind for keyboard-only users
  3415. this.player_.currentTime(this.player_.currentTime() - 5);
  3416. };
  3417. return SeekBar;
  3418. }(_slider2['default']);
  3419. /**
  3420. * Default options for the `SeekBar`
  3421. *
  3422. * @type {Object}
  3423. * @private
  3424. */
  3425. SeekBar.prototype.options_ = {
  3426. children: ['loadProgressBar', 'mouseTimeDisplay', 'playProgressBar'],
  3427. barName: 'playProgressBar'
  3428. };
  3429. /**
  3430. * Call the update event for this Slider when this event happens on the player.
  3431. *
  3432. * @type {string}
  3433. */
  3434. SeekBar.prototype.playerEvent = 'timeupdate';
  3435. _component2['default'].registerComponent('SeekBar', SeekBar);
  3436. exports['default'] = SeekBar;
  3437. },{"15":15,"17":17,"20":20,"5":5,"57":57,"80":80,"83":83,"84":84}],20:[function(_dereq_,module,exports){
  3438. 'use strict';
  3439. exports.__esModule = true;
  3440. var _component = _dereq_(5);
  3441. var _component2 = _interopRequireDefault(_component);
  3442. var _fn = _dereq_(83);
  3443. var Fn = _interopRequireWildcard(_fn);
  3444. var _formatTime = _dereq_(84);
  3445. var _formatTime2 = _interopRequireDefault(_formatTime);
  3446. 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; } }
  3447. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  3448. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  3449. 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; }
  3450. 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; } /**
  3451. * @file play-progress-bar.js
  3452. */
  3453. /**
  3454. * Shows play progress
  3455. *
  3456. * @extends Component
  3457. */
  3458. var TooltipProgressBar = function (_Component) {
  3459. _inherits(TooltipProgressBar, _Component);
  3460. /**
  3461. * Creates an instance of this class.
  3462. *
  3463. * @param {Player} player
  3464. * The `Player` that this class should be attached to.
  3465. *
  3466. * @param {Object} [options]
  3467. * The key/value store of player options.
  3468. */
  3469. function TooltipProgressBar(player, options) {
  3470. _classCallCheck(this, TooltipProgressBar);
  3471. var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
  3472. _this.updateDataAttr();
  3473. _this.on(player, 'timeupdate', _this.updateDataAttr);
  3474. player.ready(Fn.bind(_this, _this.updateDataAttr));
  3475. return _this;
  3476. }
  3477. /**
  3478. * Create the `Component`'s DOM element
  3479. *
  3480. * @return {Element}
  3481. * The element that was created.
  3482. */
  3483. TooltipProgressBar.prototype.createEl = function createEl() {
  3484. var el = _Component.prototype.createEl.call(this, 'div', {
  3485. className: 'vjs-tooltip-progress-bar vjs-slider-bar',
  3486. innerHTML: '<div class="vjs-time-tooltip"></div>\n <span class="vjs-control-text"><span>' + this.localize('Progress') + '</span>: 0%</span>'
  3487. });
  3488. this.tooltip = el.querySelector('.vjs-time-tooltip');
  3489. return el;
  3490. };
  3491. /**
  3492. * Updatet the data-current-time attribute for TooltipProgressBar
  3493. *
  3494. * @param {EventTarget~Event} [event]
  3495. * The `timeupdate` event that caused this function to run.
  3496. *
  3497. * @listens Player#timeupdate
  3498. */
  3499. TooltipProgressBar.prototype.updateDataAttr = function updateDataAttr(event) {
  3500. var time = this.player_.scrubbing() ? this.player_.getCache().currentTime : this.player_.currentTime();
  3501. var formattedTime = (0, _formatTime2['default'])(time, this.player_.duration());
  3502. this.el_.setAttribute('data-current-time', formattedTime);
  3503. this.tooltip.innerHTML = formattedTime;
  3504. };
  3505. return TooltipProgressBar;
  3506. }(_component2['default']);
  3507. _component2['default'].registerComponent('TooltipProgressBar', TooltipProgressBar);
  3508. exports['default'] = TooltipProgressBar;
  3509. },{"5":5,"83":83,"84":84}],21:[function(_dereq_,module,exports){
  3510. 'use strict';
  3511. exports.__esModule = true;
  3512. var _spacer = _dereq_(22);
  3513. var _spacer2 = _interopRequireDefault(_spacer);
  3514. var _component = _dereq_(5);
  3515. var _component2 = _interopRequireDefault(_component);
  3516. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  3517. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  3518. 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; }
  3519. 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; } /**
  3520. * @file custom-control-spacer.js
  3521. */
  3522. /**
  3523. * Spacer specifically meant to be used as an insertion point for new plugins, etc.
  3524. *
  3525. * @extends Spacer
  3526. */
  3527. var CustomControlSpacer = function (_Spacer) {
  3528. _inherits(CustomControlSpacer, _Spacer);
  3529. function CustomControlSpacer() {
  3530. _classCallCheck(this, CustomControlSpacer);
  3531. return _possibleConstructorReturn(this, _Spacer.apply(this, arguments));
  3532. }
  3533. /**
  3534. * Builds the default DOM `className`.
  3535. *
  3536. * @return {string}
  3537. * The DOM `className` for this object.
  3538. */
  3539. CustomControlSpacer.prototype.buildCSSClass = function buildCSSClass() {
  3540. return 'vjs-custom-control-spacer ' + _Spacer.prototype.buildCSSClass.call(this);
  3541. };
  3542. /**
  3543. * Create the `Component`'s DOM element
  3544. *
  3545. * @return {Element}
  3546. * The element that was created.
  3547. */
  3548. CustomControlSpacer.prototype.createEl = function createEl() {
  3549. var el = _Spacer.prototype.createEl.call(this, {
  3550. className: this.buildCSSClass()
  3551. });
  3552. // No-flex/table-cell mode requires there be some content
  3553. // in the cell to fill the remaining space of the table.
  3554. el.innerHTML = '&nbsp;';
  3555. return el;
  3556. };
  3557. return CustomControlSpacer;
  3558. }(_spacer2['default']);
  3559. _component2['default'].registerComponent('CustomControlSpacer', CustomControlSpacer);
  3560. exports['default'] = CustomControlSpacer;
  3561. },{"22":22,"5":5}],22:[function(_dereq_,module,exports){
  3562. 'use strict';
  3563. exports.__esModule = true;
  3564. var _component = _dereq_(5);
  3565. var _component2 = _interopRequireDefault(_component);
  3566. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  3567. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  3568. 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; }
  3569. 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; } /**
  3570. * @file spacer.js
  3571. */
  3572. /**
  3573. * Just an empty spacer element that can be used as an append point for plugins, etc.
  3574. * Also can be used to create space between elements when necessary.
  3575. *
  3576. * @extends Component
  3577. */
  3578. var Spacer = function (_Component) {
  3579. _inherits(Spacer, _Component);
  3580. function Spacer() {
  3581. _classCallCheck(this, Spacer);
  3582. return _possibleConstructorReturn(this, _Component.apply(this, arguments));
  3583. }
  3584. /**
  3585. * Builds the default DOM `className`.
  3586. *
  3587. * @return {string}
  3588. * The DOM `className` for this object.
  3589. */
  3590. Spacer.prototype.buildCSSClass = function buildCSSClass() {
  3591. return 'vjs-spacer ' + _Component.prototype.buildCSSClass.call(this);
  3592. };
  3593. /**
  3594. * Create the `Component`'s DOM element
  3595. *
  3596. * @return {Element}
  3597. * The element that was created.
  3598. */
  3599. Spacer.prototype.createEl = function createEl() {
  3600. return _Component.prototype.createEl.call(this, 'div', {
  3601. className: this.buildCSSClass()
  3602. });
  3603. };
  3604. return Spacer;
  3605. }(_component2['default']);
  3606. _component2['default'].registerComponent('Spacer', Spacer);
  3607. exports['default'] = Spacer;
  3608. },{"5":5}],23:[function(_dereq_,module,exports){
  3609. 'use strict';
  3610. exports.__esModule = true;
  3611. var _textTrackMenuItem = _dereq_(31);
  3612. var _textTrackMenuItem2 = _interopRequireDefault(_textTrackMenuItem);
  3613. var _component = _dereq_(5);
  3614. var _component2 = _interopRequireDefault(_component);
  3615. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  3616. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  3617. 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; }
  3618. 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; } /**
  3619. * @file caption-settings-menu-item.js
  3620. */
  3621. /**
  3622. * The menu item for caption track settings menu
  3623. *
  3624. * @extends TextTrackMenuItem
  3625. */
  3626. var CaptionSettingsMenuItem = function (_TextTrackMenuItem) {
  3627. _inherits(CaptionSettingsMenuItem, _TextTrackMenuItem);
  3628. /**
  3629. * Creates an instance of this class.
  3630. *
  3631. * @param {Player} player
  3632. * The `Player` that this class should be attached to.
  3633. *
  3634. * @param {Object} [options]
  3635. * The key/value store of player options.
  3636. */
  3637. function CaptionSettingsMenuItem(player, options) {
  3638. _classCallCheck(this, CaptionSettingsMenuItem);
  3639. options.track = {
  3640. player: player,
  3641. kind: options.kind,
  3642. label: options.kind + ' settings',
  3643. selectable: false,
  3644. 'default': false,
  3645. mode: 'disabled'
  3646. };
  3647. // CaptionSettingsMenuItem has no concept of 'selected'
  3648. options.selectable = false;
  3649. var _this = _possibleConstructorReturn(this, _TextTrackMenuItem.call(this, player, options));
  3650. _this.addClass('vjs-texttrack-settings');
  3651. _this.controlText(', opens ' + options.kind + ' settings dialog');
  3652. return _this;
  3653. }
  3654. /**
  3655. * This gets called when an `CaptionSettingsMenuItem` is "clicked". See
  3656. * {@link ClickableComponent} for more detailed information on what a click can be.
  3657. *
  3658. * @param {EventTarget~Event} [event]
  3659. * The `keydown`, `tap`, or `click` event that caused this function to be
  3660. * called.
  3661. *
  3662. * @listens tap
  3663. * @listens click
  3664. */
  3665. CaptionSettingsMenuItem.prototype.handleClick = function handleClick(event) {
  3666. this.player().getChild('textTrackSettings').show();
  3667. this.player().getChild('textTrackSettings').el_.focus();
  3668. };
  3669. return CaptionSettingsMenuItem;
  3670. }(_textTrackMenuItem2['default']);
  3671. _component2['default'].registerComponent('CaptionSettingsMenuItem', CaptionSettingsMenuItem);
  3672. exports['default'] = CaptionSettingsMenuItem;
  3673. },{"31":31,"5":5}],24:[function(_dereq_,module,exports){
  3674. 'use strict';
  3675. exports.__esModule = true;
  3676. var _textTrackButton = _dereq_(30);
  3677. var _textTrackButton2 = _interopRequireDefault(_textTrackButton);
  3678. var _component = _dereq_(5);
  3679. var _component2 = _interopRequireDefault(_component);
  3680. var _captionSettingsMenuItem = _dereq_(23);
  3681. var _captionSettingsMenuItem2 = _interopRequireDefault(_captionSettingsMenuItem);
  3682. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  3683. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  3684. 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; }
  3685. 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; } /**
  3686. * @file captions-button.js
  3687. */
  3688. /**
  3689. * The button component for toggling and selecting captions
  3690. *
  3691. * @extends TextTrackButton
  3692. */
  3693. var CaptionsButton = function (_TextTrackButton) {
  3694. _inherits(CaptionsButton, _TextTrackButton);
  3695. /**
  3696. * Creates an instance of this class.
  3697. *
  3698. * @param {Player} player
  3699. * The `Player` that this class should be attached to.
  3700. *
  3701. * @param {Object} [options]
  3702. * The key/value store of player options.
  3703. *
  3704. * @param {Component~ReadyCallback} [ready]
  3705. * The function to call when this component is ready.
  3706. */
  3707. function CaptionsButton(player, options, ready) {
  3708. _classCallCheck(this, CaptionsButton);
  3709. var _this = _possibleConstructorReturn(this, _TextTrackButton.call(this, player, options, ready));
  3710. _this.el_.setAttribute('aria-label', 'Captions Menu');
  3711. return _this;
  3712. }
  3713. /**
  3714. * Builds the default DOM `className`.
  3715. *
  3716. * @return {string}
  3717. * The DOM `className` for this object.
  3718. */
  3719. CaptionsButton.prototype.buildCSSClass = function buildCSSClass() {
  3720. return 'vjs-captions-button ' + _TextTrackButton.prototype.buildCSSClass.call(this);
  3721. };
  3722. /**
  3723. * Update caption menu items
  3724. *
  3725. * @param {EventTarget~Event} [event]
  3726. * The `addtrack` or `removetrack` event that caused this function to be
  3727. * called.
  3728. *
  3729. * @listens TextTrackList#addtrack
  3730. * @listens TextTrackList#removetrack
  3731. */
  3732. CaptionsButton.prototype.update = function update(event) {
  3733. var threshold = 2;
  3734. _TextTrackButton.prototype.update.call(this);
  3735. // if native, then threshold is 1 because no settings button
  3736. if (this.player().tech_ && this.player().tech_.featuresNativeTextTracks) {
  3737. threshold = 1;
  3738. }
  3739. if (this.items && this.items.length > threshold) {
  3740. this.show();
  3741. } else {
  3742. this.hide();
  3743. }
  3744. };
  3745. /**
  3746. * Create caption menu items
  3747. *
  3748. * @return {CaptionSettingsMenuItem[]}
  3749. * The array of current menu items.
  3750. */
  3751. CaptionsButton.prototype.createItems = function createItems() {
  3752. var items = [];
  3753. if (!(this.player().tech_ && this.player().tech_.featuresNativeTextTracks)) {
  3754. items.push(new _captionSettingsMenuItem2['default'](this.player_, { kind: this.kind_ }));
  3755. }
  3756. return _TextTrackButton.prototype.createItems.call(this, items);
  3757. };
  3758. return CaptionsButton;
  3759. }(_textTrackButton2['default']);
  3760. /**
  3761. * `kind` of TextTrack to look for to associate it with this menu.
  3762. *
  3763. * @type {string}
  3764. * @private
  3765. */
  3766. CaptionsButton.prototype.kind_ = 'captions';
  3767. /**
  3768. * The text that should display over the `CaptionsButton`s controls. Added for localization.
  3769. *
  3770. * @type {string}
  3771. * @private
  3772. */
  3773. CaptionsButton.prototype.controlText_ = 'Captions';
  3774. _component2['default'].registerComponent('CaptionsButton', CaptionsButton);
  3775. exports['default'] = CaptionsButton;
  3776. },{"23":23,"30":30,"5":5}],25:[function(_dereq_,module,exports){
  3777. 'use strict';
  3778. exports.__esModule = true;
  3779. var _textTrackButton = _dereq_(30);
  3780. var _textTrackButton2 = _interopRequireDefault(_textTrackButton);
  3781. var _component = _dereq_(5);
  3782. var _component2 = _interopRequireDefault(_component);
  3783. var _chaptersTrackMenuItem = _dereq_(26);
  3784. var _chaptersTrackMenuItem2 = _interopRequireDefault(_chaptersTrackMenuItem);
  3785. var _toTitleCase = _dereq_(91);
  3786. var _toTitleCase2 = _interopRequireDefault(_toTitleCase);
  3787. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  3788. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  3789. 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; }
  3790. 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; } /**
  3791. * @file chapters-button.js
  3792. */
  3793. /**
  3794. * The button component for toggling and selecting chapters
  3795. * Chapters act much differently than other text tracks
  3796. * Cues are navigation vs. other tracks of alternative languages
  3797. *
  3798. * @extends TextTrackButton
  3799. */
  3800. var ChaptersButton = function (_TextTrackButton) {
  3801. _inherits(ChaptersButton, _TextTrackButton);
  3802. /**
  3803. * Creates an instance of this class.
  3804. *
  3805. * @param {Player} player
  3806. * The `Player` that this class should be attached to.
  3807. *
  3808. * @param {Object} [options]
  3809. * The key/value store of player options.
  3810. *
  3811. * @param {Component~ReadyCallback} [ready]
  3812. * The function to call when this function is ready.
  3813. */
  3814. function ChaptersButton(player, options, ready) {
  3815. _classCallCheck(this, ChaptersButton);
  3816. var _this = _possibleConstructorReturn(this, _TextTrackButton.call(this, player, options, ready));
  3817. _this.el_.setAttribute('aria-label', 'Chapters Menu');
  3818. return _this;
  3819. }
  3820. /**
  3821. * Builds the default DOM `className`.
  3822. *
  3823. * @return {string}
  3824. * The DOM `className` for this object.
  3825. */
  3826. ChaptersButton.prototype.buildCSSClass = function buildCSSClass() {
  3827. return 'vjs-chapters-button ' + _TextTrackButton.prototype.buildCSSClass.call(this);
  3828. };
  3829. /**
  3830. * Update the menu based on the current state of its items.
  3831. *
  3832. * @param {EventTarget~Event} [event]
  3833. * An event that triggered this function to run.
  3834. *
  3835. * @listens TextTrackList#addtrack
  3836. * @listens TextTrackList#removetrack
  3837. * @listens TextTrackList#change
  3838. */
  3839. ChaptersButton.prototype.update = function update(event) {
  3840. if (!this.track_ || event && (event.type === 'addtrack' || event.type === 'removetrack')) {
  3841. this.setTrack(this.findChaptersTrack());
  3842. }
  3843. _TextTrackButton.prototype.update.call(this);
  3844. };
  3845. /**
  3846. * Set the currently selected track for the chapters button.
  3847. *
  3848. * @param {TextTrack} track
  3849. * The new track to select. Nothing will change if this is the currently selected
  3850. * track.
  3851. */
  3852. ChaptersButton.prototype.setTrack = function setTrack(track) {
  3853. if (this.track_ === track) {
  3854. return;
  3855. }
  3856. if (!this.updateHandler_) {
  3857. this.updateHandler_ = this.update.bind(this);
  3858. }
  3859. // here this.track_ refers to the old track instance
  3860. if (this.track_) {
  3861. var remoteTextTrackEl = this.player_.remoteTextTrackEls().getTrackElementByTrack_(this.track_);
  3862. if (remoteTextTrackEl) {
  3863. remoteTextTrackEl.removeEventListener('load', this.updateHandler_);
  3864. }
  3865. this.track_ = null;
  3866. }
  3867. this.track_ = track;
  3868. // here this.track_ refers to the new track instance
  3869. if (this.track_) {
  3870. this.track_.mode = 'hidden';
  3871. var _remoteTextTrackEl = this.player_.remoteTextTrackEls().getTrackElementByTrack_(this.track_);
  3872. if (_remoteTextTrackEl) {
  3873. _remoteTextTrackEl.addEventListener('load', this.updateHandler_);
  3874. }
  3875. }
  3876. };
  3877. /**
  3878. * Find the track object that is currently in use by this ChaptersButton
  3879. *
  3880. * @return {TextTrack|undefined}
  3881. * The current track or undefined if none was found.
  3882. */
  3883. ChaptersButton.prototype.findChaptersTrack = function findChaptersTrack() {
  3884. var tracks = this.player_.textTracks() || [];
  3885. for (var i = tracks.length - 1; i >= 0; i--) {
  3886. // We will always choose the last track as our chaptersTrack
  3887. var track = tracks[i];
  3888. if (track.kind === this.kind_) {
  3889. return track;
  3890. }
  3891. }
  3892. };
  3893. /**
  3894. * Get the caption for the ChaptersButton based on the track label. This will also
  3895. * use the current tracks localized kind as a fallback if a label does not exist.
  3896. *
  3897. * @return {string}
  3898. * The tracks current label or the localized track kind.
  3899. */
  3900. ChaptersButton.prototype.getMenuCaption = function getMenuCaption() {
  3901. if (this.track_ && this.track_.label) {
  3902. return this.track_.label;
  3903. }
  3904. return this.localize((0, _toTitleCase2['default'])(this.kind_));
  3905. };
  3906. /**
  3907. * Create menu from chapter track
  3908. *
  3909. * @return {Menu}
  3910. * New menu for the chapter buttons
  3911. */
  3912. ChaptersButton.prototype.createMenu = function createMenu() {
  3913. this.options_.title = this.getMenuCaption();
  3914. return _TextTrackButton.prototype.createMenu.call(this);
  3915. };
  3916. /**
  3917. * Create a menu item for each text track
  3918. *
  3919. * @return {TextTrackMenuItem[]}
  3920. * Array of menu items
  3921. */
  3922. ChaptersButton.prototype.createItems = function createItems() {
  3923. var items = [];
  3924. if (!this.track_) {
  3925. return items;
  3926. }
  3927. var cues = this.track_.cues;
  3928. if (!cues) {
  3929. return items;
  3930. }
  3931. for (var i = 0, l = cues.length; i < l; i++) {
  3932. var cue = cues[i];
  3933. var mi = new _chaptersTrackMenuItem2['default'](this.player_, { track: this.track_, cue: cue });
  3934. items.push(mi);
  3935. }
  3936. return items;
  3937. };
  3938. return ChaptersButton;
  3939. }(_textTrackButton2['default']);
  3940. /**
  3941. * `kind` of TextTrack to look for to associate it with this menu.
  3942. *
  3943. * @type {string}
  3944. * @private
  3945. */
  3946. ChaptersButton.prototype.kind_ = 'chapters';
  3947. /**
  3948. * The text that should display over the `ChaptersButton`s controls. Added for localization.
  3949. *
  3950. * @type {string}
  3951. * @private
  3952. */
  3953. ChaptersButton.prototype.controlText_ = 'Chapters';
  3954. _component2['default'].registerComponent('ChaptersButton', ChaptersButton);
  3955. exports['default'] = ChaptersButton;
  3956. },{"26":26,"30":30,"5":5,"91":91}],26:[function(_dereq_,module,exports){
  3957. 'use strict';
  3958. exports.__esModule = true;
  3959. var _menuItem = _dereq_(48);
  3960. var _menuItem2 = _interopRequireDefault(_menuItem);
  3961. var _component = _dereq_(5);
  3962. var _component2 = _interopRequireDefault(_component);
  3963. var _fn = _dereq_(83);
  3964. var Fn = _interopRequireWildcard(_fn);
  3965. 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; } }
  3966. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  3967. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  3968. 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; }
  3969. 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; } /**
  3970. * @file chapters-track-menu-item.js
  3971. */
  3972. /**
  3973. * The chapter track menu item
  3974. *
  3975. * @extends MenuItem
  3976. */
  3977. var ChaptersTrackMenuItem = function (_MenuItem) {
  3978. _inherits(ChaptersTrackMenuItem, _MenuItem);
  3979. /**
  3980. * Creates an instance of this class.
  3981. *
  3982. * @param {Player} player
  3983. * The `Player` that this class should be attached to.
  3984. *
  3985. * @param {Object} [options]
  3986. * The key/value store of player options.
  3987. */
  3988. function ChaptersTrackMenuItem(player, options) {
  3989. _classCallCheck(this, ChaptersTrackMenuItem);
  3990. var track = options.track;
  3991. var cue = options.cue;
  3992. var currentTime = player.currentTime();
  3993. // Modify options for parent MenuItem class's init.
  3994. options.selectable = true;
  3995. options.label = cue.text;
  3996. options.selected = cue.startTime <= currentTime && currentTime < cue.endTime;
  3997. var _this = _possibleConstructorReturn(this, _MenuItem.call(this, player, options));
  3998. _this.track = track;
  3999. _this.cue = cue;
  4000. track.addEventListener('cuechange', Fn.bind(_this, _this.update));
  4001. return _this;
  4002. }
  4003. /**
  4004. * This gets called when an `ChaptersTrackMenuItem` is "clicked". See
  4005. * {@link ClickableComponent} for more detailed information on what a click can be.
  4006. *
  4007. * @param {EventTarget~Event} [event]
  4008. * The `keydown`, `tap`, or `click` event that caused this function to be
  4009. * called.
  4010. *
  4011. * @listens tap
  4012. * @listens click
  4013. */
  4014. ChaptersTrackMenuItem.prototype.handleClick = function handleClick(event) {
  4015. _MenuItem.prototype.handleClick.call(this);
  4016. this.player_.currentTime(this.cue.startTime);
  4017. this.update(this.cue.startTime);
  4018. };
  4019. /**
  4020. * Update chapter menu item
  4021. *
  4022. * @param {EventTarget~Event} [event]
  4023. * The `cuechange` event that caused this function to run.
  4024. *
  4025. * @listens TextTrack#cuechange
  4026. */
  4027. ChaptersTrackMenuItem.prototype.update = function update(event) {
  4028. var cue = this.cue;
  4029. var currentTime = this.player_.currentTime();
  4030. // vjs.log(currentTime, cue.startTime);
  4031. this.selected(cue.startTime <= currentTime && currentTime < cue.endTime);
  4032. };
  4033. return ChaptersTrackMenuItem;
  4034. }(_menuItem2['default']);
  4035. _component2['default'].registerComponent('ChaptersTrackMenuItem', ChaptersTrackMenuItem);
  4036. exports['default'] = ChaptersTrackMenuItem;
  4037. },{"48":48,"5":5,"83":83}],27:[function(_dereq_,module,exports){
  4038. 'use strict';
  4039. exports.__esModule = true;
  4040. var _textTrackButton = _dereq_(30);
  4041. var _textTrackButton2 = _interopRequireDefault(_textTrackButton);
  4042. var _component = _dereq_(5);
  4043. var _component2 = _interopRequireDefault(_component);
  4044. var _fn = _dereq_(83);
  4045. var Fn = _interopRequireWildcard(_fn);
  4046. 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; } }
  4047. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  4048. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  4049. 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; }
  4050. 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; } /**
  4051. * @file descriptions-button.js
  4052. */
  4053. /**
  4054. * The button component for toggling and selecting descriptions
  4055. *
  4056. * @extends TextTrackButton
  4057. */
  4058. var DescriptionsButton = function (_TextTrackButton) {
  4059. _inherits(DescriptionsButton, _TextTrackButton);
  4060. /**
  4061. * Creates an instance of this class.
  4062. *
  4063. * @param {Player} player
  4064. * The `Player` that this class should be attached to.
  4065. *
  4066. * @param {Object} [options]
  4067. * The key/value store of player options.
  4068. *
  4069. * @param {Component~ReadyCallback} [ready]
  4070. * The function to call when this component is ready.
  4071. */
  4072. function DescriptionsButton(player, options, ready) {
  4073. _classCallCheck(this, DescriptionsButton);
  4074. var _this = _possibleConstructorReturn(this, _TextTrackButton.call(this, player, options, ready));
  4075. _this.el_.setAttribute('aria-label', 'Descriptions Menu');
  4076. var tracks = player.textTracks();
  4077. if (tracks) {
  4078. (function () {
  4079. var changeHandler = Fn.bind(_this, _this.handleTracksChange);
  4080. tracks.addEventListener('change', changeHandler);
  4081. _this.on('dispose', function () {
  4082. tracks.removeEventListener('change', changeHandler);
  4083. });
  4084. })();
  4085. }
  4086. return _this;
  4087. }
  4088. /**
  4089. * Handle text track change
  4090. *
  4091. * @param {EventTarget~Event} event
  4092. * The event that caused this function to run
  4093. *
  4094. * @listens TextTrackList#change
  4095. */
  4096. DescriptionsButton.prototype.handleTracksChange = function handleTracksChange(event) {
  4097. var tracks = this.player().textTracks();
  4098. var disabled = false;
  4099. // Check whether a track of a different kind is showing
  4100. for (var i = 0, l = tracks.length; i < l; i++) {
  4101. var track = tracks[i];
  4102. if (track.kind !== this.kind_ && track.mode === 'showing') {
  4103. disabled = true;
  4104. break;
  4105. }
  4106. }
  4107. // If another track is showing, disable this menu button
  4108. if (disabled) {
  4109. this.disable();
  4110. } else {
  4111. this.enable();
  4112. }
  4113. };
  4114. /**
  4115. * Builds the default DOM `className`.
  4116. *
  4117. * @return {string}
  4118. * The DOM `className` for this object.
  4119. */
  4120. DescriptionsButton.prototype.buildCSSClass = function buildCSSClass() {
  4121. return 'vjs-descriptions-button ' + _TextTrackButton.prototype.buildCSSClass.call(this);
  4122. };
  4123. return DescriptionsButton;
  4124. }(_textTrackButton2['default']);
  4125. /**
  4126. * `kind` of TextTrack to look for to associate it with this menu.
  4127. *
  4128. * @type {string}
  4129. * @private
  4130. */
  4131. DescriptionsButton.prototype.kind_ = 'descriptions';
  4132. /**
  4133. * The text that should display over the `DescriptionsButton`s controls. Added for localization.
  4134. *
  4135. * @type {string}
  4136. * @private
  4137. */
  4138. DescriptionsButton.prototype.controlText_ = 'Descriptions';
  4139. _component2['default'].registerComponent('DescriptionsButton', DescriptionsButton);
  4140. exports['default'] = DescriptionsButton;
  4141. },{"30":30,"5":5,"83":83}],28:[function(_dereq_,module,exports){
  4142. 'use strict';
  4143. exports.__esModule = true;
  4144. var _textTrackMenuItem = _dereq_(31);
  4145. var _textTrackMenuItem2 = _interopRequireDefault(_textTrackMenuItem);
  4146. var _component = _dereq_(5);
  4147. var _component2 = _interopRequireDefault(_component);
  4148. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  4149. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  4150. 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; }
  4151. 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; } /**
  4152. * @file off-text-track-menu-item.js
  4153. */
  4154. /**
  4155. * A special menu item for turning of a specific type of text track
  4156. *
  4157. * @extends TextTrackMenuItem
  4158. */
  4159. var OffTextTrackMenuItem = function (_TextTrackMenuItem) {
  4160. _inherits(OffTextTrackMenuItem, _TextTrackMenuItem);
  4161. /**
  4162. * Creates an instance of this class.
  4163. *
  4164. * @param {Player} player
  4165. * The `Player` that this class should be attached to.
  4166. *
  4167. * @param {Object} [options]
  4168. * The key/value store of player options.
  4169. */
  4170. function OffTextTrackMenuItem(player, options) {
  4171. _classCallCheck(this, OffTextTrackMenuItem);
  4172. // Create pseudo track info
  4173. // Requires options['kind']
  4174. options.track = {
  4175. player: player,
  4176. kind: options.kind,
  4177. label: options.kind + ' off',
  4178. 'default': false,
  4179. mode: 'disabled'
  4180. };
  4181. // MenuItem is selectable
  4182. options.selectable = true;
  4183. var _this = _possibleConstructorReturn(this, _TextTrackMenuItem.call(this, player, options));
  4184. _this.selected(true);
  4185. return _this;
  4186. }
  4187. /**
  4188. * Handle text track change
  4189. *
  4190. * @param {EventTarget~Event} event
  4191. * The event that caused this function to run
  4192. */
  4193. OffTextTrackMenuItem.prototype.handleTracksChange = function handleTracksChange(event) {
  4194. var tracks = this.player().textTracks();
  4195. var selected = true;
  4196. for (var i = 0, l = tracks.length; i < l; i++) {
  4197. var track = tracks[i];
  4198. if (track.kind === this.track.kind && track.mode === 'showing') {
  4199. selected = false;
  4200. break;
  4201. }
  4202. }
  4203. this.selected(selected);
  4204. };
  4205. return OffTextTrackMenuItem;
  4206. }(_textTrackMenuItem2['default']);
  4207. _component2['default'].registerComponent('OffTextTrackMenuItem', OffTextTrackMenuItem);
  4208. exports['default'] = OffTextTrackMenuItem;
  4209. },{"31":31,"5":5}],29:[function(_dereq_,module,exports){
  4210. 'use strict';
  4211. exports.__esModule = true;
  4212. var _textTrackButton = _dereq_(30);
  4213. var _textTrackButton2 = _interopRequireDefault(_textTrackButton);
  4214. var _component = _dereq_(5);
  4215. var _component2 = _interopRequireDefault(_component);
  4216. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  4217. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  4218. 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; }
  4219. 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; } /**
  4220. * @file subtitles-button.js
  4221. */
  4222. /**
  4223. * The button component for toggling and selecting subtitles
  4224. *
  4225. * @extends TextTrackButton
  4226. */
  4227. var SubtitlesButton = function (_TextTrackButton) {
  4228. _inherits(SubtitlesButton, _TextTrackButton);
  4229. /**
  4230. * Creates an instance of this class.
  4231. *
  4232. * @param {Player} player
  4233. * The `Player` that this class should be attached to.
  4234. *
  4235. * @param {Object} [options]
  4236. * The key/value store of player options.
  4237. *
  4238. * @param {Component~ReadyCallback} [ready]
  4239. * The function to call when this component is ready.
  4240. */
  4241. function SubtitlesButton(player, options, ready) {
  4242. _classCallCheck(this, SubtitlesButton);
  4243. var _this = _possibleConstructorReturn(this, _TextTrackButton.call(this, player, options, ready));
  4244. _this.el_.setAttribute('aria-label', 'Subtitles Menu');
  4245. return _this;
  4246. }
  4247. /**
  4248. * Builds the default DOM `className`.
  4249. *
  4250. * @return {string}
  4251. * The DOM `className` for this object.
  4252. */
  4253. SubtitlesButton.prototype.buildCSSClass = function buildCSSClass() {
  4254. return 'vjs-subtitles-button ' + _TextTrackButton.prototype.buildCSSClass.call(this);
  4255. };
  4256. return SubtitlesButton;
  4257. }(_textTrackButton2['default']);
  4258. /**
  4259. * `kind` of TextTrack to look for to associate it with this menu.
  4260. *
  4261. * @type {string}
  4262. * @private
  4263. */
  4264. SubtitlesButton.prototype.kind_ = 'subtitles';
  4265. /**
  4266. * The text that should display over the `SubtitlesButton`s controls. Added for localization.
  4267. *
  4268. * @type {string}
  4269. * @private
  4270. */
  4271. SubtitlesButton.prototype.controlText_ = 'Subtitles';
  4272. _component2['default'].registerComponent('SubtitlesButton', SubtitlesButton);
  4273. exports['default'] = SubtitlesButton;
  4274. },{"30":30,"5":5}],30:[function(_dereq_,module,exports){
  4275. 'use strict';
  4276. exports.__esModule = true;
  4277. var _trackButton = _dereq_(36);
  4278. var _trackButton2 = _interopRequireDefault(_trackButton);
  4279. var _component = _dereq_(5);
  4280. var _component2 = _interopRequireDefault(_component);
  4281. var _textTrackMenuItem = _dereq_(31);
  4282. var _textTrackMenuItem2 = _interopRequireDefault(_textTrackMenuItem);
  4283. var _offTextTrackMenuItem = _dereq_(28);
  4284. var _offTextTrackMenuItem2 = _interopRequireDefault(_offTextTrackMenuItem);
  4285. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  4286. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  4287. 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; }
  4288. 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; } /**
  4289. * @file text-track-button.js
  4290. */
  4291. /**
  4292. * The base class for buttons that toggle specific text track types (e.g. subtitles)
  4293. *
  4294. * @extends MenuButton
  4295. */
  4296. var TextTrackButton = function (_TrackButton) {
  4297. _inherits(TextTrackButton, _TrackButton);
  4298. /**
  4299. * Creates an instance of this class.
  4300. *
  4301. * @param {Player} player
  4302. * The `Player` that this class should be attached to.
  4303. *
  4304. * @param {Object} [options={}]
  4305. * The key/value store of player options.
  4306. */
  4307. function TextTrackButton(player) {
  4308. var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  4309. _classCallCheck(this, TextTrackButton);
  4310. options.tracks = player.textTracks();
  4311. return _possibleConstructorReturn(this, _TrackButton.call(this, player, options));
  4312. }
  4313. /**
  4314. * Create a menu item for each text track
  4315. *
  4316. * @param {TextTrackMenuItem[]} [items=[]]
  4317. * Existing array of items to use during creation
  4318. *
  4319. * @return {TextTrackMenuItem[]}
  4320. * Array of menu items that were created
  4321. */
  4322. TextTrackButton.prototype.createItems = function createItems() {
  4323. var items = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
  4324. // Add an OFF menu item to turn all tracks off
  4325. items.push(new _offTextTrackMenuItem2['default'](this.player_, { kind: this.kind_ }));
  4326. var tracks = this.player_.textTracks();
  4327. if (!tracks) {
  4328. return items;
  4329. }
  4330. for (var i = 0; i < tracks.length; i++) {
  4331. var track = tracks[i];
  4332. // only add tracks that are of the appropriate kind and have a label
  4333. if (track.kind === this.kind_) {
  4334. items.push(new _textTrackMenuItem2['default'](this.player_, {
  4335. track: track,
  4336. // MenuItem is selectable
  4337. selectable: true
  4338. }));
  4339. }
  4340. }
  4341. return items;
  4342. };
  4343. return TextTrackButton;
  4344. }(_trackButton2['default']);
  4345. _component2['default'].registerComponent('TextTrackButton', TextTrackButton);
  4346. exports['default'] = TextTrackButton;
  4347. },{"28":28,"31":31,"36":36,"5":5}],31:[function(_dereq_,module,exports){
  4348. 'use strict';
  4349. exports.__esModule = true;
  4350. 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; };
  4351. var _menuItem = _dereq_(48);
  4352. var _menuItem2 = _interopRequireDefault(_menuItem);
  4353. var _component = _dereq_(5);
  4354. var _component2 = _interopRequireDefault(_component);
  4355. var _fn = _dereq_(83);
  4356. var Fn = _interopRequireWildcard(_fn);
  4357. var _window = _dereq_(95);
  4358. var _window2 = _interopRequireDefault(_window);
  4359. var _document = _dereq_(94);
  4360. var _document2 = _interopRequireDefault(_document);
  4361. 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; } }
  4362. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  4363. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  4364. 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; }
  4365. 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; } /**
  4366. * @file text-track-menu-item.js
  4367. */
  4368. /**
  4369. * The specific menu item type for selecting a language within a text track kind
  4370. *
  4371. * @extends MenuItem
  4372. */
  4373. var TextTrackMenuItem = function (_MenuItem) {
  4374. _inherits(TextTrackMenuItem, _MenuItem);
  4375. /**
  4376. * Creates an instance of this class.
  4377. *
  4378. * @param {Player} player
  4379. * The `Player` that this class should be attached to.
  4380. *
  4381. * @param {Object} [options]
  4382. * The key/value store of player options.
  4383. */
  4384. function TextTrackMenuItem(player, options) {
  4385. _classCallCheck(this, TextTrackMenuItem);
  4386. var track = options.track;
  4387. var tracks = player.textTracks();
  4388. // Modify options for parent MenuItem class's init.
  4389. options.label = track.label || track.language || 'Unknown';
  4390. options.selected = track['default'] || track.mode === 'showing';
  4391. var _this = _possibleConstructorReturn(this, _MenuItem.call(this, player, options));
  4392. _this.track = track;
  4393. if (tracks) {
  4394. (function () {
  4395. var changeHandler = Fn.bind(_this, _this.handleTracksChange);
  4396. tracks.addEventListener('change', changeHandler);
  4397. _this.on('dispose', function () {
  4398. tracks.removeEventListener('change', changeHandler);
  4399. });
  4400. })();
  4401. }
  4402. // iOS7 doesn't dispatch change events to TextTrackLists when an
  4403. // associated track's mode changes. Without something like
  4404. // Object.observe() (also not present on iOS7), it's not
  4405. // possible to detect changes to the mode attribute and polyfill
  4406. // the change event. As a poor substitute, we manually dispatch
  4407. // change events whenever the controls modify the mode.
  4408. if (tracks && tracks.onchange === undefined) {
  4409. (function () {
  4410. var event = void 0;
  4411. _this.on(['tap', 'click'], function () {
  4412. if (_typeof(_window2['default'].Event) !== 'object') {
  4413. // Android 2.3 throws an Illegal Constructor error for window.Event
  4414. try {
  4415. event = new _window2['default'].Event('change');
  4416. } catch (err) {
  4417. // continue regardless of error
  4418. }
  4419. }
  4420. if (!event) {
  4421. event = _document2['default'].createEvent('Event');
  4422. event.initEvent('change', true, true);
  4423. }
  4424. tracks.dispatchEvent(event);
  4425. });
  4426. })();
  4427. }
  4428. return _this;
  4429. }
  4430. /**
  4431. * This gets called when an `TextTrackMenuItem` is "clicked". See
  4432. * {@link ClickableComponent} for more detailed information on what a click can be.
  4433. *
  4434. * @param {EventTarget~Event} event
  4435. * The `keydown`, `tap`, or `click` event that caused this function to be
  4436. * called.
  4437. *
  4438. * @listens tap
  4439. * @listens click
  4440. */
  4441. TextTrackMenuItem.prototype.handleClick = function handleClick(event) {
  4442. var kind = this.track.kind;
  4443. var tracks = this.player_.textTracks();
  4444. _MenuItem.prototype.handleClick.call(this, event);
  4445. if (!tracks) {
  4446. return;
  4447. }
  4448. for (var i = 0; i < tracks.length; i++) {
  4449. var track = tracks[i];
  4450. if (track.kind !== kind) {
  4451. continue;
  4452. }
  4453. if (track === this.track) {
  4454. track.mode = 'showing';
  4455. } else {
  4456. track.mode = 'disabled';
  4457. }
  4458. }
  4459. };
  4460. /**
  4461. * Handle text track list change
  4462. *
  4463. * @param {EventTarget~Event} event
  4464. * The `change` event that caused this function to be called.
  4465. *
  4466. * @listens TextTrackList#change
  4467. */
  4468. TextTrackMenuItem.prototype.handleTracksChange = function handleTracksChange(event) {
  4469. this.selected(this.track.mode === 'showing');
  4470. };
  4471. return TextTrackMenuItem;
  4472. }(_menuItem2['default']);
  4473. _component2['default'].registerComponent('TextTrackMenuItem', TextTrackMenuItem);
  4474. exports['default'] = TextTrackMenuItem;
  4475. },{"48":48,"5":5,"83":83,"94":94,"95":95}],32:[function(_dereq_,module,exports){
  4476. 'use strict';
  4477. exports.__esModule = true;
  4478. var _component = _dereq_(5);
  4479. var _component2 = _interopRequireDefault(_component);
  4480. var _dom = _dereq_(81);
  4481. var Dom = _interopRequireWildcard(_dom);
  4482. var _formatTime = _dereq_(84);
  4483. var _formatTime2 = _interopRequireDefault(_formatTime);
  4484. 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; } }
  4485. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  4486. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  4487. 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; }
  4488. 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; } /**
  4489. * @file current-time-display.js
  4490. */
  4491. /**
  4492. * Displays the current time
  4493. *
  4494. * @extends Component
  4495. */
  4496. var CurrentTimeDisplay = function (_Component) {
  4497. _inherits(CurrentTimeDisplay, _Component);
  4498. /**
  4499. * Creates an instance of this class.
  4500. *
  4501. * @param {Player} player
  4502. * The `Player` that this class should be attached to.
  4503. *
  4504. * @param {Object} [options]
  4505. * The key/value store of player options.
  4506. */
  4507. function CurrentTimeDisplay(player, options) {
  4508. _classCallCheck(this, CurrentTimeDisplay);
  4509. var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
  4510. _this.on(player, 'timeupdate', _this.updateContent);
  4511. return _this;
  4512. }
  4513. /**
  4514. * Create the `Component`'s DOM element
  4515. *
  4516. * @return {Element}
  4517. * The element that was created.
  4518. */
  4519. CurrentTimeDisplay.prototype.createEl = function createEl() {
  4520. var el = _Component.prototype.createEl.call(this, 'div', {
  4521. className: 'vjs-current-time vjs-time-control vjs-control'
  4522. });
  4523. this.contentEl_ = Dom.createEl('div', {
  4524. className: 'vjs-current-time-display',
  4525. // label the current time for screen reader users
  4526. innerHTML: '<span class="vjs-control-text">Current Time </span>' + '0:00'
  4527. }, {
  4528. // tell screen readers not to automatically read the time as it changes
  4529. 'aria-live': 'off'
  4530. });
  4531. el.appendChild(this.contentEl_);
  4532. return el;
  4533. };
  4534. /**
  4535. * Update current time display
  4536. *
  4537. * @param {EventTarget~Event} [event]
  4538. * The `timeupdate` event that caused this function to run.
  4539. *
  4540. * @listens Player#timeupdate
  4541. */
  4542. CurrentTimeDisplay.prototype.updateContent = function updateContent(event) {
  4543. // Allows for smooth scrubbing, when player can't keep up.
  4544. var time = this.player_.scrubbing() ? this.player_.getCache().currentTime : this.player_.currentTime();
  4545. var localizedText = this.localize('Current Time');
  4546. var formattedTime = (0, _formatTime2['default'])(time, this.player_.duration());
  4547. if (formattedTime !== this.formattedTime_) {
  4548. this.formattedTime_ = formattedTime;
  4549. this.contentEl_.innerHTML = '<span class="vjs-control-text">' + localizedText + '</span> ' + formattedTime;
  4550. }
  4551. };
  4552. return CurrentTimeDisplay;
  4553. }(_component2['default']);
  4554. _component2['default'].registerComponent('CurrentTimeDisplay', CurrentTimeDisplay);
  4555. exports['default'] = CurrentTimeDisplay;
  4556. },{"5":5,"81":81,"84":84}],33:[function(_dereq_,module,exports){
  4557. 'use strict';
  4558. exports.__esModule = true;
  4559. var _component = _dereq_(5);
  4560. var _component2 = _interopRequireDefault(_component);
  4561. var _dom = _dereq_(81);
  4562. var Dom = _interopRequireWildcard(_dom);
  4563. var _formatTime = _dereq_(84);
  4564. var _formatTime2 = _interopRequireDefault(_formatTime);
  4565. 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; } }
  4566. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  4567. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  4568. 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; }
  4569. 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; } /**
  4570. * @file duration-display.js
  4571. */
  4572. /**
  4573. * Displays the duration
  4574. *
  4575. * @extends Component
  4576. */
  4577. var DurationDisplay = function (_Component) {
  4578. _inherits(DurationDisplay, _Component);
  4579. /**
  4580. * Creates an instance of this class.
  4581. *
  4582. * @param {Player} player
  4583. * The `Player` that this class should be attached to.
  4584. *
  4585. * @param {Object} [options]
  4586. * The key/value store of player options.
  4587. */
  4588. function DurationDisplay(player, options) {
  4589. _classCallCheck(this, DurationDisplay);
  4590. var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
  4591. _this.on(player, 'durationchange', _this.updateContent);
  4592. // Also listen for timeupdate and loadedmetadata because removing those
  4593. // listeners could have broken dependent applications/libraries. These
  4594. // can likely be removed for 6.0.
  4595. _this.on(player, 'timeupdate', _this.updateContent);
  4596. _this.on(player, 'loadedmetadata', _this.updateContent);
  4597. return _this;
  4598. }
  4599. /**
  4600. * Create the `Component`'s DOM element
  4601. *
  4602. * @return {Element}
  4603. * The element that was created.
  4604. */
  4605. DurationDisplay.prototype.createEl = function createEl() {
  4606. var el = _Component.prototype.createEl.call(this, 'div', {
  4607. className: 'vjs-duration vjs-time-control vjs-control'
  4608. });
  4609. this.contentEl_ = Dom.createEl('div', {
  4610. className: 'vjs-duration-display',
  4611. // label the duration time for screen reader users
  4612. innerHTML: '<span class="vjs-control-text">' + this.localize('Duration Time') + '</span> 0:00'
  4613. }, {
  4614. // tell screen readers not to automatically read the time as it changes
  4615. 'aria-live': 'off'
  4616. });
  4617. el.appendChild(this.contentEl_);
  4618. return el;
  4619. };
  4620. /**
  4621. * Update duration time display.
  4622. *
  4623. * @param {EventTarget~Event} [event]
  4624. * The `durationchange`, `timeupdate`, or `loadedmetadata` event that caused
  4625. * this function to be called.
  4626. *
  4627. * @listens Player#durationchange
  4628. * @listens Player#timeupdate
  4629. * @listens Player#loadedmetadata
  4630. */
  4631. DurationDisplay.prototype.updateContent = function updateContent(event) {
  4632. var duration = this.player_.duration();
  4633. if (duration && this.duration_ !== duration) {
  4634. this.duration_ = duration;
  4635. var localizedText = this.localize('Duration Time');
  4636. var formattedTime = (0, _formatTime2['default'])(duration);
  4637. // label the duration time for screen reader users
  4638. this.contentEl_.innerHTML = '<span class="vjs-control-text">' + localizedText + '</span> ' + formattedTime;
  4639. }
  4640. };
  4641. return DurationDisplay;
  4642. }(_component2['default']);
  4643. _component2['default'].registerComponent('DurationDisplay', DurationDisplay);
  4644. exports['default'] = DurationDisplay;
  4645. },{"5":5,"81":81,"84":84}],34:[function(_dereq_,module,exports){
  4646. 'use strict';
  4647. exports.__esModule = true;
  4648. var _component = _dereq_(5);
  4649. var _component2 = _interopRequireDefault(_component);
  4650. var _dom = _dereq_(81);
  4651. var Dom = _interopRequireWildcard(_dom);
  4652. var _formatTime = _dereq_(84);
  4653. var _formatTime2 = _interopRequireDefault(_formatTime);
  4654. 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; } }
  4655. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  4656. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  4657. 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; }
  4658. 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; } /**
  4659. * @file remaining-time-display.js
  4660. */
  4661. /**
  4662. * Displays the time left in the video
  4663. *
  4664. * @extends Component
  4665. */
  4666. var RemainingTimeDisplay = function (_Component) {
  4667. _inherits(RemainingTimeDisplay, _Component);
  4668. /**
  4669. * Creates an instance of this class.
  4670. *
  4671. * @param {Player} player
  4672. * The `Player` that this class should be attached to.
  4673. *
  4674. * @param {Object} [options]
  4675. * The key/value store of player options.
  4676. */
  4677. function RemainingTimeDisplay(player, options) {
  4678. _classCallCheck(this, RemainingTimeDisplay);
  4679. var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
  4680. _this.on(player, 'timeupdate', _this.updateContent);
  4681. _this.on(player, 'durationchange', _this.updateContent);
  4682. return _this;
  4683. }
  4684. /**
  4685. * Create the `Component`'s DOM element
  4686. *
  4687. * @return {Element}
  4688. * The element that was created.
  4689. */
  4690. RemainingTimeDisplay.prototype.createEl = function createEl() {
  4691. var el = _Component.prototype.createEl.call(this, 'div', {
  4692. className: 'vjs-remaining-time vjs-time-control vjs-control'
  4693. });
  4694. this.contentEl_ = Dom.createEl('div', {
  4695. className: 'vjs-remaining-time-display',
  4696. // label the remaining time for screen reader users
  4697. innerHTML: '<span class="vjs-control-text">' + this.localize('Remaining Time') + '</span> -0:00'
  4698. }, {
  4699. // tell screen readers not to automatically read the time as it changes
  4700. 'aria-live': 'off'
  4701. });
  4702. el.appendChild(this.contentEl_);
  4703. return el;
  4704. };
  4705. /**
  4706. * Update remaining time display.
  4707. *
  4708. * @param {EventTarget~Event} [event]
  4709. * The `timeupdate` or `durationchange` event that caused this to run.
  4710. *
  4711. * @listens Player#timeupdate
  4712. * @listens Player#durationchange
  4713. */
  4714. RemainingTimeDisplay.prototype.updateContent = function updateContent(event) {
  4715. if (this.player_.duration()) {
  4716. var localizedText = this.localize('Remaining Time');
  4717. var formattedTime = (0, _formatTime2['default'])(this.player_.remainingTime());
  4718. if (formattedTime !== this.formattedTime_) {
  4719. this.formattedTime_ = formattedTime;
  4720. this.contentEl_.innerHTML = '<span class="vjs-control-text">' + localizedText + '</span> -' + formattedTime;
  4721. }
  4722. }
  4723. // Allows for smooth scrubbing, when player can't keep up.
  4724. // var time = (this.player_.scrubbing()) ? this.player_.getCache().currentTime : this.player_.currentTime();
  4725. // this.contentEl_.innerHTML = vjs.formatTime(time, this.player_.duration());
  4726. };
  4727. return RemainingTimeDisplay;
  4728. }(_component2['default']);
  4729. _component2['default'].registerComponent('RemainingTimeDisplay', RemainingTimeDisplay);
  4730. exports['default'] = RemainingTimeDisplay;
  4731. },{"5":5,"81":81,"84":84}],35:[function(_dereq_,module,exports){
  4732. 'use strict';
  4733. exports.__esModule = true;
  4734. var _component = _dereq_(5);
  4735. var _component2 = _interopRequireDefault(_component);
  4736. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  4737. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  4738. 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; }
  4739. 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; } /**
  4740. * @file time-divider.js
  4741. */
  4742. /**
  4743. * The separator between the current time and duration.
  4744. * Can be hidden if it's not needed in the design.
  4745. *
  4746. * @extends Component
  4747. */
  4748. var TimeDivider = function (_Component) {
  4749. _inherits(TimeDivider, _Component);
  4750. function TimeDivider() {
  4751. _classCallCheck(this, TimeDivider);
  4752. return _possibleConstructorReturn(this, _Component.apply(this, arguments));
  4753. }
  4754. /**
  4755. * Create the component's DOM element
  4756. *
  4757. * @return {Element}
  4758. * The element that was created.
  4759. */
  4760. TimeDivider.prototype.createEl = function createEl() {
  4761. return _Component.prototype.createEl.call(this, 'div', {
  4762. className: 'vjs-time-control vjs-time-divider',
  4763. innerHTML: '<div><span>/</span></div>'
  4764. });
  4765. };
  4766. return TimeDivider;
  4767. }(_component2['default']);
  4768. _component2['default'].registerComponent('TimeDivider', TimeDivider);
  4769. exports['default'] = TimeDivider;
  4770. },{"5":5}],36:[function(_dereq_,module,exports){
  4771. 'use strict';
  4772. exports.__esModule = true;
  4773. var _menuButton = _dereq_(47);
  4774. var _menuButton2 = _interopRequireDefault(_menuButton);
  4775. var _component = _dereq_(5);
  4776. var _component2 = _interopRequireDefault(_component);
  4777. var _fn = _dereq_(83);
  4778. var Fn = _interopRequireWildcard(_fn);
  4779. 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; } }
  4780. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  4781. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  4782. 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; }
  4783. 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; } /**
  4784. * @file track-button.js
  4785. */
  4786. /**
  4787. * The base class for buttons that toggle specific track types (e.g. subtitles).
  4788. *
  4789. * @extends MenuButton
  4790. */
  4791. var TrackButton = function (_MenuButton) {
  4792. _inherits(TrackButton, _MenuButton);
  4793. /**
  4794. * Creates an instance of this class.
  4795. *
  4796. * @param {Player} player
  4797. * The `Player` that this class should be attached to.
  4798. *
  4799. * @param {Object} [options]
  4800. * The key/value store of player options.
  4801. */
  4802. function TrackButton(player, options) {
  4803. _classCallCheck(this, TrackButton);
  4804. var tracks = options.tracks;
  4805. var _this = _possibleConstructorReturn(this, _MenuButton.call(this, player, options));
  4806. if (_this.items.length <= 1) {
  4807. _this.hide();
  4808. }
  4809. if (!tracks) {
  4810. return _possibleConstructorReturn(_this);
  4811. }
  4812. var updateHandler = Fn.bind(_this, _this.update);
  4813. tracks.addEventListener('removetrack', updateHandler);
  4814. tracks.addEventListener('addtrack', updateHandler);
  4815. _this.player_.on('dispose', function () {
  4816. tracks.removeEventListener('removetrack', updateHandler);
  4817. tracks.removeEventListener('addtrack', updateHandler);
  4818. });
  4819. return _this;
  4820. }
  4821. return TrackButton;
  4822. }(_menuButton2['default']);
  4823. _component2['default'].registerComponent('TrackButton', TrackButton);
  4824. exports['default'] = TrackButton;
  4825. },{"47":47,"5":5,"83":83}],37:[function(_dereq_,module,exports){
  4826. 'use strict';
  4827. exports.__esModule = true;
  4828. var _slider = _dereq_(57);
  4829. var _slider2 = _interopRequireDefault(_slider);
  4830. var _component = _dereq_(5);
  4831. var _component2 = _interopRequireDefault(_component);
  4832. var _fn = _dereq_(83);
  4833. var Fn = _interopRequireWildcard(_fn);
  4834. _dereq_(39);
  4835. 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; } }
  4836. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  4837. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  4838. 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; }
  4839. 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; } /**
  4840. * @file volume-bar.js
  4841. */
  4842. // Required children
  4843. /**
  4844. * The bar that contains the volume level and can be clicked on to adjust the level
  4845. *
  4846. * @extends Slider
  4847. */
  4848. var VolumeBar = function (_Slider) {
  4849. _inherits(VolumeBar, _Slider);
  4850. /**
  4851. * Creates an instance of this class.
  4852. *
  4853. * @param {Player} player
  4854. * The `Player` that this class should be attached to.
  4855. *
  4856. * @param {Object} [options]
  4857. * The key/value store of player options.
  4858. */
  4859. function VolumeBar(player, options) {
  4860. _classCallCheck(this, VolumeBar);
  4861. var _this = _possibleConstructorReturn(this, _Slider.call(this, player, options));
  4862. _this.on(player, 'volumechange', _this.updateARIAAttributes);
  4863. player.ready(Fn.bind(_this, _this.updateARIAAttributes));
  4864. return _this;
  4865. }
  4866. /**
  4867. * Create the `Component`'s DOM element
  4868. *
  4869. * @return {Element}
  4870. * The element that was created.
  4871. */
  4872. VolumeBar.prototype.createEl = function createEl() {
  4873. return _Slider.prototype.createEl.call(this, 'div', {
  4874. className: 'vjs-volume-bar vjs-slider-bar'
  4875. }, {
  4876. 'aria-label': 'volume level'
  4877. });
  4878. };
  4879. /**
  4880. * Handle movement events on the {@link VolumeMenuButton}.
  4881. *
  4882. * @param {EventTarget~Event} event
  4883. * The event that caused this function to run.
  4884. *
  4885. * @listens mousemove
  4886. */
  4887. VolumeBar.prototype.handleMouseMove = function handleMouseMove(event) {
  4888. this.checkMuted();
  4889. this.player_.volume(this.calculateDistance(event));
  4890. };
  4891. /**
  4892. * If the player is muted unmute it.
  4893. */
  4894. VolumeBar.prototype.checkMuted = function checkMuted() {
  4895. if (this.player_.muted()) {
  4896. this.player_.muted(false);
  4897. }
  4898. };
  4899. /**
  4900. * Get percent of volume level
  4901. *
  4902. * @return {number}
  4903. * Volume level percent as a decimal number.
  4904. */
  4905. VolumeBar.prototype.getPercent = function getPercent() {
  4906. if (this.player_.muted()) {
  4907. return 0;
  4908. }
  4909. return this.player_.volume();
  4910. };
  4911. /**
  4912. * Increase volume level for keyboard users
  4913. */
  4914. VolumeBar.prototype.stepForward = function stepForward() {
  4915. this.checkMuted();
  4916. this.player_.volume(this.player_.volume() + 0.1);
  4917. };
  4918. /**
  4919. * Decrease volume level for keyboard users
  4920. */
  4921. VolumeBar.prototype.stepBack = function stepBack() {
  4922. this.checkMuted();
  4923. this.player_.volume(this.player_.volume() - 0.1);
  4924. };
  4925. /**
  4926. * Update ARIA accessibility attributes
  4927. *
  4928. * @param {EventTarget~Event} [event]
  4929. * The `volumechange` event that caused this function to run.
  4930. *
  4931. * @listens Player#volumechange
  4932. */
  4933. VolumeBar.prototype.updateARIAAttributes = function updateARIAAttributes(event) {
  4934. // Current value of volume bar as a percentage
  4935. var volume = (this.player_.volume() * 100).toFixed(2);
  4936. this.el_.setAttribute('aria-valuenow', volume);
  4937. this.el_.setAttribute('aria-valuetext', volume + '%');
  4938. };
  4939. return VolumeBar;
  4940. }(_slider2['default']);
  4941. /**
  4942. * Default options for the `VolumeBar`
  4943. *
  4944. * @type {Object}
  4945. * @private
  4946. */
  4947. VolumeBar.prototype.options_ = {
  4948. children: ['volumeLevel'],
  4949. barName: 'volumeLevel'
  4950. };
  4951. /**
  4952. * Call the update event for this Slider when this event happens on the player.
  4953. *
  4954. * @type {string}
  4955. */
  4956. VolumeBar.prototype.playerEvent = 'volumechange';
  4957. _component2['default'].registerComponent('VolumeBar', VolumeBar);
  4958. exports['default'] = VolumeBar;
  4959. },{"39":39,"5":5,"57":57,"83":83}],38:[function(_dereq_,module,exports){
  4960. 'use strict';
  4961. exports.__esModule = true;
  4962. var _component = _dereq_(5);
  4963. var _component2 = _interopRequireDefault(_component);
  4964. _dereq_(37);
  4965. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  4966. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  4967. 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; }
  4968. 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; } /**
  4969. * @file volume-control.js
  4970. */
  4971. // Required children
  4972. /**
  4973. * The component for controlling the volume level
  4974. *
  4975. * @extends Component
  4976. */
  4977. var VolumeControl = function (_Component) {
  4978. _inherits(VolumeControl, _Component);
  4979. /**
  4980. * Creates an instance of this class.
  4981. *
  4982. * @param {Player} player
  4983. * The `Player` that this class should be attached to.
  4984. *
  4985. * @param {Object} [options={}]
  4986. * The key/value store of player options.
  4987. */
  4988. function VolumeControl(player, options) {
  4989. _classCallCheck(this, VolumeControl);
  4990. // hide volume controls when they're not supported by the current tech
  4991. var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
  4992. if (player.tech_ && player.tech_.featuresVolumeControl === false) {
  4993. _this.addClass('vjs-hidden');
  4994. }
  4995. _this.on(player, 'loadstart', function () {
  4996. if (player.tech_.featuresVolumeControl === false) {
  4997. this.addClass('vjs-hidden');
  4998. } else {
  4999. this.removeClass('vjs-hidden');
  5000. }
  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. VolumeControl.prototype.createEl = function createEl() {
  5011. return _Component.prototype.createEl.call(this, 'div', {
  5012. className: 'vjs-volume-control vjs-control'
  5013. });
  5014. };
  5015. return VolumeControl;
  5016. }(_component2['default']);
  5017. /**
  5018. * Default options for the `VolumeControl`
  5019. *
  5020. * @type {Object}
  5021. * @private
  5022. */
  5023. VolumeControl.prototype.options_ = {
  5024. children: ['volumeBar']
  5025. };
  5026. _component2['default'].registerComponent('VolumeControl', VolumeControl);
  5027. exports['default'] = VolumeControl;
  5028. },{"37":37,"5":5}],39:[function(_dereq_,module,exports){
  5029. 'use strict';
  5030. exports.__esModule = true;
  5031. var _component = _dereq_(5);
  5032. var _component2 = _interopRequireDefault(_component);
  5033. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  5034. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  5035. 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; }
  5036. 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; } /**
  5037. * @file volume-level.js
  5038. */
  5039. /**
  5040. * Shows volume level
  5041. *
  5042. * @extends Component
  5043. */
  5044. var VolumeLevel = function (_Component) {
  5045. _inherits(VolumeLevel, _Component);
  5046. function VolumeLevel() {
  5047. _classCallCheck(this, VolumeLevel);
  5048. return _possibleConstructorReturn(this, _Component.apply(this, arguments));
  5049. }
  5050. /**
  5051. * Create the `Component`'s DOM element
  5052. *
  5053. * @return {Element}
  5054. * The element that was created.
  5055. */
  5056. VolumeLevel.prototype.createEl = function createEl() {
  5057. return _Component.prototype.createEl.call(this, 'div', {
  5058. className: 'vjs-volume-level',
  5059. innerHTML: '<span class="vjs-control-text"></span>'
  5060. });
  5061. };
  5062. return VolumeLevel;
  5063. }(_component2['default']);
  5064. _component2['default'].registerComponent('VolumeLevel', VolumeLevel);
  5065. exports['default'] = VolumeLevel;
  5066. },{"5":5}],40:[function(_dereq_,module,exports){
  5067. 'use strict';
  5068. exports.__esModule = true;
  5069. var _fn = _dereq_(83);
  5070. var Fn = _interopRequireWildcard(_fn);
  5071. var _component = _dereq_(5);
  5072. var _component2 = _interopRequireDefault(_component);
  5073. var _popup = _dereq_(54);
  5074. var _popup2 = _interopRequireDefault(_popup);
  5075. var _popupButton = _dereq_(53);
  5076. var _popupButton2 = _interopRequireDefault(_popupButton);
  5077. var _muteToggle = _dereq_(11);
  5078. var _muteToggle2 = _interopRequireDefault(_muteToggle);
  5079. var _volumeBar = _dereq_(37);
  5080. var _volumeBar2 = _interopRequireDefault(_volumeBar);
  5081. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  5082. 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; } }
  5083. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  5084. 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; }
  5085. 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; } /**
  5086. * @file volume-menu-button.js
  5087. */
  5088. /**
  5089. * Button for volume popup
  5090. *
  5091. * @extends PopupButton
  5092. */
  5093. var VolumeMenuButton = function (_PopupButton) {
  5094. _inherits(VolumeMenuButton, _PopupButton);
  5095. /**
  5096. * Creates an instance of this class.
  5097. *
  5098. * @param {Player} player
  5099. * The `Player` that this class should be attached to.
  5100. *
  5101. * @param {Object} [options={}]
  5102. * The key/value store of player options.
  5103. */
  5104. function VolumeMenuButton(player) {
  5105. var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  5106. _classCallCheck(this, VolumeMenuButton);
  5107. // Default to inline
  5108. if (options.inline === undefined) {
  5109. options.inline = true;
  5110. }
  5111. // If the vertical option isn't passed at all, default to true.
  5112. if (options.vertical === undefined) {
  5113. // If an inline volumeMenuButton is used, we should default to using
  5114. // a horizontal slider for obvious reasons.
  5115. if (options.inline) {
  5116. options.vertical = false;
  5117. } else {
  5118. options.vertical = true;
  5119. }
  5120. }
  5121. // The vertical option needs to be set on the volumeBar as well,
  5122. // since that will need to be passed along to the VolumeBar constructor
  5123. options.volumeBar = options.volumeBar || {};
  5124. options.volumeBar.vertical = !!options.vertical;
  5125. // Same listeners as MuteToggle
  5126. var _this = _possibleConstructorReturn(this, _PopupButton.call(this, player, options));
  5127. _this.on(player, 'volumechange', _this.volumeUpdate);
  5128. _this.on(player, 'loadstart', _this.volumeUpdate);
  5129. // hide mute toggle if the current tech doesn't support volume control
  5130. function updateVisibility() {
  5131. if (player.tech_ && player.tech_.featuresVolumeControl === false) {
  5132. this.addClass('vjs-hidden');
  5133. } else {
  5134. this.removeClass('vjs-hidden');
  5135. }
  5136. }
  5137. updateVisibility.call(_this);
  5138. _this.on(player, 'loadstart', updateVisibility);
  5139. _this.on(_this.volumeBar, ['slideractive', 'focus'], function () {
  5140. this.addClass('vjs-slider-active');
  5141. });
  5142. _this.on(_this.volumeBar, ['sliderinactive', 'blur'], function () {
  5143. this.removeClass('vjs-slider-active');
  5144. });
  5145. _this.on(_this.volumeBar, ['focus'], function () {
  5146. this.addClass('vjs-lock-showing');
  5147. });
  5148. _this.on(_this.volumeBar, ['blur'], function () {
  5149. this.removeClass('vjs-lock-showing');
  5150. });
  5151. return _this;
  5152. }
  5153. /**
  5154. * Builds the default DOM `className`.
  5155. *
  5156. * @return {string}
  5157. * The DOM `className` for this object.
  5158. */
  5159. VolumeMenuButton.prototype.buildCSSClass = function buildCSSClass() {
  5160. var orientationClass = '';
  5161. if (this.options_.vertical) {
  5162. orientationClass = 'vjs-volume-menu-button-vertical';
  5163. } else {
  5164. orientationClass = 'vjs-volume-menu-button-horizontal';
  5165. }
  5166. return 'vjs-volume-menu-button ' + _PopupButton.prototype.buildCSSClass.call(this) + ' ' + orientationClass;
  5167. };
  5168. /**
  5169. * Create the VolumeMenuButton popup
  5170. *
  5171. * @return {Popup}
  5172. * The popup that was created
  5173. */
  5174. VolumeMenuButton.prototype.createPopup = function createPopup() {
  5175. var popup = new _popup2['default'](this.player_, {
  5176. contentElType: 'div'
  5177. });
  5178. var vb = new _volumeBar2['default'](this.player_, this.options_.volumeBar);
  5179. popup.addChild(vb);
  5180. this.menuContent = popup;
  5181. this.volumeBar = vb;
  5182. this.attachVolumeBarEvents();
  5183. return popup;
  5184. };
  5185. /**
  5186. * This gets called when an `VolumeMenuButton` is "clicked". See
  5187. * {@link ClickableComponent} for more detailed information on what a click can be.
  5188. *
  5189. * @param {EventTarget~Event} [event]
  5190. * The `keydown`, `tap`, or `click` event that caused this function to be
  5191. * called.
  5192. *
  5193. * @listens tap
  5194. * @listens click
  5195. */
  5196. VolumeMenuButton.prototype.handleClick = function handleClick(event) {
  5197. _muteToggle2['default'].prototype.handleClick.call(this);
  5198. _PopupButton.prototype.handleClick.call(this);
  5199. };
  5200. /**
  5201. * Add events listeners to the created `VolumeBar`.
  5202. */
  5203. VolumeMenuButton.prototype.attachVolumeBarEvents = function attachVolumeBarEvents() {
  5204. this.menuContent.on(['mousedown', 'touchdown'], Fn.bind(this, this.handleMouseDown));
  5205. };
  5206. /**
  5207. * Handle the `mousedown` and `touchdown` events on the `VolumeBar`
  5208. *
  5209. * @param {EventTarget~Event} [event]
  5210. * The `mousedown` or `touchdown` event that caused this to run.
  5211. *
  5212. * @listens mousedown
  5213. * @listens touchdown
  5214. */
  5215. VolumeMenuButton.prototype.handleMouseDown = function handleMouseDown(event) {
  5216. this.on(['mousemove', 'touchmove'], Fn.bind(this.volumeBar, this.volumeBar.handleMouseMove));
  5217. this.on(this.el_.ownerDocument, ['mouseup', 'touchend'], this.handleMouseUp);
  5218. };
  5219. /**
  5220. * Handle the `mouseup` and `touchend` events on the `VolumeBar`
  5221. *
  5222. * @param {EventTarget~Event} [event]
  5223. * The `mouseup` or `touchend` event that caused this to run.
  5224. *
  5225. * @listens mouseup
  5226. * @listens touchend
  5227. */
  5228. VolumeMenuButton.prototype.handleMouseUp = function handleMouseUp(event) {
  5229. this.off(['mousemove', 'touchmove'], Fn.bind(this.volumeBar, this.volumeBar.handleMouseMove));
  5230. };
  5231. return VolumeMenuButton;
  5232. }(_popupButton2['default']);
  5233. /**
  5234. * @borrows MuteToggle#update as VolumeMenuButton#volumeUpdate
  5235. */
  5236. VolumeMenuButton.prototype.volumeUpdate = _muteToggle2['default'].prototype.update;
  5237. /**
  5238. * The text that should display over the `VolumeMenuButton`s controls. Added for localization.
  5239. *
  5240. * @type {string}
  5241. * @private
  5242. */
  5243. VolumeMenuButton.prototype.controlText_ = 'Mute';
  5244. _component2['default'].registerComponent('VolumeMenuButton', VolumeMenuButton);
  5245. exports['default'] = VolumeMenuButton;
  5246. },{"11":11,"37":37,"5":5,"53":53,"54":54,"83":83}],41:[function(_dereq_,module,exports){
  5247. 'use strict';
  5248. exports.__esModule = true;
  5249. var _component = _dereq_(5);
  5250. var _component2 = _interopRequireDefault(_component);
  5251. var _modalDialog = _dereq_(50);
  5252. var _modalDialog2 = _interopRequireDefault(_modalDialog);
  5253. var _mergeOptions = _dereq_(87);
  5254. var _mergeOptions2 = _interopRequireDefault(_mergeOptions);
  5255. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  5256. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  5257. 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; }
  5258. 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; } /**
  5259. * @file error-display.js
  5260. */
  5261. /**
  5262. * A display that indicates an error has occurred. This means that the video
  5263. * is unplayable.
  5264. *
  5265. * @extends ModalDialog
  5266. */
  5267. var ErrorDisplay = function (_ModalDialog) {
  5268. _inherits(ErrorDisplay, _ModalDialog);
  5269. /**
  5270. * Creates an instance of this class.
  5271. *
  5272. * @param {Player} player
  5273. * The `Player` that this class should be attached to.
  5274. *
  5275. * @param {Object} [options]
  5276. * The key/value store of player options.
  5277. */
  5278. function ErrorDisplay(player, options) {
  5279. _classCallCheck(this, ErrorDisplay);
  5280. var _this = _possibleConstructorReturn(this, _ModalDialog.call(this, player, options));
  5281. _this.on(player, 'error', _this.open);
  5282. return _this;
  5283. }
  5284. /**
  5285. * Builds the default DOM `className`.
  5286. *
  5287. * @return {string}
  5288. * The DOM `className` for this object.
  5289. *
  5290. * @deprecated Since version 5.
  5291. */
  5292. ErrorDisplay.prototype.buildCSSClass = function buildCSSClass() {
  5293. return 'vjs-error-display ' + _ModalDialog.prototype.buildCSSClass.call(this);
  5294. };
  5295. /**
  5296. * Gets the localized error message based on the `Player`s error.
  5297. *
  5298. * @return {string}
  5299. * The `Player`s error message localized or an empty string.
  5300. */
  5301. ErrorDisplay.prototype.content = function content() {
  5302. var error = this.player().error();
  5303. return error ? this.localize(error.message) : '';
  5304. };
  5305. return ErrorDisplay;
  5306. }(_modalDialog2['default']);
  5307. /**
  5308. * The default options for an `ErrorDisplay`.
  5309. *
  5310. * @private
  5311. */
  5312. ErrorDisplay.prototype.options_ = (0, _mergeOptions2['default'])(_modalDialog2['default'].prototype.options_, {
  5313. fillAlways: true,
  5314. temporary: false,
  5315. uncloseable: true
  5316. });
  5317. _component2['default'].registerComponent('ErrorDisplay', ErrorDisplay);
  5318. exports['default'] = ErrorDisplay;
  5319. },{"5":5,"50":50,"87":87}],42:[function(_dereq_,module,exports){
  5320. 'use strict';
  5321. exports.__esModule = true;
  5322. var _events = _dereq_(82);
  5323. var Events = _interopRequireWildcard(_events);
  5324. 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; } }
  5325. /**
  5326. * `EventTarget` is a class that can have the same API as the DOM `EventTarget`. It
  5327. * adds shorthand functions that wrap around lengthy functions. For example:
  5328. * the `on` function is a wrapper around `addEventListener`.
  5329. *
  5330. * @see [EventTarget Spec]{@link https://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-EventTarget}
  5331. * @class EventTarget
  5332. */
  5333. var EventTarget = function EventTarget() {};
  5334. /**
  5335. * A Custom DOM event.
  5336. *
  5337. * @typedef {Object} EventTarget~Event
  5338. * @see [Properties]{@link https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent}
  5339. */
  5340. /**
  5341. * All event listeners should follow the following format.
  5342. *
  5343. * @callback EventTarget~EventListener
  5344. * @this {EventTarget}
  5345. *
  5346. * @param {EventTarget~Event} event
  5347. * the event that triggered this function
  5348. *
  5349. * @param {Object} [hash]
  5350. * hash of data sent during the event
  5351. */
  5352. /**
  5353. * An object containing event names as keys and booleans as values.
  5354. *
  5355. * > NOTE: If an event name is set to a true value here {@link EventTarget#trigger}
  5356. * will have extra functionality. See that function for more information.
  5357. *
  5358. * @property EventTarget.prototype.allowedEvents_
  5359. * @private
  5360. */
  5361. /**
  5362. * @file src/js/event-target.js
  5363. */
  5364. EventTarget.prototype.allowedEvents_ = {};
  5365. /**
  5366. * Adds an `event listener` to an instance of an `EventTarget`. An `event listener` is a
  5367. * function that will get called when an event with a certain name gets triggered.
  5368. *
  5369. * @param {string|string[]} type
  5370. * An event name or an array of event names.
  5371. *
  5372. * @param {EventTarget~EventListener} fn
  5373. * The function to call with `EventTarget`s
  5374. */
  5375. EventTarget.prototype.on = function (type, fn) {
  5376. // Remove the addEventListener alias before calling Events.on
  5377. // so we don't get into an infinite type loop
  5378. var ael = this.addEventListener;
  5379. this.addEventListener = function () {};
  5380. Events.on(this, type, fn);
  5381. this.addEventListener = ael;
  5382. };
  5383. /**
  5384. * An alias of {@link EventTarget#on}. Allows `EventTarget` to mimic
  5385. * the standard DOM API.
  5386. *
  5387. * @function
  5388. * @see {@link EventTarget#on}
  5389. */
  5390. EventTarget.prototype.addEventListener = EventTarget.prototype.on;
  5391. /**
  5392. * Removes an `event listener` for a specific event from an instance of `EventTarget`.
  5393. * This makes it so that the `event listener` will no longer get called when the
  5394. * named event happens.
  5395. *
  5396. * @param {string|string[]} type
  5397. * An event name or an array of event names.
  5398. *
  5399. * @param {EventTarget~EventListener} fn
  5400. * The function to remove.
  5401. */
  5402. EventTarget.prototype.off = function (type, fn) {
  5403. Events.off(this, type, fn);
  5404. };
  5405. /**
  5406. * An alias of {@link EventTarget#off}. Allows `EventTarget` to mimic
  5407. * the standard DOM API.
  5408. *
  5409. * @function
  5410. * @see {@link EventTarget#off}
  5411. */
  5412. EventTarget.prototype.removeEventListener = EventTarget.prototype.off;
  5413. /**
  5414. * This function will add an `event listener` that gets triggered only once. After the
  5415. * first trigger it will get removed. This is like adding an `event listener`
  5416. * with {@link EventTarget#on} that calls {@link EventTarget#off} on itself.
  5417. *
  5418. * @param {string|string[]} type
  5419. * An event name or an array of event names.
  5420. *
  5421. * @param {EventTarget~EventListener} fn
  5422. * The function to be called once for each event name.
  5423. */
  5424. EventTarget.prototype.one = function (type, fn) {
  5425. // Remove the addEventListener alialing Events.on
  5426. // so we don't get into an infinite type loop
  5427. var ael = this.addEventListener;
  5428. this.addEventListener = function () {};
  5429. Events.one(this, type, fn);
  5430. this.addEventListener = ael;
  5431. };
  5432. /**
  5433. * This function causes an event to happen. This will then cause any `event listeners`
  5434. * that are waiting for that event, to get called. If there are no `event listeners`
  5435. * for an event then nothing will happen.
  5436. *
  5437. * If the name of the `Event` that is being triggered is in `EventTarget.allowedEvents_`.
  5438. * Trigger will also call the `on` + `uppercaseEventName` function.
  5439. *
  5440. * Example:
  5441. * 'click' is in `EventTarget.allowedEvents_`, so, trigger will attempt to call
  5442. * `onClick` if it exists.
  5443. *
  5444. * @param {string|EventTarget~Event|Object} event
  5445. * The name of the event, an `Event`, or an object with a key of type set to
  5446. * an event name.
  5447. */
  5448. EventTarget.prototype.trigger = function (event) {
  5449. var type = event.type || event;
  5450. if (typeof event === 'string') {
  5451. event = { type: type };
  5452. }
  5453. event = Events.fixEvent(event);
  5454. if (this.allowedEvents_[type] && this['on' + type]) {
  5455. this['on' + type](event);
  5456. }
  5457. Events.trigger(this, event);
  5458. };
  5459. /**
  5460. * An alias of {@link EventTarget#trigger}. Allows `EventTarget` to mimic
  5461. * the standard DOM API.
  5462. *
  5463. * @function
  5464. * @see {@link EventTarget#trigger}
  5465. */
  5466. EventTarget.prototype.dispatchEvent = EventTarget.prototype.trigger;
  5467. exports['default'] = EventTarget;
  5468. },{"82":82}],43:[function(_dereq_,module,exports){
  5469. 'use strict';
  5470. exports.__esModule = true;
  5471. 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; };
  5472. var _log = _dereq_(86);
  5473. var _log2 = _interopRequireDefault(_log);
  5474. var _obj = _dereq_(88);
  5475. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  5476. /**
  5477. * @file extend.js
  5478. * @module extend
  5479. */
  5480. /**
  5481. * A combination of node inherits and babel's inherits (after transpile).
  5482. * Both work the same but node adds `super_` to the subClass
  5483. * and Bable adds the superClass as __proto__. Both seem useful.
  5484. *
  5485. * @param {Object} subClass
  5486. * The class to inherit to
  5487. *
  5488. * @param {Object} superClass
  5489. * The class to inherit from
  5490. *
  5491. * @private
  5492. */
  5493. var _inherits = function _inherits(subClass, superClass) {
  5494. if (typeof superClass !== 'function' && superClass !== null) {
  5495. throw new TypeError('Super expression must either be null or a function, not ' + (typeof superClass === 'undefined' ? 'undefined' : _typeof(superClass)));
  5496. }
  5497. subClass.prototype = Object.create(superClass && superClass.prototype, {
  5498. constructor: {
  5499. value: subClass,
  5500. enumerable: false,
  5501. writable: true,
  5502. configurable: true
  5503. }
  5504. });
  5505. if (superClass) {
  5506. // node
  5507. subClass.super_ = superClass;
  5508. }
  5509. };
  5510. /**
  5511. * Function for subclassing using the same inheritance that
  5512. * videojs uses internally
  5513. *
  5514. * @param {Object} superClass
  5515. * The class to inherit from
  5516. *
  5517. * @param {Object} [subClassMethods={}]
  5518. * The class to inherit to
  5519. *
  5520. * @return {Object}
  5521. * The new object with subClassMethods that inherited superClass.
  5522. */
  5523. var extendFn = function extendFn(superClass) {
  5524. var subClassMethods = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  5525. var subClass = function subClass() {
  5526. superClass.apply(this, arguments);
  5527. };
  5528. var methods = {};
  5529. if ((0, _obj.isObject)(subClassMethods)) {
  5530. if (typeof subClassMethods.init === 'function') {
  5531. _log2['default'].warn('Constructor logic via init() is deprecated; please use constructor() instead.');
  5532. subClassMethods.constructor = subClassMethods.init;
  5533. }
  5534. if (subClassMethods.constructor !== Object.prototype.constructor) {
  5535. subClass = subClassMethods.constructor;
  5536. }
  5537. methods = subClassMethods;
  5538. } else if (typeof subClassMethods === 'function') {
  5539. subClass = subClassMethods;
  5540. }
  5541. _inherits(subClass, superClass);
  5542. // Extend subObj's prototype with functions and other properties from props
  5543. for (var name in methods) {
  5544. if (methods.hasOwnProperty(name)) {
  5545. subClass.prototype[name] = methods[name];
  5546. }
  5547. }
  5548. return subClass;
  5549. };
  5550. exports['default'] = extendFn;
  5551. },{"86":86,"88":88}],44:[function(_dereq_,module,exports){
  5552. 'use strict';
  5553. exports.__esModule = true;
  5554. var _document = _dereq_(94);
  5555. var _document2 = _interopRequireDefault(_document);
  5556. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  5557. /**
  5558. * Store the browser-specific methods for the fullscreen API.
  5559. *
  5560. * @type {Object}
  5561. * @see [Specification]{@link https://fullscreen.spec.whatwg.org}
  5562. * @see [Map Approach From Screenfull.js]{@link https://github.com/sindresorhus/screenfull.js}
  5563. */
  5564. var FullscreenApi = {};
  5565. // browser API methods
  5566. /**
  5567. * @file fullscreen-api.js
  5568. * @module fullscreen-api
  5569. * @private
  5570. */
  5571. var apiMap = [['requestFullscreen', 'exitFullscreen', 'fullscreenElement', 'fullscreenEnabled', 'fullscreenchange', 'fullscreenerror'],
  5572. // WebKit
  5573. ['webkitRequestFullscreen', 'webkitExitFullscreen', 'webkitFullscreenElement', 'webkitFullscreenEnabled', 'webkitfullscreenchange', 'webkitfullscreenerror'],
  5574. // Old WebKit (Safari 5.1)
  5575. ['webkitRequestFullScreen', 'webkitCancelFullScreen', 'webkitCurrentFullScreenElement', 'webkitCancelFullScreen', 'webkitfullscreenchange', 'webkitfullscreenerror'],
  5576. // Mozilla
  5577. ['mozRequestFullScreen', 'mozCancelFullScreen', 'mozFullScreenElement', 'mozFullScreenEnabled', 'mozfullscreenchange', 'mozfullscreenerror'],
  5578. // Microsoft
  5579. ['msRequestFullscreen', 'msExitFullscreen', 'msFullscreenElement', 'msFullscreenEnabled', 'MSFullscreenChange', 'MSFullscreenError']];
  5580. var specApi = apiMap[0];
  5581. var browserApi = void 0;
  5582. // determine the supported set of functions
  5583. for (var i = 0; i < apiMap.length; i++) {
  5584. // check for exitFullscreen function
  5585. if (apiMap[i][1] in _document2['default']) {
  5586. browserApi = apiMap[i];
  5587. break;
  5588. }
  5589. }
  5590. // map the browser API names to the spec API names
  5591. if (browserApi) {
  5592. for (var _i = 0; _i < browserApi.length; _i++) {
  5593. FullscreenApi[specApi[_i]] = browserApi[_i];
  5594. }
  5595. }
  5596. exports['default'] = FullscreenApi;
  5597. },{"94":94}],45:[function(_dereq_,module,exports){
  5598. 'use strict';
  5599. exports.__esModule = true;
  5600. var _component = _dereq_(5);
  5601. var _component2 = _interopRequireDefault(_component);
  5602. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  5603. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  5604. 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; }
  5605. 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; } /**
  5606. * @file loading-spinner.js
  5607. */
  5608. /**
  5609. * A loading spinner for use during waiting/loading events.
  5610. *
  5611. * @extends Component
  5612. */
  5613. var LoadingSpinner = function (_Component) {
  5614. _inherits(LoadingSpinner, _Component);
  5615. function LoadingSpinner() {
  5616. _classCallCheck(this, LoadingSpinner);
  5617. return _possibleConstructorReturn(this, _Component.apply(this, arguments));
  5618. }
  5619. /**
  5620. * Create the `LoadingSpinner`s DOM element.
  5621. *
  5622. * @return {Element}
  5623. * The dom element that gets created.
  5624. */
  5625. LoadingSpinner.prototype.createEl = function createEl() {
  5626. return _Component.prototype.createEl.call(this, 'div', {
  5627. className: 'vjs-loading-spinner',
  5628. dir: 'ltr'
  5629. });
  5630. };
  5631. return LoadingSpinner;
  5632. }(_component2['default']);
  5633. _component2['default'].registerComponent('LoadingSpinner', LoadingSpinner);
  5634. exports['default'] = LoadingSpinner;
  5635. },{"5":5}],46:[function(_dereq_,module,exports){
  5636. 'use strict';
  5637. exports.__esModule = true;
  5638. var _obj = _dereq_(88);
  5639. /**
  5640. * A Custom `MediaError` class which mimics the standard HTML5 `MediaError` class.
  5641. *
  5642. * @param {number|string|Object|MediaError} value
  5643. * This can be of multiple types:
  5644. * - number: should be a standard error code
  5645. * - string: an error message (the code will be 0)
  5646. * - Object: arbitrary properties
  5647. * - `MediaError` (native): used to populate a video.js `MediaError` object
  5648. * - `MediaError` (video.js): will return itself if it's already a
  5649. * video.js `MediaError` object.
  5650. *
  5651. * @see [MediaError Spec]{@link https://dev.w3.org/html5/spec-author-view/video.html#mediaerror}
  5652. * @see [Encrypted MediaError Spec]{@link https://www.w3.org/TR/2013/WD-encrypted-media-20130510/#error-codes}
  5653. *
  5654. * @class MediaError
  5655. */
  5656. function MediaError(value) {
  5657. // Allow redundant calls to this constructor to avoid having `instanceof`
  5658. // checks peppered around the code.
  5659. if (value instanceof MediaError) {
  5660. return value;
  5661. }
  5662. if (typeof value === 'number') {
  5663. this.code = value;
  5664. } else if (typeof value === 'string') {
  5665. // default code is zero, so this is a custom error
  5666. this.message = value;
  5667. } else if ((0, _obj.isObject)(value)) {
  5668. // We assign the `code` property manually because native `MediaError` objects
  5669. // do not expose it as an own/enumerable property of the object.
  5670. if (typeof value.code === 'number') {
  5671. this.code = value.code;
  5672. }
  5673. (0, _obj.assign)(this, value);
  5674. }
  5675. if (!this.message) {
  5676. this.message = MediaError.defaultMessages[this.code] || '';
  5677. }
  5678. }
  5679. /**
  5680. * The error code that refers two one of the defined `MediaError` types
  5681. *
  5682. * @type {Number}
  5683. */
  5684. /**
  5685. * @file media-error.js
  5686. */
  5687. MediaError.prototype.code = 0;
  5688. /**
  5689. * An optional message that to show with the error. Message is not part of the HTML5
  5690. * video spec but allows for more informative custom errors.
  5691. *
  5692. * @type {String}
  5693. */
  5694. MediaError.prototype.message = '';
  5695. /**
  5696. * An optional status code that can be set by plugins to allow even more detail about
  5697. * the error. For example a plugin might provide a specific HTTP status code and an
  5698. * error message for that code. Then when the plugin gets that error this class will
  5699. * know how to display an error message for it. This allows a custom message to show
  5700. * up on the `Player` error overlay.
  5701. *
  5702. * @type {Array}
  5703. */
  5704. MediaError.prototype.status = null;
  5705. /**
  5706. * Errors indexed by the W3C standard. The order **CANNOT CHANGE**! See the
  5707. * specification listed under {@link MediaError} for more information.
  5708. *
  5709. * @enum {array}
  5710. * @readonly
  5711. * @property {string} 0 - MEDIA_ERR_CUSTOM
  5712. * @property {string} 1 - MEDIA_ERR_CUSTOM
  5713. * @property {string} 2 - MEDIA_ERR_ABORTED
  5714. * @property {string} 3 - MEDIA_ERR_NETWORK
  5715. * @property {string} 4 - MEDIA_ERR_SRC_NOT_SUPPORTED
  5716. * @property {string} 5 - MEDIA_ERR_ENCRYPTED
  5717. */
  5718. MediaError.errorTypes = ['MEDIA_ERR_CUSTOM', 'MEDIA_ERR_ABORTED', 'MEDIA_ERR_NETWORK', 'MEDIA_ERR_DECODE', 'MEDIA_ERR_SRC_NOT_SUPPORTED', 'MEDIA_ERR_ENCRYPTED'];
  5719. /**
  5720. * The default `MediaError` messages based on the {@link MediaError.errorTypes}.
  5721. *
  5722. * @type {Array}
  5723. * @constant
  5724. */
  5725. MediaError.defaultMessages = {
  5726. 1: 'You aborted the media playback',
  5727. 2: 'A network error caused the media download to fail part-way.',
  5728. 3: 'The media playback was aborted due to a corruption problem or because the media used features your browser did not support.',
  5729. 4: 'The media could not be loaded, either because the server or network failed or because the format is not supported.',
  5730. 5: 'The media is encrypted and we do not have the keys to decrypt it.'
  5731. };
  5732. // Add types as properties on MediaError
  5733. // e.g. MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED = 4;
  5734. for (var errNum = 0; errNum < MediaError.errorTypes.length; errNum++) {
  5735. MediaError[MediaError.errorTypes[errNum]] = errNum;
  5736. // values should be accessible on both the class and instance
  5737. MediaError.prototype[MediaError.errorTypes[errNum]] = errNum;
  5738. }
  5739. // jsdocs for instance/static members added above
  5740. // instance methods use `#` and static methods use `.`
  5741. /**
  5742. * W3C error code for any custom error.
  5743. *
  5744. * @member MediaError#MEDIA_ERR_CUSTOM
  5745. * @constant {number}
  5746. * @default 0
  5747. */
  5748. /**
  5749. * W3C error code for any custom error.
  5750. *
  5751. * @member MediaError.MEDIA_ERR_CUSTOM
  5752. * @constant {number}
  5753. * @default 0
  5754. */
  5755. /**
  5756. * W3C error code for media error aborted.
  5757. *
  5758. * @member MediaError#MEDIA_ERR_ABORTED
  5759. * @constant {number}
  5760. * @default 1
  5761. */
  5762. /**
  5763. * W3C error code for media error aborted.
  5764. *
  5765. * @member MediaError.MEDIA_ERR_ABORTED
  5766. * @constant {number}
  5767. * @default 1
  5768. */
  5769. /**
  5770. * W3C error code for any network error.
  5771. *
  5772. * @member MediaError#MEDIA_ERR_NETWORK
  5773. * @constant {number}
  5774. * @default 2
  5775. */
  5776. /**
  5777. * W3C error code for any network error.
  5778. *
  5779. * @member MediaError.MEDIA_ERR_NETWORK
  5780. * @constant {number}
  5781. * @default 2
  5782. */
  5783. /**
  5784. * W3C error code for any decoding error.
  5785. *
  5786. * @member MediaError#MEDIA_ERR_DECODE
  5787. * @constant {number}
  5788. * @default 3
  5789. */
  5790. /**
  5791. * W3C error code for any decoding error.
  5792. *
  5793. * @member MediaError.MEDIA_ERR_DECODE
  5794. * @constant {number}
  5795. * @default 3
  5796. */
  5797. /**
  5798. * W3C error code for any time that a source is not supported.
  5799. *
  5800. * @member MediaError#MEDIA_ERR_SRC_NOT_SUPPORTED
  5801. * @constant {number}
  5802. * @default 4
  5803. */
  5804. /**
  5805. * W3C error code for any time that a source is not supported.
  5806. *
  5807. * @member MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED
  5808. * @constant {number}
  5809. * @default 4
  5810. */
  5811. /**
  5812. * W3C error code for any time that a source is encrypted.
  5813. *
  5814. * @member MediaError#MEDIA_ERR_ENCRYPTED
  5815. * @constant {number}
  5816. * @default 5
  5817. */
  5818. /**
  5819. * W3C error code for any time that a source is encrypted.
  5820. *
  5821. * @member MediaError.MEDIA_ERR_ENCRYPTED
  5822. * @constant {number}
  5823. * @default 5
  5824. */
  5825. exports['default'] = MediaError;
  5826. },{"88":88}],47:[function(_dereq_,module,exports){
  5827. 'use strict';
  5828. exports.__esModule = true;
  5829. var _clickableComponent = _dereq_(3);
  5830. var _clickableComponent2 = _interopRequireDefault(_clickableComponent);
  5831. var _component = _dereq_(5);
  5832. var _component2 = _interopRequireDefault(_component);
  5833. var _menu = _dereq_(49);
  5834. var _menu2 = _interopRequireDefault(_menu);
  5835. var _dom = _dereq_(81);
  5836. var Dom = _interopRequireWildcard(_dom);
  5837. var _fn = _dereq_(83);
  5838. var Fn = _interopRequireWildcard(_fn);
  5839. var _toTitleCase = _dereq_(91);
  5840. var _toTitleCase2 = _interopRequireDefault(_toTitleCase);
  5841. 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; } }
  5842. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  5843. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  5844. 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; }
  5845. 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; } /**
  5846. * @file menu-button.js
  5847. */
  5848. /**
  5849. * A `MenuButton` class for any popup {@link Menu}.
  5850. *
  5851. * @extends ClickableComponent
  5852. */
  5853. var MenuButton = function (_ClickableComponent) {
  5854. _inherits(MenuButton, _ClickableComponent);
  5855. /**
  5856. * Creates an instance of this class.
  5857. *
  5858. * @param {Player} player
  5859. * The `Player` that this class should be attached to.
  5860. *
  5861. * @param {Object} [options={}]
  5862. * The key/value store of player options.
  5863. */
  5864. function MenuButton(player) {
  5865. var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  5866. _classCallCheck(this, MenuButton);
  5867. var _this = _possibleConstructorReturn(this, _ClickableComponent.call(this, player, options));
  5868. _this.update();
  5869. _this.enabled_ = true;
  5870. _this.el_.setAttribute('aria-haspopup', 'true');
  5871. _this.el_.setAttribute('role', 'menuitem');
  5872. _this.on('keydown', _this.handleSubmenuKeyPress);
  5873. return _this;
  5874. }
  5875. /**
  5876. * Update the menu based on the current state of its items.
  5877. */
  5878. MenuButton.prototype.update = function update() {
  5879. var menu = this.createMenu();
  5880. if (this.menu) {
  5881. this.removeChild(this.menu);
  5882. }
  5883. this.menu = menu;
  5884. this.addChild(menu);
  5885. /**
  5886. * Track the state of the menu button
  5887. *
  5888. * @type {Boolean}
  5889. * @private
  5890. */
  5891. this.buttonPressed_ = false;
  5892. this.el_.setAttribute('aria-expanded', 'false');
  5893. if (this.items && this.items.length === 0) {
  5894. this.hide();
  5895. } else if (this.items && this.items.length > 1) {
  5896. this.show();
  5897. }
  5898. };
  5899. /**
  5900. * Create the menu and add all items to it.
  5901. *
  5902. * @return {Menu}
  5903. * The constructed menu
  5904. */
  5905. MenuButton.prototype.createMenu = function createMenu() {
  5906. var menu = new _menu2['default'](this.player_);
  5907. // Add a title list item to the top
  5908. if (this.options_.title) {
  5909. var title = Dom.createEl('li', {
  5910. className: 'vjs-menu-title',
  5911. innerHTML: (0, _toTitleCase2['default'])(this.options_.title),
  5912. tabIndex: -1
  5913. });
  5914. menu.children_.unshift(title);
  5915. Dom.insertElFirst(title, menu.contentEl());
  5916. }
  5917. this.items = this.createItems();
  5918. if (this.items) {
  5919. // Add menu items to the menu
  5920. for (var i = 0; i < this.items.length; i++) {
  5921. menu.addItem(this.items[i]);
  5922. }
  5923. }
  5924. return menu;
  5925. };
  5926. /**
  5927. * Create the list of menu items. Specific to each subclass.
  5928. *
  5929. * @abstract
  5930. */
  5931. MenuButton.prototype.createItems = function createItems() {};
  5932. /**
  5933. * Create the `MenuButtons`s DOM element.
  5934. *
  5935. * @return {Element}
  5936. * The element that gets created.
  5937. */
  5938. MenuButton.prototype.createEl = function createEl() {
  5939. return _ClickableComponent.prototype.createEl.call(this, 'div', {
  5940. className: this.buildCSSClass()
  5941. });
  5942. };
  5943. /**
  5944. * Builds the default DOM `className`.
  5945. *
  5946. * @return {string}
  5947. * The DOM `className` for this object.
  5948. */
  5949. MenuButton.prototype.buildCSSClass = function buildCSSClass() {
  5950. var menuButtonClass = 'vjs-menu-button';
  5951. // If the inline option is passed, we want to use different styles altogether.
  5952. if (this.options_.inline === true) {
  5953. menuButtonClass += '-inline';
  5954. } else {
  5955. menuButtonClass += '-popup';
  5956. }
  5957. return 'vjs-menu-button ' + menuButtonClass + ' ' + _ClickableComponent.prototype.buildCSSClass.call(this);
  5958. };
  5959. /**
  5960. * Handle a click on a `MenuButton`.
  5961. * See {@link ClickableComponent#handleClick} for instances where this is called.
  5962. *
  5963. * @param {EventTarget~Event} event
  5964. * The `keydown`, `tap`, or `click` event that caused this function to be
  5965. * called.
  5966. *
  5967. * @listens tap
  5968. * @listens click
  5969. */
  5970. MenuButton.prototype.handleClick = function handleClick(event) {
  5971. // When you click the button it adds focus, which will show the menu.
  5972. // So we'll remove focus when the mouse leaves the button. Focus is needed
  5973. // for tab navigation.
  5974. this.one(this.menu.contentEl(), 'mouseleave', Fn.bind(this, function (e) {
  5975. this.unpressButton();
  5976. this.el_.blur();
  5977. }));
  5978. if (this.buttonPressed_) {
  5979. this.unpressButton();
  5980. } else {
  5981. this.pressButton();
  5982. }
  5983. };
  5984. /**
  5985. * Handle tab, escape, down arrow, and up arrow keys for `MenuButton`. See
  5986. * {@link ClickableComponent#handleKeyPress} for instances where this is called.
  5987. *
  5988. * @param {EventTarget~Event} event
  5989. * The `keydown` event that caused this function to be called.
  5990. *
  5991. * @listens keydown
  5992. */
  5993. MenuButton.prototype.handleKeyPress = function handleKeyPress(event) {
  5994. // Escape (27) key or Tab (9) key unpress the 'button'
  5995. if (event.which === 27 || event.which === 9) {
  5996. if (this.buttonPressed_) {
  5997. this.unpressButton();
  5998. }
  5999. // Don't preventDefault for Tab key - we still want to lose focus
  6000. if (event.which !== 9) {
  6001. event.preventDefault();
  6002. }
  6003. // Up (38) key or Down (40) key press the 'button'
  6004. } else if (event.which === 38 || event.which === 40) {
  6005. if (!this.buttonPressed_) {
  6006. this.pressButton();
  6007. event.preventDefault();
  6008. }
  6009. } else {
  6010. _ClickableComponent.prototype.handleKeyPress.call(this, event);
  6011. }
  6012. };
  6013. /**
  6014. * Handle a `keydown` event on a sub-menu. The listener for this is added in
  6015. * the constructor.
  6016. *
  6017. * @param {EventTarget~Event} event
  6018. * Key press event
  6019. *
  6020. * @listens keydown
  6021. */
  6022. MenuButton.prototype.handleSubmenuKeyPress = function handleSubmenuKeyPress(event) {
  6023. // Escape (27) key or Tab (9) key unpress the 'button'
  6024. if (event.which === 27 || event.which === 9) {
  6025. if (this.buttonPressed_) {
  6026. this.unpressButton();
  6027. }
  6028. // Don't preventDefault for Tab key - we still want to lose focus
  6029. if (event.which !== 9) {
  6030. event.preventDefault();
  6031. }
  6032. }
  6033. };
  6034. /**
  6035. * Put the current `MenuButton` into a pressed state.
  6036. */
  6037. MenuButton.prototype.pressButton = function pressButton() {
  6038. if (this.enabled_) {
  6039. this.buttonPressed_ = true;
  6040. this.menu.lockShowing();
  6041. this.el_.setAttribute('aria-expanded', 'true');
  6042. // set the focus into the submenu
  6043. this.menu.focus();
  6044. }
  6045. };
  6046. /**
  6047. * Take the current `MenuButton` out of a pressed state.
  6048. */
  6049. MenuButton.prototype.unpressButton = function unpressButton() {
  6050. if (this.enabled_) {
  6051. this.buttonPressed_ = false;
  6052. this.menu.unlockShowing();
  6053. this.el_.setAttribute('aria-expanded', 'false');
  6054. // Set focus back to this menu button
  6055. this.el_.focus();
  6056. }
  6057. };
  6058. /**
  6059. * Disable the `MenuButton`. Don't allow it to be clicked.
  6060. *
  6061. * @return {MenuButton}
  6062. * Returns itself; method can be chained.
  6063. */
  6064. MenuButton.prototype.disable = function disable() {
  6065. // Unpress, but don't force focus on this button
  6066. this.buttonPressed_ = false;
  6067. this.menu.unlockShowing();
  6068. this.el_.setAttribute('aria-expanded', 'false');
  6069. this.enabled_ = false;
  6070. return _ClickableComponent.prototype.disable.call(this);
  6071. };
  6072. /**
  6073. * Enable the `MenuButton`. Allow it to be clicked.
  6074. *
  6075. * @return {MenuButton}
  6076. * Returns itself; method can be chained.
  6077. */
  6078. MenuButton.prototype.enable = function enable() {
  6079. this.enabled_ = true;
  6080. return _ClickableComponent.prototype.enable.call(this);
  6081. };
  6082. return MenuButton;
  6083. }(_clickableComponent2['default']);
  6084. _component2['default'].registerComponent('MenuButton', MenuButton);
  6085. exports['default'] = MenuButton;
  6086. },{"3":3,"49":49,"5":5,"81":81,"83":83,"91":91}],48:[function(_dereq_,module,exports){
  6087. 'use strict';
  6088. exports.__esModule = true;
  6089. var _clickableComponent = _dereq_(3);
  6090. var _clickableComponent2 = _interopRequireDefault(_clickableComponent);
  6091. var _component = _dereq_(5);
  6092. var _component2 = _interopRequireDefault(_component);
  6093. var _obj = _dereq_(88);
  6094. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  6095. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  6096. 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; }
  6097. 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; } /**
  6098. * @file menu-item.js
  6099. */
  6100. /**
  6101. * The component for a menu item. `<li>`
  6102. *
  6103. * @extends ClickableComponent
  6104. */
  6105. var MenuItem = function (_ClickableComponent) {
  6106. _inherits(MenuItem, _ClickableComponent);
  6107. /**
  6108. * Creates an instance of the this class.
  6109. *
  6110. * @param {Player} player
  6111. * The `Player` that this class should be attached to.
  6112. *
  6113. * @param {Object} [options={}]
  6114. * The key/value store of player options.
  6115. *
  6116. */
  6117. function MenuItem(player, options) {
  6118. _classCallCheck(this, MenuItem);
  6119. var _this = _possibleConstructorReturn(this, _ClickableComponent.call(this, player, options));
  6120. _this.selectable = options.selectable;
  6121. _this.selected(options.selected);
  6122. if (_this.selectable) {
  6123. // TODO: May need to be either menuitemcheckbox or menuitemradio,
  6124. // and may need logical grouping of menu items.
  6125. _this.el_.setAttribute('role', 'menuitemcheckbox');
  6126. } else {
  6127. _this.el_.setAttribute('role', 'menuitem');
  6128. }
  6129. return _this;
  6130. }
  6131. /**
  6132. * Create the `MenuItem's DOM element
  6133. *
  6134. * @param {string} [type=li]
  6135. * Element's node type, not actually used, always set to `li`.
  6136. *
  6137. * @param {Object} [props={}]
  6138. * An object of properties that should be set on the element
  6139. *
  6140. * @param {Object} [attrs={}]
  6141. * An object of attributes that should be set on the element
  6142. *
  6143. * @return {Element}
  6144. * The element that gets created.
  6145. */
  6146. MenuItem.prototype.createEl = function createEl(type, props, attrs) {
  6147. return _ClickableComponent.prototype.createEl.call(this, 'li', (0, _obj.assign)({
  6148. className: 'vjs-menu-item',
  6149. innerHTML: this.localize(this.options_.label),
  6150. tabIndex: -1
  6151. }, props), attrs);
  6152. };
  6153. /**
  6154. * Any click on a `MenuItem` puts int into the selected state.
  6155. * See {@link ClickableComponent#handleClick} for instances where this is called.
  6156. *
  6157. * @param {EventTarget~Event} event
  6158. * The `keydown`, `tap`, or `click` event that caused this function to be
  6159. * called.
  6160. *
  6161. * @listens tap
  6162. * @listens click
  6163. */
  6164. MenuItem.prototype.handleClick = function handleClick(event) {
  6165. this.selected(true);
  6166. };
  6167. /**
  6168. * Set the state for this menu item as selected or not.
  6169. *
  6170. * @param {boolean} selected
  6171. * if the menu item is selected or not
  6172. */
  6173. MenuItem.prototype.selected = function selected(_selected) {
  6174. if (this.selectable) {
  6175. if (_selected) {
  6176. this.addClass('vjs-selected');
  6177. this.el_.setAttribute('aria-checked', 'true');
  6178. // aria-checked isn't fully supported by browsers/screen readers,
  6179. // so indicate selected state to screen reader in the control text.
  6180. this.controlText(', selected');
  6181. } else {
  6182. this.removeClass('vjs-selected');
  6183. this.el_.setAttribute('aria-checked', 'false');
  6184. // Indicate un-selected state to screen reader
  6185. // Note that a space clears out the selected state text
  6186. this.controlText(' ');
  6187. }
  6188. }
  6189. };
  6190. return MenuItem;
  6191. }(_clickableComponent2['default']);
  6192. _component2['default'].registerComponent('MenuItem', MenuItem);
  6193. exports['default'] = MenuItem;
  6194. },{"3":3,"5":5,"88":88}],49:[function(_dereq_,module,exports){
  6195. 'use strict';
  6196. exports.__esModule = true;
  6197. var _component = _dereq_(5);
  6198. var _component2 = _interopRequireDefault(_component);
  6199. var _dom = _dereq_(81);
  6200. var Dom = _interopRequireWildcard(_dom);
  6201. var _fn = _dereq_(83);
  6202. var Fn = _interopRequireWildcard(_fn);
  6203. var _events = _dereq_(82);
  6204. var Events = _interopRequireWildcard(_events);
  6205. 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; } }
  6206. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  6207. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  6208. 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; }
  6209. 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; } /**
  6210. * @file menu.js
  6211. */
  6212. /**
  6213. * The Menu component is used to build popup menus, including subtitle and
  6214. * captions selection menus.
  6215. *
  6216. * @extends Component
  6217. */
  6218. var Menu = function (_Component) {
  6219. _inherits(Menu, _Component);
  6220. /**
  6221. * Create an instance of this class.
  6222. *
  6223. * @param {Player} player
  6224. * the player that this component should attach to
  6225. *
  6226. * @param {Object} [options]
  6227. * Object of option names and values
  6228. *
  6229. */
  6230. function Menu(player, options) {
  6231. _classCallCheck(this, Menu);
  6232. var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
  6233. _this.focusedChild_ = -1;
  6234. _this.on('keydown', _this.handleKeyPress);
  6235. return _this;
  6236. }
  6237. /**
  6238. * Add a {@link MenuItem} to the menu.
  6239. *
  6240. * @param {Object|string} component
  6241. * The name or instance of the `MenuItem` to add.
  6242. *
  6243. */
  6244. Menu.prototype.addItem = function addItem(component) {
  6245. this.addChild(component);
  6246. component.on('click', Fn.bind(this, function (event) {
  6247. this.unlockShowing();
  6248. // TODO: Need to set keyboard focus back to the menuButton
  6249. }));
  6250. };
  6251. /**
  6252. * Create the `Menu`s DOM element.
  6253. *
  6254. * @return {Element}
  6255. * the element that was created
  6256. */
  6257. Menu.prototype.createEl = function createEl() {
  6258. var contentElType = this.options_.contentElType || 'ul';
  6259. this.contentEl_ = Dom.createEl(contentElType, {
  6260. className: 'vjs-menu-content'
  6261. });
  6262. this.contentEl_.setAttribute('role', 'menu');
  6263. var el = _Component.prototype.createEl.call(this, 'div', {
  6264. append: this.contentEl_,
  6265. className: 'vjs-menu'
  6266. });
  6267. el.setAttribute('role', 'presentation');
  6268. el.appendChild(this.contentEl_);
  6269. // Prevent clicks from bubbling up. Needed for Menu Buttons,
  6270. // where a click on the parent is significant
  6271. Events.on(el, 'click', function (event) {
  6272. event.preventDefault();
  6273. event.stopImmediatePropagation();
  6274. });
  6275. return el;
  6276. };
  6277. /**
  6278. * Handle a `keydown` event on this menu. This listener is added in the constructor.
  6279. *
  6280. * @param {EventTarget~Event} event
  6281. * A `keydown` event that happened on the menu.
  6282. *
  6283. * @listens keydown
  6284. */
  6285. Menu.prototype.handleKeyPress = function handleKeyPress(event) {
  6286. // Left and Down Arrows
  6287. if (event.which === 37 || event.which === 40) {
  6288. event.preventDefault();
  6289. this.stepForward();
  6290. // Up and Right Arrows
  6291. } else if (event.which === 38 || event.which === 39) {
  6292. event.preventDefault();
  6293. this.stepBack();
  6294. }
  6295. };
  6296. /**
  6297. * Move to next (lower) menu item for keyboard users.
  6298. */
  6299. Menu.prototype.stepForward = function stepForward() {
  6300. var stepChild = 0;
  6301. if (this.focusedChild_ !== undefined) {
  6302. stepChild = this.focusedChild_ + 1;
  6303. }
  6304. this.focus(stepChild);
  6305. };
  6306. /**
  6307. * Move to previous (higher) menu item for keyboard users.
  6308. */
  6309. Menu.prototype.stepBack = function stepBack() {
  6310. var stepChild = 0;
  6311. if (this.focusedChild_ !== undefined) {
  6312. stepChild = this.focusedChild_ - 1;
  6313. }
  6314. this.focus(stepChild);
  6315. };
  6316. /**
  6317. * Set focus on a {@link MenuItem} in the `Menu`.
  6318. *
  6319. * @param {Object|string} [item=0]
  6320. * Index of child item set focus on.
  6321. */
  6322. Menu.prototype.focus = function focus() {
  6323. var item = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
  6324. var children = this.children().slice();
  6325. var haveTitle = children.length && children[0].className && /vjs-menu-title/.test(children[0].className);
  6326. if (haveTitle) {
  6327. children.shift();
  6328. }
  6329. if (children.length > 0) {
  6330. if (item < 0) {
  6331. item = 0;
  6332. } else if (item >= children.length) {
  6333. item = children.length - 1;
  6334. }
  6335. this.focusedChild_ = item;
  6336. children[item].el_.focus();
  6337. }
  6338. };
  6339. return Menu;
  6340. }(_component2['default']);
  6341. _component2['default'].registerComponent('Menu', Menu);
  6342. exports['default'] = Menu;
  6343. },{"5":5,"81":81,"82":82,"83":83}],50:[function(_dereq_,module,exports){
  6344. 'use strict';
  6345. exports.__esModule = true;
  6346. var _dom = _dereq_(81);
  6347. var Dom = _interopRequireWildcard(_dom);
  6348. var _fn = _dereq_(83);
  6349. var Fn = _interopRequireWildcard(_fn);
  6350. var _component = _dereq_(5);
  6351. var _component2 = _interopRequireDefault(_component);
  6352. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  6353. 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; } }
  6354. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  6355. 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; }
  6356. 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; } /**
  6357. * @file modal-dialog.js
  6358. */
  6359. var MODAL_CLASS_NAME = 'vjs-modal-dialog';
  6360. var ESC = 27;
  6361. /**
  6362. * The `ModalDialog` displays over the video and its controls, which blocks
  6363. * interaction with the player until it is closed.
  6364. *
  6365. * Modal dialogs include a "Close" button and will close when that button
  6366. * is activated - or when ESC is pressed anywhere.
  6367. *
  6368. * @extends Component
  6369. */
  6370. var ModalDialog = function (_Component) {
  6371. _inherits(ModalDialog, _Component);
  6372. /**
  6373. * Create an instance of this class.
  6374. *
  6375. * @param {Player} player
  6376. * The `Player` that this class should be attached to.
  6377. *
  6378. * @param {Object} [options]
  6379. * The key/value store of player options.
  6380. *
  6381. * @param {Mixed} [options.content=undefined]
  6382. * Provide customized content for this modal.
  6383. *
  6384. * @param {string} [options.description]
  6385. * A text description for the modal, primarily for accessibility.
  6386. *
  6387. * @param {boolean} [options.fillAlways=false]
  6388. * Normally, modals are automatically filled only the first time
  6389. * they open. This tells the modal to refresh its content
  6390. * every time it opens.
  6391. *
  6392. * @param {string} [options.label]
  6393. * A text label for the modal, primarily for accessibility.
  6394. *
  6395. * @param {boolean} [options.temporary=true]
  6396. * If `true`, the modal can only be opened once; it will be
  6397. * disposed as soon as it's closed.
  6398. *
  6399. * @param {boolean} [options.uncloseable=false]
  6400. * If `true`, the user will not be able to close the modal
  6401. * through the UI in the normal ways. Programmatic closing is
  6402. * still possible.
  6403. */
  6404. function ModalDialog(player, options) {
  6405. _classCallCheck(this, ModalDialog);
  6406. var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
  6407. _this.opened_ = _this.hasBeenOpened_ = _this.hasBeenFilled_ = false;
  6408. _this.closeable(!_this.options_.uncloseable);
  6409. _this.content(_this.options_.content);
  6410. // Make sure the contentEl is defined AFTER any children are initialized
  6411. // because we only want the contents of the modal in the contentEl
  6412. // (not the UI elements like the close button).
  6413. _this.contentEl_ = Dom.createEl('div', {
  6414. className: MODAL_CLASS_NAME + '-content'
  6415. }, {
  6416. role: 'document'
  6417. });
  6418. _this.descEl_ = Dom.createEl('p', {
  6419. className: MODAL_CLASS_NAME + '-description vjs-offscreen',
  6420. id: _this.el().getAttribute('aria-describedby')
  6421. });
  6422. Dom.textContent(_this.descEl_, _this.description());
  6423. _this.el_.appendChild(_this.descEl_);
  6424. _this.el_.appendChild(_this.contentEl_);
  6425. return _this;
  6426. }
  6427. /**
  6428. * Create the `ModalDialog`'s DOM element
  6429. *
  6430. * @return {Element}
  6431. * The DOM element that gets created.
  6432. */
  6433. ModalDialog.prototype.createEl = function createEl() {
  6434. return _Component.prototype.createEl.call(this, 'div', {
  6435. className: this.buildCSSClass(),
  6436. tabIndex: -1
  6437. }, {
  6438. 'aria-describedby': this.id() + '_description',
  6439. 'aria-hidden': 'true',
  6440. 'aria-label': this.label(),
  6441. 'role': 'dialog'
  6442. });
  6443. };
  6444. /**
  6445. * Builds the default DOM `className`.
  6446. *
  6447. * @return {string}
  6448. * The DOM `className` for this object.
  6449. */
  6450. ModalDialog.prototype.buildCSSClass = function buildCSSClass() {
  6451. return MODAL_CLASS_NAME + ' vjs-hidden ' + _Component.prototype.buildCSSClass.call(this);
  6452. };
  6453. /**
  6454. * Handles `keydown` events on the document, looking for ESC, which closes
  6455. * the modal.
  6456. *
  6457. * @param {EventTarget~Event} e
  6458. * The keypress that triggered this event.
  6459. *
  6460. * @listens keydown
  6461. */
  6462. ModalDialog.prototype.handleKeyPress = function handleKeyPress(e) {
  6463. if (e.which === ESC && this.closeable()) {
  6464. this.close();
  6465. }
  6466. };
  6467. /**
  6468. * Returns the label string for this modal. Primarily used for accessibility.
  6469. *
  6470. * @return {string}
  6471. * the localized or raw label of this modal.
  6472. */
  6473. ModalDialog.prototype.label = function label() {
  6474. return this.options_.label || this.localize('Modal Window');
  6475. };
  6476. /**
  6477. * Returns the description string for this modal. Primarily used for
  6478. * accessibility.
  6479. *
  6480. * @return {string}
  6481. * The localized or raw description of this modal.
  6482. */
  6483. ModalDialog.prototype.description = function description() {
  6484. var desc = this.options_.description || this.localize('This is a modal window.');
  6485. // Append a universal closeability message if the modal is closeable.
  6486. if (this.closeable()) {
  6487. desc += ' ' + this.localize('This modal can be closed by pressing the Escape key or activating the close button.');
  6488. }
  6489. return desc;
  6490. };
  6491. /**
  6492. * Opens the modal.
  6493. *
  6494. * @fires ModalDialog#beforemodalopen
  6495. * @fires ModalDialog#modalopen
  6496. *
  6497. * @return {ModalDialog}
  6498. * Returns itself; method can be chained.
  6499. */
  6500. ModalDialog.prototype.open = function open() {
  6501. if (!this.opened_) {
  6502. var player = this.player();
  6503. /**
  6504. * Fired just before a `ModalDialog` is opened.
  6505. *
  6506. * @event ModalDialog#beforemodalopen
  6507. * @type {EventTarget~Event}
  6508. */
  6509. this.trigger('beforemodalopen');
  6510. this.opened_ = true;
  6511. // Fill content if the modal has never opened before and
  6512. // never been filled.
  6513. if (this.options_.fillAlways || !this.hasBeenOpened_ && !this.hasBeenFilled_) {
  6514. this.fill();
  6515. }
  6516. // If the player was playing, pause it and take note of its previously
  6517. // playing state.
  6518. this.wasPlaying_ = !player.paused();
  6519. if (this.wasPlaying_) {
  6520. player.pause();
  6521. }
  6522. if (this.closeable()) {
  6523. this.on(this.el_.ownerDocument, 'keydown', Fn.bind(this, this.handleKeyPress));
  6524. }
  6525. player.controls(false);
  6526. this.show();
  6527. this.el().setAttribute('aria-hidden', 'false');
  6528. /**
  6529. * Fired just after a `ModalDialog` is opened.
  6530. *
  6531. * @event ModalDialog#modalopen
  6532. * @type {EventTarget~Event}
  6533. */
  6534. this.trigger('modalopen');
  6535. this.hasBeenOpened_ = true;
  6536. }
  6537. return this;
  6538. };
  6539. /**
  6540. * If the `ModalDialog` is currently open or closed.
  6541. *
  6542. * @param {boolean} [value]
  6543. * If given, it will open (`true`) or close (`false`) the modal.
  6544. *
  6545. * @return {boolean}
  6546. * the current open state of the modaldialog
  6547. */
  6548. ModalDialog.prototype.opened = function opened(value) {
  6549. if (typeof value === 'boolean') {
  6550. this[value ? 'open' : 'close']();
  6551. }
  6552. return this.opened_;
  6553. };
  6554. /**
  6555. * Closes the modal, does nothing if the `ModalDialog` is
  6556. * not open.
  6557. *
  6558. * @fires ModalDialog#beforemodalclose
  6559. * @fires ModalDialog#modalclose
  6560. *
  6561. * @return {ModalDialog}
  6562. * Returns itself; method can be chained.
  6563. */
  6564. ModalDialog.prototype.close = function close() {
  6565. if (this.opened_) {
  6566. var player = this.player();
  6567. /**
  6568. * Fired just before a `ModalDialog` is closed.
  6569. *
  6570. * @event ModalDialog#beforemodalclose
  6571. * @type {EventTarget~Event}
  6572. */
  6573. this.trigger('beforemodalclose');
  6574. this.opened_ = false;
  6575. if (this.wasPlaying_) {
  6576. player.play();
  6577. }
  6578. if (this.closeable()) {
  6579. this.off(this.el_.ownerDocument, 'keydown', Fn.bind(this, this.handleKeyPress));
  6580. }
  6581. player.controls(true);
  6582. this.hide();
  6583. this.el().setAttribute('aria-hidden', 'true');
  6584. /**
  6585. * Fired just after a `ModalDialog` is closed.
  6586. *
  6587. * @event ModalDialog#modalclose
  6588. * @type {EventTarget~Event}
  6589. */
  6590. this.trigger('modalclose');
  6591. if (this.options_.temporary) {
  6592. this.dispose();
  6593. }
  6594. }
  6595. return this;
  6596. };
  6597. /**
  6598. * Check to see if the `ModalDialog` is closeable via the UI.
  6599. *
  6600. * @param {boolean} [value]
  6601. * If given as a boolean, it will set the `closeable` option.
  6602. *
  6603. * @return {boolean}
  6604. * Returns the final value of the closable option.
  6605. */
  6606. ModalDialog.prototype.closeable = function closeable(value) {
  6607. if (typeof value === 'boolean') {
  6608. var closeable = this.closeable_ = !!value;
  6609. var close = this.getChild('closeButton');
  6610. // If this is being made closeable and has no close button, add one.
  6611. if (closeable && !close) {
  6612. // The close button should be a child of the modal - not its
  6613. // content element, so temporarily change the content element.
  6614. var temp = this.contentEl_;
  6615. this.contentEl_ = this.el_;
  6616. close = this.addChild('closeButton', { controlText: 'Close Modal Dialog' });
  6617. this.contentEl_ = temp;
  6618. this.on(close, 'close', this.close);
  6619. }
  6620. // If this is being made uncloseable and has a close button, remove it.
  6621. if (!closeable && close) {
  6622. this.off(close, 'close', this.close);
  6623. this.removeChild(close);
  6624. close.dispose();
  6625. }
  6626. }
  6627. return this.closeable_;
  6628. };
  6629. /**
  6630. * Fill the modal's content element with the modal's "content" option.
  6631. * The content element will be emptied before this change takes place.
  6632. *
  6633. * @return {ModalDialog}
  6634. * Returns itself; method can be chained.
  6635. */
  6636. ModalDialog.prototype.fill = function fill() {
  6637. return this.fillWith(this.content());
  6638. };
  6639. /**
  6640. * Fill the modal's content element with arbitrary content.
  6641. * The content element will be emptied before this change takes place.
  6642. *
  6643. * @fires ModalDialog#beforemodalfill
  6644. * @fires ModalDialog#modalfill
  6645. *
  6646. * @param {Mixed} [content]
  6647. * The same rules apply to this as apply to the `content` option.
  6648. *
  6649. * @return {ModalDialog}
  6650. * Returns itself; method can be chained.
  6651. */
  6652. ModalDialog.prototype.fillWith = function fillWith(content) {
  6653. var contentEl = this.contentEl();
  6654. var parentEl = contentEl.parentNode;
  6655. var nextSiblingEl = contentEl.nextSibling;
  6656. /**
  6657. * Fired just before a `ModalDialog` is filled with content.
  6658. *
  6659. * @event ModalDialog#beforemodalfill
  6660. * @type {EventTarget~Event}
  6661. */
  6662. this.trigger('beforemodalfill');
  6663. this.hasBeenFilled_ = true;
  6664. // Detach the content element from the DOM before performing
  6665. // manipulation to avoid modifying the live DOM multiple times.
  6666. parentEl.removeChild(contentEl);
  6667. this.empty();
  6668. Dom.insertContent(contentEl, content);
  6669. /**
  6670. * Fired just after a `ModalDialog` is filled with content.
  6671. *
  6672. * @event ModalDialog#modalfill
  6673. * @type {EventTarget~Event}
  6674. */
  6675. this.trigger('modalfill');
  6676. // Re-inject the re-filled content element.
  6677. if (nextSiblingEl) {
  6678. parentEl.insertBefore(contentEl, nextSiblingEl);
  6679. } else {
  6680. parentEl.appendChild(contentEl);
  6681. }
  6682. return this;
  6683. };
  6684. /**
  6685. * Empties the content element. This happens anytime the modal is filled.
  6686. *
  6687. * @fires ModalDialog#beforemodalempty
  6688. * @fires ModalDialog#modalempty
  6689. *
  6690. * @return {ModalDialog}
  6691. * Returns itself; method can be chained.
  6692. */
  6693. ModalDialog.prototype.empty = function empty() {
  6694. /**
  6695. * Fired just before a `ModalDialog` is emptied.
  6696. *
  6697. * @event ModalDialog#beforemodalempty
  6698. * @type {EventTarget~Event}
  6699. */
  6700. this.trigger('beforemodalempty');
  6701. Dom.emptyEl(this.contentEl());
  6702. /**
  6703. * Fired just after a `ModalDialog` is emptied.
  6704. *
  6705. * @event ModalDialog#modalempty
  6706. * @type {EventTarget~Event}
  6707. */
  6708. this.trigger('modalempty');
  6709. return this;
  6710. };
  6711. /**
  6712. * Gets or sets the modal content, which gets normalized before being
  6713. * rendered into the DOM.
  6714. *
  6715. * This does not update the DOM or fill the modal, but it is called during
  6716. * that process.
  6717. *
  6718. * @param {Mixed} [value]
  6719. * If defined, sets the internal content value to be used on the
  6720. * next call(s) to `fill`. This value is normalized before being
  6721. * inserted. To "clear" the internal content value, pass `null`.
  6722. *
  6723. * @return {Mixed}
  6724. * The current content of the modal dialog
  6725. */
  6726. ModalDialog.prototype.content = function content(value) {
  6727. if (typeof value !== 'undefined') {
  6728. this.content_ = value;
  6729. }
  6730. return this.content_;
  6731. };
  6732. return ModalDialog;
  6733. }(_component2['default']);
  6734. /**
  6735. * Default options for `ModalDialog` default options.
  6736. *
  6737. * @type {Object}
  6738. * @private
  6739. */
  6740. ModalDialog.prototype.options_ = {
  6741. temporary: true
  6742. };
  6743. _component2['default'].registerComponent('ModalDialog', ModalDialog);
  6744. exports['default'] = ModalDialog;
  6745. },{"5":5,"81":81,"83":83}],51:[function(_dereq_,module,exports){
  6746. 'use strict';
  6747. exports.__esModule = true;
  6748. var _component = _dereq_(5);
  6749. var _component2 = _interopRequireDefault(_component);
  6750. var _document = _dereq_(94);
  6751. var _document2 = _interopRequireDefault(_document);
  6752. var _window = _dereq_(95);
  6753. var _window2 = _interopRequireDefault(_window);
  6754. var _events = _dereq_(82);
  6755. var Events = _interopRequireWildcard(_events);
  6756. var _dom = _dereq_(81);
  6757. var Dom = _interopRequireWildcard(_dom);
  6758. var _fn = _dereq_(83);
  6759. var Fn = _interopRequireWildcard(_fn);
  6760. var _guid = _dereq_(85);
  6761. var Guid = _interopRequireWildcard(_guid);
  6762. var _browser = _dereq_(78);
  6763. var browser = _interopRequireWildcard(_browser);
  6764. var _log = _dereq_(86);
  6765. var _log2 = _interopRequireDefault(_log);
  6766. var _toTitleCase = _dereq_(91);
  6767. var _toTitleCase2 = _interopRequireDefault(_toTitleCase);
  6768. var _timeRanges = _dereq_(90);
  6769. var _buffer = _dereq_(79);
  6770. var _stylesheet = _dereq_(89);
  6771. var stylesheet = _interopRequireWildcard(_stylesheet);
  6772. var _fullscreenApi = _dereq_(44);
  6773. var _fullscreenApi2 = _interopRequireDefault(_fullscreenApi);
  6774. var _mediaError = _dereq_(46);
  6775. var _mediaError2 = _interopRequireDefault(_mediaError);
  6776. var _tuple = _dereq_(97);
  6777. var _tuple2 = _interopRequireDefault(_tuple);
  6778. var _obj = _dereq_(88);
  6779. var _mergeOptions = _dereq_(87);
  6780. var _mergeOptions2 = _interopRequireDefault(_mergeOptions);
  6781. var _textTrackListConverter = _dereq_(69);
  6782. var _textTrackListConverter2 = _interopRequireDefault(_textTrackListConverter);
  6783. var _modalDialog = _dereq_(50);
  6784. var _modalDialog2 = _interopRequireDefault(_modalDialog);
  6785. var _tech = _dereq_(62);
  6786. var _tech2 = _interopRequireDefault(_tech);
  6787. var _audioTrackList = _dereq_(63);
  6788. var _audioTrackList2 = _interopRequireDefault(_audioTrackList);
  6789. var _videoTrackList = _dereq_(76);
  6790. var _videoTrackList2 = _interopRequireDefault(_videoTrackList);
  6791. _dereq_(61);
  6792. _dereq_(59);
  6793. _dereq_(55);
  6794. _dereq_(68);
  6795. _dereq_(45);
  6796. _dereq_(1);
  6797. _dereq_(4);
  6798. _dereq_(8);
  6799. _dereq_(41);
  6800. _dereq_(71);
  6801. _dereq_(60);
  6802. 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; } }
  6803. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  6804. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  6805. 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; }
  6806. 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; } /**
  6807. * @file player.js
  6808. */
  6809. // Subclasses Component
  6810. // The following imports are used only to ensure that the corresponding modules
  6811. // are always included in the video.js package. Importing the modules will
  6812. // execute them and they will register themselves with video.js.
  6813. // Import Html5 tech, at least for disposing the original video tag.
  6814. // The following tech events are simply re-triggered
  6815. // on the player when they happen
  6816. var TECH_EVENTS_RETRIGGER = [
  6817. /**
  6818. * Fired while the user agent is downloading media data.
  6819. *
  6820. * @event Player#progress
  6821. * @type {EventTarget~Event}
  6822. */
  6823. /**
  6824. * Retrigger the `progress` event that was triggered by the {@link Tech}.
  6825. *
  6826. * @private
  6827. * @method Player#handleTechProgress_
  6828. * @fires Player#progress
  6829. * @listens Tech#progress
  6830. */
  6831. 'progress',
  6832. /**
  6833. * Fires when the loading of an audio/video is aborted.
  6834. *
  6835. * @event Player#abort
  6836. * @type {EventTarget~Event}
  6837. */
  6838. /**
  6839. * Retrigger the `abort` event that was triggered by the {@link Tech}.
  6840. *
  6841. * @private
  6842. * @method Player#handleTechAbort_
  6843. * @fires Player#abort
  6844. * @listens Tech#abort
  6845. */
  6846. 'abort',
  6847. /**
  6848. * Fires when the browser is intentionally not getting media data.
  6849. *
  6850. * @event Player#suspend
  6851. * @type {EventTarget~Event}
  6852. */
  6853. /**
  6854. * Retrigger the `suspend` event that was triggered by the {@link Tech}.
  6855. *
  6856. * @private
  6857. * @method Player#handleTechSuspend_
  6858. * @fires Player#suspend
  6859. * @listens Tech#suspend
  6860. */
  6861. 'suspend',
  6862. /**
  6863. * Fires when the current playlist is empty.
  6864. *
  6865. * @event Player#emptied
  6866. * @type {EventTarget~Event}
  6867. */
  6868. /**
  6869. * Retrigger the `emptied` event that was triggered by the {@link Tech}.
  6870. *
  6871. * @private
  6872. * @method Player#handleTechEmptied_
  6873. * @fires Player#emptied
  6874. * @listens Tech#emptied
  6875. */
  6876. 'emptied',
  6877. /**
  6878. * Fires when the browser is trying to get media data, but data is not available.
  6879. *
  6880. * @event Player#stalled
  6881. * @type {EventTarget~Event}
  6882. */
  6883. /**
  6884. * Retrigger the `stalled` event that was triggered by the {@link Tech}.
  6885. *
  6886. * @private
  6887. * @method Player#handleTechStalled_
  6888. * @fires Player#stalled
  6889. * @listens Tech#stalled
  6890. */
  6891. 'stalled',
  6892. /**
  6893. * Fires when the browser has loaded meta data for the audio/video.
  6894. *
  6895. * @event Player#loadedmetadata
  6896. * @type {EventTarget~Event}
  6897. */
  6898. /**
  6899. * Retrigger the `stalled` event that was triggered by the {@link Tech}.
  6900. *
  6901. * @private
  6902. * @method Player#handleTechLoadedmetadata_
  6903. * @fires Player#loadedmetadata
  6904. * @listens Tech#loadedmetadata
  6905. */
  6906. 'loadedmetadata',
  6907. /**
  6908. * Fires when the browser has loaded the current frame of the audio/video.
  6909. *
  6910. * @event player#loadeddata
  6911. * @type {event}
  6912. */
  6913. /**
  6914. * Retrigger the `loadeddata` event that was triggered by the {@link Tech}.
  6915. *
  6916. * @private
  6917. * @method Player#handleTechLoaddeddata_
  6918. * @fires Player#loadeddata
  6919. * @listens Tech#loadeddata
  6920. */
  6921. 'loadeddata',
  6922. /**
  6923. * Fires when the current playback position has changed.
  6924. *
  6925. * @event player#timeupdate
  6926. * @type {event}
  6927. */
  6928. /**
  6929. * Retrigger the `timeupdate` event that was triggered by the {@link Tech}.
  6930. *
  6931. * @private
  6932. * @method Player#handleTechTimeUpdate_
  6933. * @fires Player#timeupdate
  6934. * @listens Tech#timeupdate
  6935. */
  6936. 'timeupdate',
  6937. /**
  6938. * Fires when the playing speed of the audio/video is changed
  6939. *
  6940. * @event player#ratechange
  6941. * @type {event}
  6942. */
  6943. /**
  6944. * Retrigger the `ratechange` event that was triggered by the {@link Tech}.
  6945. *
  6946. * @private
  6947. * @method Player#handleTechRatechange_
  6948. * @fires Player#ratechange
  6949. * @listens Tech#ratechange
  6950. */
  6951. 'ratechange',
  6952. /**
  6953. * Fires when the volume has been changed
  6954. *
  6955. * @event player#volumechange
  6956. * @type {event}
  6957. */
  6958. /**
  6959. * Retrigger the `volumechange` event that was triggered by the {@link Tech}.
  6960. *
  6961. * @private
  6962. * @method Player#handleTechVolumechange_
  6963. * @fires Player#volumechange
  6964. * @listens Tech#volumechange
  6965. */
  6966. 'volumechange',
  6967. /**
  6968. * Fires when the text track has been changed
  6969. *
  6970. * @event player#texttrackchange
  6971. * @type {event}
  6972. */
  6973. /**
  6974. * Retrigger the `texttrackchange` event that was triggered by the {@link Tech}.
  6975. *
  6976. * @private
  6977. * @method Player#handleTechTexttrackchange_
  6978. * @fires Player#texttrackchange
  6979. * @listens Tech#texttrackchange
  6980. */
  6981. 'texttrackchange'];
  6982. /**
  6983. * An instance of the `Player` class is created when any of the Video.js setup methods
  6984. * are used to initialize a video.
  6985. *
  6986. * After an instance has been created it can be accessed globally in two ways:
  6987. * 1. By calling `videojs('example_video_1');`
  6988. * 2. By using it directly via `videojs.players.example_video_1;`
  6989. *
  6990. * @extends Component
  6991. */
  6992. var Player = function (_Component) {
  6993. _inherits(Player, _Component);
  6994. /**
  6995. * Create an instance of this class.
  6996. *
  6997. * @param {Element} tag
  6998. * The original video DOM element used for configuring options.
  6999. *
  7000. * @param {Object} [options]
  7001. * Object of option names and values.
  7002. *
  7003. * @param {Component~ReadyCallback} [ready]
  7004. * Ready callback function.
  7005. */
  7006. function Player(tag, options, ready) {
  7007. _classCallCheck(this, Player);
  7008. // Make sure tag ID exists
  7009. tag.id = tag.id || 'vjs_video_' + Guid.newGUID();
  7010. // Set Options
  7011. // The options argument overrides options set in the video tag
  7012. // which overrides globally set options.
  7013. // This latter part coincides with the load order
  7014. // (tag must exist before Player)
  7015. options = (0, _obj.assign)(Player.getTagSettings(tag), options);
  7016. // Delay the initialization of children because we need to set up
  7017. // player properties first, and can't use `this` before `super()`
  7018. options.initChildren = false;
  7019. // Same with creating the element
  7020. options.createEl = false;
  7021. // we don't want the player to report touch activity on itself
  7022. // see enableTouchActivity in Component
  7023. options.reportTouchActivity = false;
  7024. // If language is not set, get the closest lang attribute
  7025. if (!options.language) {
  7026. if (typeof tag.closest === 'function') {
  7027. var closest = tag.closest('[lang]');
  7028. if (closest) {
  7029. options.language = closest.getAttribute('lang');
  7030. }
  7031. } else {
  7032. var element = tag;
  7033. while (element && element.nodeType === 1) {
  7034. if (Dom.getElAttributes(element).hasOwnProperty('lang')) {
  7035. options.language = element.getAttribute('lang');
  7036. break;
  7037. }
  7038. element = element.parentNode;
  7039. }
  7040. }
  7041. }
  7042. // Run base component initializing with new options
  7043. // if the global option object was accidentally blown away by
  7044. // someone, bail early with an informative error
  7045. var _this = _possibleConstructorReturn(this, _Component.call(this, null, options, ready));
  7046. if (!_this.options_ || !_this.options_.techOrder || !_this.options_.techOrder.length) {
  7047. throw new Error('No techOrder specified. Did you overwrite ' + 'videojs.options instead of just changing the ' + 'properties you want to override?');
  7048. }
  7049. // Store the original tag used to set options
  7050. _this.tag = tag;
  7051. // Store the tag attributes used to restore html5 element
  7052. _this.tagAttributes = tag && Dom.getElAttributes(tag);
  7053. // Update current language
  7054. _this.language(_this.options_.language);
  7055. // Update Supported Languages
  7056. if (options.languages) {
  7057. (function () {
  7058. // Normalise player option languages to lowercase
  7059. var languagesToLower = {};
  7060. Object.getOwnPropertyNames(options.languages).forEach(function (name) {
  7061. languagesToLower[name.toLowerCase()] = options.languages[name];
  7062. });
  7063. _this.languages_ = languagesToLower;
  7064. })();
  7065. } else {
  7066. _this.languages_ = Player.prototype.options_.languages;
  7067. }
  7068. // Cache for video property values.
  7069. _this.cache_ = {};
  7070. // Set poster
  7071. _this.poster_ = options.poster || '';
  7072. // Set controls
  7073. _this.controls_ = !!options.controls;
  7074. // Original tag settings stored in options
  7075. // now remove immediately so native controls don't flash.
  7076. // May be turned back on by HTML5 tech if nativeControlsForTouch is true
  7077. tag.controls = false;
  7078. /*
  7079. * Store the internal state of scrubbing
  7080. *
  7081. * @private
  7082. * @return {Boolean} True if the user is scrubbing
  7083. */
  7084. _this.scrubbing_ = false;
  7085. _this.el_ = _this.createEl();
  7086. // We also want to pass the original player options to each component and plugin
  7087. // as well so they don't need to reach back into the player for options later.
  7088. // We also need to do another copy of this.options_ so we don't end up with
  7089. // an infinite loop.
  7090. var playerOptionsCopy = (0, _mergeOptions2['default'])(_this.options_);
  7091. // Load plugins
  7092. if (options.plugins) {
  7093. (function () {
  7094. var plugins = options.plugins;
  7095. Object.getOwnPropertyNames(plugins).forEach(function (name) {
  7096. if (typeof this[name] === 'function') {
  7097. this[name](plugins[name]);
  7098. } else {
  7099. _log2['default'].error('Unable to find plugin:', name);
  7100. }
  7101. }, _this);
  7102. })();
  7103. }
  7104. _this.options_.playerOptions = playerOptionsCopy;
  7105. _this.initChildren();
  7106. // Set isAudio based on whether or not an audio tag was used
  7107. _this.isAudio(tag.nodeName.toLowerCase() === 'audio');
  7108. // Update controls className. Can't do this when the controls are initially
  7109. // set because the element doesn't exist yet.
  7110. if (_this.controls()) {
  7111. _this.addClass('vjs-controls-enabled');
  7112. } else {
  7113. _this.addClass('vjs-controls-disabled');
  7114. }
  7115. // Set ARIA label and region role depending on player type
  7116. _this.el_.setAttribute('role', 'region');
  7117. if (_this.isAudio()) {
  7118. _this.el_.setAttribute('aria-label', 'audio player');
  7119. } else {
  7120. _this.el_.setAttribute('aria-label', 'video player');
  7121. }
  7122. if (_this.isAudio()) {
  7123. _this.addClass('vjs-audio');
  7124. }
  7125. if (_this.flexNotSupported_()) {
  7126. _this.addClass('vjs-no-flex');
  7127. }
  7128. // TODO: Make this smarter. Toggle user state between touching/mousing
  7129. // using events, since devices can have both touch and mouse events.
  7130. // if (browser.TOUCH_ENABLED) {
  7131. // this.addClass('vjs-touch-enabled');
  7132. // }
  7133. // iOS Safari has broken hover handling
  7134. if (!browser.IS_IOS) {
  7135. _this.addClass('vjs-workinghover');
  7136. }
  7137. // Make player easily findable by ID
  7138. Player.players[_this.id_] = _this;
  7139. // When the player is first initialized, trigger activity so components
  7140. // like the control bar show themselves if needed
  7141. _this.userActive(true);
  7142. _this.reportUserActivity();
  7143. _this.listenForUserActivity_();
  7144. _this.on('fullscreenchange', _this.handleFullscreenChange_);
  7145. _this.on('stageclick', _this.handleStageClick_);
  7146. return _this;
  7147. }
  7148. /**
  7149. * Destroys the video player and does any necessary cleanup.
  7150. *
  7151. * This is especially helpful if you are dynamically adding and removing videos
  7152. * to/from the DOM.
  7153. *
  7154. * @fires Player#dispose
  7155. */
  7156. Player.prototype.dispose = function dispose() {
  7157. /**
  7158. * Called when the player is being disposed of.
  7159. *
  7160. * @event Player#dispose
  7161. * @type {EventTarget~Event}
  7162. */
  7163. this.trigger('dispose');
  7164. // prevent dispose from being called twice
  7165. this.off('dispose');
  7166. if (this.styleEl_ && this.styleEl_.parentNode) {
  7167. this.styleEl_.parentNode.removeChild(this.styleEl_);
  7168. }
  7169. // Kill reference to this player
  7170. Player.players[this.id_] = null;
  7171. if (this.tag && this.tag.player) {
  7172. this.tag.player = null;
  7173. }
  7174. if (this.el_ && this.el_.player) {
  7175. this.el_.player = null;
  7176. }
  7177. if (this.tech_) {
  7178. this.tech_.dispose();
  7179. }
  7180. _Component.prototype.dispose.call(this);
  7181. };
  7182. /**
  7183. * Create the `Player`'s DOM element.
  7184. *
  7185. * @return {Element}
  7186. * The DOM element that gets created.
  7187. */
  7188. Player.prototype.createEl = function createEl() {
  7189. var tag = this.tag;
  7190. var el = void 0;
  7191. var playerElIngest = this.playerElIngest_ = tag.parentNode && tag.parentNode.hasAttribute && tag.parentNode.hasAttribute('data-vjs-player');
  7192. if (playerElIngest) {
  7193. el = this.el_ = tag.parentNode;
  7194. } else {
  7195. el = this.el_ = _Component.prototype.createEl.call(this, 'div');
  7196. }
  7197. // Remove width/height attrs from tag so CSS can make it 100% width/height
  7198. tag.removeAttribute('width');
  7199. tag.removeAttribute('height');
  7200. // Copy over all the attributes from the tag, including ID and class
  7201. // ID will now reference player box, not the video tag
  7202. var attrs = Dom.getElAttributes(tag);
  7203. Object.getOwnPropertyNames(attrs).forEach(function (attr) {
  7204. // workaround so we don't totally break IE7
  7205. // http://stackoverflow.com/questions/3653444/css-styles-not-applied-on-dynamic-elements-in-internet-explorer-7
  7206. if (attr === 'class') {
  7207. el.className += ' ' + attrs[attr];
  7208. } else {
  7209. el.setAttribute(attr, attrs[attr]);
  7210. }
  7211. });
  7212. // Update tag id/class for use as HTML5 playback tech
  7213. // Might think we should do this after embedding in container so .vjs-tech class
  7214. // doesn't flash 100% width/height, but class only applies with .video-js parent
  7215. tag.playerId = tag.id;
  7216. tag.id += '_html5_api';
  7217. tag.className = 'vjs-tech';
  7218. // Make player findable on elements
  7219. tag.player = el.player = this;
  7220. // Default state of video is paused
  7221. this.addClass('vjs-paused');
  7222. // Add a style element in the player that we'll use to set the width/height
  7223. // of the player in a way that's still overrideable by CSS, just like the
  7224. // video element
  7225. if (_window2['default'].VIDEOJS_NO_DYNAMIC_STYLE !== true) {
  7226. this.styleEl_ = stylesheet.createStyleElement('vjs-styles-dimensions');
  7227. var defaultsStyleEl = Dom.$('.vjs-styles-defaults');
  7228. var head = Dom.$('head');
  7229. head.insertBefore(this.styleEl_, defaultsStyleEl ? defaultsStyleEl.nextSibling : head.firstChild);
  7230. }
  7231. // Pass in the width/height/aspectRatio options which will update the style el
  7232. this.width(this.options_.width);
  7233. this.height(this.options_.height);
  7234. this.fluid(this.options_.fluid);
  7235. this.aspectRatio(this.options_.aspectRatio);
  7236. // Hide any links within the video/audio tag, because IE doesn't hide them completely.
  7237. var links = tag.getElementsByTagName('a');
  7238. for (var i = 0; i < links.length; i++) {
  7239. var linkEl = links.item(i);
  7240. Dom.addElClass(linkEl, 'vjs-hidden');
  7241. linkEl.setAttribute('hidden', 'hidden');
  7242. }
  7243. // insertElFirst seems to cause the networkState to flicker from 3 to 2, so
  7244. // keep track of the original for later so we can know if the source originally failed
  7245. tag.initNetworkState_ = tag.networkState;
  7246. // Wrap video tag in div (el/box) container
  7247. if (tag.parentNode && !playerElIngest) {
  7248. tag.parentNode.insertBefore(el, tag);
  7249. }
  7250. // insert the tag as the first child of the player element
  7251. // then manually add it to the children array so that this.addChild
  7252. // will work properly for other components
  7253. //
  7254. // Breaks iPhone, fixed in HTML5 setup.
  7255. Dom.insertElFirst(tag, el);
  7256. this.children_.unshift(tag);
  7257. this.el_ = el;
  7258. return el;
  7259. };
  7260. /**
  7261. * A getter/setter for the `Player`'s width.
  7262. *
  7263. * @param {number} [value]
  7264. * The value to set the `Player's width to.
  7265. *
  7266. * @return {number}
  7267. * The current width of the `Player`.
  7268. */
  7269. Player.prototype.width = function width(value) {
  7270. return this.dimension('width', value);
  7271. };
  7272. /**
  7273. * A getter/setter for the `Player`'s height.
  7274. *
  7275. * @param {number} [value]
  7276. * The value to set the `Player's heigth to.
  7277. *
  7278. * @return {number}
  7279. * The current heigth of the `Player`.
  7280. */
  7281. Player.prototype.height = function height(value) {
  7282. return this.dimension('height', value);
  7283. };
  7284. /**
  7285. * A getter/setter for the `Player`'s width & height.
  7286. *
  7287. * @param {string} dimension
  7288. * This string can be:
  7289. * - 'width'
  7290. * - 'height'
  7291. *
  7292. * @param {number} [value]
  7293. * Value for dimension specified in the first argument.
  7294. *
  7295. * @return {Player|number}
  7296. * - Returns itself when setting; method can be chained.
  7297. * - The dimension arguments value when getting (width/height).
  7298. */
  7299. Player.prototype.dimension = function dimension(_dimension, value) {
  7300. var privDimension = _dimension + '_';
  7301. if (value === undefined) {
  7302. return this[privDimension] || 0;
  7303. }
  7304. if (value === '') {
  7305. // If an empty string is given, reset the dimension to be automatic
  7306. this[privDimension] = undefined;
  7307. } else {
  7308. var parsedVal = parseFloat(value);
  7309. if (isNaN(parsedVal)) {
  7310. _log2['default'].error('Improper value "' + value + '" supplied for for ' + _dimension);
  7311. return this;
  7312. }
  7313. this[privDimension] = parsedVal;
  7314. }
  7315. this.updateStyleEl_();
  7316. return this;
  7317. };
  7318. /**
  7319. * A getter/setter/toggler for the vjs-fluid `className` on the `Player`.
  7320. *
  7321. * @param {boolean} [bool]
  7322. * - A value of true adds the class.
  7323. * - A value of false removes the class.
  7324. * - No value will toggle the fluid class.
  7325. *
  7326. * @return {boolean|undefined}
  7327. * - The value of fluid when getting.
  7328. * - `undefined` when setting.
  7329. */
  7330. Player.prototype.fluid = function fluid(bool) {
  7331. if (bool === undefined) {
  7332. return !!this.fluid_;
  7333. }
  7334. this.fluid_ = !!bool;
  7335. if (bool) {
  7336. this.addClass('vjs-fluid');
  7337. } else {
  7338. this.removeClass('vjs-fluid');
  7339. }
  7340. this.updateStyleEl_();
  7341. };
  7342. /**
  7343. * Get/Set the aspect ratio
  7344. *
  7345. * @param {string} [ratio]
  7346. * Aspect ratio for player
  7347. *
  7348. * @return {string|undefined}
  7349. * returns the current aspect ratio when getting
  7350. */
  7351. /**
  7352. * A getter/setter for the `Player`'s aspect ratio.
  7353. *
  7354. * @param {string} [ratio]
  7355. * The value to set the `Player's aspect ratio to.
  7356. *
  7357. * @return {string|undefined}
  7358. * - The current aspect ratio of the `Player` when getting.
  7359. * - undefined when setting
  7360. */
  7361. Player.prototype.aspectRatio = function aspectRatio(ratio) {
  7362. if (ratio === undefined) {
  7363. return this.aspectRatio_;
  7364. }
  7365. // Check for width:height format
  7366. if (!/^\d+\:\d+$/.test(ratio)) {
  7367. throw new Error('Improper value supplied for aspect ratio. The format should be width:height, for example 16:9.');
  7368. }
  7369. this.aspectRatio_ = ratio;
  7370. // We're assuming if you set an aspect ratio you want fluid mode,
  7371. // because in fixed mode you could calculate width and height yourself.
  7372. this.fluid(true);
  7373. this.updateStyleEl_();
  7374. };
  7375. /**
  7376. * Update styles of the `Player` element (height, width and aspect ratio).
  7377. *
  7378. * @private
  7379. * @listens Tech#loadedmetadata
  7380. */
  7381. Player.prototype.updateStyleEl_ = function updateStyleEl_() {
  7382. if (_window2['default'].VIDEOJS_NO_DYNAMIC_STYLE === true) {
  7383. var _width = typeof this.width_ === 'number' ? this.width_ : this.options_.width;
  7384. var _height = typeof this.height_ === 'number' ? this.height_ : this.options_.height;
  7385. var techEl = this.tech_ && this.tech_.el();
  7386. if (techEl) {
  7387. if (_width >= 0) {
  7388. techEl.width = _width;
  7389. }
  7390. if (_height >= 0) {
  7391. techEl.height = _height;
  7392. }
  7393. }
  7394. return;
  7395. }
  7396. var width = void 0;
  7397. var height = void 0;
  7398. var aspectRatio = void 0;
  7399. var idClass = void 0;
  7400. // The aspect ratio is either used directly or to calculate width and height.
  7401. if (this.aspectRatio_ !== undefined && this.aspectRatio_ !== 'auto') {
  7402. // Use any aspectRatio that's been specifically set
  7403. aspectRatio = this.aspectRatio_;
  7404. } else if (this.videoWidth() > 0) {
  7405. // Otherwise try to get the aspect ratio from the video metadata
  7406. aspectRatio = this.videoWidth() + ':' + this.videoHeight();
  7407. } else {
  7408. // Or use a default. The video element's is 2:1, but 16:9 is more common.
  7409. aspectRatio = '16:9';
  7410. }
  7411. // Get the ratio as a decimal we can use to calculate dimensions
  7412. var ratioParts = aspectRatio.split(':');
  7413. var ratioMultiplier = ratioParts[1] / ratioParts[0];
  7414. if (this.width_ !== undefined) {
  7415. // Use any width that's been specifically set
  7416. width = this.width_;
  7417. } else if (this.height_ !== undefined) {
  7418. // Or calulate the width from the aspect ratio if a height has been set
  7419. width = this.height_ / ratioMultiplier;
  7420. } else {
  7421. // Or use the video's metadata, or use the video el's default of 300
  7422. width = this.videoWidth() || 300;
  7423. }
  7424. if (this.height_ !== undefined) {
  7425. // Use any height that's been specifically set
  7426. height = this.height_;
  7427. } else {
  7428. // Otherwise calculate the height from the ratio and the width
  7429. height = width * ratioMultiplier;
  7430. }
  7431. // Ensure the CSS class is valid by starting with an alpha character
  7432. if (/^[^a-zA-Z]/.test(this.id())) {
  7433. idClass = 'dimensions-' + this.id();
  7434. } else {
  7435. idClass = this.id() + '-dimensions';
  7436. }
  7437. // Ensure the right class is still on the player for the style element
  7438. this.addClass(idClass);
  7439. 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 ');
  7440. };
  7441. /**
  7442. * Load/Create an instance of playback {@link Tech} including element
  7443. * and API methods. Then append the `Tech` element in `Player` as a child.
  7444. *
  7445. * @param {string} techName
  7446. * name of the playback technology
  7447. *
  7448. * @param {string} source
  7449. * video source
  7450. *
  7451. * @private
  7452. */
  7453. Player.prototype.loadTech_ = function loadTech_(techName, source) {
  7454. var _this2 = this;
  7455. // Pause and remove current playback technology
  7456. if (this.tech_) {
  7457. this.unloadTech_();
  7458. }
  7459. // get rid of the HTML5 video tag as soon as we are using another tech
  7460. if (techName !== 'Html5' && this.tag) {
  7461. _tech2['default'].getTech('Html5').disposeMediaElement(this.tag);
  7462. this.tag.player = null;
  7463. this.tag = null;
  7464. }
  7465. this.techName_ = techName;
  7466. // Turn off API access because we're loading a new tech that might load asynchronously
  7467. this.isReady_ = false;
  7468. // Grab tech-specific options from player options and add source and parent element to use.
  7469. var techOptions = (0, _obj.assign)({
  7470. source: source,
  7471. 'nativeControlsForTouch': this.options_.nativeControlsForTouch,
  7472. 'playerId': this.id(),
  7473. 'techId': this.id() + '_' + techName + '_api',
  7474. 'videoTracks': this.videoTracks_,
  7475. 'textTracks': this.textTracks_,
  7476. 'audioTracks': this.audioTracks_,
  7477. 'autoplay': this.options_.autoplay,
  7478. 'preload': this.options_.preload,
  7479. 'loop': this.options_.loop,
  7480. 'muted': this.options_.muted,
  7481. 'poster': this.poster(),
  7482. 'language': this.language(),
  7483. 'playerElIngest': this.playerElIngest_ || false,
  7484. 'vtt.js': this.options_['vtt.js']
  7485. }, this.options_[techName.toLowerCase()]);
  7486. if (this.tag) {
  7487. techOptions.tag = this.tag;
  7488. }
  7489. if (source) {
  7490. this.currentType_ = source.type;
  7491. if (source.src === this.cache_.src && this.cache_.currentTime > 0) {
  7492. techOptions.startTime = this.cache_.currentTime;
  7493. }
  7494. this.cache_.sources = null;
  7495. this.cache_.source = source;
  7496. this.cache_.src = source.src;
  7497. }
  7498. // Initialize tech instance
  7499. var TechComponent = _tech2['default'].getTech(techName);
  7500. // Support old behavior of techs being registered as components.
  7501. // Remove once that deprecated behavior is removed.
  7502. if (!TechComponent) {
  7503. TechComponent = _component2['default'].getComponent(techName);
  7504. }
  7505. this.tech_ = new TechComponent(techOptions);
  7506. // player.triggerReady is always async, so don't need this to be async
  7507. this.tech_.ready(Fn.bind(this, this.handleTechReady_), true);
  7508. _textTrackListConverter2['default'].jsonToTextTracks(this.textTracksJson_ || [], this.tech_);
  7509. // Listen to all HTML5-defined events and trigger them on the player
  7510. TECH_EVENTS_RETRIGGER.forEach(function (event) {
  7511. _this2.on(_this2.tech_, event, _this2['handleTech' + (0, _toTitleCase2['default'])(event) + '_']);
  7512. });
  7513. this.on(this.tech_, 'loadstart', this.handleTechLoadStart_);
  7514. this.on(this.tech_, 'waiting', this.handleTechWaiting_);
  7515. this.on(this.tech_, 'canplay', this.handleTechCanPlay_);
  7516. this.on(this.tech_, 'canplaythrough', this.handleTechCanPlayThrough_);
  7517. this.on(this.tech_, 'playing', this.handleTechPlaying_);
  7518. this.on(this.tech_, 'ended', this.handleTechEnded_);
  7519. this.on(this.tech_, 'seeking', this.handleTechSeeking_);
  7520. this.on(this.tech_, 'seeked', this.handleTechSeeked_);
  7521. this.on(this.tech_, 'play', this.handleTechPlay_);
  7522. this.on(this.tech_, 'firstplay', this.handleTechFirstPlay_);
  7523. this.on(this.tech_, 'pause', this.handleTechPause_);
  7524. this.on(this.tech_, 'durationchange', this.handleTechDurationChange_);
  7525. this.on(this.tech_, 'fullscreenchange', this.handleTechFullscreenChange_);
  7526. this.on(this.tech_, 'error', this.handleTechError_);
  7527. this.on(this.tech_, 'loadedmetadata', this.updateStyleEl_);
  7528. this.on(this.tech_, 'posterchange', this.handleTechPosterChange_);
  7529. this.on(this.tech_, 'textdata', this.handleTechTextData_);
  7530. this.usingNativeControls(this.techGet_('controls'));
  7531. if (this.controls() && !this.usingNativeControls()) {
  7532. this.addTechControlsListeners_();
  7533. }
  7534. // Add the tech element in the DOM if it was not already there
  7535. // Make sure to not insert the original video element if using Html5
  7536. if (this.tech_.el().parentNode !== this.el() && (techName !== 'Html5' || !this.tag)) {
  7537. Dom.insertElFirst(this.tech_.el(), this.el());
  7538. }
  7539. // Get rid of the original video tag reference after the first tech is loaded
  7540. if (this.tag) {
  7541. this.tag.player = null;
  7542. this.tag = null;
  7543. }
  7544. };
  7545. /**
  7546. * Unload and dispose of the current playback {@link Tech}.
  7547. *
  7548. * @private
  7549. */
  7550. Player.prototype.unloadTech_ = function unloadTech_() {
  7551. // Save the current text tracks so that we can reuse the same text tracks with the next tech
  7552. this.videoTracks_ = this.videoTracks();
  7553. this.textTracks_ = this.textTracks();
  7554. this.audioTracks_ = this.audioTracks();
  7555. this.textTracksJson_ = _textTrackListConverter2['default'].textTracksToJson(this.tech_);
  7556. this.isReady_ = false;
  7557. this.tech_.dispose();
  7558. this.tech_ = false;
  7559. };
  7560. /**
  7561. * Return a reference to the current {@link Tech}, but only if given an object with the
  7562. * `IWillNotUseThisInPlugins` property having a true value. This is try and prevent misuse
  7563. * of techs by plugins.
  7564. *
  7565. * @param {Object} safety
  7566. * An object that must contain `{IWillNotUseThisInPlugins: true}`
  7567. *
  7568. * @param {boolean} safety.IWillNotUseThisInPlugins
  7569. * Must be set to true or else this function will throw an error.
  7570. *
  7571. * @return {Tech}
  7572. * The Tech
  7573. */
  7574. Player.prototype.tech = function tech(safety) {
  7575. if (safety && safety.IWillNotUseThisInPlugins) {
  7576. return this.tech_;
  7577. }
  7578. var errorText = '\n Please make sure that you are not using this inside of a plugin.\n To disable this alert and error, please pass in an object with\n `IWillNotUseThisInPlugins` to the `tech` method. See\n https://github.com/videojs/video.js/issues/2617 for more info.\n ';
  7579. _window2['default'].alert(errorText);
  7580. throw new Error(errorText);
  7581. };
  7582. /**
  7583. * Set up click and touch listeners for the playback element
  7584. *
  7585. * - On desktops: a click on the video itself will toggle playback
  7586. * - On mobile devices: a click on the video toggles controls
  7587. * which is done by toggling the user state between active and
  7588. * inactive
  7589. * - A tap can signal that a user has become active or has become inactive
  7590. * e.g. a quick tap on an iPhone movie should reveal the controls. Another
  7591. * quick tap should hide them again (signaling the user is in an inactive
  7592. * viewing state)
  7593. * - In addition to this, we still want the user to be considered inactive after
  7594. * a few seconds of inactivity.
  7595. *
  7596. * > Note: the only part of iOS interaction we can't mimic with this setup
  7597. * is a touch and hold on the video element counting as activity in order to
  7598. * keep the controls showing, but that shouldn't be an issue. A touch and hold
  7599. * on any controls will still keep the user active
  7600. *
  7601. * @private
  7602. */
  7603. Player.prototype.addTechControlsListeners_ = function addTechControlsListeners_() {
  7604. // Make sure to remove all the previous listeners in case we are called multiple times.
  7605. this.removeTechControlsListeners_();
  7606. // Some browsers (Chrome & IE) don't trigger a click on a flash swf, but do
  7607. // trigger mousedown/up.
  7608. // http://stackoverflow.com/questions/1444562/javascript-onclick-event-over-flash-object
  7609. // Any touch events are set to block the mousedown event from happening
  7610. this.on(this.tech_, 'mousedown', this.handleTechClick_);
  7611. // If the controls were hidden we don't want that to change without a tap event
  7612. // so we'll check if the controls were already showing before reporting user
  7613. // activity
  7614. this.on(this.tech_, 'touchstart', this.handleTechTouchStart_);
  7615. this.on(this.tech_, 'touchmove', this.handleTechTouchMove_);
  7616. this.on(this.tech_, 'touchend', this.handleTechTouchEnd_);
  7617. // The tap listener needs to come after the touchend listener because the tap
  7618. // listener cancels out any reportedUserActivity when setting userActive(false)
  7619. this.on(this.tech_, 'tap', this.handleTechTap_);
  7620. };
  7621. /**
  7622. * Remove the listeners used for click and tap controls. This is needed for
  7623. * toggling to controls disabled, where a tap/touch should do nothing.
  7624. *
  7625. * @private
  7626. */
  7627. Player.prototype.removeTechControlsListeners_ = function removeTechControlsListeners_() {
  7628. // We don't want to just use `this.off()` because there might be other needed
  7629. // listeners added by techs that extend this.
  7630. this.off(this.tech_, 'tap', this.handleTechTap_);
  7631. this.off(this.tech_, 'touchstart', this.handleTechTouchStart_);
  7632. this.off(this.tech_, 'touchmove', this.handleTechTouchMove_);
  7633. this.off(this.tech_, 'touchend', this.handleTechTouchEnd_);
  7634. this.off(this.tech_, 'mousedown', this.handleTechClick_);
  7635. };
  7636. /**
  7637. * Player waits for the tech to be ready
  7638. *
  7639. * @private
  7640. */
  7641. Player.prototype.handleTechReady_ = function handleTechReady_() {
  7642. this.triggerReady();
  7643. // Keep the same volume as before
  7644. if (this.cache_.volume) {
  7645. this.techCall_('setVolume', this.cache_.volume);
  7646. }
  7647. // Look if the tech found a higher resolution poster while loading
  7648. this.handleTechPosterChange_();
  7649. // Update the duration if available
  7650. this.handleTechDurationChange_();
  7651. // Chrome and Safari both have issues with autoplay.
  7652. // In Safari (5.1.1), when we move the video element into the container div, autoplay doesn't work.
  7653. // In Chrome (15), if you have autoplay + a poster + no controls, the video gets hidden (but audio plays)
  7654. // This fixes both issues. Need to wait for API, so it updates displays correctly
  7655. if ((this.src() || this.currentSrc()) && this.tag && this.options_.autoplay && this.paused()) {
  7656. try {
  7657. // Chrome Fix. Fixed in Chrome v16.
  7658. delete this.tag.poster;
  7659. } catch (e) {
  7660. (0, _log2['default'])('deleting tag.poster throws in some browsers', e);
  7661. }
  7662. this.play();
  7663. }
  7664. };
  7665. /**
  7666. * Retrigger the `loadstart` event that was triggered by the {@link Tech}. This
  7667. * function will also trigger {@link Player#firstplay} if it is the first loadstart
  7668. * for a video.
  7669. *
  7670. * @fires Player#loadstart
  7671. * @fires Player#firstplay
  7672. * @listens Tech#loadstart
  7673. * @private
  7674. */
  7675. Player.prototype.handleTechLoadStart_ = function handleTechLoadStart_() {
  7676. // TODO: Update to use `emptied` event instead. See #1277.
  7677. this.removeClass('vjs-ended');
  7678. this.removeClass('vjs-seeking');
  7679. // reset the error state
  7680. this.error(null);
  7681. // If it's already playing we want to trigger a firstplay event now.
  7682. // The firstplay event relies on both the play and loadstart events
  7683. // which can happen in any order for a new source
  7684. if (!this.paused()) {
  7685. /**
  7686. * Fired when the user agent begins looking for media data
  7687. *
  7688. * @event Player#loadstart
  7689. * @type {EventTarget~Event}
  7690. */
  7691. this.trigger('loadstart');
  7692. this.trigger('firstplay');
  7693. } else {
  7694. // reset the hasStarted state
  7695. this.hasStarted(false);
  7696. this.trigger('loadstart');
  7697. }
  7698. };
  7699. /**
  7700. * Add/remove the vjs-has-started class
  7701. *
  7702. * @fires Player#firstplay
  7703. *
  7704. * @param {boolean} hasStarted
  7705. * - true: adds the class
  7706. * - false: remove the class
  7707. *
  7708. * @return {boolean}
  7709. * the boolean value of hasStarted
  7710. */
  7711. Player.prototype.hasStarted = function hasStarted(_hasStarted) {
  7712. if (_hasStarted !== undefined) {
  7713. // only update if this is a new value
  7714. if (this.hasStarted_ !== _hasStarted) {
  7715. this.hasStarted_ = _hasStarted;
  7716. if (_hasStarted) {
  7717. this.addClass('vjs-has-started');
  7718. // trigger the firstplay event if this newly has played
  7719. this.trigger('firstplay');
  7720. } else {
  7721. this.removeClass('vjs-has-started');
  7722. }
  7723. }
  7724. return this;
  7725. }
  7726. return !!this.hasStarted_;
  7727. };
  7728. /**
  7729. * Fired whenever the media begins or resumes playback
  7730. *
  7731. * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#dom-media-play}
  7732. * @fires Player#play
  7733. * @listens Tech#play
  7734. * @private
  7735. */
  7736. Player.prototype.handleTechPlay_ = function handleTechPlay_() {
  7737. this.removeClass('vjs-ended');
  7738. this.removeClass('vjs-paused');
  7739. this.addClass('vjs-playing');
  7740. // hide the poster when the user hits play
  7741. this.hasStarted(true);
  7742. /**
  7743. * Triggered whenever an {@link Tech#play} event happens. Indicates that
  7744. * playback has started or resumed.
  7745. *
  7746. * @event Player#play
  7747. * @type {EventTarget~Event}
  7748. */
  7749. this.trigger('play');
  7750. };
  7751. /**
  7752. * Retrigger the `waiting` event that was triggered by the {@link Tech}.
  7753. *
  7754. * @fires Player#waiting
  7755. * @listens Tech#waiting
  7756. * @private
  7757. */
  7758. Player.prototype.handleTechWaiting_ = function handleTechWaiting_() {
  7759. var _this3 = this;
  7760. this.addClass('vjs-waiting');
  7761. /**
  7762. * A readyState change on the DOM element has caused playback to stop.
  7763. *
  7764. * @event Player#waiting
  7765. * @type {EventTarget~Event}
  7766. */
  7767. this.trigger('waiting');
  7768. this.one('timeupdate', function () {
  7769. return _this3.removeClass('vjs-waiting');
  7770. });
  7771. };
  7772. /**
  7773. * Retrigger the `canplay` event that was triggered by the {@link Tech}.
  7774. * > Note: This is not consistent between browsers. See #1351
  7775. *
  7776. * @fires Player#canplay
  7777. * @listens Tech#canplay
  7778. * @private
  7779. */
  7780. Player.prototype.handleTechCanPlay_ = function handleTechCanPlay_() {
  7781. this.removeClass('vjs-waiting');
  7782. /**
  7783. * The media has a readyState of HAVE_FUTURE_DATA or greater.
  7784. *
  7785. * @event Player#canplay
  7786. * @type {EventTarget~Event}
  7787. */
  7788. this.trigger('canplay');
  7789. };
  7790. /**
  7791. * Retrigger the `canplaythrough` event that was triggered by the {@link Tech}.
  7792. *
  7793. * @fires Player#canplaythrough
  7794. * @listens Tech#canplaythrough
  7795. * @private
  7796. */
  7797. Player.prototype.handleTechCanPlayThrough_ = function handleTechCanPlayThrough_() {
  7798. this.removeClass('vjs-waiting');
  7799. /**
  7800. * The media has a readyState of HAVE_ENOUGH_DATA or greater. This means that the
  7801. * entire media file can be played without buffering.
  7802. *
  7803. * @event Player#canplaythrough
  7804. * @type {EventTarget~Event}
  7805. */
  7806. this.trigger('canplaythrough');
  7807. };
  7808. /**
  7809. * Retrigger the `playing` event that was triggered by the {@link Tech}.
  7810. *
  7811. * @fires Player#playing
  7812. * @listens Tech#playing
  7813. * @private
  7814. */
  7815. Player.prototype.handleTechPlaying_ = function handleTechPlaying_() {
  7816. this.removeClass('vjs-waiting');
  7817. /**
  7818. * The media is no longer blocked from playback, and has started playing.
  7819. *
  7820. * @event Player#playing
  7821. * @type {EventTarget~Event}
  7822. */
  7823. this.trigger('playing');
  7824. };
  7825. /**
  7826. * Retrigger the `seeking` event that was triggered by the {@link Tech}.
  7827. *
  7828. * @fires Player#seeking
  7829. * @listens Tech#seeking
  7830. * @private
  7831. */
  7832. Player.prototype.handleTechSeeking_ = function handleTechSeeking_() {
  7833. this.addClass('vjs-seeking');
  7834. /**
  7835. * Fired whenever the player is jumping to a new time
  7836. *
  7837. * @event Player#seeking
  7838. * @type {EventTarget~Event}
  7839. */
  7840. this.trigger('seeking');
  7841. };
  7842. /**
  7843. * Retrigger the `seeked` event that was triggered by the {@link Tech}.
  7844. *
  7845. * @fires Player#seeked
  7846. * @listens Tech#seeked
  7847. * @private
  7848. */
  7849. Player.prototype.handleTechSeeked_ = function handleTechSeeked_() {
  7850. this.removeClass('vjs-seeking');
  7851. /**
  7852. * Fired when the player has finished jumping to a new time
  7853. *
  7854. * @event Player#seeked
  7855. * @type {EventTarget~Event}
  7856. */
  7857. this.trigger('seeked');
  7858. };
  7859. /**
  7860. * Retrigger the `firstplay` event that was triggered by the {@link Tech}.
  7861. *
  7862. * @fires Player#firstplay
  7863. * @listens Tech#firstplay
  7864. * @deprecated As of 6.0 passing the `starttime` option to the player will be deprecated
  7865. * @private
  7866. */
  7867. Player.prototype.handleTechFirstPlay_ = function handleTechFirstPlay_() {
  7868. // If the first starttime attribute is specified
  7869. // then we will start at the given offset in seconds
  7870. if (this.options_.starttime) {
  7871. _log2['default'].warn('Passing the `starttime` option to the player will be deprecated in 6.0');
  7872. this.currentTime(this.options_.starttime);
  7873. }
  7874. this.addClass('vjs-has-started');
  7875. /**
  7876. * Fired the first time a video is played. Not part of the HLS spec, and this is
  7877. * probably not the best implementation yet, so use sparingly. If you don't have a
  7878. * reason to prevent playback, use `myPlayer.one('play');` instead.
  7879. *
  7880. * @event Player#firstplay
  7881. * @type {EventTarget~Event}
  7882. */
  7883. this.trigger('firstplay');
  7884. };
  7885. /**
  7886. * Retrigger the `pause` event that was triggered by the {@link Tech}.
  7887. *
  7888. * @fires Player#pause
  7889. * @listens Tech#pause
  7890. * @private
  7891. */
  7892. Player.prototype.handleTechPause_ = function handleTechPause_() {
  7893. this.removeClass('vjs-playing');
  7894. this.addClass('vjs-paused');
  7895. /**
  7896. * Fired whenever the media has been paused
  7897. *
  7898. * @event Player#pause
  7899. * @type {EventTarget~Event}
  7900. */
  7901. this.trigger('pause');
  7902. };
  7903. /**
  7904. * Retrigger the `ended` event that was triggered by the {@link Tech}.
  7905. *
  7906. * @fires Player#ended
  7907. * @listens Tech#ended
  7908. * @private
  7909. */
  7910. Player.prototype.handleTechEnded_ = function handleTechEnded_() {
  7911. this.addClass('vjs-ended');
  7912. if (this.options_.loop) {
  7913. this.currentTime(0);
  7914. this.play();
  7915. } else if (!this.paused()) {
  7916. this.pause();
  7917. }
  7918. /**
  7919. * Fired when the end of the media resource is reached (currentTime == duration)
  7920. *
  7921. * @event Player#ended
  7922. * @type {EventTarget~Event}
  7923. */
  7924. this.trigger('ended');
  7925. };
  7926. /**
  7927. * Fired when the duration of the media resource is first known or changed
  7928. *
  7929. * @listens Tech#durationchange
  7930. * @private
  7931. */
  7932. Player.prototype.handleTechDurationChange_ = function handleTechDurationChange_() {
  7933. this.duration(this.techGet_('duration'));
  7934. };
  7935. /**
  7936. * Handle a click on the media element to play/pause
  7937. *
  7938. * @param {EventTarget~Event} event
  7939. * the event that caused this function to trigger
  7940. *
  7941. * @listens Tech#mousedown
  7942. * @private
  7943. */
  7944. Player.prototype.handleTechClick_ = function handleTechClick_(event) {
  7945. // We're using mousedown to detect clicks thanks to Flash, but mousedown
  7946. // will also be triggered with right-clicks, so we need to prevent that
  7947. if (event.button !== 0) {
  7948. return;
  7949. }
  7950. // When controls are disabled a click should not toggle playback because
  7951. // the click is considered a control
  7952. if (this.controls()) {
  7953. if (this.paused()) {
  7954. this.play();
  7955. } else {
  7956. this.pause();
  7957. }
  7958. }
  7959. };
  7960. /**
  7961. * Handle a tap on the media element. It will toggle the user
  7962. * activity state, which hides and shows the controls.
  7963. *
  7964. * @listens Tech#tap
  7965. * @private
  7966. */
  7967. Player.prototype.handleTechTap_ = function handleTechTap_() {
  7968. this.userActive(!this.userActive());
  7969. };
  7970. /**
  7971. * Handle touch to start
  7972. *
  7973. * @listens Tech#touchstart
  7974. * @private
  7975. */
  7976. Player.prototype.handleTechTouchStart_ = function handleTechTouchStart_() {
  7977. this.userWasActive = this.userActive();
  7978. };
  7979. /**
  7980. * Handle touch to move
  7981. *
  7982. * @listens Tech#touchmove
  7983. * @private
  7984. */
  7985. Player.prototype.handleTechTouchMove_ = function handleTechTouchMove_() {
  7986. if (this.userWasActive) {
  7987. this.reportUserActivity();
  7988. }
  7989. };
  7990. /**
  7991. * Handle touch to end
  7992. *
  7993. * @param {EventTarget~Event} event
  7994. * the touchend event that triggered
  7995. * this function
  7996. *
  7997. * @listens Tech#touchend
  7998. * @private
  7999. */
  8000. Player.prototype.handleTechTouchEnd_ = function handleTechTouchEnd_(event) {
  8001. // Stop the mouse events from also happening
  8002. event.preventDefault();
  8003. };
  8004. /**
  8005. * Fired when the player switches in or out of fullscreen mode
  8006. *
  8007. * @private
  8008. * @listens Player#fullscreenchange
  8009. */
  8010. Player.prototype.handleFullscreenChange_ = function handleFullscreenChange_() {
  8011. if (this.isFullscreen()) {
  8012. this.addClass('vjs-fullscreen');
  8013. } else {
  8014. this.removeClass('vjs-fullscreen');
  8015. }
  8016. };
  8017. /**
  8018. * native click events on the SWF aren't triggered on IE11, Win8.1RT
  8019. * use stageclick events triggered from inside the SWF instead
  8020. *
  8021. * @private
  8022. * @listens stageclick
  8023. */
  8024. Player.prototype.handleStageClick_ = function handleStageClick_() {
  8025. this.reportUserActivity();
  8026. };
  8027. /**
  8028. * Handle Tech Fullscreen Change
  8029. *
  8030. * @param {EventTarget~Event} event
  8031. * the fullscreenchange event that triggered this function
  8032. *
  8033. * @param {Object} data
  8034. * the data that was sent with the event
  8035. *
  8036. * @private
  8037. * @listens Tech#fullscreenchange
  8038. * @fires Player#fullscreenchange
  8039. */
  8040. Player.prototype.handleTechFullscreenChange_ = function handleTechFullscreenChange_(event, data) {
  8041. if (data) {
  8042. this.isFullscreen(data.isFullscreen);
  8043. }
  8044. /**
  8045. * Fired when going in and out of fullscreen.
  8046. *
  8047. * @event Player#fullscreenchange
  8048. * @type {EventTarget~Event}
  8049. */
  8050. this.trigger('fullscreenchange');
  8051. };
  8052. /**
  8053. * Fires when an error occurred during the loading of an audio/video.
  8054. *
  8055. * @private
  8056. * @listens Tech#error
  8057. */
  8058. Player.prototype.handleTechError_ = function handleTechError_() {
  8059. var error = this.tech_.error();
  8060. this.error(error);
  8061. };
  8062. /**
  8063. * Retrigger the `textdata` event that was triggered by the {@link Tech}.
  8064. *
  8065. * @fires Player#textdata
  8066. * @listens Tech#textdata
  8067. * @private
  8068. */
  8069. Player.prototype.handleTechTextData_ = function handleTechTextData_() {
  8070. var data = null;
  8071. if (arguments.length > 1) {
  8072. data = arguments[1];
  8073. }
  8074. /**
  8075. * Fires when we get a textdata event from tech
  8076. *
  8077. * @event Player#textdata
  8078. * @type {EventTarget~Event}
  8079. */
  8080. this.trigger('textdata', data);
  8081. };
  8082. /**
  8083. * Get object for cached values.
  8084. *
  8085. * @return {Object}
  8086. * get the current object cache
  8087. */
  8088. Player.prototype.getCache = function getCache() {
  8089. return this.cache_;
  8090. };
  8091. /**
  8092. * Pass values to the playback tech
  8093. *
  8094. * @param {string} [method]
  8095. * the method to call
  8096. *
  8097. * @param {Object} arg
  8098. * the argument to pass
  8099. *
  8100. * @private
  8101. */
  8102. Player.prototype.techCall_ = function techCall_(method, arg) {
  8103. // If it's not ready yet, call method when it is
  8104. if (this.tech_ && !this.tech_.isReady_) {
  8105. this.tech_.ready(function () {
  8106. this[method](arg);
  8107. }, true);
  8108. // Otherwise call method now
  8109. } else {
  8110. try {
  8111. if (this.tech_) {
  8112. this.tech_[method](arg);
  8113. }
  8114. } catch (e) {
  8115. (0, _log2['default'])(e);
  8116. throw e;
  8117. }
  8118. }
  8119. };
  8120. /**
  8121. * Get calls can't wait for the tech, and sometimes don't need to.
  8122. *
  8123. * @param {string} method
  8124. * Tech method
  8125. *
  8126. * @return {Function|undefined}
  8127. * the method or undefined
  8128. *
  8129. * @private
  8130. */
  8131. Player.prototype.techGet_ = function techGet_(method) {
  8132. if (this.tech_ && this.tech_.isReady_) {
  8133. // Flash likes to die and reload when you hide or reposition it.
  8134. // In these cases the object methods go away and we get errors.
  8135. // When that happens we'll catch the errors and inform tech that it's not ready any more.
  8136. try {
  8137. return this.tech_[method]();
  8138. } catch (e) {
  8139. // When building additional tech libs, an expected method may not be defined yet
  8140. if (this.tech_[method] === undefined) {
  8141. (0, _log2['default'])('Video.js: ' + method + ' method not defined for ' + this.techName_ + ' playback technology.', e);
  8142. // When a method isn't available on the object it throws a TypeError
  8143. } else if (e.name === 'TypeError') {
  8144. (0, _log2['default'])('Video.js: ' + method + ' unavailable on ' + this.techName_ + ' playback technology element.', e);
  8145. this.tech_.isReady_ = false;
  8146. } else {
  8147. (0, _log2['default'])(e);
  8148. }
  8149. throw e;
  8150. }
  8151. }
  8152. return;
  8153. };
  8154. /**
  8155. * start media playback
  8156. *
  8157. * @return {Player}
  8158. * A reference to the player object this function was called on
  8159. */
  8160. Player.prototype.play = function play() {
  8161. // Only calls the tech's play if we already have a src loaded
  8162. if (this.src() || this.currentSrc()) {
  8163. this.techCall_('play');
  8164. } else {
  8165. this.tech_.one('loadstart', function () {
  8166. this.play();
  8167. });
  8168. }
  8169. return this;
  8170. };
  8171. /**
  8172. * Pause the video playback
  8173. *
  8174. * @return {Player}
  8175. * A reference to the player object this function was called on
  8176. */
  8177. Player.prototype.pause = function pause() {
  8178. this.techCall_('pause');
  8179. return this;
  8180. };
  8181. /**
  8182. * Check if the player is paused or has yet to play
  8183. *
  8184. * @return {boolean}
  8185. * - false: if the media is currently playing
  8186. * - true: if media is not currently playing
  8187. */
  8188. Player.prototype.paused = function paused() {
  8189. // The initial state of paused should be true (in Safari it's actually false)
  8190. return this.techGet_('paused') === false ? false : true;
  8191. };
  8192. /**
  8193. * Returns whether or not the user is "scrubbing". Scrubbing is
  8194. * when the user has clicked the progress bar handle and is
  8195. * dragging it along the progress bar.
  8196. *
  8197. * @param {boolean} [isScrubbing]
  8198. * wether the user is or is not scrubbing
  8199. *
  8200. * @return {boolean|Player}
  8201. * A instance of the player that called this function when setting,
  8202. * and the value of scrubbing when getting
  8203. */
  8204. Player.prototype.scrubbing = function scrubbing(isScrubbing) {
  8205. if (isScrubbing !== undefined) {
  8206. this.scrubbing_ = !!isScrubbing;
  8207. if (isScrubbing) {
  8208. this.addClass('vjs-scrubbing');
  8209. } else {
  8210. this.removeClass('vjs-scrubbing');
  8211. }
  8212. return this;
  8213. }
  8214. return this.scrubbing_;
  8215. };
  8216. /**
  8217. * Get or set the current time (in seconds)
  8218. *
  8219. * @param {number|string} [seconds]
  8220. * The time to seek to in seconds
  8221. *
  8222. * @return {Player|number}
  8223. * - the current time in seconds when getting
  8224. * - a reference to the current player object when
  8225. * getting
  8226. */
  8227. Player.prototype.currentTime = function currentTime(seconds) {
  8228. if (seconds !== undefined) {
  8229. this.techCall_('setCurrentTime', seconds);
  8230. return this;
  8231. }
  8232. // cache last currentTime and return. default to 0 seconds
  8233. //
  8234. // Caching the currentTime is meant to prevent a massive amount of reads on the tech's
  8235. // currentTime when scrubbing, but may not provide much performance benefit afterall.
  8236. // Should be tested. Also something has to read the actual current time or the cache will
  8237. // never get updated.
  8238. this.cache_.currentTime = this.techGet_('currentTime') || 0;
  8239. return this.cache_.currentTime;
  8240. };
  8241. /**
  8242. * Normally gets the length in time of the video in seconds;
  8243. * in all but the rarest use cases an argument will NOT be passed to the method
  8244. *
  8245. * > **NOTE**: The video must have started loading before the duration can be
  8246. * known, and in the case of Flash, may not be known until the video starts
  8247. * playing.
  8248. *
  8249. * @fires Player#durationchange
  8250. *
  8251. * @param {number} [seconds]
  8252. * The duration of the video to set in seconds
  8253. *
  8254. * @return {number|Player}
  8255. * - The duration of the video in seconds when getting
  8256. * - A reference to the player that called this function
  8257. * when setting
  8258. */
  8259. Player.prototype.duration = function duration(seconds) {
  8260. if (seconds === undefined) {
  8261. return this.cache_.duration || 0;
  8262. }
  8263. seconds = parseFloat(seconds) || 0;
  8264. // Standardize on Inifity for signaling video is live
  8265. if (seconds < 0) {
  8266. seconds = Infinity;
  8267. }
  8268. if (seconds !== this.cache_.duration) {
  8269. // Cache the last set value for optimized scrubbing (esp. Flash)
  8270. this.cache_.duration = seconds;
  8271. if (seconds === Infinity) {
  8272. this.addClass('vjs-live');
  8273. } else {
  8274. this.removeClass('vjs-live');
  8275. }
  8276. /**
  8277. * @event Player#durationchange
  8278. * @type {EventTarget~Event}
  8279. */
  8280. this.trigger('durationchange');
  8281. }
  8282. return this;
  8283. };
  8284. /**
  8285. * Calculates how much time is left in the video. Not part
  8286. * of the native video API.
  8287. *
  8288. * @return {number}
  8289. * The time remaining in seconds
  8290. */
  8291. Player.prototype.remainingTime = function remainingTime() {
  8292. return this.duration() - this.currentTime();
  8293. };
  8294. //
  8295. // Kind of like an array of portions of the video that have been downloaded.
  8296. /**
  8297. * Get a TimeRange object with an array of the times of the video
  8298. * that have been downloaded. If you just want the percent of the
  8299. * video that's been downloaded, use bufferedPercent.
  8300. *
  8301. * @see [Buffered Spec]{@link http://dev.w3.org/html5/spec/video.html#dom-media-buffered}
  8302. *
  8303. * @return {TimeRange}
  8304. * A mock TimeRange object (following HTML spec)
  8305. */
  8306. Player.prototype.buffered = function buffered() {
  8307. var buffered = this.techGet_('buffered');
  8308. if (!buffered || !buffered.length) {
  8309. buffered = (0, _timeRanges.createTimeRange)(0, 0);
  8310. }
  8311. return buffered;
  8312. };
  8313. /**
  8314. * Get the percent (as a decimal) of the video that's been downloaded.
  8315. * This method is not a part of the native HTML video API.
  8316. *
  8317. * @return {number}
  8318. * A decimal between 0 and 1 representing the percent
  8319. * that is bufferred 0 being 0% and 1 being 100%
  8320. */
  8321. Player.prototype.bufferedPercent = function bufferedPercent() {
  8322. return (0, _buffer.bufferedPercent)(this.buffered(), this.duration());
  8323. };
  8324. /**
  8325. * Get the ending time of the last buffered time range
  8326. * This is used in the progress bar to encapsulate all time ranges.
  8327. *
  8328. * @return {number}
  8329. * The end of the last buffered time range
  8330. */
  8331. Player.prototype.bufferedEnd = function bufferedEnd() {
  8332. var buffered = this.buffered();
  8333. var duration = this.duration();
  8334. var end = buffered.end(buffered.length - 1);
  8335. if (end > duration) {
  8336. end = duration;
  8337. }
  8338. return end;
  8339. };
  8340. /**
  8341. * Get or set the current volume of the media
  8342. *
  8343. * @param {number} [percentAsDecimal]
  8344. * The new volume as a decimal percent:
  8345. * - 0 is muted/0%/off
  8346. * - 1.0 is 100%/full
  8347. * - 0.5 is half volume or 50%
  8348. *
  8349. * @return {Player|number}
  8350. * a reference to the calling player when setting and the
  8351. * current volume as a percent when getting
  8352. */
  8353. Player.prototype.volume = function volume(percentAsDecimal) {
  8354. var vol = void 0;
  8355. if (percentAsDecimal !== undefined) {
  8356. // Force value to between 0 and 1
  8357. vol = Math.max(0, Math.min(1, parseFloat(percentAsDecimal)));
  8358. this.cache_.volume = vol;
  8359. this.techCall_('setVolume', vol);
  8360. return this;
  8361. }
  8362. // Default to 1 when returning current volume.
  8363. vol = parseFloat(this.techGet_('volume'));
  8364. return isNaN(vol) ? 1 : vol;
  8365. };
  8366. /**
  8367. * Get the current muted state, or turn mute on or off
  8368. *
  8369. * @param {boolean} [muted]
  8370. * - true to mute
  8371. * - false to unmute
  8372. *
  8373. * @return {boolean|Player}
  8374. * - true if mute is on and getting
  8375. * - false if mute is off and getting
  8376. * - A reference to the current player when setting
  8377. */
  8378. Player.prototype.muted = function muted(_muted) {
  8379. if (_muted !== undefined) {
  8380. this.techCall_('setMuted', _muted);
  8381. return this;
  8382. }
  8383. return this.techGet_('muted') || false;
  8384. };
  8385. /**
  8386. * Check if current tech can support native fullscreen
  8387. * (e.g. with built in controls like iOS, so not our flash swf)
  8388. *
  8389. * @return {boolean}
  8390. * if native fullscreen is supported
  8391. */
  8392. Player.prototype.supportsFullScreen = function supportsFullScreen() {
  8393. return this.techGet_('supportsFullScreen') || false;
  8394. };
  8395. /**
  8396. * Check if the player is in fullscreen mode or tell the player that it
  8397. * is or is not in fullscreen mode.
  8398. *
  8399. * > NOTE: As of the latest HTML5 spec, isFullscreen is no longer an official
  8400. * property and instead document.fullscreenElement is used. But isFullscreen is
  8401. * still a valuable property for internal player workings.
  8402. *
  8403. * @param {boolean} [isFS]
  8404. * Set the players current fullscreen state
  8405. *
  8406. * @return {boolean|Player}
  8407. * - true if fullscreen is on and getting
  8408. * - false if fullscreen is off and getting
  8409. * - A reference to the current player when setting
  8410. */
  8411. Player.prototype.isFullscreen = function isFullscreen(isFS) {
  8412. if (isFS !== undefined) {
  8413. this.isFullscreen_ = !!isFS;
  8414. return this;
  8415. }
  8416. return !!this.isFullscreen_;
  8417. };
  8418. /**
  8419. * Increase the size of the video to full screen
  8420. * In some browsers, full screen is not supported natively, so it enters
  8421. * "full window mode", where the video fills the browser window.
  8422. * In browsers and devices that support native full screen, sometimes the
  8423. * browser's default controls will be shown, and not the Video.js custom skin.
  8424. * This includes most mobile devices (iOS, Android) and older versions of
  8425. * Safari.
  8426. *
  8427. * @fires Player#fullscreenchange
  8428. * @return {Player}
  8429. * A reference to the current player
  8430. */
  8431. Player.prototype.requestFullscreen = function requestFullscreen() {
  8432. var fsApi = _fullscreenApi2['default'];
  8433. this.isFullscreen(true);
  8434. if (fsApi.requestFullscreen) {
  8435. // the browser supports going fullscreen at the element level so we can
  8436. // take the controls fullscreen as well as the video
  8437. // Trigger fullscreenchange event after change
  8438. // We have to specifically add this each time, and remove
  8439. // when canceling fullscreen. Otherwise if there's multiple
  8440. // players on a page, they would all be reacting to the same fullscreen
  8441. // events
  8442. Events.on(_document2['default'], fsApi.fullscreenchange, Fn.bind(this, function documentFullscreenChange(e) {
  8443. this.isFullscreen(_document2['default'][fsApi.fullscreenElement]);
  8444. // If cancelling fullscreen, remove event listener.
  8445. if (this.isFullscreen() === false) {
  8446. Events.off(_document2['default'], fsApi.fullscreenchange, documentFullscreenChange);
  8447. }
  8448. /**
  8449. * @event Player#fullscreenchange
  8450. * @type {EventTarget~Event}
  8451. */
  8452. this.trigger('fullscreenchange');
  8453. }));
  8454. this.el_[fsApi.requestFullscreen]();
  8455. } else if (this.tech_.supportsFullScreen()) {
  8456. // we can't take the video.js controls fullscreen but we can go fullscreen
  8457. // with native controls
  8458. this.techCall_('enterFullScreen');
  8459. } else {
  8460. // fullscreen isn't supported so we'll just stretch the video element to
  8461. // fill the viewport
  8462. this.enterFullWindow();
  8463. /**
  8464. * @event Player#fullscreenchange
  8465. * @type {EventTarget~Event}
  8466. */
  8467. this.trigger('fullscreenchange');
  8468. }
  8469. return this;
  8470. };
  8471. /**
  8472. * Return the video to its normal size after having been in full screen mode
  8473. *
  8474. * @fires Player#fullscreenchange
  8475. *
  8476. * @return {Player}
  8477. * A reference to the current player
  8478. */
  8479. Player.prototype.exitFullscreen = function exitFullscreen() {
  8480. var fsApi = _fullscreenApi2['default'];
  8481. this.isFullscreen(false);
  8482. // Check for browser element fullscreen support
  8483. if (fsApi.requestFullscreen) {
  8484. _document2['default'][fsApi.exitFullscreen]();
  8485. } else if (this.tech_.supportsFullScreen()) {
  8486. this.techCall_('exitFullScreen');
  8487. } else {
  8488. this.exitFullWindow();
  8489. /**
  8490. * @event Player#fullscreenchange
  8491. * @type {EventTarget~Event}
  8492. */
  8493. this.trigger('fullscreenchange');
  8494. }
  8495. return this;
  8496. };
  8497. /**
  8498. * When fullscreen isn't supported we can stretch the
  8499. * video container to as wide as the browser will let us.
  8500. *
  8501. * @fires Player#enterFullWindow
  8502. */
  8503. Player.prototype.enterFullWindow = function enterFullWindow() {
  8504. this.isFullWindow = true;
  8505. // Storing original doc overflow value to return to when fullscreen is off
  8506. this.docOrigOverflow = _document2['default'].documentElement.style.overflow;
  8507. // Add listener for esc key to exit fullscreen
  8508. Events.on(_document2['default'], 'keydown', Fn.bind(this, this.fullWindowOnEscKey));
  8509. // Hide any scroll bars
  8510. _document2['default'].documentElement.style.overflow = 'hidden';
  8511. // Apply fullscreen styles
  8512. Dom.addElClass(_document2['default'].body, 'vjs-full-window');
  8513. /**
  8514. * @event Player#enterFullWindow
  8515. * @type {EventTarget~Event}
  8516. */
  8517. this.trigger('enterFullWindow');
  8518. };
  8519. /**
  8520. * Check for call to either exit full window or
  8521. * full screen on ESC key
  8522. *
  8523. * @param {string} event
  8524. * Event to check for key press
  8525. */
  8526. Player.prototype.fullWindowOnEscKey = function fullWindowOnEscKey(event) {
  8527. if (event.keyCode === 27) {
  8528. if (this.isFullscreen() === true) {
  8529. this.exitFullscreen();
  8530. } else {
  8531. this.exitFullWindow();
  8532. }
  8533. }
  8534. };
  8535. /**
  8536. * Exit full window
  8537. *
  8538. * @fires Player#exitFullWindow
  8539. */
  8540. Player.prototype.exitFullWindow = function exitFullWindow() {
  8541. this.isFullWindow = false;
  8542. Events.off(_document2['default'], 'keydown', this.fullWindowOnEscKey);
  8543. // Unhide scroll bars.
  8544. _document2['default'].documentElement.style.overflow = this.docOrigOverflow;
  8545. // Remove fullscreen styles
  8546. Dom.removeElClass(_document2['default'].body, 'vjs-full-window');
  8547. // Resize the box, controller, and poster to original sizes
  8548. // this.positionAll();
  8549. /**
  8550. * @event Player#exitFullWindow
  8551. * @type {EventTarget~Event}
  8552. */
  8553. this.trigger('exitFullWindow');
  8554. };
  8555. /**
  8556. * Check whether the player can play a given mimetype
  8557. *
  8558. * @see https://www.w3.org/TR/2011/WD-html5-20110113/video.html#dom-navigator-canplaytype
  8559. *
  8560. * @param {string} type
  8561. * The mimetype to check
  8562. *
  8563. * @return {string}
  8564. * 'probably', 'maybe', or '' (empty string)
  8565. */
  8566. Player.prototype.canPlayType = function canPlayType(type) {
  8567. var can = void 0;
  8568. // Loop through each playback technology in the options order
  8569. for (var i = 0, j = this.options_.techOrder; i < j.length; i++) {
  8570. var techName = (0, _toTitleCase2['default'])(j[i]);
  8571. var tech = _tech2['default'].getTech(techName);
  8572. // Support old behavior of techs being registered as components.
  8573. // Remove once that deprecated behavior is removed.
  8574. if (!tech) {
  8575. tech = _component2['default'].getComponent(techName);
  8576. }
  8577. // Check if the current tech is defined before continuing
  8578. if (!tech) {
  8579. _log2['default'].error('The "' + techName + '" tech is undefined. Skipped browser support check for that tech.');
  8580. continue;
  8581. }
  8582. // Check if the browser supports this technology
  8583. if (tech.isSupported()) {
  8584. can = tech.canPlayType(type);
  8585. if (can) {
  8586. return can;
  8587. }
  8588. }
  8589. }
  8590. return '';
  8591. };
  8592. /**
  8593. * Select source based on tech-order or source-order
  8594. * Uses source-order selection if `options.sourceOrder` is truthy. Otherwise,
  8595. * defaults to tech-order selection
  8596. *
  8597. * @param {Array} sources
  8598. * The sources for a media asset
  8599. *
  8600. * @return {Object|boolean}
  8601. * Object of source and tech order or false
  8602. */
  8603. Player.prototype.selectSource = function selectSource(sources) {
  8604. var _this4 = this;
  8605. // Get only the techs specified in `techOrder` that exist and are supported by the
  8606. // current platform
  8607. var techs = this.options_.techOrder.map(_toTitleCase2['default']).map(function (techName) {
  8608. // `Component.getComponent(...)` is for support of old behavior of techs
  8609. // being registered as components.
  8610. // Remove once that deprecated behavior is removed.
  8611. return [techName, _tech2['default'].getTech(techName) || _component2['default'].getComponent(techName)];
  8612. }).filter(function (_ref) {
  8613. var techName = _ref[0],
  8614. tech = _ref[1];
  8615. // Check if the current tech is defined before continuing
  8616. if (tech) {
  8617. // Check if the browser supports this technology
  8618. return tech.isSupported();
  8619. }
  8620. _log2['default'].error('The "' + techName + '" tech is undefined. Skipped browser support check for that tech.');
  8621. return false;
  8622. });
  8623. // Iterate over each `innerArray` element once per `outerArray` element and execute
  8624. // `tester` with both. If `tester` returns a non-falsy value, exit early and return
  8625. // that value.
  8626. var findFirstPassingTechSourcePair = function findFirstPassingTechSourcePair(outerArray, innerArray, tester) {
  8627. var found = void 0;
  8628. outerArray.some(function (outerChoice) {
  8629. return innerArray.some(function (innerChoice) {
  8630. found = tester(outerChoice, innerChoice);
  8631. if (found) {
  8632. return true;
  8633. }
  8634. });
  8635. });
  8636. return found;
  8637. };
  8638. var foundSourceAndTech = void 0;
  8639. var flip = function flip(fn) {
  8640. return function (a, b) {
  8641. return fn(b, a);
  8642. };
  8643. };
  8644. var finder = function finder(_ref2, source) {
  8645. var techName = _ref2[0],
  8646. tech = _ref2[1];
  8647. if (tech.canPlaySource(source, _this4.options_[techName.toLowerCase()])) {
  8648. return { source: source, tech: techName };
  8649. }
  8650. };
  8651. // Depending on the truthiness of `options.sourceOrder`, we swap the order of techs and sources
  8652. // to select from them based on their priority.
  8653. if (this.options_.sourceOrder) {
  8654. // Source-first ordering
  8655. foundSourceAndTech = findFirstPassingTechSourcePair(sources, techs, flip(finder));
  8656. } else {
  8657. // Tech-first ordering
  8658. foundSourceAndTech = findFirstPassingTechSourcePair(techs, sources, finder);
  8659. }
  8660. return foundSourceAndTech || false;
  8661. };
  8662. /**
  8663. * The source function updates the video source
  8664. * There are three types of variables you can pass as the argument.
  8665. * **URL string**: A URL to the the video file. Use this method if you are sure
  8666. * the current playback technology (HTML5/Flash) can support the source you
  8667. * provide. Currently only MP4 files can be used in both HTML5 and Flash.
  8668. *
  8669. * @param {Tech~SourceObject|Tech~SourceObject[]} [source]
  8670. * One SourceObject or an array of SourceObjects
  8671. *
  8672. * @return {string|Player}
  8673. * - The current video source when getting
  8674. * - The player when setting
  8675. */
  8676. Player.prototype.src = function src(source) {
  8677. if (source === undefined) {
  8678. return this.techGet_('src');
  8679. }
  8680. var currentTech = _tech2['default'].getTech(this.techName_);
  8681. // Support old behavior of techs being registered as components.
  8682. // Remove once that deprecated behavior is removed.
  8683. if (!currentTech) {
  8684. currentTech = _component2['default'].getComponent(this.techName_);
  8685. }
  8686. // case: Array of source objects to choose from and pick the best to play
  8687. if (Array.isArray(source)) {
  8688. this.sourceList_(source);
  8689. // case: URL String (http://myvideo...)
  8690. } else if (typeof source === 'string') {
  8691. // create a source object from the string
  8692. this.src({ src: source });
  8693. // case: Source object { src: '', type: '' ... }
  8694. } else if (source instanceof Object) {
  8695. // check if the source has a type and the loaded tech cannot play the source
  8696. // if there's no type we'll just try the current tech
  8697. if (source.type && !currentTech.canPlaySource(source, this.options_[this.techName_.toLowerCase()])) {
  8698. // create a source list with the current source and send through
  8699. // the tech loop to check for a compatible technology
  8700. this.sourceList_([source]);
  8701. } else {
  8702. this.cache_.sources = null;
  8703. this.cache_.source = source;
  8704. this.cache_.src = source.src;
  8705. this.currentType_ = source.type || '';
  8706. // wait until the tech is ready to set the source
  8707. this.ready(function () {
  8708. // The setSource tech method was added with source handlers
  8709. // so older techs won't support it
  8710. // We need to check the direct prototype for the case where subclasses
  8711. // of the tech do not support source handlers
  8712. if (currentTech.prototype.hasOwnProperty('setSource')) {
  8713. this.techCall_('setSource', source);
  8714. } else {
  8715. this.techCall_('src', source.src);
  8716. }
  8717. if (this.options_.preload === 'auto') {
  8718. this.load();
  8719. }
  8720. if (this.options_.autoplay) {
  8721. this.play();
  8722. }
  8723. // Set the source synchronously if possible (#2326)
  8724. }, true);
  8725. }
  8726. }
  8727. return this;
  8728. };
  8729. /**
  8730. * Handle an array of source objects
  8731. *
  8732. * @param {Tech~SourceObject[]} sources
  8733. * Array of source objects
  8734. *
  8735. * @private
  8736. */
  8737. Player.prototype.sourceList_ = function sourceList_(sources) {
  8738. var sourceTech = this.selectSource(sources);
  8739. if (sourceTech) {
  8740. if (sourceTech.tech === this.techName_) {
  8741. // if this technology is already loaded, set the source
  8742. this.src(sourceTech.source);
  8743. } else {
  8744. // load this technology with the chosen source
  8745. this.loadTech_(sourceTech.tech, sourceTech.source);
  8746. }
  8747. this.cache_.sources = sources;
  8748. } else {
  8749. // We need to wrap this in a timeout to give folks a chance to add error event handlers
  8750. this.setTimeout(function () {
  8751. this.error({ code: 4, message: this.localize(this.options_.notSupportedMessage) });
  8752. }, 0);
  8753. // we could not find an appropriate tech, but let's still notify the delegate that this is it
  8754. // this needs a better comment about why this is needed
  8755. this.triggerReady();
  8756. }
  8757. };
  8758. /**
  8759. * Begin loading the src data.
  8760. *
  8761. * @return {Player}
  8762. * A reference to the player
  8763. */
  8764. Player.prototype.load = function load() {
  8765. this.techCall_('load');
  8766. return this;
  8767. };
  8768. /**
  8769. * Reset the player. Loads the first tech in the techOrder,
  8770. * and calls `reset` on the tech`.
  8771. *
  8772. * @return {Player}
  8773. * A reference to the player
  8774. */
  8775. Player.prototype.reset = function reset() {
  8776. this.loadTech_((0, _toTitleCase2['default'])(this.options_.techOrder[0]), null);
  8777. this.techCall_('reset');
  8778. return this;
  8779. };
  8780. /**
  8781. * Returns all of the current source objects.
  8782. *
  8783. * @return {Tech~SourceObject[]}
  8784. * The current source objects
  8785. */
  8786. Player.prototype.currentSources = function currentSources() {
  8787. var source = this.currentSource();
  8788. var sources = [];
  8789. // assume `{}` or `{ src }`
  8790. if (Object.keys(source).length !== 0) {
  8791. sources.push(source);
  8792. }
  8793. return this.cache_.sources || sources;
  8794. };
  8795. /**
  8796. * Returns the current source object.
  8797. *
  8798. * @return {Tech~SourceObject}
  8799. * The current source object
  8800. */
  8801. Player.prototype.currentSource = function currentSource() {
  8802. var source = {};
  8803. var src = this.currentSrc();
  8804. if (src) {
  8805. source.src = src;
  8806. }
  8807. return this.cache_.source || source;
  8808. };
  8809. /**
  8810. * Returns the fully qualified URL of the current source value e.g. http://mysite.com/video.mp4
  8811. * Can be used in conjuction with `currentType` to assist in rebuilding the current source object.
  8812. *
  8813. * @return {string}
  8814. * The current source
  8815. */
  8816. Player.prototype.currentSrc = function currentSrc() {
  8817. return this.techGet_('currentSrc') || this.cache_.src || '';
  8818. };
  8819. /**
  8820. * Get the current source type e.g. video/mp4
  8821. * This can allow you rebuild the current source object so that you could load the same
  8822. * source and tech later
  8823. *
  8824. * @return {string}
  8825. * The source MIME type
  8826. */
  8827. Player.prototype.currentType = function currentType() {
  8828. return this.currentType_ || '';
  8829. };
  8830. /**
  8831. * Get or set the preload attribute
  8832. *
  8833. * @param {boolean} [value]
  8834. * - true means that we should preload
  8835. * - false maens that we should not preload
  8836. *
  8837. * @return {string|Player}
  8838. * - the preload attribute value when getting
  8839. * - the player when setting
  8840. */
  8841. Player.prototype.preload = function preload(value) {
  8842. if (value !== undefined) {
  8843. this.techCall_('setPreload', value);
  8844. this.options_.preload = value;
  8845. return this;
  8846. }
  8847. return this.techGet_('preload');
  8848. };
  8849. /**
  8850. * Get or set the autoplay attribute.
  8851. *
  8852. * @param {boolean} [value]
  8853. * - true means that we should autoplay
  8854. * - false maens that we should not autoplay
  8855. *
  8856. * @return {string|Player}
  8857. * - the current value of autoplay
  8858. * - the player when setting
  8859. */
  8860. Player.prototype.autoplay = function autoplay(value) {
  8861. if (value !== undefined) {
  8862. this.techCall_('setAutoplay', value);
  8863. this.options_.autoplay = value;
  8864. return this;
  8865. }
  8866. return this.techGet_('autoplay', value);
  8867. };
  8868. /**
  8869. * Get or set the loop attribute on the video element.
  8870. *
  8871. * @param {boolean} [value]
  8872. * - true means that we should loop the video
  8873. * - false means that we should not loop the video
  8874. *
  8875. * @return {string|Player}
  8876. * - the current value of loop when getting
  8877. * - the player when setting
  8878. */
  8879. Player.prototype.loop = function loop(value) {
  8880. if (value !== undefined) {
  8881. this.techCall_('setLoop', value);
  8882. this.options_.loop = value;
  8883. return this;
  8884. }
  8885. return this.techGet_('loop');
  8886. };
  8887. /**
  8888. * Get or set the poster image source url
  8889. *
  8890. * @fires Player#posterchange
  8891. *
  8892. * @param {string} [src]
  8893. * Poster image source URL
  8894. *
  8895. * @return {string|Player}
  8896. * - the current value of poster when getting
  8897. * - the player when setting
  8898. */
  8899. Player.prototype.poster = function poster(src) {
  8900. if (src === undefined) {
  8901. return this.poster_;
  8902. }
  8903. // The correct way to remove a poster is to set as an empty string
  8904. // other falsey values will throw errors
  8905. if (!src) {
  8906. src = '';
  8907. }
  8908. // update the internal poster variable
  8909. this.poster_ = src;
  8910. // update the tech's poster
  8911. this.techCall_('setPoster', src);
  8912. // alert components that the poster has been set
  8913. /**
  8914. * This event fires when the poster image is changed on the player.
  8915. *
  8916. * @event Player#posterchange
  8917. * @type {EventTarget~Event}
  8918. */
  8919. this.trigger('posterchange');
  8920. return this;
  8921. };
  8922. /**
  8923. * Some techs (e.g. YouTube) can provide a poster source in an
  8924. * asynchronous way. We want the poster component to use this
  8925. * poster source so that it covers up the tech's controls.
  8926. * (YouTube's play button). However we only want to use this
  8927. * soruce if the player user hasn't set a poster through
  8928. * the normal APIs.
  8929. *
  8930. * @fires Player#posterchange
  8931. * @listens Tech#posterchange
  8932. * @private
  8933. */
  8934. Player.prototype.handleTechPosterChange_ = function handleTechPosterChange_() {
  8935. if (!this.poster_ && this.tech_ && this.tech_.poster) {
  8936. this.poster_ = this.tech_.poster() || '';
  8937. // Let components know the poster has changed
  8938. this.trigger('posterchange');
  8939. }
  8940. };
  8941. /**
  8942. * Get or set whether or not the controls are showing.
  8943. *
  8944. * @fires Player#controlsenabled
  8945. *
  8946. * @param {boolean} [bool]
  8947. * - true to turn controls on
  8948. * - false to turn controls off
  8949. *
  8950. * @return {boolean|Player}
  8951. * - the current value of controls when getting
  8952. * - the player when setting
  8953. */
  8954. Player.prototype.controls = function controls(bool) {
  8955. if (bool !== undefined) {
  8956. bool = !!bool;
  8957. // Don't trigger a change event unless it actually changed
  8958. if (this.controls_ !== bool) {
  8959. this.controls_ = bool;
  8960. if (this.usingNativeControls()) {
  8961. this.techCall_('setControls', bool);
  8962. }
  8963. if (bool) {
  8964. this.removeClass('vjs-controls-disabled');
  8965. this.addClass('vjs-controls-enabled');
  8966. /**
  8967. * @event Player#controlsenabled
  8968. * @type {EventTarget~Event}
  8969. */
  8970. this.trigger('controlsenabled');
  8971. if (!this.usingNativeControls()) {
  8972. this.addTechControlsListeners_();
  8973. }
  8974. } else {
  8975. this.removeClass('vjs-controls-enabled');
  8976. this.addClass('vjs-controls-disabled');
  8977. /**
  8978. * @event Player#controlsdisabled
  8979. * @type {EventTarget~Event}
  8980. */
  8981. this.trigger('controlsdisabled');
  8982. if (!this.usingNativeControls()) {
  8983. this.removeTechControlsListeners_();
  8984. }
  8985. }
  8986. }
  8987. return this;
  8988. }
  8989. return !!this.controls_;
  8990. };
  8991. /**
  8992. * Toggle native controls on/off. Native controls are the controls built into
  8993. * devices (e.g. default iPhone controls), Flash, or other techs
  8994. * (e.g. Vimeo Controls)
  8995. * **This should only be set by the current tech, because only the tech knows
  8996. * if it can support native controls**
  8997. *
  8998. * @fires Player#usingnativecontrols
  8999. * @fires Player#usingcustomcontrols
  9000. *
  9001. * @param {boolean} [bool]
  9002. * - true to turn native controls on
  9003. * - false to turn native controls off
  9004. *
  9005. * @return {boolean|Player}
  9006. * - the current value of native controls when getting
  9007. * - the player when setting
  9008. */
  9009. Player.prototype.usingNativeControls = function usingNativeControls(bool) {
  9010. if (bool !== undefined) {
  9011. bool = !!bool;
  9012. // Don't trigger a change event unless it actually changed
  9013. if (this.usingNativeControls_ !== bool) {
  9014. this.usingNativeControls_ = bool;
  9015. if (bool) {
  9016. this.addClass('vjs-using-native-controls');
  9017. /**
  9018. * player is using the native device controls
  9019. *
  9020. * @event Player#usingnativecontrols
  9021. * @type {EventTarget~Event}
  9022. */
  9023. this.trigger('usingnativecontrols');
  9024. } else {
  9025. this.removeClass('vjs-using-native-controls');
  9026. /**
  9027. * player is using the custom HTML controls
  9028. *
  9029. * @event Player#usingcustomcontrols
  9030. * @type {EventTarget~Event}
  9031. */
  9032. this.trigger('usingcustomcontrols');
  9033. }
  9034. }
  9035. return this;
  9036. }
  9037. return !!this.usingNativeControls_;
  9038. };
  9039. /**
  9040. * Set or get the current MediaError
  9041. *
  9042. * @fires Player#error
  9043. *
  9044. * @param {MediaError|string|number} [err]
  9045. * A MediaError or a string/number to be turned
  9046. * into a MediaError
  9047. *
  9048. * @return {MediaError|null|Player}
  9049. * - The current MediaError when getting (or null)
  9050. * - The player when setting
  9051. */
  9052. Player.prototype.error = function error(err) {
  9053. if (err === undefined) {
  9054. return this.error_ || null;
  9055. }
  9056. // restoring to default
  9057. if (err === null) {
  9058. this.error_ = err;
  9059. this.removeClass('vjs-error');
  9060. if (this.errorDisplay) {
  9061. this.errorDisplay.close();
  9062. }
  9063. return this;
  9064. }
  9065. this.error_ = new _mediaError2['default'](err);
  9066. // add the vjs-error classname to the player
  9067. this.addClass('vjs-error');
  9068. // log the name of the error type and any message
  9069. // ie8 just logs "[object object]" if you just log the error object
  9070. _log2['default'].error('(CODE:' + this.error_.code + ' ' + _mediaError2['default'].errorTypes[this.error_.code] + ')', this.error_.message, this.error_);
  9071. /**
  9072. * @event Player#error
  9073. * @type {EventTarget~Event}
  9074. */
  9075. this.trigger('error');
  9076. return this;
  9077. };
  9078. /**
  9079. * Report user activity
  9080. *
  9081. * @param {Object} event
  9082. * Event object
  9083. */
  9084. Player.prototype.reportUserActivity = function reportUserActivity(event) {
  9085. this.userActivity_ = true;
  9086. };
  9087. /**
  9088. * Get/set if user is active
  9089. *
  9090. * @fires Player#useractive
  9091. * @fires Player#userinactive
  9092. *
  9093. * @param {boolean} [bool]
  9094. * - true if the user is active
  9095. * - false if the user is inactive
  9096. * @return {boolean|Player}
  9097. * - the current value of userActive when getting
  9098. * - the player when setting
  9099. */
  9100. Player.prototype.userActive = function userActive(bool) {
  9101. if (bool !== undefined) {
  9102. bool = !!bool;
  9103. if (bool !== this.userActive_) {
  9104. this.userActive_ = bool;
  9105. if (bool) {
  9106. // If the user was inactive and is now active we want to reset the
  9107. // inactivity timer
  9108. this.userActivity_ = true;
  9109. this.removeClass('vjs-user-inactive');
  9110. this.addClass('vjs-user-active');
  9111. /**
  9112. * @event Player#useractive
  9113. * @type {EventTarget~Event}
  9114. */
  9115. this.trigger('useractive');
  9116. } else {
  9117. // We're switching the state to inactive manually, so erase any other
  9118. // activity
  9119. this.userActivity_ = false;
  9120. // Chrome/Safari/IE have bugs where when you change the cursor it can
  9121. // trigger a mousemove event. This causes an issue when you're hiding
  9122. // the cursor when the user is inactive, and a mousemove signals user
  9123. // activity. Making it impossible to go into inactive mode. Specifically
  9124. // this happens in fullscreen when we really need to hide the cursor.
  9125. //
  9126. // When this gets resolved in ALL browsers it can be removed
  9127. // https://code.google.com/p/chromium/issues/detail?id=103041
  9128. if (this.tech_) {
  9129. this.tech_.one('mousemove', function (e) {
  9130. e.stopPropagation();
  9131. e.preventDefault();
  9132. });
  9133. }
  9134. this.removeClass('vjs-user-active');
  9135. this.addClass('vjs-user-inactive');
  9136. /**
  9137. * @event Player#userinactive
  9138. * @type {EventTarget~Event}
  9139. */
  9140. this.trigger('userinactive');
  9141. }
  9142. }
  9143. return this;
  9144. }
  9145. return this.userActive_;
  9146. };
  9147. /**
  9148. * Listen for user activity based on timeout value
  9149. *
  9150. * @private
  9151. */
  9152. Player.prototype.listenForUserActivity_ = function listenForUserActivity_() {
  9153. var mouseInProgress = void 0;
  9154. var lastMoveX = void 0;
  9155. var lastMoveY = void 0;
  9156. var handleActivity = Fn.bind(this, this.reportUserActivity);
  9157. var handleMouseMove = function handleMouseMove(e) {
  9158. // #1068 - Prevent mousemove spamming
  9159. // Chrome Bug: https://code.google.com/p/chromium/issues/detail?id=366970
  9160. if (e.screenX !== lastMoveX || e.screenY !== lastMoveY) {
  9161. lastMoveX = e.screenX;
  9162. lastMoveY = e.screenY;
  9163. handleActivity();
  9164. }
  9165. };
  9166. var handleMouseDown = function handleMouseDown() {
  9167. handleActivity();
  9168. // For as long as the they are touching the device or have their mouse down,
  9169. // we consider them active even if they're not moving their finger or mouse.
  9170. // So we want to continue to update that they are active
  9171. this.clearInterval(mouseInProgress);
  9172. // Setting userActivity=true now and setting the interval to the same time
  9173. // as the activityCheck interval (250) should ensure we never miss the
  9174. // next activityCheck
  9175. mouseInProgress = this.setInterval(handleActivity, 250);
  9176. };
  9177. var handleMouseUp = function handleMouseUp(event) {
  9178. handleActivity();
  9179. // Stop the interval that maintains activity if the mouse/touch is down
  9180. this.clearInterval(mouseInProgress);
  9181. };
  9182. // Any mouse movement will be considered user activity
  9183. this.on('mousedown', handleMouseDown);
  9184. this.on('mousemove', handleMouseMove);
  9185. this.on('mouseup', handleMouseUp);
  9186. // Listen for keyboard navigation
  9187. // Shouldn't need to use inProgress interval because of key repeat
  9188. this.on('keydown', handleActivity);
  9189. this.on('keyup', handleActivity);
  9190. // Run an interval every 250 milliseconds instead of stuffing everything into
  9191. // the mousemove/touchmove function itself, to prevent performance degradation.
  9192. // `this.reportUserActivity` simply sets this.userActivity_ to true, which
  9193. // then gets picked up by this loop
  9194. // http://ejohn.org/blog/learning-from-twitter/
  9195. var inactivityTimeout = void 0;
  9196. this.setInterval(function () {
  9197. // Check to see if mouse/touch activity has happened
  9198. if (this.userActivity_) {
  9199. // Reset the activity tracker
  9200. this.userActivity_ = false;
  9201. // If the user state was inactive, set the state to active
  9202. this.userActive(true);
  9203. // Clear any existing inactivity timeout to start the timer over
  9204. this.clearTimeout(inactivityTimeout);
  9205. var timeout = this.options_.inactivityTimeout;
  9206. if (timeout > 0) {
  9207. // In <timeout> milliseconds, if no more activity has occurred the
  9208. // user will be considered inactive
  9209. inactivityTimeout = this.setTimeout(function () {
  9210. // Protect against the case where the inactivityTimeout can trigger just
  9211. // before the next user activity is picked up by the activity check loop
  9212. // causing a flicker
  9213. if (!this.userActivity_) {
  9214. this.userActive(false);
  9215. }
  9216. }, timeout);
  9217. }
  9218. }
  9219. }, 250);
  9220. };
  9221. /**
  9222. * Gets or sets the current playback rate. A playback rate of
  9223. * 1.0 represents normal speed and 0.5 would indicate half-speed
  9224. * playback, for instance.
  9225. *
  9226. * @see https://html.spec.whatwg.org/multipage/embedded-content.html#dom-media-playbackrate
  9227. *
  9228. * @param {number} [rate]
  9229. * New playback rate to set.
  9230. *
  9231. * @return {number|Player}
  9232. * - The current playback rate when getting or 1.0
  9233. * - the player when setting
  9234. */
  9235. Player.prototype.playbackRate = function playbackRate(rate) {
  9236. if (rate !== undefined) {
  9237. this.techCall_('setPlaybackRate', rate);
  9238. return this;
  9239. }
  9240. if (this.tech_ && this.tech_.featuresPlaybackRate) {
  9241. return this.techGet_('playbackRate');
  9242. }
  9243. return 1.0;
  9244. };
  9245. /**
  9246. * Gets or sets the audio flag
  9247. *
  9248. * @param {boolean} bool
  9249. * - true signals that this is an audio player
  9250. * - false signals that this is not an audio player
  9251. *
  9252. * @return {Player|boolean}
  9253. * - the current value of isAudio when getting
  9254. * - the player if setting
  9255. */
  9256. Player.prototype.isAudio = function isAudio(bool) {
  9257. if (bool !== undefined) {
  9258. this.isAudio_ = !!bool;
  9259. return this;
  9260. }
  9261. return !!this.isAudio_;
  9262. };
  9263. /**
  9264. * Get the {@link VideoTrackList}
  9265. *
  9266. * @see https://html.spec.whatwg.org/multipage/embedded-content.html#videotracklist
  9267. *
  9268. * @return {VideoTrackList}
  9269. * the current video track list
  9270. */
  9271. Player.prototype.videoTracks = function videoTracks() {
  9272. // if we have not yet loadTech_, we create videoTracks_
  9273. // these will be passed to the tech during loading
  9274. if (!this.tech_) {
  9275. this.videoTracks_ = this.videoTracks_ || new _videoTrackList2['default']();
  9276. return this.videoTracks_;
  9277. }
  9278. return this.tech_.videoTracks();
  9279. };
  9280. /**
  9281. * Get the {@link AudioTrackList}
  9282. *
  9283. * @see https://html.spec.whatwg.org/multipage/embedded-content.html#audiotracklist
  9284. *
  9285. * @return {AudioTrackList}
  9286. * the current audio track list
  9287. */
  9288. Player.prototype.audioTracks = function audioTracks() {
  9289. // if we have not yet loadTech_, we create videoTracks_
  9290. // these will be passed to the tech during loading
  9291. if (!this.tech_) {
  9292. this.audioTracks_ = this.audioTracks_ || new _audioTrackList2['default']();
  9293. return this.audioTracks_;
  9294. }
  9295. return this.tech_.audioTracks();
  9296. };
  9297. /**
  9298. * Get the {@link TextTrackList}
  9299. *
  9300. * Text tracks are tracks of timed text events.
  9301. * - Captions: text displayed over the video
  9302. * for the hearing impaired
  9303. * - Subtitles: text displayed over the video for
  9304. * those who don't understand language in the video
  9305. * - Chapters: text displayed in a menu allowing the user to jump
  9306. * to particular points (chapters) in the video
  9307. * - Descriptions: (not yet implemented) audio descriptions that are read back to
  9308. * the user by a screen reading device
  9309. *
  9310. * @see http://www.w3.org/html/wg/drafts/html/master/embedded-content-0.html#dom-media-texttracks
  9311. *
  9312. * @return {TextTrackList|undefined}
  9313. * The current TextTrackList or undefined if
  9314. * or undefined if we don't have a tech
  9315. */
  9316. Player.prototype.textTracks = function textTracks() {
  9317. // cannot use techGet_ directly because it checks to see whether the tech is ready.
  9318. // Flash is unlikely to be ready in time but textTracks should still work.
  9319. if (this.tech_) {
  9320. return this.tech_.textTracks();
  9321. }
  9322. };
  9323. /**
  9324. * Get the "remote" {@link TextTrackList}. Remote Text Tracks
  9325. * are tracks that were added to the HTML video element and can
  9326. * be removed, whereas normal texttracks cannot be removed.
  9327. *
  9328. *
  9329. * @return {TextTrackList|undefined}
  9330. * The current remote text track list or undefined
  9331. * if we don't have a tech
  9332. */
  9333. Player.prototype.remoteTextTracks = function remoteTextTracks() {
  9334. if (this.tech_) {
  9335. return this.tech_.remoteTextTracks();
  9336. }
  9337. };
  9338. /**
  9339. * Get the "remote" {@link HTMLTrackElementList}.
  9340. * This gives the user all of the DOM elements that match up
  9341. * with the remote {@link TextTrackList}.
  9342. *
  9343. * @return {HTMLTrackElementList}
  9344. * The current remote text track list elements
  9345. * or undefined if we don't have a tech
  9346. */
  9347. Player.prototype.remoteTextTrackEls = function remoteTextTrackEls() {
  9348. if (this.tech_) {
  9349. return this.tech_.remoteTextTrackEls();
  9350. }
  9351. };
  9352. /**
  9353. * A helper method for adding a {@link TextTrack} to our
  9354. * {@link TextTrackList}.
  9355. *
  9356. * In addition to the W3C settings we allow adding additional info through options.
  9357. *
  9358. * @see http://www.w3.org/html/wg/drafts/html/master/embedded-content-0.html#dom-media-addtexttrack
  9359. *
  9360. * @param {string} [kind]
  9361. * the kind of TextTrack you are adding
  9362. *
  9363. * @param {string} [label]
  9364. * the label to give the TextTrack label
  9365. *
  9366. * @param {string} [language]
  9367. * the language to set on the TextTrack
  9368. *
  9369. * @return {TextTrack|undefined}
  9370. * the TextTrack that was added or undefined
  9371. * if there is no tech
  9372. */
  9373. Player.prototype.addTextTrack = function addTextTrack(kind, label, language) {
  9374. if (this.tech_) {
  9375. return this.tech_.addTextTrack(kind, label, language);
  9376. }
  9377. };
  9378. /**
  9379. * Create a remote {@link TextTrack} and an {@link HTMLTrackElement}. It will
  9380. * automatically removed from the video element whenever the source changes, unless
  9381. * manualCleanup is set to false.
  9382. *
  9383. * @param {Object} options
  9384. * Options to pass to {@link HTMLTrackElement} during creation. See
  9385. * {@link HTMLTrackElement} for object properties that you should use.
  9386. *
  9387. * @param {boolean} [manualCleanup=true] if set to false, the TextTrack will be
  9388. *
  9389. * @return {HTMLTrackElement}
  9390. * the HTMLTrackElement that was created and added
  9391. * to the HTMLTrackElementList and the remote
  9392. * TextTrackList
  9393. *
  9394. * @deprecated The default value of the "manualCleanup" parameter will default
  9395. * to "false" in upcoming versions of Video.js
  9396. */
  9397. Player.prototype.addRemoteTextTrack = function addRemoteTextTrack(options, manualCleanup) {
  9398. if (this.tech_) {
  9399. return this.tech_.addRemoteTextTrack(options, manualCleanup);
  9400. }
  9401. };
  9402. /**
  9403. * Remove a remote {@link TextTrack} from the respective
  9404. * {@link TextTrackList} and {@link HTMLTrackElementList}.
  9405. *
  9406. * @param {Object} track
  9407. * Remote {@link TextTrack} to remove
  9408. *
  9409. * @return {undefined}
  9410. * does not return anything
  9411. */
  9412. Player.prototype.removeRemoteTextTrack = function removeRemoteTextTrack() {
  9413. var _ref3 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
  9414. _ref3$track = _ref3.track,
  9415. track = _ref3$track === undefined ? arguments[0] : _ref3$track;
  9416. // destructure the input into an object with a track argument, defaulting to arguments[0]
  9417. // default the whole argument to an empty object if nothing was passed in
  9418. if (this.tech_) {
  9419. return this.tech_.removeRemoteTextTrack(track);
  9420. }
  9421. };
  9422. /**
  9423. * Get video width
  9424. *
  9425. * @return {number}
  9426. * current video width
  9427. */
  9428. Player.prototype.videoWidth = function videoWidth() {
  9429. return this.tech_ && this.tech_.videoWidth && this.tech_.videoWidth() || 0;
  9430. };
  9431. /**
  9432. * Get video height
  9433. *
  9434. * @return {number}
  9435. * current video height
  9436. */
  9437. Player.prototype.videoHeight = function videoHeight() {
  9438. return this.tech_ && this.tech_.videoHeight && this.tech_.videoHeight() || 0;
  9439. };
  9440. // Methods to add support for
  9441. // initialTime: function() { return this.techCall_('initialTime'); },
  9442. // startOffsetTime: function() { return this.techCall_('startOffsetTime'); },
  9443. // played: function() { return this.techCall_('played'); },
  9444. // defaultPlaybackRate: function() { return this.techCall_('defaultPlaybackRate'); },
  9445. // defaultMuted: function() { return this.techCall_('defaultMuted'); }
  9446. /**
  9447. * The player's language code
  9448. * NOTE: The language should be set in the player options if you want the
  9449. * the controls to be built with a specific language. Changing the lanugage
  9450. * later will not update controls text.
  9451. *
  9452. * @param {string} [code]
  9453. * the language code to set the player to
  9454. *
  9455. * @return {string|Player}
  9456. * - The current language code when getting
  9457. * - A reference to the player when setting
  9458. */
  9459. Player.prototype.language = function language(code) {
  9460. if (code === undefined) {
  9461. return this.language_;
  9462. }
  9463. this.language_ = String(code).toLowerCase();
  9464. return this;
  9465. };
  9466. /**
  9467. * Get the player's language dictionary
  9468. * Merge every time, because a newly added plugin might call videojs.addLanguage() at any time
  9469. * Languages specified directly in the player options have precedence
  9470. *
  9471. * @return {Array}
  9472. * An array of of supported languages
  9473. */
  9474. Player.prototype.languages = function languages() {
  9475. return (0, _mergeOptions2['default'])(Player.prototype.options_.languages, this.languages_);
  9476. };
  9477. /**
  9478. * returns a JavaScript object reperesenting the current track
  9479. * information. **DOES not return it as JSON**
  9480. *
  9481. * @return {Object}
  9482. * Object representing the current of track info
  9483. */
  9484. Player.prototype.toJSON = function toJSON() {
  9485. var options = (0, _mergeOptions2['default'])(this.options_);
  9486. var tracks = options.tracks;
  9487. options.tracks = [];
  9488. for (var i = 0; i < tracks.length; i++) {
  9489. var track = tracks[i];
  9490. // deep merge tracks and null out player so no circular references
  9491. track = (0, _mergeOptions2['default'])(track);
  9492. track.player = undefined;
  9493. options.tracks[i] = track;
  9494. }
  9495. return options;
  9496. };
  9497. /**
  9498. * Creates a simple modal dialog (an instance of the {@link ModalDialog}
  9499. * component) that immediately overlays the player with arbitrary
  9500. * content and removes itself when closed.
  9501. *
  9502. * @param {string|Function|Element|Array|null} content
  9503. * Same as {@link ModalDialog#content}'s param of the same name.
  9504. * The most straight-forward usage is to provide a string or DOM
  9505. * element.
  9506. *
  9507. * @param {Object} [options]
  9508. * Extra options which will be passed on to the {@link ModalDialog}.
  9509. *
  9510. * @return {ModalDialog}
  9511. * the {@link ModalDialog} that was created
  9512. */
  9513. Player.prototype.createModal = function createModal(content, options) {
  9514. var _this5 = this;
  9515. options = options || {};
  9516. options.content = content || '';
  9517. var modal = new _modalDialog2['default'](this, options);
  9518. this.addChild(modal);
  9519. modal.on('dispose', function () {
  9520. _this5.removeChild(modal);
  9521. });
  9522. return modal.open();
  9523. };
  9524. /**
  9525. * Gets tag settings
  9526. *
  9527. * @param {Element} tag
  9528. * The player tag
  9529. *
  9530. * @return {Object}
  9531. * An object containing all of the settings
  9532. * for a player tag
  9533. */
  9534. Player.getTagSettings = function getTagSettings(tag) {
  9535. var baseOptions = {
  9536. sources: [],
  9537. tracks: []
  9538. };
  9539. var tagOptions = Dom.getElAttributes(tag);
  9540. var dataSetup = tagOptions['data-setup'];
  9541. if (Dom.hasElClass(tag, 'vjs-fluid')) {
  9542. tagOptions.fluid = true;
  9543. }
  9544. // Check if data-setup attr exists.
  9545. if (dataSetup !== null) {
  9546. // Parse options JSON
  9547. // If empty string, make it a parsable json object.
  9548. var _safeParseTuple = (0, _tuple2['default'])(dataSetup || '{}'),
  9549. err = _safeParseTuple[0],
  9550. data = _safeParseTuple[1];
  9551. if (err) {
  9552. _log2['default'].error(err);
  9553. }
  9554. (0, _obj.assign)(tagOptions, data);
  9555. }
  9556. (0, _obj.assign)(baseOptions, tagOptions);
  9557. // Get tag children settings
  9558. if (tag.hasChildNodes()) {
  9559. var children = tag.childNodes;
  9560. for (var i = 0, j = children.length; i < j; i++) {
  9561. var child = children[i];
  9562. // Change case needed: http://ejohn.org/blog/nodename-case-sensitivity/
  9563. var childName = child.nodeName.toLowerCase();
  9564. if (childName === 'source') {
  9565. baseOptions.sources.push(Dom.getElAttributes(child));
  9566. } else if (childName === 'track') {
  9567. baseOptions.tracks.push(Dom.getElAttributes(child));
  9568. }
  9569. }
  9570. }
  9571. return baseOptions;
  9572. };
  9573. /**
  9574. * Determine wether or not flexbox is supported
  9575. *
  9576. * @return {boolean}
  9577. * - true if flexbox is supported
  9578. * - false if flexbox is not supported
  9579. */
  9580. Player.prototype.flexNotSupported_ = function flexNotSupported_() {
  9581. var elem = _document2['default'].createElement('i');
  9582. // Note: We don't actually use flexBasis (or flexOrder), but it's one of the more
  9583. // common flex features that we can rely on when checking for flex support.
  9584. return !('flexBasis' in elem.style || 'webkitFlexBasis' in elem.style || 'mozFlexBasis' in elem.style || 'msFlexBasis' in elem.style ||
  9585. // IE10-specific (2012 flex spec)
  9586. 'msFlexOrder' in elem.style);
  9587. };
  9588. return Player;
  9589. }(_component2['default']);
  9590. /**
  9591. * Global player list
  9592. *
  9593. * @type {Object}
  9594. */
  9595. Player.players = {};
  9596. var navigator = _window2['default'].navigator;
  9597. /*
  9598. * Player instance options, surfaced using options
  9599. * options = Player.prototype.options_
  9600. * Make changes in options, not here.
  9601. *
  9602. * @type {Object}
  9603. * @private
  9604. */
  9605. Player.prototype.options_ = {
  9606. // Default order of fallback technology
  9607. techOrder: ['html5', 'flash'],
  9608. // techOrder: ['flash','html5'],
  9609. html5: {},
  9610. flash: {},
  9611. // defaultVolume: 0.85,
  9612. defaultVolume: 0.00,
  9613. // default inactivity timeout
  9614. inactivityTimeout: 2000,
  9615. // default playback rates
  9616. playbackRates: [],
  9617. // Add playback rate selection by adding rates
  9618. // 'playbackRates': [0.5, 1, 1.5, 2],
  9619. // Included control sets
  9620. children: ['mediaLoader', 'posterImage', 'textTrackDisplay', 'loadingSpinner', 'bigPlayButton', 'controlBar', 'errorDisplay', 'textTrackSettings'],
  9621. language: navigator && (navigator.languages && navigator.languages[0] || navigator.userLanguage || navigator.language) || 'en',
  9622. // locales and their language translations
  9623. languages: {},
  9624. // Default message to show when a video cannot be played.
  9625. notSupportedMessage: 'No compatible source was found for this media.'
  9626. };
  9627. [
  9628. /**
  9629. * Returns whether or not the player is in the "ended" state.
  9630. *
  9631. * @return {Boolean} True if the player is in the ended state, false if not.
  9632. * @method Player#ended
  9633. */
  9634. 'ended',
  9635. /**
  9636. * Returns whether or not the player is in the "seeking" state.
  9637. *
  9638. * @return {Boolean} True if the player is in the seeking state, false if not.
  9639. * @method Player#seeking
  9640. */
  9641. 'seeking',
  9642. /**
  9643. * Returns the TimeRanges of the media that are currently available
  9644. * for seeking to.
  9645. *
  9646. * @return {TimeRanges} the seekable intervals of the media timeline
  9647. * @method Player#seekable
  9648. */
  9649. 'seekable',
  9650. /**
  9651. * Returns the current state of network activity for the element, from
  9652. * the codes in the list below.
  9653. * - NETWORK_EMPTY (numeric value 0)
  9654. * The element has not yet been initialised. All attributes are in
  9655. * their initial states.
  9656. * - NETWORK_IDLE (numeric value 1)
  9657. * The element's resource selection algorithm is active and has
  9658. * selected a resource, but it is not actually using the network at
  9659. * this time.
  9660. * - NETWORK_LOADING (numeric value 2)
  9661. * The user agent is actively trying to download data.
  9662. * - NETWORK_NO_SOURCE (numeric value 3)
  9663. * The element's resource selection algorithm is active, but it has
  9664. * not yet found a resource to use.
  9665. *
  9666. * @see https://html.spec.whatwg.org/multipage/embedded-content.html#network-states
  9667. * @return {number} the current network activity state
  9668. * @method Player#networkState
  9669. */
  9670. 'networkState',
  9671. /**
  9672. * Returns a value that expresses the current state of the element
  9673. * with respect to rendering the current playback position, from the
  9674. * codes in the list below.
  9675. * - HAVE_NOTHING (numeric value 0)
  9676. * No information regarding the media resource is available.
  9677. * - HAVE_METADATA (numeric value 1)
  9678. * Enough of the resource has been obtained that the duration of the
  9679. * resource is available.
  9680. * - HAVE_CURRENT_DATA (numeric value 2)
  9681. * Data for the immediate current playback position is available.
  9682. * - HAVE_FUTURE_DATA (numeric value 3)
  9683. * Data for the immediate current playback position is available, as
  9684. * well as enough data for the user agent to advance the current
  9685. * playback position in the direction of playback.
  9686. * - HAVE_ENOUGH_DATA (numeric value 4)
  9687. * The user agent estimates that enough data is available for
  9688. * playback to proceed uninterrupted.
  9689. *
  9690. * @see https://html.spec.whatwg.org/multipage/embedded-content.html#dom-media-readystate
  9691. * @return {number} the current playback rendering state
  9692. * @method Player#readyState
  9693. */
  9694. 'readyState'].forEach(function (fn) {
  9695. Player.prototype[fn] = function () {
  9696. return this.techGet_(fn);
  9697. };
  9698. });
  9699. TECH_EVENTS_RETRIGGER.forEach(function (event) {
  9700. Player.prototype['handleTech' + (0, _toTitleCase2['default'])(event) + '_'] = function () {
  9701. return this.trigger(event);
  9702. };
  9703. });
  9704. /**
  9705. * Fired when the player has initial duration and dimension information
  9706. *
  9707. * @event Player#loadedmetadata
  9708. * @type {EventTarget~Event}
  9709. */
  9710. /**
  9711. * Fired when the player has downloaded data at the current playback position
  9712. *
  9713. * @event Player#loadeddata
  9714. * @type {EventTarget~Event}
  9715. */
  9716. /**
  9717. * Fired when the current playback position has changed *
  9718. * During playback this is fired every 15-250 milliseconds, depending on the
  9719. * playback technology in use.
  9720. *
  9721. * @event Player#timeupdate
  9722. * @type {EventTarget~Event}
  9723. */
  9724. /**
  9725. * Fired when the volume changes
  9726. *
  9727. * @event Player#volumechange
  9728. * @type {EventTarget~Event}
  9729. */
  9730. _component2['default'].registerComponent('Player', Player);
  9731. exports['default'] = Player;
  9732. },{"1":1,"4":4,"41":41,"44":44,"45":45,"46":46,"5":5,"50":50,"55":55,"59":59,"60":60,"61":61,"62":62,"63":63,"68":68,"69":69,"71":71,"76":76,"78":78,"79":79,"8":8,"81":81,"82":82,"83":83,"85":85,"86":86,"87":87,"88":88,"89":89,"90":90,"91":91,"94":94,"95":95,"97":97}],52:[function(_dereq_,module,exports){
  9733. 'use strict';
  9734. exports.__esModule = true;
  9735. var _player = _dereq_(51);
  9736. var _player2 = _interopRequireDefault(_player);
  9737. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  9738. /**
  9739. * The method for registering a video.js plugin. {@link videojs:videojs.registerPlugin].
  9740. *
  9741. * @param {string} name
  9742. * The name of the plugin that is being registered
  9743. *
  9744. * @param {plugins:PluginFn} init
  9745. * The function that gets run when a `Player` initializes.
  9746. */
  9747. var plugin = function plugin(name, init) {
  9748. _player2['default'].prototype[name] = init;
  9749. }; /**
  9750. * @file plugins.js
  9751. * @module plugins
  9752. */
  9753. exports['default'] = plugin;
  9754. },{"51":51}],53:[function(_dereq_,module,exports){
  9755. 'use strict';
  9756. exports.__esModule = true;
  9757. var _clickableComponent = _dereq_(3);
  9758. var _clickableComponent2 = _interopRequireDefault(_clickableComponent);
  9759. var _component = _dereq_(5);
  9760. var _component2 = _interopRequireDefault(_component);
  9761. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  9762. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  9763. 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; }
  9764. 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; } /**
  9765. * @file popup-button.js
  9766. */
  9767. /**
  9768. * A button class for use with {@link Popup} controls
  9769. *
  9770. * @extends ClickableComponent
  9771. */
  9772. var PopupButton = function (_ClickableComponent) {
  9773. _inherits(PopupButton, _ClickableComponent);
  9774. /**
  9775. * Create an instance of this class.
  9776. *
  9777. * @param {Player} player
  9778. * The `Player` that this class should be attached to.
  9779. *
  9780. * @param {Object} [options]
  9781. * The key/value store of player options.
  9782. */
  9783. function PopupButton(player) {
  9784. var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  9785. _classCallCheck(this, PopupButton);
  9786. var _this = _possibleConstructorReturn(this, _ClickableComponent.call(this, player, options));
  9787. _this.update();
  9788. return _this;
  9789. }
  9790. /**
  9791. * Update the `Popup` that this button is attached to.
  9792. */
  9793. PopupButton.prototype.update = function update() {
  9794. var popup = this.createPopup();
  9795. if (this.popup) {
  9796. this.removeChild(this.popup);
  9797. }
  9798. this.popup = popup;
  9799. this.addChild(popup);
  9800. if (this.items && this.items.length === 0) {
  9801. this.hide();
  9802. } else if (this.items && this.items.length > 1) {
  9803. this.show();
  9804. }
  9805. };
  9806. /**
  9807. * Create a `Popup`. - Override with specific functionality for component
  9808. *
  9809. * @abstract
  9810. */
  9811. PopupButton.prototype.createPopup = function createPopup() {};
  9812. /**
  9813. * Create the `PopupButton`s DOM element.
  9814. *
  9815. * @return {Element}
  9816. * The element that gets created.
  9817. */
  9818. PopupButton.prototype.createEl = function createEl() {
  9819. return _ClickableComponent.prototype.createEl.call(this, 'div', {
  9820. className: this.buildCSSClass()
  9821. });
  9822. };
  9823. /**
  9824. * Builds the default DOM `className`.
  9825. *
  9826. * @return {string}
  9827. * The DOM `className` for this object.
  9828. */
  9829. PopupButton.prototype.buildCSSClass = function buildCSSClass() {
  9830. var menuButtonClass = 'vjs-menu-button';
  9831. // If the inline option is passed, we want to use different styles altogether.
  9832. if (this.options_.inline === true) {
  9833. menuButtonClass += '-inline';
  9834. } else {
  9835. menuButtonClass += '-popup';
  9836. }
  9837. return 'vjs-menu-button ' + menuButtonClass + ' ' + _ClickableComponent.prototype.buildCSSClass.call(this);
  9838. };
  9839. return PopupButton;
  9840. }(_clickableComponent2['default']);
  9841. _component2['default'].registerComponent('PopupButton', PopupButton);
  9842. exports['default'] = PopupButton;
  9843. },{"3":3,"5":5}],54:[function(_dereq_,module,exports){
  9844. 'use strict';
  9845. exports.__esModule = true;
  9846. var _component = _dereq_(5);
  9847. var _component2 = _interopRequireDefault(_component);
  9848. var _dom = _dereq_(81);
  9849. var Dom = _interopRequireWildcard(_dom);
  9850. var _fn = _dereq_(83);
  9851. var Fn = _interopRequireWildcard(_fn);
  9852. var _events = _dereq_(82);
  9853. var Events = _interopRequireWildcard(_events);
  9854. 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; } }
  9855. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  9856. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  9857. 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; }
  9858. 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; } /**
  9859. * @file popup.js
  9860. */
  9861. /**
  9862. * The Popup component is used to build pop up controls.
  9863. *
  9864. * @extends Component
  9865. */
  9866. var Popup = function (_Component) {
  9867. _inherits(Popup, _Component);
  9868. function Popup() {
  9869. _classCallCheck(this, Popup);
  9870. return _possibleConstructorReturn(this, _Component.apply(this, arguments));
  9871. }
  9872. /**
  9873. * Add a popup item to the popup
  9874. *
  9875. * @param {Object|string} component
  9876. * Component or component type to add
  9877. *
  9878. */
  9879. Popup.prototype.addItem = function addItem(component) {
  9880. this.addChild(component);
  9881. component.on('click', Fn.bind(this, function () {
  9882. this.unlockShowing();
  9883. }));
  9884. };
  9885. /**
  9886. * Create the `PopupButton`s DOM element.
  9887. *
  9888. * @return {Element}
  9889. * The element that gets created.
  9890. */
  9891. Popup.prototype.createEl = function createEl() {
  9892. var contentElType = this.options_.contentElType || 'ul';
  9893. this.contentEl_ = Dom.createEl(contentElType, {
  9894. className: 'vjs-menu-content'
  9895. });
  9896. var el = _Component.prototype.createEl.call(this, 'div', {
  9897. append: this.contentEl_,
  9898. className: 'vjs-menu'
  9899. });
  9900. el.appendChild(this.contentEl_);
  9901. // Prevent clicks from bubbling up. Needed for Popup Buttons,
  9902. // where a click on the parent is significant
  9903. Events.on(el, 'click', function (event) {
  9904. event.preventDefault();
  9905. event.stopImmediatePropagation();
  9906. });
  9907. return el;
  9908. };
  9909. return Popup;
  9910. }(_component2['default']);
  9911. _component2['default'].registerComponent('Popup', Popup);
  9912. exports['default'] = Popup;
  9913. },{"5":5,"81":81,"82":82,"83":83}],55:[function(_dereq_,module,exports){
  9914. 'use strict';
  9915. exports.__esModule = true;
  9916. var _clickableComponent = _dereq_(3);
  9917. var _clickableComponent2 = _interopRequireDefault(_clickableComponent);
  9918. var _component = _dereq_(5);
  9919. var _component2 = _interopRequireDefault(_component);
  9920. var _fn = _dereq_(83);
  9921. var Fn = _interopRequireWildcard(_fn);
  9922. var _dom = _dereq_(81);
  9923. var Dom = _interopRequireWildcard(_dom);
  9924. var _browser = _dereq_(78);
  9925. var browser = _interopRequireWildcard(_browser);
  9926. 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; } }
  9927. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  9928. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  9929. 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; }
  9930. 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; } /**
  9931. * @file poster-image.js
  9932. */
  9933. /**
  9934. * A `ClickableComponent` that handles showing the poster image for the player.
  9935. *
  9936. * @extends ClickableComponent
  9937. */
  9938. var PosterImage = function (_ClickableComponent) {
  9939. _inherits(PosterImage, _ClickableComponent);
  9940. /**
  9941. * Create an instance of this class.
  9942. *
  9943. * @param {Player} player
  9944. * The `Player` that this class should attach to.
  9945. *
  9946. * @param {Object} [options]
  9947. * The key/value store of player options.
  9948. */
  9949. function PosterImage(player, options) {
  9950. _classCallCheck(this, PosterImage);
  9951. var _this = _possibleConstructorReturn(this, _ClickableComponent.call(this, player, options));
  9952. _this.update();
  9953. player.on('posterchange', Fn.bind(_this, _this.update));
  9954. return _this;
  9955. }
  9956. /**
  9957. * Clean up and dispose of the `PosterImage`.
  9958. */
  9959. PosterImage.prototype.dispose = function dispose() {
  9960. this.player().off('posterchange', this.update);
  9961. _ClickableComponent.prototype.dispose.call(this);
  9962. };
  9963. /**
  9964. * Create the `PosterImage`s DOM element.
  9965. *
  9966. * @return {Element}
  9967. * The element that gets created.
  9968. */
  9969. PosterImage.prototype.createEl = function createEl() {
  9970. var el = Dom.createEl('div', {
  9971. className: 'vjs-poster',
  9972. // Don't want poster to be tabbable.
  9973. tabIndex: -1
  9974. });
  9975. // To ensure the poster image resizes while maintaining its original aspect
  9976. // ratio, use a div with `background-size` when available. For browsers that
  9977. // do not support `background-size` (e.g. IE8), fall back on using a regular
  9978. // img element.
  9979. if (!browser.BACKGROUND_SIZE_SUPPORTED) {
  9980. this.fallbackImg_ = Dom.createEl('img');
  9981. el.appendChild(this.fallbackImg_);
  9982. }
  9983. return el;
  9984. };
  9985. /**
  9986. * An {@link EventTarget~EventListener} for {@link Player#posterchange} events.
  9987. *
  9988. * @listens Player#posterchange
  9989. *
  9990. * @param {EventTarget~Event} [event]
  9991. * The `Player#posterchange` event that triggered this function.
  9992. */
  9993. PosterImage.prototype.update = function update(event) {
  9994. var url = this.player().poster();
  9995. this.setSrc(url);
  9996. // If there's no poster source we should display:none on this component
  9997. // so it's not still clickable or right-clickable
  9998. if (url) {
  9999. this.show();
  10000. } else {
  10001. this.hide();
  10002. }
  10003. };
  10004. /**
  10005. * Set the source of the `PosterImage` depending on the display method.
  10006. *
  10007. * @param {string} url
  10008. * The URL to the source for the `PosterImage`.
  10009. */
  10010. PosterImage.prototype.setSrc = function setSrc(url) {
  10011. if (this.fallbackImg_) {
  10012. this.fallbackImg_.src = url;
  10013. } else {
  10014. var backgroundImage = '';
  10015. // Any falsey values should stay as an empty string, otherwise
  10016. // this will throw an extra error
  10017. if (url) {
  10018. backgroundImage = 'url("' + url + '")';
  10019. }
  10020. this.el_.style.backgroundImage = backgroundImage;
  10021. }
  10022. };
  10023. /**
  10024. * An {@link EventTarget~EventListener} for clicks on the `PosterImage`. See
  10025. * {@link ClickableComponent#handleClick} for instances where this will be triggered.
  10026. *
  10027. * @listens tap
  10028. * @listens click
  10029. * @listens keydown
  10030. *
  10031. * @param {EventTarget~Event} event
  10032. + The `click`, `tap` or `keydown` event that caused this function to be called.
  10033. */
  10034. PosterImage.prototype.handleClick = function handleClick(event) {
  10035. // We don't want a click to trigger playback when controls are disabled
  10036. if (!this.player_.controls()) {
  10037. return;
  10038. }
  10039. if (this.player_.paused()) {
  10040. this.player_.play();
  10041. } else {
  10042. this.player_.pause();
  10043. }
  10044. };
  10045. return PosterImage;
  10046. }(_clickableComponent2['default']);
  10047. _component2['default'].registerComponent('PosterImage', PosterImage);
  10048. exports['default'] = PosterImage;
  10049. },{"3":3,"5":5,"78":78,"81":81,"83":83}],56:[function(_dereq_,module,exports){
  10050. 'use strict';
  10051. exports.__esModule = true;
  10052. exports.hasLoaded = exports.autoSetupTimeout = exports.autoSetup = undefined;
  10053. var _dom = _dereq_(81);
  10054. var Dom = _interopRequireWildcard(_dom);
  10055. var _events = _dereq_(82);
  10056. var Events = _interopRequireWildcard(_events);
  10057. var _document = _dereq_(94);
  10058. var _document2 = _interopRequireDefault(_document);
  10059. var _window = _dereq_(95);
  10060. var _window2 = _interopRequireDefault(_window);
  10061. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  10062. 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; } }
  10063. /**
  10064. * @file setup.js - Functions for setting up a player without
  10065. * user interaction based on the data-setup `attribute` of the video tag.
  10066. *
  10067. * @module setup
  10068. */
  10069. var _windowLoaded = false;
  10070. var videojs = void 0;
  10071. /**
  10072. * Set up any tags that have a data-setup `attribute` when the player is started.
  10073. */
  10074. var autoSetup = function autoSetup() {
  10075. // Protect against breakage in non-browser environments.
  10076. if (!Dom.isReal()) {
  10077. return;
  10078. }
  10079. // One day, when we stop supporting IE8, go back to this, but in the meantime...*hack hack hack*
  10080. // var vids = Array.prototype.slice.call(document.getElementsByTagName('video'));
  10081. // var audios = Array.prototype.slice.call(document.getElementsByTagName('audio'));
  10082. // var mediaEls = vids.concat(audios);
  10083. // Because IE8 doesn't support calling slice on a node list, we need to loop
  10084. // through each list of elements to build up a new, combined list of elements.
  10085. var vids = _document2['default'].getElementsByTagName('video');
  10086. var audios = _document2['default'].getElementsByTagName('audio');
  10087. var mediaEls = [];
  10088. if (vids && vids.length > 0) {
  10089. for (var i = 0, e = vids.length; i < e; i++) {
  10090. mediaEls.push(vids[i]);
  10091. }
  10092. }
  10093. if (audios && audios.length > 0) {
  10094. for (var _i = 0, _e = audios.length; _i < _e; _i++) {
  10095. mediaEls.push(audios[_i]);
  10096. }
  10097. }
  10098. // Check if any media elements exist
  10099. if (mediaEls && mediaEls.length > 0) {
  10100. for (var _i2 = 0, _e2 = mediaEls.length; _i2 < _e2; _i2++) {
  10101. var mediaEl = mediaEls[_i2];
  10102. // Check if element exists, has getAttribute func.
  10103. // IE seems to consider typeof el.getAttribute == 'object' instead of
  10104. // 'function' like expected, at least when loading the player immediately.
  10105. if (mediaEl && mediaEl.getAttribute) {
  10106. // Make sure this player hasn't already been set up.
  10107. if (mediaEl.player === undefined) {
  10108. var options = mediaEl.getAttribute('data-setup');
  10109. // Check if data-setup attr exists.
  10110. // We only auto-setup if they've added the data-setup attr.
  10111. if (options !== null) {
  10112. // Create new video.js instance.
  10113. videojs(mediaEl);
  10114. }
  10115. }
  10116. // If getAttribute isn't defined, we need to wait for the DOM.
  10117. } else {
  10118. autoSetupTimeout(1);
  10119. break;
  10120. }
  10121. }
  10122. // No videos were found, so keep looping unless page is finished loading.
  10123. } else if (!_windowLoaded) {
  10124. autoSetupTimeout(1);
  10125. }
  10126. };
  10127. /**
  10128. * Wait until the page is loaded before running autoSetup. This will be called in
  10129. * autoSetup if `hasLoaded` returns false.
  10130. *
  10131. * @param {number} wait
  10132. * How long to wait in ms
  10133. *
  10134. * @param {videojs} [vjs]
  10135. * The videojs library function
  10136. */
  10137. function autoSetupTimeout(wait, vjs) {
  10138. if (vjs) {
  10139. videojs = vjs;
  10140. }
  10141. _window2['default'].setTimeout(autoSetup, wait);
  10142. }
  10143. if (Dom.isReal() && _document2['default'].readyState === 'complete') {
  10144. _windowLoaded = true;
  10145. } else {
  10146. /**
  10147. * Listen for the load event on window, and set _windowLoaded to true.
  10148. *
  10149. * @listens load
  10150. */
  10151. Events.one(_window2['default'], 'load', function () {
  10152. _windowLoaded = true;
  10153. });
  10154. }
  10155. /**
  10156. * check if the document has been loaded
  10157. */
  10158. var hasLoaded = function hasLoaded() {
  10159. return _windowLoaded;
  10160. };
  10161. exports.autoSetup = autoSetup;
  10162. exports.autoSetupTimeout = autoSetupTimeout;
  10163. exports.hasLoaded = hasLoaded;
  10164. },{"81":81,"82":82,"94":94,"95":95}],57:[function(_dereq_,module,exports){
  10165. 'use strict';
  10166. exports.__esModule = true;
  10167. var _component = _dereq_(5);
  10168. var _component2 = _interopRequireDefault(_component);
  10169. var _dom = _dereq_(81);
  10170. var Dom = _interopRequireWildcard(_dom);
  10171. var _obj = _dereq_(88);
  10172. 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; } }
  10173. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  10174. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  10175. 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; }
  10176. 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; } /**
  10177. * @file slider.js
  10178. */
  10179. /**
  10180. * The base functionality for a slider. Can be vertical or horizontal.
  10181. * For instance the volume bar or the seek bar on a video is a slider.
  10182. *
  10183. * @extends Component
  10184. */
  10185. var Slider = function (_Component) {
  10186. _inherits(Slider, _Component);
  10187. /**
  10188. * Create an instance of this class
  10189. *
  10190. * @param {Player} player
  10191. * The `Player` that this class should be attached to.
  10192. *
  10193. * @param {Object} [options]
  10194. * The key/value store of player options.
  10195. */
  10196. function Slider(player, options) {
  10197. _classCallCheck(this, Slider);
  10198. // Set property names to bar to match with the child Slider class is looking for
  10199. var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
  10200. _this.bar = _this.getChild(_this.options_.barName);
  10201. // Set a horizontal or vertical class on the slider depending on the slider type
  10202. _this.vertical(!!_this.options_.vertical);
  10203. _this.on('mousedown', _this.handleMouseDown);
  10204. _this.on('touchstart', _this.handleMouseDown);
  10205. _this.on('focus', _this.handleFocus);
  10206. _this.on('blur', _this.handleBlur);
  10207. _this.on('click', _this.handleClick);
  10208. _this.on(player, 'controlsvisible', _this.update);
  10209. _this.on(player, _this.playerEvent, _this.update);
  10210. return _this;
  10211. }
  10212. /**
  10213. * Create the `Button`s DOM element.
  10214. *
  10215. * @param {string} type
  10216. * Type of element to create.
  10217. *
  10218. * @param {Object} [props={}]
  10219. * List of properties in Object form.
  10220. *
  10221. * @param {Object} [attributes={}]
  10222. * list of attributes in Object form.
  10223. *
  10224. * @return {Element}
  10225. * The element that gets created.
  10226. */
  10227. Slider.prototype.createEl = function createEl(type) {
  10228. var props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  10229. var attributes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
  10230. // Add the slider element class to all sub classes
  10231. props.className = props.className + ' vjs-slider';
  10232. props = (0, _obj.assign)({
  10233. tabIndex: 0
  10234. }, props);
  10235. attributes = (0, _obj.assign)({
  10236. 'role': 'slider',
  10237. 'aria-valuenow': 0,
  10238. 'aria-valuemin': 0,
  10239. 'aria-valuemax': 100,
  10240. 'tabIndex': 0
  10241. }, attributes);
  10242. return _Component.prototype.createEl.call(this, type, props, attributes);
  10243. };
  10244. /**
  10245. * Handle `mousedown` or `touchstart` events on the `Slider`.
  10246. *
  10247. * @param {EventTarget~Event} event
  10248. * `mousedown` or `touchstart` event that triggered this function
  10249. *
  10250. * @listens mousedown
  10251. * @listens touchstart
  10252. * @fires Slider#slideractive
  10253. */
  10254. Slider.prototype.handleMouseDown = function handleMouseDown(event) {
  10255. var doc = this.bar.el_.ownerDocument;
  10256. event.preventDefault();
  10257. Dom.blockTextSelection();
  10258. this.addClass('vjs-sliding');
  10259. /**
  10260. * Triggered when the slider is in an active state
  10261. *
  10262. * @event Slider#slideractive
  10263. * @type {EventTarget~Event}
  10264. */
  10265. this.trigger('slideractive');
  10266. this.on(doc, 'mousemove', this.handleMouseMove);
  10267. this.on(doc, 'mouseup', this.handleMouseUp);
  10268. this.on(doc, 'touchmove', this.handleMouseMove);
  10269. this.on(doc, 'touchend', this.handleMouseUp);
  10270. this.handleMouseMove(event);
  10271. };
  10272. /**
  10273. * Handle the `mousemove`, `touchmove`, and `mousedown` events on this `Slider`.
  10274. * The `mousemove` and `touchmove` events will only only trigger this function during
  10275. * `mousedown` and `touchstart`. This is due to {@link Slider#handleMouseDown} and
  10276. * {@link Slider#handleMouseUp}.
  10277. *
  10278. * @param {EventTarget~Event} event
  10279. * `mousedown`, `mousemove`, `touchstart`, or `touchmove` event that triggered
  10280. * this function
  10281. *
  10282. * @listens mousemove
  10283. * @listens touchmove
  10284. */
  10285. Slider.prototype.handleMouseMove = function handleMouseMove(event) {};
  10286. /**
  10287. * Handle `mouseup` or `touchend` events on the `Slider`.
  10288. *
  10289. * @param {EventTarget~Event} event
  10290. * `mouseup` or `touchend` event that triggered this function.
  10291. *
  10292. * @listens touchend
  10293. * @listens mouseup
  10294. * @fires Slider#sliderinactive
  10295. */
  10296. Slider.prototype.handleMouseUp = function handleMouseUp() {
  10297. var doc = this.bar.el_.ownerDocument;
  10298. Dom.unblockTextSelection();
  10299. this.removeClass('vjs-sliding');
  10300. /**
  10301. * Triggered when the slider is no longer in an active state.
  10302. *
  10303. * @event Slider#sliderinactive
  10304. * @type {EventTarget~Event}
  10305. */
  10306. this.trigger('sliderinactive');
  10307. this.off(doc, 'mousemove', this.handleMouseMove);
  10308. this.off(doc, 'mouseup', this.handleMouseUp);
  10309. this.off(doc, 'touchmove', this.handleMouseMove);
  10310. this.off(doc, 'touchend', this.handleMouseUp);
  10311. this.update();
  10312. };
  10313. /**
  10314. * Update the progress bar of the `Slider`.
  10315. */
  10316. Slider.prototype.update = function update() {
  10317. // In VolumeBar init we have a setTimeout for update that pops and update to the end of the
  10318. // execution stack. The player is destroyed before then update will cause an error
  10319. if (!this.el_) {
  10320. return;
  10321. }
  10322. // If scrubbing, we could use a cached value to make the handle keep up with the user's mouse.
  10323. // On HTML5 browsers scrubbing is really smooth, but some flash players are slow, so we might want to utilize this later.
  10324. // var progress = (this.player_.scrubbing()) ? this.player_.getCache().currentTime / this.player_.duration() : this.player_.currentTime() / this.player_.duration();
  10325. var progress = this.getPercent();
  10326. var bar = this.bar;
  10327. // If there's no bar...
  10328. if (!bar) {
  10329. return;
  10330. }
  10331. // Protect against no duration and other division issues
  10332. if (typeof progress !== 'number' || progress !== progress || progress < 0 || progress === Infinity) {
  10333. progress = 0;
  10334. }
  10335. // Convert to a percentage for setting
  10336. var percentage = (progress * 100).toFixed(2) + '%';
  10337. // Set the new bar width or height
  10338. if (this.vertical()) {
  10339. bar.el().style.height = percentage;
  10340. } else {
  10341. bar.el().style.width = percentage;
  10342. }
  10343. };
  10344. /**
  10345. * Calculate distance for slider
  10346. *
  10347. * @param {EventTarget~Event} event
  10348. * The event that caused this function to run.
  10349. *
  10350. * @return {number}
  10351. * The current position of the Slider.
  10352. * - postition.x for vertical `Slider`s
  10353. * - postition.y for horizontal `Slider`s
  10354. */
  10355. Slider.prototype.calculateDistance = function calculateDistance(event) {
  10356. var position = Dom.getPointerPosition(this.el_, event);
  10357. if (this.vertical()) {
  10358. return position.y;
  10359. }
  10360. return position.x;
  10361. };
  10362. /**
  10363. * Handle a `focus` event on this `Slider`.
  10364. *
  10365. * @param {EventTarget~Event} event
  10366. * The `focus` event that caused this function to run.
  10367. *
  10368. * @listens focus
  10369. */
  10370. Slider.prototype.handleFocus = function handleFocus() {
  10371. this.on(this.bar.el_.ownerDocument, 'keydown', this.handleKeyPress);
  10372. };
  10373. /**
  10374. * Handle a `keydown` event on the `Slider`. Watches for left, rigth, up, and down
  10375. * arrow keys. This function will only be called when the slider has focus. See
  10376. * {@link Slider#handleFocus} and {@link Slider#handleBlur}.
  10377. *
  10378. * @param {EventTarget~Event} event
  10379. * the `keydown` event that caused this function to run.
  10380. *
  10381. * @listens keydown
  10382. */
  10383. Slider.prototype.handleKeyPress = function handleKeyPress(event) {
  10384. // Left and Down Arrows
  10385. if (event.which === 37 || event.which === 40) {
  10386. event.preventDefault();
  10387. this.stepBack();
  10388. // Up and Right Arrows
  10389. } else if (event.which === 38 || event.which === 39) {
  10390. event.preventDefault();
  10391. this.stepForward();
  10392. }
  10393. };
  10394. /**
  10395. * Handle a `blur` event on this `Slider`.
  10396. *
  10397. * @param {EventTarget~Event} event
  10398. * The `blur` event that caused this function to run.
  10399. *
  10400. * @listens blur
  10401. */
  10402. Slider.prototype.handleBlur = function handleBlur() {
  10403. this.off(this.bar.el_.ownerDocument, 'keydown', this.handleKeyPress);
  10404. };
  10405. /**
  10406. * Listener for click events on slider, used to prevent clicks
  10407. * from bubbling up to parent elements like button menus.
  10408. *
  10409. * @param {Object} event
  10410. * Event that caused this object to run
  10411. */
  10412. Slider.prototype.handleClick = function handleClick(event) {
  10413. event.stopImmediatePropagation();
  10414. event.preventDefault();
  10415. };
  10416. /**
  10417. * Get/set if slider is horizontal for vertical
  10418. *
  10419. * @param {boolean} [bool]
  10420. * - true if slider is vertical,
  10421. * - false is horizontal
  10422. *
  10423. * @return {boolean|Slider}
  10424. * - true if slider is vertical, and getting
  10425. * - false is horizontal, and getting
  10426. * - a reference to this object when setting
  10427. */
  10428. Slider.prototype.vertical = function vertical(bool) {
  10429. if (bool === undefined) {
  10430. return this.vertical_ || false;
  10431. }
  10432. this.vertical_ = !!bool;
  10433. if (this.vertical_) {
  10434. this.addClass('vjs-slider-vertical');
  10435. } else {
  10436. this.addClass('vjs-slider-horizontal');
  10437. }
  10438. return this;
  10439. };
  10440. return Slider;
  10441. }(_component2['default']);
  10442. _component2['default'].registerComponent('Slider', Slider);
  10443. exports['default'] = Slider;
  10444. },{"5":5,"81":81,"88":88}],58:[function(_dereq_,module,exports){
  10445. 'use strict';
  10446. exports.__esModule = true;
  10447. /**
  10448. * @file flash-rtmp.js
  10449. * @module flash-rtmp
  10450. */
  10451. /**
  10452. * Add RTMP properties to the {@link Flash} Tech.
  10453. *
  10454. * @param {Flash} Flash
  10455. * The flash tech class.
  10456. *
  10457. * @mixin FlashRtmpDecorator
  10458. */
  10459. function FlashRtmpDecorator(Flash) {
  10460. Flash.streamingFormats = {
  10461. 'rtmp/mp4': 'MP4',
  10462. 'rtmp/flv': 'FLV'
  10463. };
  10464. /**
  10465. * Join connection and stream with an ampersand.
  10466. *
  10467. * @param {string} connection
  10468. * The connection string.
  10469. *
  10470. * @param {string} stream
  10471. * The stream string.
  10472. */
  10473. Flash.streamFromParts = function (connection, stream) {
  10474. return connection + '&' + stream;
  10475. };
  10476. /**
  10477. * The flash parts object that contains connection and stream info.
  10478. *
  10479. * @typedef {Object} Flash~PartsObject
  10480. *
  10481. * @property {string} connection
  10482. * The connection string of a source, defaults to an empty string.
  10483. *
  10484. * @property {string} stream
  10485. * The stream string of the source, defaults to an empty string.
  10486. */
  10487. /**
  10488. * Convert a source url into a stream and connection parts.
  10489. *
  10490. * @param {string} src
  10491. * the source url
  10492. *
  10493. * @return {Flash~PartsObject}
  10494. * The parts object that contains a connection and a stream
  10495. */
  10496. Flash.streamToParts = function (src) {
  10497. var parts = {
  10498. connection: '',
  10499. stream: ''
  10500. };
  10501. if (!src) {
  10502. return parts;
  10503. }
  10504. // Look for the normal URL separator we expect, '&'.
  10505. // If found, we split the URL into two pieces around the
  10506. // first '&'.
  10507. var connEnd = src.search(/&(?!\w+=)/);
  10508. var streamBegin = void 0;
  10509. if (connEnd !== -1) {
  10510. streamBegin = connEnd + 1;
  10511. } else {
  10512. // If there's not a '&', we use the last '/' as the delimiter.
  10513. connEnd = streamBegin = src.lastIndexOf('/') + 1;
  10514. if (connEnd === 0) {
  10515. // really, there's not a '/'?
  10516. connEnd = streamBegin = src.length;
  10517. }
  10518. }
  10519. parts.connection = src.substring(0, connEnd);
  10520. parts.stream = src.substring(streamBegin, src.length);
  10521. return parts;
  10522. };
  10523. /**
  10524. * Check if the source type is a streaming type.
  10525. *
  10526. * @param {string} srcType
  10527. * The mime type to check.
  10528. *
  10529. * @return {boolean}
  10530. * - True if the source type is a streaming type.
  10531. * - False if the source type is not a streaming type.
  10532. */
  10533. Flash.isStreamingType = function (srcType) {
  10534. return srcType in Flash.streamingFormats;
  10535. };
  10536. // RTMP has four variations, any string starting
  10537. // with one of these protocols should be valid
  10538. /**
  10539. * Regular expression used to check if the source is an rtmp source.
  10540. *
  10541. * @property {RegExp} Flash.RTMP_RE
  10542. */
  10543. Flash.RTMP_RE = /^rtmp[set]?:\/\//i;
  10544. /**
  10545. * Check if the source itself is a streaming type.
  10546. *
  10547. * @param {string} src
  10548. * The url to the source.
  10549. *
  10550. * @return {boolean}
  10551. * - True if the source url indicates that the source is streaming.
  10552. * - False if the shource url indicates that the source url is not streaming.
  10553. */
  10554. Flash.isStreamingSrc = function (src) {
  10555. return Flash.RTMP_RE.test(src);
  10556. };
  10557. /**
  10558. * A source handler for RTMP urls
  10559. * @type {Object}
  10560. */
  10561. Flash.rtmpSourceHandler = {};
  10562. /**
  10563. * Check if Flash can play the given mime type.
  10564. *
  10565. * @param {string} type
  10566. * The mime type to check
  10567. *
  10568. * @return {string}
  10569. * 'maybe', or '' (empty string)
  10570. */
  10571. Flash.rtmpSourceHandler.canPlayType = function (type) {
  10572. if (Flash.isStreamingType(type)) {
  10573. return 'maybe';
  10574. }
  10575. return '';
  10576. };
  10577. /**
  10578. * Check if Flash can handle the source natively
  10579. *
  10580. * @param {Object} source
  10581. * The source object
  10582. *
  10583. * @param {Object} [options]
  10584. * The options passed to the tech
  10585. *
  10586. * @return {string}
  10587. * 'maybe', or '' (empty string)
  10588. */
  10589. Flash.rtmpSourceHandler.canHandleSource = function (source, options) {
  10590. var can = Flash.rtmpSourceHandler.canPlayType(source.type);
  10591. if (can) {
  10592. return can;
  10593. }
  10594. if (Flash.isStreamingSrc(source.src)) {
  10595. return 'maybe';
  10596. }
  10597. return '';
  10598. };
  10599. /**
  10600. * Pass the source to the flash object.
  10601. *
  10602. * @param {Object} source
  10603. * The source object
  10604. *
  10605. * @param {Flash} tech
  10606. * The instance of the Flash tech
  10607. *
  10608. * @param {Object} [options]
  10609. * The options to pass to the source
  10610. */
  10611. Flash.rtmpSourceHandler.handleSource = function (source, tech, options) {
  10612. var srcParts = Flash.streamToParts(source.src);
  10613. tech.setRtmpConnection(srcParts.connection);
  10614. tech.setRtmpStream(srcParts.stream);
  10615. };
  10616. // Register the native source handler
  10617. Flash.registerSourceHandler(Flash.rtmpSourceHandler);
  10618. return Flash;
  10619. }
  10620. exports['default'] = FlashRtmpDecorator;
  10621. },{}],59:[function(_dereq_,module,exports){
  10622. 'use strict';
  10623. exports.__esModule = true;
  10624. var _tech = _dereq_(62);
  10625. var _tech2 = _interopRequireDefault(_tech);
  10626. var _dom = _dereq_(81);
  10627. var Dom = _interopRequireWildcard(_dom);
  10628. var _url = _dereq_(92);
  10629. var Url = _interopRequireWildcard(_url);
  10630. var _timeRanges = _dereq_(90);
  10631. var _flashRtmp = _dereq_(58);
  10632. var _flashRtmp2 = _interopRequireDefault(_flashRtmp);
  10633. var _component = _dereq_(5);
  10634. var _component2 = _interopRequireDefault(_component);
  10635. var _window = _dereq_(95);
  10636. var _window2 = _interopRequireDefault(_window);
  10637. var _obj = _dereq_(88);
  10638. 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; } }
  10639. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  10640. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  10641. 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; }
  10642. 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; } /**
  10643. * @file flash.js
  10644. * VideoJS-SWF - Custom Flash Player with HTML5-ish API
  10645. * https://github.com/zencoder/video-js-swf
  10646. * Not using setupTriggers. Using global onEvent func to distribute events
  10647. */
  10648. var navigator = _window2['default'].navigator;
  10649. /**
  10650. * Flash Media Controller - Wrapper for Flash Media API
  10651. *
  10652. * @mixes FlashRtmpDecorator
  10653. * @mixes Tech~SouceHandlerAdditions
  10654. * @extends Tech
  10655. */
  10656. var Flash = function (_Tech) {
  10657. _inherits(Flash, _Tech);
  10658. /**
  10659. * Create an instance of this Tech.
  10660. *
  10661. * @param {Object} [options]
  10662. * The key/value store of player options.
  10663. *
  10664. * @param {Component~ReadyCallback} ready
  10665. * Callback function to call when the `Flash` Tech is ready.
  10666. */
  10667. function Flash(options, ready) {
  10668. _classCallCheck(this, Flash);
  10669. // Set the source when ready
  10670. var _this = _possibleConstructorReturn(this, _Tech.call(this, options, ready));
  10671. if (options.source) {
  10672. _this.ready(function () {
  10673. this.setSource(options.source);
  10674. }, true);
  10675. }
  10676. // Having issues with Flash reloading on certain page actions (hide/resize/fullscreen) in certain browsers
  10677. // This allows resetting the playhead when we catch the reload
  10678. if (options.startTime) {
  10679. _this.ready(function () {
  10680. this.load();
  10681. this.play();
  10682. this.currentTime(options.startTime);
  10683. }, true);
  10684. }
  10685. // Add global window functions that the swf expects
  10686. // A 4.x workflow we weren't able to solve for in 5.0
  10687. // because of the need to hard code these functions
  10688. // into the swf for security reasons
  10689. _window2['default'].videojs = _window2['default'].videojs || {};
  10690. _window2['default'].videojs.Flash = _window2['default'].videojs.Flash || {};
  10691. _window2['default'].videojs.Flash.onReady = Flash.onReady;
  10692. _window2['default'].videojs.Flash.onEvent = Flash.onEvent;
  10693. _window2['default'].videojs.Flash.onError = Flash.onError;
  10694. _this.on('seeked', function () {
  10695. this.lastSeekTarget_ = undefined;
  10696. });
  10697. return _this;
  10698. }
  10699. /**
  10700. * Create the `Flash` Tech's DOM element.
  10701. *
  10702. * @return {Element}
  10703. * The element that gets created.
  10704. */
  10705. Flash.prototype.createEl = function createEl() {
  10706. var options = this.options_;
  10707. // If video.js is hosted locally you should also set the location
  10708. // for the hosted swf, which should be relative to the page (not video.js)
  10709. // Otherwise this adds a CDN url.
  10710. // The CDN also auto-adds a swf URL for that specific version.
  10711. if (!options.swf) {
  10712. var ver = '5.1.0';
  10713. options.swf = '//vjs.zencdn.net/swf/' + ver + '/video-js.swf';
  10714. }
  10715. // Generate ID for swf object
  10716. var objId = options.techId;
  10717. // Merge default flashvars with ones passed in to init
  10718. var flashVars = (0, _obj.assign)({
  10719. // SWF Callback Functions
  10720. readyFunction: 'videojs.Flash.onReady',
  10721. eventProxyFunction: 'videojs.Flash.onEvent',
  10722. errorEventProxyFunction: 'videojs.Flash.onError',
  10723. // Player Settings
  10724. autoplay: options.autoplay,
  10725. preload: options.preload,
  10726. loop: options.loop,
  10727. muted: options.muted
  10728. }, options.flashVars);
  10729. // Merge default parames with ones passed in
  10730. var params = (0, _obj.assign)({
  10731. // Opaque is needed to overlay controls, but can affect playback performance
  10732. wmode: 'opaque',
  10733. // Using bgcolor prevents a white flash when the object is loading
  10734. bgcolor: '#000000'
  10735. }, options.params);
  10736. // Merge default attributes with ones passed in
  10737. var attributes = (0, _obj.assign)({
  10738. // Both ID and Name needed or swf to identify itself
  10739. id: objId,
  10740. name: objId,
  10741. 'class': 'vjs-tech'
  10742. }, options.attributes);
  10743. this.el_ = Flash.embed(options.swf, flashVars, params, attributes);
  10744. this.el_.tech = this;
  10745. return this.el_;
  10746. };
  10747. /**
  10748. * Called by {@link Player#play} to play using the `Flash` `Tech`.
  10749. */
  10750. Flash.prototype.play = function play() {
  10751. if (this.ended()) {
  10752. this.setCurrentTime(0);
  10753. }
  10754. this.el_.vjs_play();
  10755. };
  10756. /**
  10757. * Called by {@link Player#pause} to pause using the `Flash` `Tech`.
  10758. */
  10759. Flash.prototype.pause = function pause() {
  10760. this.el_.vjs_pause();
  10761. };
  10762. /**
  10763. * A getter/setter for the `Flash` Tech's source object.
  10764. * > Note: Please use {@link Flash#setSource}
  10765. *
  10766. * @param {Tech~SourceObject} [src]
  10767. * The source object you want to set on the `Flash` techs.
  10768. *
  10769. * @return {Tech~SourceObject|undefined}
  10770. * - The current source object when a source is not passed in.
  10771. * - undefined when setting
  10772. *
  10773. * @deprecated Since version 5.
  10774. */
  10775. Flash.prototype.src = function src(_src) {
  10776. if (_src === undefined) {
  10777. return this.currentSrc();
  10778. }
  10779. // Setting src through `src` not `setSrc` will be deprecated
  10780. return this.setSrc(_src);
  10781. };
  10782. /**
  10783. * A getter/setter for the `Flash` Tech's source object.
  10784. *
  10785. * @param {Tech~SourceObject} [src]
  10786. * The source object you want to set on the `Flash` techs.
  10787. *
  10788. * @return {Tech~SourceObject|undefined}
  10789. * - The current source object when a source is not passed in.
  10790. * - undefined when setting
  10791. */
  10792. Flash.prototype.setSrc = function setSrc(src) {
  10793. var _this2 = this;
  10794. // Make sure source URL is absolute.
  10795. src = Url.getAbsoluteURL(src);
  10796. this.el_.vjs_src(src);
  10797. // Currently the SWF doesn't autoplay if you load a source later.
  10798. // e.g. Load player w/ no source, wait 2s, set src.
  10799. if (this.autoplay()) {
  10800. this.setTimeout(function () {
  10801. return _this2.play();
  10802. }, 0);
  10803. }
  10804. };
  10805. /**
  10806. * Indicates whether the media is currently seeking to a new position or not.
  10807. *
  10808. * @return {boolean}
  10809. * - True if seeking to a new position
  10810. * - False otherwise
  10811. */
  10812. Flash.prototype.seeking = function seeking() {
  10813. return this.lastSeekTarget_ !== undefined;
  10814. };
  10815. /**
  10816. * Returns the current time in seconds that the media is at in playback.
  10817. *
  10818. * @param {number} time
  10819. * Current playtime of the media in seconds.
  10820. */
  10821. Flash.prototype.setCurrentTime = function setCurrentTime(time) {
  10822. var seekable = this.seekable();
  10823. if (seekable.length) {
  10824. // clamp to the current seekable range
  10825. time = time > seekable.start(0) ? time : seekable.start(0);
  10826. time = time < seekable.end(seekable.length - 1) ? time : seekable.end(seekable.length - 1);
  10827. this.lastSeekTarget_ = time;
  10828. this.trigger('seeking');
  10829. this.el_.vjs_setProperty('currentTime', time);
  10830. _Tech.prototype.setCurrentTime.call(this);
  10831. }
  10832. };
  10833. /**
  10834. * Get the current playback time in seconds
  10835. *
  10836. * @return {number}
  10837. * The current time of playback in seconds.
  10838. */
  10839. Flash.prototype.currentTime = function currentTime() {
  10840. // when seeking make the reported time keep up with the requested time
  10841. // by reading the time we're seeking to
  10842. if (this.seeking()) {
  10843. return this.lastSeekTarget_ || 0;
  10844. }
  10845. return this.el_.vjs_getProperty('currentTime');
  10846. };
  10847. /**
  10848. * Get the current source
  10849. *
  10850. * @method currentSrc
  10851. * @return {Tech~SourceObject}
  10852. * The current source
  10853. */
  10854. Flash.prototype.currentSrc = function currentSrc() {
  10855. if (this.currentSource_) {
  10856. return this.currentSource_.src;
  10857. }
  10858. return this.el_.vjs_getProperty('currentSrc');
  10859. };
  10860. /**
  10861. * Get the total duration of the current media.
  10862. *
  10863. * @return {number}
  10864. 8 The total duration of the current media.
  10865. */
  10866. Flash.prototype.duration = function duration() {
  10867. if (this.readyState() === 0) {
  10868. return NaN;
  10869. }
  10870. var duration = this.el_.vjs_getProperty('duration');
  10871. return duration >= 0 ? duration : Infinity;
  10872. };
  10873. /**
  10874. * Load media into Tech.
  10875. */
  10876. Flash.prototype.load = function load() {
  10877. this.el_.vjs_load();
  10878. };
  10879. /**
  10880. * Get the poster image that was set on the tech.
  10881. */
  10882. Flash.prototype.poster = function poster() {
  10883. this.el_.vjs_getProperty('poster');
  10884. };
  10885. /**
  10886. * Poster images are not handled by the Flash tech so make this is a no-op.
  10887. */
  10888. Flash.prototype.setPoster = function setPoster() {};
  10889. /**
  10890. * Determine the time ranges that can be seeked to in the media.
  10891. *
  10892. * @return {TimeRange}
  10893. * Returns the time ranges that can be seeked to.
  10894. */
  10895. Flash.prototype.seekable = function seekable() {
  10896. var duration = this.duration();
  10897. if (duration === 0) {
  10898. return (0, _timeRanges.createTimeRange)();
  10899. }
  10900. return (0, _timeRanges.createTimeRange)(0, duration);
  10901. };
  10902. /**
  10903. * Get and create a `TimeRange` object for buffering.
  10904. *
  10905. * @return {TimeRange}
  10906. * The time range object that was created.
  10907. */
  10908. Flash.prototype.buffered = function buffered() {
  10909. var ranges = this.el_.vjs_getProperty('buffered');
  10910. if (ranges.length === 0) {
  10911. return (0, _timeRanges.createTimeRange)();
  10912. }
  10913. return (0, _timeRanges.createTimeRange)(ranges[0][0], ranges[0][1]);
  10914. };
  10915. /**
  10916. * Get fullscreen support -
  10917. *
  10918. * Flash does not allow fullscreen through javascript
  10919. * so this always returns false.
  10920. *
  10921. * @return {boolean}
  10922. * The Flash tech does not support fullscreen, so it will always return false.
  10923. */
  10924. Flash.prototype.supportsFullScreen = function supportsFullScreen() {
  10925. // Flash does not allow fullscreen through javascript
  10926. return false;
  10927. };
  10928. /**
  10929. * Flash does not allow fullscreen through javascript
  10930. * so this always returns false.
  10931. *
  10932. * @return {boolean}
  10933. * The Flash tech does not support fullscreen, so it will always return false.
  10934. */
  10935. Flash.prototype.enterFullScreen = function enterFullScreen() {
  10936. return false;
  10937. };
  10938. return Flash;
  10939. }(_tech2['default']);
  10940. // Create setters and getters for attributes
  10941. var _api = Flash.prototype;
  10942. var _readWrite = 'rtmpConnection,rtmpStream,preload,defaultPlaybackRate,playbackRate,autoplay,loop,mediaGroup,controller,controls,volume,muted,defaultMuted'.split(',');
  10943. var _readOnly = 'networkState,readyState,initialTime,startOffsetTime,paused,ended,videoWidth,videoHeight'.split(',');
  10944. function _createSetter(attr) {
  10945. var attrUpper = attr.charAt(0).toUpperCase() + attr.slice(1);
  10946. _api['set' + attrUpper] = function (val) {
  10947. return this.el_.vjs_setProperty(attr, val);
  10948. };
  10949. }
  10950. function _createGetter(attr) {
  10951. _api[attr] = function () {
  10952. return this.el_.vjs_getProperty(attr);
  10953. };
  10954. }
  10955. // Create getter and setters for all read/write attributes
  10956. for (var i = 0; i < _readWrite.length; i++) {
  10957. _createGetter(_readWrite[i]);
  10958. _createSetter(_readWrite[i]);
  10959. }
  10960. // Create getters for read-only attributes
  10961. for (var _i = 0; _i < _readOnly.length; _i++) {
  10962. _createGetter(_readOnly[_i]);
  10963. }
  10964. /** ------------------------------ Getters ------------------------------ **/
  10965. /**
  10966. * Get the value of `rtmpConnection` from the swf.
  10967. *
  10968. * @method Flash#rtmpConnection
  10969. * @return {string}
  10970. * The current value of `rtmpConnection` on the swf.
  10971. */
  10972. /**
  10973. * Get the value of `rtmpStream` from the swf.
  10974. *
  10975. * @method Flash#rtmpStream
  10976. * @return {string}
  10977. * The current value of `rtmpStream` on the swf.
  10978. */
  10979. /**
  10980. * Get the value of `preload` from the swf. `preload` indicates
  10981. * what should download before the media is interacted with. It can have the following
  10982. * values:
  10983. * - none: nothing should be downloaded
  10984. * - metadata: poster and the first few frames of the media may be downloaded to get
  10985. * media dimensions and other metadata
  10986. * - auto: allow the media and metadata for the media to be downloaded before
  10987. * interaction
  10988. *
  10989. * @method Flash#preload
  10990. * @return {string}
  10991. * The value of `preload` from the swf. Will be 'none', 'metadata',
  10992. * or 'auto'.
  10993. */
  10994. /**
  10995. * Get the value of `defaultPlaybackRate` from the swf.
  10996. *
  10997. * @method Flash#defaultPlaybackRate
  10998. * @return {number}
  10999. * The current value of `defaultPlaybackRate` on the swf.
  11000. */
  11001. /**
  11002. * Get the value of `playbackRate` from the swf. `playbackRate` indicates
  11003. * the rate at which the media is currently playing back. Examples:
  11004. * - if playbackRate is set to 2, media will play twice as fast.
  11005. * - if playbackRate is set to 0.5, media will play half as fast.
  11006. *
  11007. * @method Flash#playbackRate
  11008. * @return {number}
  11009. * The value of `playbackRate` from the swf. A number indicating
  11010. * the current playback speed of the media, where 1 is normal speed.
  11011. */
  11012. /**
  11013. * Get the value of `autoplay` from the swf. `autoplay` indicates
  11014. * that the media should start to play as soon as the page is ready.
  11015. *
  11016. * @method Flash#autoplay
  11017. * @return {boolean}
  11018. * - The value of `autoplay` from the swf.
  11019. * - True indicates that the media ashould start as soon as the page loads.
  11020. * - False indicates that the media should not start as soon as the page loads.
  11021. */
  11022. /**
  11023. * Get the value of `loop` from the swf. `loop` indicates
  11024. * that the media should return to the start of the media and continue playing once
  11025. * it reaches the end.
  11026. *
  11027. * @method Flash#loop
  11028. * @return {boolean}
  11029. * - The value of `loop` from the swf.
  11030. * - True indicates that playback should seek back to start once
  11031. * the end of a media is reached.
  11032. * - False indicates that playback should not loop back to the start when the
  11033. * end of the media is reached.
  11034. */
  11035. /**
  11036. * Get the value of `mediaGroup` from the swf.
  11037. *
  11038. * @method Flash#mediaGroup
  11039. * @return {string}
  11040. * The current value of `mediaGroup` on the swf.
  11041. */
  11042. /**
  11043. * Get the value of `controller` from the swf.
  11044. *
  11045. * @method Flash#controller
  11046. * @return {string}
  11047. * The current value of `controller` on the swf.
  11048. */
  11049. /**
  11050. * Get the value of `controls` from the swf. `controls` indicates
  11051. * whether the native flash controls should be shown or hidden.
  11052. *
  11053. * @method Flash#controls
  11054. * @return {boolean}
  11055. * - The value of `controls` from the swf.
  11056. * - True indicates that native controls should be showing.
  11057. * - False indicates that native controls should be hidden.
  11058. */
  11059. /**
  11060. * Get the value of the `volume` from the swf. `volume` indicates the current
  11061. * audio level as a percentage in decimal form. This means that 1 is 100%, 0.5 is 50%, and
  11062. * so on.
  11063. *
  11064. * @method Flash#volume
  11065. * @return {number}
  11066. * The volume percent as a decimal. Value will be between 0-1.
  11067. */
  11068. /**
  11069. * Get the value of the `muted` from the swf. `muted` indicates the current
  11070. * audio level should be silent.
  11071. *
  11072. * @method Flash#muted
  11073. * @return {boolean}
  11074. * - True if the audio should be set to silent
  11075. * - False otherwise
  11076. */
  11077. /**
  11078. * Get the value of `defaultMuted` from the swf. `defaultMuted` indicates
  11079. * whether the media should start muted or not. Only changes the default state of the
  11080. * media. `muted` and `defaultMuted` can have different values. `muted` indicates the
  11081. * current state.
  11082. *
  11083. * @method Flash#defaultMuted
  11084. * @return {boolean}
  11085. * - The value of `defaultMuted` from the swf.
  11086. * - True indicates that the media should start muted.
  11087. * - False indicates that the media should not start muted.
  11088. */
  11089. /**
  11090. * Get the value of `networkState` from the swf. `networkState` indicates
  11091. * the current network state. It returns an enumeration from the following list:
  11092. * - 0: NETWORK_EMPTY
  11093. * - 1: NEWORK_IDLE
  11094. * - 2: NETWORK_LOADING
  11095. * - 3: NETWORK_NO_SOURCE
  11096. *
  11097. * @method Flash#networkState
  11098. * @return {number}
  11099. * The value of `networkState` from the swf. This will be a number
  11100. * from the list in the description.
  11101. */
  11102. /**
  11103. * Get the value of `readyState` from the swf. `readyState` indicates
  11104. * the current state of the media element. It returns an enumeration from the
  11105. * following list:
  11106. * - 0: HAVE_NOTHING
  11107. * - 1: HAVE_METADATA
  11108. * - 2: HAVE_CURRENT_DATA
  11109. * - 3: HAVE_FUTURE_DATA
  11110. * - 4: HAVE_ENOUGH_DATA
  11111. *
  11112. * @method Flash#readyState
  11113. * @return {number}
  11114. * The value of `readyState` from the swf. This will be a number
  11115. * from the list in the description.
  11116. */
  11117. /**
  11118. * Get the value of `readyState` from the swf. `readyState` indicates
  11119. * the current state of the media element. It returns an enumeration from the
  11120. * following list:
  11121. * - 0: HAVE_NOTHING
  11122. * - 1: HAVE_METADATA
  11123. * - 2: HAVE_CURRENT_DATA
  11124. * - 3: HAVE_FUTURE_DATA
  11125. * - 4: HAVE_ENOUGH_DATA
  11126. *
  11127. * @method Flash#readyState
  11128. * @return {number}
  11129. * The value of `readyState` from the swf. This will be a number
  11130. * from the list in the description.
  11131. */
  11132. /**
  11133. * Get the value of `initialTime` from the swf.
  11134. *
  11135. * @method Flash#initialTime
  11136. * @return {number}
  11137. * The `initialTime` proprety on the swf.
  11138. */
  11139. /**
  11140. * Get the value of `startOffsetTime` from the swf.
  11141. *
  11142. * @method Flash#startOffsetTime
  11143. * @return {number}
  11144. * The `startOffsetTime` proprety on the swf.
  11145. */
  11146. /**
  11147. * Get the value of `paused` from the swf. `paused` indicates whether the swf
  11148. * is current paused or not.
  11149. *
  11150. * @method Flash#paused
  11151. * @return {boolean}
  11152. * The value of `paused` from the swf.
  11153. */
  11154. /**
  11155. * Get the value of `ended` from the swf. `ended` indicates whether
  11156. * the media has reached the end or not.
  11157. *
  11158. * @method Flash#ended
  11159. * @return {boolean}
  11160. * - True indicates that the media has ended.
  11161. * - False indicates that the media has not ended.
  11162. *
  11163. * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-ended}
  11164. */
  11165. /**
  11166. * Get the value of `videoWidth` from the swf. `videoWidth` indicates
  11167. * the current width of the media in css pixels.
  11168. *
  11169. * @method Flash#videoWidth
  11170. * @return {number}
  11171. * The value of `videoWidth` from the swf. This will be a number
  11172. * in css pixels.
  11173. */
  11174. /**
  11175. * Get the value of `videoHeight` from the swf. `videoHeigth` indicates
  11176. * the current height of the media in css pixels.
  11177. *
  11178. * @method Flassh.prototype.videoHeight
  11179. * @return {number}
  11180. * The value of `videoHeight` from the swf. This will be a number
  11181. * in css pixels.
  11182. */
  11183. /** ------------------------------ Setters ------------------------------ **/
  11184. /**
  11185. * Set the value of `rtmpConnection` on the swf.
  11186. *
  11187. * @method Flash#setRtmpConnection
  11188. * @param {string} rtmpConnection
  11189. * New value to set the `rtmpConnection` property to.
  11190. */
  11191. /**
  11192. * Set the value of `rtmpStream` on the swf.
  11193. *
  11194. * @method Flash#setRtmpStream
  11195. * @param {string} rtmpStream
  11196. * New value to set the `rtmpStream` property to.
  11197. */
  11198. /**
  11199. * Set the value of `preload` on the swf. `preload` indicates
  11200. * what should download before the media is interacted with. It can have the following
  11201. * values:
  11202. * - none: nothing should be downloaded
  11203. * - metadata: poster and the first few frames of the media may be downloaded to get
  11204. * media dimensions and other metadata
  11205. * - auto: allow the media and metadata for the media to be downloaded before
  11206. * interaction
  11207. *
  11208. * @method Flash#setPreload
  11209. * @param {string} preload
  11210. * The value of `preload` to set on the swf. Should be 'none', 'metadata',
  11211. * or 'auto'.
  11212. */
  11213. /**
  11214. * Set the value of `defaultPlaybackRate` on the swf.
  11215. *
  11216. * @method Flash#setDefaultPlaybackRate
  11217. * @param {number} defaultPlaybackRate
  11218. * New value to set the `defaultPlaybackRate` property to.
  11219. */
  11220. /**
  11221. * Set the value of `playbackRate` on the swf. `playbackRate` indicates
  11222. * the rate at which the media is currently playing back. Examples:
  11223. * - if playbackRate is set to 2, media will play twice as fast.
  11224. * - if playbackRate is set to 0.5, media will play half as fast.
  11225. *
  11226. * @method Flash#setPlaybackRate
  11227. * @param {number} playbackRate
  11228. * New value of `playbackRate` on the swf. A number indicating
  11229. * the current playback speed of the media, where 1 is normal speed.
  11230. */
  11231. /**
  11232. * Set the value of `autoplay` on the swf. `autoplay` indicates
  11233. * that the media should start to play as soon as the page is ready.
  11234. *
  11235. * @method Flash#setAutoplay
  11236. * @param {boolean} autoplay
  11237. * - The value of `autoplay` from the swf.
  11238. * - True indicates that the media ashould start as soon as the page loads.
  11239. * - False indicates that the media should not start as soon as the page loads.
  11240. */
  11241. /**
  11242. * Set the value of `loop` on the swf. `loop` indicates
  11243. * that the media should return to the start of the media and continue playing once
  11244. * it reaches the end.
  11245. *
  11246. * @method Flash#setLoop
  11247. * @param {boolean} loop
  11248. * - True indicates that playback should seek back to start once
  11249. * the end of a media is reached.
  11250. * - False indicates that playback should not loop back to the start when the
  11251. * end of the media is reached.
  11252. */
  11253. /**
  11254. * Set the value of `mediaGroup` on the swf.
  11255. *
  11256. * @method Flash#setMediaGroup
  11257. * @param {string} mediaGroup
  11258. * New value of `mediaGroup` to set on the swf.
  11259. */
  11260. /**
  11261. * Set the value of `controller` on the swf.
  11262. *
  11263. * @method Flash#setController
  11264. * @param {string} controller
  11265. * New value the current value of `controller` on the swf.
  11266. */
  11267. /**
  11268. * Get the value of `controls` from the swf. `controls` indicates
  11269. * whether the native flash controls should be shown or hidden.
  11270. *
  11271. * @method Flash#controls
  11272. * @return {boolean}
  11273. * - The value of `controls` from the swf.
  11274. * - True indicates that native controls should be showing.
  11275. * - False indicates that native controls should be hidden.
  11276. */
  11277. /**
  11278. * Set the value of the `volume` on the swf. `volume` indicates the current
  11279. * audio level as a percentage in decimal form. This means that 1 is 100%, 0.5 is 50%, and
  11280. * so on.
  11281. *
  11282. * @method Flash#setVolume
  11283. * @param {number} percentAsDecimal
  11284. * The volume percent as a decimal. Value will be between 0-1.
  11285. */
  11286. /**
  11287. * Set the value of the `muted` on the swf. `muted` indicates that the current
  11288. * audio level should be silent.
  11289. *
  11290. * @method Flash#setMuted
  11291. * @param {boolean} muted
  11292. * - True if the audio should be set to silent
  11293. * - False otherwise
  11294. */
  11295. /**
  11296. * Set the value of `defaultMuted` on the swf. `defaultMuted` indicates
  11297. * whether the media should start muted or not. Only changes the default state of the
  11298. * media. `muted` and `defaultMuted` can have different values. `muted` indicates the
  11299. * current state.
  11300. *
  11301. * @method Flash#setDefaultMuted
  11302. * @param {boolean} defaultMuted
  11303. * - True indicates that the media should start muted.
  11304. * - False indicates that the media should not start muted.
  11305. */
  11306. /* Flash Support Testing -------------------------------------------------------- */
  11307. /**
  11308. * Check if the Flash tech is currently supported.
  11309. *
  11310. * @return {boolean}
  11311. * - True if the flash tech is supported.
  11312. * - False otherwise.
  11313. */
  11314. Flash.isSupported = function () {
  11315. return Flash.version()[0] >= 10;
  11316. // return swfobject.hasFlashPlayerVersion('10');
  11317. };
  11318. // Add Source Handler pattern functions to this tech
  11319. _tech2['default'].withSourceHandlers(Flash);
  11320. /*
  11321. * Native source handler for flash, simply passes the source to the swf element.
  11322. *
  11323. * @property {Tech~SourceObject} source
  11324. * The source object
  11325. *
  11326. * @property {Flash} tech
  11327. * The instance of the Flash tech
  11328. */
  11329. Flash.nativeSourceHandler = {};
  11330. /**
  11331. * Check if the Flash can play the given mime type.
  11332. *
  11333. * @param {string} type
  11334. * The mimetype to check
  11335. *
  11336. * @return {string}
  11337. * 'maybe', or '' (empty string)
  11338. */
  11339. Flash.nativeSourceHandler.canPlayType = function (type) {
  11340. if (type in Flash.formats) {
  11341. return 'maybe';
  11342. }
  11343. return '';
  11344. };
  11345. /**
  11346. * Check if the media element can handle a source natively.
  11347. *
  11348. * @param {Tech~SourceObject} source
  11349. * The source object
  11350. *
  11351. * @param {Object} [options]
  11352. * Options to be passed to the tech.
  11353. *
  11354. * @return {string}
  11355. * 'maybe', or '' (empty string).
  11356. */
  11357. Flash.nativeSourceHandler.canHandleSource = function (source, options) {
  11358. var type = void 0;
  11359. function guessMimeType(src) {
  11360. var ext = Url.getFileExtension(src);
  11361. if (ext) {
  11362. return 'video/' + ext;
  11363. }
  11364. return '';
  11365. }
  11366. if (!source.type) {
  11367. type = guessMimeType(source.src);
  11368. } else {
  11369. // Strip code information from the type because we don't get that specific
  11370. type = source.type.replace(/;.*/, '').toLowerCase();
  11371. }
  11372. return Flash.nativeSourceHandler.canPlayType(type);
  11373. };
  11374. /**
  11375. * Pass the source to the swf.
  11376. *
  11377. * @param {Tech~SourceObject} source
  11378. * The source object
  11379. *
  11380. * @param {Flash} tech
  11381. * The instance of the Flash tech
  11382. *
  11383. * @param {Object} [options]
  11384. * The options to pass to the source
  11385. */
  11386. Flash.nativeSourceHandler.handleSource = function (source, tech, options) {
  11387. tech.setSrc(source.src);
  11388. };
  11389. /**
  11390. * noop for native source handler dispose, as cleanup will happen automatically.
  11391. */
  11392. Flash.nativeSourceHandler.dispose = function () {};
  11393. // Register the native source handler
  11394. Flash.registerSourceHandler(Flash.nativeSourceHandler);
  11395. /**
  11396. * Flash supported mime types.
  11397. *
  11398. * @constant {Object}
  11399. */
  11400. Flash.formats = {
  11401. 'video/flv': 'FLV',
  11402. 'video/x-flv': 'FLV',
  11403. 'video/mp4': 'MP4',
  11404. 'video/m4v': 'MP4'
  11405. };
  11406. /**
  11407. * Called when the the swf is "ready", and makes sure that the swf is really
  11408. * ready using {@link Flash#checkReady}
  11409. */
  11410. Flash.onReady = function (currSwf) {
  11411. var el = Dom.getEl(currSwf);
  11412. var tech = el && el.tech;
  11413. // if there is no el then the tech has been disposed
  11414. // and the tech element was removed from the player div
  11415. if (tech && tech.el()) {
  11416. // check that the flash object is really ready
  11417. Flash.checkReady(tech);
  11418. }
  11419. };
  11420. /**
  11421. * The SWF isn't always ready when it says it is. Sometimes the API functions still
  11422. * need to be added to the object. If it's not ready, we set a timeout to check again
  11423. * shortly.
  11424. *
  11425. * @param {Flash} tech
  11426. * The instance of the flash tech to check.
  11427. */
  11428. Flash.checkReady = function (tech) {
  11429. // stop worrying if the tech has been disposed
  11430. if (!tech.el()) {
  11431. return;
  11432. }
  11433. // check if API property exists
  11434. if (tech.el().vjs_getProperty) {
  11435. // tell tech it's ready
  11436. tech.triggerReady();
  11437. } else {
  11438. // wait longer
  11439. this.setTimeout(function () {
  11440. Flash.checkReady(tech);
  11441. }, 50);
  11442. }
  11443. };
  11444. /**
  11445. * Trigger events from the swf on the Flash Tech.
  11446. *
  11447. * @param {number} swfID
  11448. * The id of the swf that had the event
  11449. *
  11450. * @param {string} eventName
  11451. * The name of the event to trigger
  11452. */
  11453. Flash.onEvent = function (swfID, eventName) {
  11454. var tech = Dom.getEl(swfID).tech;
  11455. var args = Array.prototype.slice.call(arguments, 2);
  11456. // dispatch Flash events asynchronously for two reasons:
  11457. // - Flash swallows any exceptions generated by javascript it
  11458. // invokes
  11459. // - Flash is suspended until the javascript returns which may cause
  11460. // playback performance issues
  11461. tech.setTimeout(function () {
  11462. tech.trigger(eventName, args);
  11463. }, 1);
  11464. };
  11465. /**
  11466. * Log errors from the swf on the Flash tech.
  11467. *
  11468. * @param {number} swfID
  11469. * The id of the swf that had an error.
  11470. *
  11471. * @param {string} The error string
  11472. * The error to set on the Flash Tech.
  11473. *
  11474. * @return {MediaError|undefined}
  11475. * - Returns a MediaError when err is 'srcnotfound'
  11476. * - Returns undefined otherwise.
  11477. */
  11478. Flash.onError = function (swfID, err) {
  11479. var tech = Dom.getEl(swfID).tech;
  11480. // trigger MEDIA_ERR_SRC_NOT_SUPPORTED
  11481. if (err === 'srcnotfound') {
  11482. return tech.error(4);
  11483. }
  11484. // trigger a custom error
  11485. tech.error('FLASH: ' + err);
  11486. };
  11487. /**
  11488. * Get the current version of Flash that is in use on the page.
  11489. *
  11490. * @return {Array}
  11491. * an array of versions that are available.
  11492. */
  11493. Flash.version = function () {
  11494. var version = '0,0,0';
  11495. // IE
  11496. try {
  11497. version = new _window2['default'].ActiveXObject('ShockwaveFlash.ShockwaveFlash').GetVariable('$version').replace(/\D+/g, ',').match(/^,?(.+),?$/)[1];
  11498. // other browsers
  11499. } catch (e) {
  11500. try {
  11501. if (navigator.mimeTypes['application/x-shockwave-flash'].enabledPlugin) {
  11502. version = (navigator.plugins['Shockwave Flash 2.0'] || navigator.plugins['Shockwave Flash']).description.replace(/\D+/g, ',').match(/^,?(.+),?$/)[1];
  11503. }
  11504. } catch (err) {
  11505. // satisfy linter
  11506. }
  11507. }
  11508. return version.split(',');
  11509. };
  11510. /**
  11511. * Only use for non-iframe embeds.
  11512. *
  11513. * @param {Object} swf
  11514. * The videojs-swf object.
  11515. *
  11516. * @param {Object} flashVars
  11517. * Names and values to use as flash option variables.
  11518. *
  11519. * @param {Object} params
  11520. * Style parameters to set on the object.
  11521. *
  11522. * @param {Object} attributes
  11523. * Attributes to set on the element.
  11524. *
  11525. * @return {Element}
  11526. * The embeded Flash DOM element.
  11527. */
  11528. Flash.embed = function (swf, flashVars, params, attributes) {
  11529. var code = Flash.getEmbedCode(swf, flashVars, params, attributes);
  11530. // Get element by embedding code and retrieving created element
  11531. var obj = Dom.createEl('div', { innerHTML: code }).childNodes[0];
  11532. return obj;
  11533. };
  11534. /**
  11535. * Only use for non-iframe embeds.
  11536. *
  11537. * @param {Object} swf
  11538. * The videojs-swf object.
  11539. *
  11540. * @param {Object} flashVars
  11541. * Names and values to use as flash option variables.
  11542. *
  11543. * @param {Object} params
  11544. * Style parameters to set on the object.
  11545. *
  11546. * @param {Object} attributes
  11547. * Attributes to set on the element.
  11548. *
  11549. * @return {Element}
  11550. * The embeded Flash DOM element.
  11551. */
  11552. Flash.getEmbedCode = function (swf, flashVars, params, attributes) {
  11553. var objTag = '<object type="application/x-shockwave-flash" ';
  11554. var flashVarsString = '';
  11555. var paramsString = '';
  11556. var attrsString = '';
  11557. // Convert flash vars to string
  11558. if (flashVars) {
  11559. Object.getOwnPropertyNames(flashVars).forEach(function (key) {
  11560. flashVarsString += key + '=' + flashVars[key] + '&amp;';
  11561. });
  11562. }
  11563. // Add swf, flashVars, and other default params
  11564. params = (0, _obj.assign)({
  11565. movie: swf,
  11566. flashvars: flashVarsString,
  11567. // Required to talk to swf
  11568. allowScriptAccess: 'always',
  11569. // All should be default, but having security issues.
  11570. allowNetworking: 'all'
  11571. }, params);
  11572. // Create param tags string
  11573. Object.getOwnPropertyNames(params).forEach(function (key) {
  11574. paramsString += '<param name="' + key + '" value="' + params[key] + '" />';
  11575. });
  11576. attributes = (0, _obj.assign)({
  11577. // Add swf to attributes (need both for IE and Others to work)
  11578. data: swf,
  11579. // Default to 100% width/height
  11580. width: '100%',
  11581. height: '100%'
  11582. }, attributes);
  11583. // Create Attributes string
  11584. Object.getOwnPropertyNames(attributes).forEach(function (key) {
  11585. attrsString += key + '="' + attributes[key] + '" ';
  11586. });
  11587. return '' + objTag + attrsString + '>' + paramsString + '</object>';
  11588. };
  11589. // Run Flash through the RTMP decorator
  11590. (0, _flashRtmp2['default'])(Flash);
  11591. _component2['default'].registerComponent('Flash', Flash);
  11592. _tech2['default'].registerTech('Flash', Flash);
  11593. exports['default'] = Flash;
  11594. },{"5":5,"58":58,"62":62,"81":81,"88":88,"90":90,"92":92,"95":95}],60:[function(_dereq_,module,exports){
  11595. 'use strict';
  11596. exports.__esModule = true;
  11597. 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; };
  11598. 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.']);
  11599. var _tech = _dereq_(62);
  11600. var _tech2 = _interopRequireDefault(_tech);
  11601. var _component = _dereq_(5);
  11602. var _component2 = _interopRequireDefault(_component);
  11603. var _dom = _dereq_(81);
  11604. var Dom = _interopRequireWildcard(_dom);
  11605. var _url = _dereq_(92);
  11606. var Url = _interopRequireWildcard(_url);
  11607. var _fn = _dereq_(83);
  11608. var Fn = _interopRequireWildcard(_fn);
  11609. var _log = _dereq_(86);
  11610. var _log2 = _interopRequireDefault(_log);
  11611. var _tsml = _dereq_(98);
  11612. var _tsml2 = _interopRequireDefault(_tsml);
  11613. var _browser = _dereq_(78);
  11614. var browser = _interopRequireWildcard(_browser);
  11615. var _document = _dereq_(94);
  11616. var _document2 = _interopRequireDefault(_document);
  11617. var _window = _dereq_(95);
  11618. var _window2 = _interopRequireDefault(_window);
  11619. var _obj = _dereq_(88);
  11620. var _mergeOptions = _dereq_(87);
  11621. var _mergeOptions2 = _interopRequireDefault(_mergeOptions);
  11622. var _toTitleCase = _dereq_(91);
  11623. var _toTitleCase2 = _interopRequireDefault(_toTitleCase);
  11624. 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; } }
  11625. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  11626. function _taggedTemplateLiteralLoose(strings, raw) { strings.raw = raw; return strings; }
  11627. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  11628. 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; }
  11629. 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; } /**
  11630. * @file html5.js
  11631. */
  11632. /**
  11633. * HTML5 Media Controller - Wrapper for HTML5 Media API
  11634. *
  11635. * @mixes Tech~SouceHandlerAdditions
  11636. * @extends Tech
  11637. */
  11638. var Html5 = function (_Tech) {
  11639. _inherits(Html5, _Tech);
  11640. /**
  11641. * Create an instance of this Tech.
  11642. *
  11643. * @param {Object} [options]
  11644. * The key/value store of player options.
  11645. *
  11646. * @param {Component~ReadyCallback} ready
  11647. * Callback function to call when the `HTML5` Tech is ready.
  11648. */
  11649. function Html5(options, ready) {
  11650. _classCallCheck(this, Html5);
  11651. var _this = _possibleConstructorReturn(this, _Tech.call(this, options, ready));
  11652. var source = options.source;
  11653. var crossoriginTracks = false;
  11654. // Set the source if one is provided
  11655. // 1) Check if the source is new (if not, we want to keep the original so playback isn't interrupted)
  11656. // 2) Check to see if the network state of the tag was failed at init, and if so, reset the source
  11657. // anyway so the error gets fired.
  11658. if (source && (_this.el_.currentSrc !== source.src || options.tag && options.tag.initNetworkState_ === 3)) {
  11659. _this.setSource(source);
  11660. } else {
  11661. _this.handleLateInit_(_this.el_);
  11662. }
  11663. if (_this.el_.hasChildNodes()) {
  11664. var nodes = _this.el_.childNodes;
  11665. var nodesLength = nodes.length;
  11666. var removeNodes = [];
  11667. while (nodesLength--) {
  11668. var node = nodes[nodesLength];
  11669. var nodeName = node.nodeName.toLowerCase();
  11670. if (nodeName === 'track') {
  11671. if (!_this.featuresNativeTextTracks) {
  11672. // Empty video tag tracks so the built-in player doesn't use them also.
  11673. // This may not be fast enough to stop HTML5 browsers from reading the tags
  11674. // so we'll need to turn off any default tracks if we're manually doing
  11675. // captions and subtitles. videoElement.textTracks
  11676. removeNodes.push(node);
  11677. } else {
  11678. // store HTMLTrackElement and TextTrack to remote list
  11679. _this.remoteTextTrackEls().addTrackElement_(node);
  11680. _this.remoteTextTracks().addTrack_(node.track);
  11681. if (!crossoriginTracks && !_this.el_.hasAttribute('crossorigin') && Url.isCrossOrigin(node.src)) {
  11682. crossoriginTracks = true;
  11683. }
  11684. }
  11685. }
  11686. }
  11687. for (var i = 0; i < removeNodes.length; i++) {
  11688. _this.el_.removeChild(removeNodes[i]);
  11689. }
  11690. }
  11691. // TODO: add text tracks into this list
  11692. var trackTypes = ['audio', 'video'];
  11693. // ProxyNative Video/Audio Track
  11694. trackTypes.forEach(function (type) {
  11695. var elTracks = _this.el()[type + 'Tracks'];
  11696. var techTracks = _this[type + 'Tracks']();
  11697. var capitalType = (0, _toTitleCase2['default'])(type);
  11698. if (!_this['featuresNative' + capitalType + 'Tracks'] || !elTracks || !elTracks.addEventListener) {
  11699. return;
  11700. }
  11701. _this['handle' + capitalType + 'TrackChange_'] = function (e) {
  11702. techTracks.trigger({
  11703. type: 'change',
  11704. target: techTracks,
  11705. currentTarget: techTracks,
  11706. srcElement: techTracks
  11707. });
  11708. };
  11709. _this['handle' + capitalType + 'TrackAdd_'] = function (e) {
  11710. return techTracks.addTrack(e.track);
  11711. };
  11712. _this['handle' + capitalType + 'TrackRemove_'] = function (e) {
  11713. return techTracks.removeTrack(e.track);
  11714. };
  11715. elTracks.addEventListener('change', _this['handle' + capitalType + 'TrackChange_']);
  11716. elTracks.addEventListener('addtrack', _this['handle' + capitalType + 'TrackAdd_']);
  11717. elTracks.addEventListener('removetrack', _this['handle' + capitalType + 'TrackRemove_']);
  11718. _this['removeOld' + capitalType + 'Tracks_'] = function (e) {
  11719. return _this.removeOldTracks_(techTracks, elTracks);
  11720. };
  11721. // Remove (native) tracks that are not used anymore
  11722. _this.on('loadstart', _this['removeOld' + capitalType + 'Tracks_']);
  11723. });
  11724. if (_this.featuresNativeTextTracks) {
  11725. if (crossoriginTracks) {
  11726. _log2['default'].warn((0, _tsml2['default'])(_templateObject));
  11727. }
  11728. _this.handleTextTrackChange_ = Fn.bind(_this, _this.handleTextTrackChange);
  11729. _this.handleTextTrackAdd_ = Fn.bind(_this, _this.handleTextTrackAdd);
  11730. _this.handleTextTrackRemove_ = Fn.bind(_this, _this.handleTextTrackRemove);
  11731. _this.proxyNativeTextTracks_();
  11732. }
  11733. // Determine if native controls should be used
  11734. // Our goal should be to get the custom controls on mobile solid everywhere
  11735. // so we can remove this all together. Right now this will block custom
  11736. // controls on touch enabled laptops like the Chrome Pixel
  11737. if ((browser.TOUCH_ENABLED || browser.IS_IPHONE || browser.IS_NATIVE_ANDROID) && options.nativeControlsForTouch === true) {
  11738. _this.setControls(true);
  11739. }
  11740. // on iOS, we want to proxy `webkitbeginfullscreen` and `webkitendfullscreen`
  11741. // into a `fullscreenchange` event
  11742. _this.proxyWebkitFullscreen_();
  11743. _this.triggerReady();
  11744. return _this;
  11745. }
  11746. /**
  11747. * Dispose of `HTML5` media element and remove all tracks.
  11748. */
  11749. Html5.prototype.dispose = function dispose() {
  11750. var _this2 = this;
  11751. // Un-ProxyNativeTracks
  11752. ['audio', 'video', 'text'].forEach(function (type) {
  11753. var capitalType = (0, _toTitleCase2['default'])(type);
  11754. var tl = _this2.el_[type + 'Tracks'];
  11755. if (tl && tl.removeEventListener) {
  11756. tl.removeEventListener('change', _this2['handle' + capitalType + 'TrackChange_']);
  11757. tl.removeEventListener('addtrack', _this2['handle' + capitalType + 'TrackAdd_']);
  11758. tl.removeEventListener('removetrack', _this2['handle' + capitalType + 'TrackRemove_']);
  11759. }
  11760. // Stop removing old text tracks
  11761. if (tl) {
  11762. _this2.off('loadstart', _this2['removeOld' + capitalType + 'Tracks_']);
  11763. }
  11764. });
  11765. Html5.disposeMediaElement(this.el_);
  11766. // tech will handle clearing of the emulated track list
  11767. _Tech.prototype.dispose.call(this);
  11768. };
  11769. /**
  11770. * Create the `Html5` Tech's DOM element.
  11771. *
  11772. * @return {Element}
  11773. * The element that gets created.
  11774. */
  11775. Html5.prototype.createEl = function createEl() {
  11776. var el = this.options_.tag;
  11777. // Check if this browser supports moving the element into the box.
  11778. // On the iPhone video will break if you move the element,
  11779. // So we have to create a brand new element.
  11780. // If we ingested the player div, we do not need to move the media element.
  11781. if (!el || !(this.options_.playerElIngest || this.movingMediaElementInDOM)) {
  11782. // If the original tag is still there, clone and remove it.
  11783. if (el) {
  11784. var clone = el.cloneNode(true);
  11785. if (el.parentNode) {
  11786. el.parentNode.insertBefore(clone, el);
  11787. }
  11788. Html5.disposeMediaElement(el);
  11789. el = clone;
  11790. } else {
  11791. el = _document2['default'].createElement('video');
  11792. // determine if native controls should be used
  11793. var tagAttributes = this.options_.tag && Dom.getElAttributes(this.options_.tag);
  11794. var attributes = (0, _mergeOptions2['default'])({}, tagAttributes);
  11795. if (!browser.TOUCH_ENABLED || this.options_.nativeControlsForTouch !== true) {
  11796. delete attributes.controls;
  11797. }
  11798. Dom.setElAttributes(el, (0, _obj.assign)(attributes, {
  11799. id: this.options_.techId,
  11800. 'class': 'vjs-tech'
  11801. }));
  11802. }
  11803. el.playerId = this.options_.playerId;
  11804. }
  11805. // Update specific tag settings, in case they were overridden
  11806. var settingsAttrs = ['autoplay', 'preload', 'loop', 'muted'];
  11807. for (var i = settingsAttrs.length - 1; i >= 0; i--) {
  11808. var attr = settingsAttrs[i];
  11809. var overwriteAttrs = {};
  11810. if (typeof this.options_[attr] !== 'undefined') {
  11811. overwriteAttrs[attr] = this.options_[attr];
  11812. }
  11813. Dom.setElAttributes(el, overwriteAttrs);
  11814. }
  11815. return el;
  11816. };
  11817. /**
  11818. * This will be triggered if the loadstart event has already fired, before videojs was
  11819. * ready. Two known examples of when this can happen are:
  11820. * 1. If we're loading the playback object after it has started loading
  11821. * 2. The media is already playing the (often with autoplay on) then
  11822. *
  11823. * This function will fire another loadstart so that videojs can catchup.
  11824. *
  11825. * @fires Tech#loadstart
  11826. *
  11827. * @return {undefined}
  11828. * returns nothing.
  11829. */
  11830. Html5.prototype.handleLateInit_ = function handleLateInit_(el) {
  11831. var _this3 = this;
  11832. if (el.networkState === 0 || el.networkState === 3) {
  11833. // The video element hasn't started loading the source yet
  11834. // or didn't find a source
  11835. return;
  11836. }
  11837. if (el.readyState === 0) {
  11838. var _ret = function () {
  11839. // NetworkState is set synchronously BUT loadstart is fired at the
  11840. // end of the current stack, usually before setInterval(fn, 0).
  11841. // So at this point we know loadstart may have already fired or is
  11842. // about to fire, and either way the player hasn't seen it yet.
  11843. // We don't want to fire loadstart prematurely here and cause a
  11844. // double loadstart so we'll wait and see if it happens between now
  11845. // and the next loop, and fire it if not.
  11846. // HOWEVER, we also want to make sure it fires before loadedmetadata
  11847. // which could also happen between now and the next loop, so we'll
  11848. // watch for that also.
  11849. var loadstartFired = false;
  11850. var setLoadstartFired = function setLoadstartFired() {
  11851. loadstartFired = true;
  11852. };
  11853. _this3.on('loadstart', setLoadstartFired);
  11854. var triggerLoadstart = function triggerLoadstart() {
  11855. // We did miss the original loadstart. Make sure the player
  11856. // sees loadstart before loadedmetadata
  11857. if (!loadstartFired) {
  11858. this.trigger('loadstart');
  11859. }
  11860. };
  11861. _this3.on('loadedmetadata', triggerLoadstart);
  11862. _this3.ready(function () {
  11863. this.off('loadstart', setLoadstartFired);
  11864. this.off('loadedmetadata', triggerLoadstart);
  11865. if (!loadstartFired) {
  11866. // We did miss the original native loadstart. Fire it now.
  11867. this.trigger('loadstart');
  11868. }
  11869. });
  11870. return {
  11871. v: void 0
  11872. };
  11873. }();
  11874. if ((typeof _ret === 'undefined' ? 'undefined' : _typeof(_ret)) === "object") return _ret.v;
  11875. }
  11876. // From here on we know that loadstart already fired and we missed it.
  11877. // The other readyState events aren't as much of a problem if we double
  11878. // them, so not going to go to as much trouble as loadstart to prevent
  11879. // that unless we find reason to.
  11880. var eventsToTrigger = ['loadstart'];
  11881. // loadedmetadata: newly equal to HAVE_METADATA (1) or greater
  11882. eventsToTrigger.push('loadedmetadata');
  11883. // loadeddata: newly increased to HAVE_CURRENT_DATA (2) or greater
  11884. if (el.readyState >= 2) {
  11885. eventsToTrigger.push('loadeddata');
  11886. }
  11887. // canplay: newly increased to HAVE_FUTURE_DATA (3) or greater
  11888. if (el.readyState >= 3) {
  11889. eventsToTrigger.push('canplay');
  11890. }
  11891. // canplaythrough: newly equal to HAVE_ENOUGH_DATA (4)
  11892. if (el.readyState >= 4) {
  11893. eventsToTrigger.push('canplaythrough');
  11894. }
  11895. // We still need to give the player time to add event listeners
  11896. this.ready(function () {
  11897. eventsToTrigger.forEach(function (type) {
  11898. this.trigger(type);
  11899. }, this);
  11900. });
  11901. };
  11902. /**
  11903. * Add event listeners to native text track events. This adds the native text tracks
  11904. * to our emulated {@link TextTrackList}.
  11905. */
  11906. Html5.prototype.proxyNativeTextTracks_ = function proxyNativeTextTracks_() {
  11907. var tt = this.el().textTracks;
  11908. if (tt) {
  11909. // Add tracks - if player is initialised after DOM loaded, textTracks
  11910. // will not trigger addtrack
  11911. for (var i = 0; i < tt.length; i++) {
  11912. this.textTracks().addTrack_(tt[i]);
  11913. }
  11914. if (tt.addEventListener) {
  11915. tt.addEventListener('change', this.handleTextTrackChange_);
  11916. tt.addEventListener('addtrack', this.handleTextTrackAdd_);
  11917. tt.addEventListener('removetrack', this.handleTextTrackRemove_);
  11918. }
  11919. // Remove (native) texttracks that are not used anymore
  11920. this.on('loadstart', this.removeOldTextTracks_);
  11921. }
  11922. };
  11923. /**
  11924. * Handle any {@link TextTrackList} `change` event.
  11925. *
  11926. * @param {EventTarget~Event} e
  11927. * The `change` event that caused this to run.
  11928. *
  11929. * @listens TextTrackList#change
  11930. */
  11931. Html5.prototype.handleTextTrackChange = function handleTextTrackChange(e) {
  11932. var tt = this.textTracks();
  11933. this.textTracks().trigger({
  11934. type: 'change',
  11935. target: tt,
  11936. currentTarget: tt,
  11937. srcElement: tt
  11938. });
  11939. };
  11940. /**
  11941. * Handle any {@link TextTrackList} `addtrack` event.
  11942. *
  11943. * @param {EventTarget~Event} e
  11944. * The `addtrack` event that caused this to run.
  11945. *
  11946. * @listens TextTrackList#addtrack
  11947. */
  11948. Html5.prototype.handleTextTrackAdd = function handleTextTrackAdd(e) {
  11949. this.textTracks().addTrack_(e.track);
  11950. };
  11951. /**
  11952. * Handle any {@link TextTrackList} `removetrack` event.
  11953. *
  11954. * @param {EventTarget~Event} e
  11955. * The `removetrack` event that caused this to run.
  11956. *
  11957. * @listens TextTrackList#removetrack
  11958. */
  11959. Html5.prototype.handleTextTrackRemove = function handleTextTrackRemove(e) {
  11960. this.textTracks().removeTrack_(e.track);
  11961. };
  11962. /**
  11963. * This function removes any {@link AudioTrack}s, {@link VideoTrack}s, or
  11964. * {@link TextTrack}s that are not in the media elements TrackList.
  11965. *
  11966. * @param {TrackList} techTracks
  11967. * HTML5 Tech's TrackList to search through
  11968. *
  11969. * @param {TrackList} elTracks
  11970. * HTML5 media elements TrackList to search trough.
  11971. *
  11972. * @private
  11973. */
  11974. Html5.prototype.removeOldTracks_ = function removeOldTracks_(techTracks, elTracks) {
  11975. // This will loop over the techTracks and check if they are still used by the HTML5 media element
  11976. // If not, they will be removed from the emulated list
  11977. var removeTracks = [];
  11978. if (!elTracks) {
  11979. return;
  11980. }
  11981. for (var i = 0; i < techTracks.length; i++) {
  11982. var techTrack = techTracks[i];
  11983. var found = false;
  11984. for (var j = 0; j < elTracks.length; j++) {
  11985. if (elTracks[j] === techTrack) {
  11986. found = true;
  11987. break;
  11988. }
  11989. }
  11990. if (!found) {
  11991. removeTracks.push(techTrack);
  11992. }
  11993. }
  11994. for (var _i = 0; _i < removeTracks.length; _i++) {
  11995. var track = removeTracks[_i];
  11996. techTracks.removeTrack_(track);
  11997. }
  11998. };
  11999. /**
  12000. * Remove {@link TextTrack}s that dont exist in the native track list from our
  12001. * emulated {@link TextTrackList}.
  12002. *
  12003. * @listens Tech#loadstart
  12004. */
  12005. Html5.prototype.removeOldTextTracks_ = function removeOldTextTracks_(e) {
  12006. var techTracks = this.textTracks();
  12007. var elTracks = this.el().textTracks;
  12008. this.removeOldTracks_(techTracks, elTracks);
  12009. };
  12010. /**
  12011. * Called by {@link Player#play} to play using the `Html5` `Tech`.
  12012. */
  12013. Html5.prototype.play = function play() {
  12014. var playPromise = this.el_.play();
  12015. // Catch/silence error when a pause interrupts a play request
  12016. // on browsers which return a promise
  12017. if (playPromise !== undefined && typeof playPromise.then === 'function') {
  12018. playPromise.then(null, function (e) {});
  12019. }
  12020. };
  12021. /**
  12022. * Set current time for the `HTML5` tech.
  12023. *
  12024. * @param {number} seconds
  12025. * Set the current time of the media to this.
  12026. */
  12027. Html5.prototype.setCurrentTime = function setCurrentTime(seconds) {
  12028. try {
  12029. this.el_.currentTime = seconds;
  12030. } catch (e) {
  12031. (0, _log2['default'])(e, 'Video is not ready. (Video.js)');
  12032. // this.warning(VideoJS.warnings.videoNotReady);
  12033. }
  12034. };
  12035. /**
  12036. * Get the current duration of the HTML5 media element.
  12037. *
  12038. * @return {number}
  12039. * The duration of the media or 0 if there is no duration.
  12040. */
  12041. Html5.prototype.duration = function duration() {
  12042. var _this4 = this;
  12043. // Android Chrome will report duration as Infinity for VOD HLS until after
  12044. // playback has started, which triggers the live display erroneously.
  12045. // Return NaN if playback has not started and trigger a durationupdate once
  12046. // the duration can be reliably known.
  12047. if (this.el_.duration === Infinity && browser.IS_ANDROID && browser.IS_CHROME) {
  12048. if (this.el_.currentTime === 0) {
  12049. var _ret2 = function () {
  12050. // Wait for the first `timeupdate` with currentTime > 0 - there may be
  12051. // several with 0
  12052. var checkProgress = function checkProgress() {
  12053. if (_this4.el_.currentTime > 0) {
  12054. // Trigger durationchange for genuinely live video
  12055. if (_this4.el_.duration === Infinity) {
  12056. _this4.trigger('durationchange');
  12057. }
  12058. _this4.off('timeupdate', checkProgress);
  12059. }
  12060. };
  12061. _this4.on('timeupdate', checkProgress);
  12062. return {
  12063. v: NaN
  12064. };
  12065. }();
  12066. if ((typeof _ret2 === 'undefined' ? 'undefined' : _typeof(_ret2)) === "object") return _ret2.v;
  12067. }
  12068. }
  12069. return this.el_.duration || NaN;
  12070. };
  12071. /**
  12072. * Get the current width of the HTML5 media element.
  12073. *
  12074. * @return {number}
  12075. * The width of the HTML5 media element.
  12076. */
  12077. Html5.prototype.width = function width() {
  12078. return this.el_.offsetWidth;
  12079. };
  12080. /**
  12081. * Get the current height of the HTML5 media element.
  12082. *
  12083. * @return {number}
  12084. * The heigth of the HTML5 media element.
  12085. */
  12086. Html5.prototype.height = function height() {
  12087. return this.el_.offsetHeight;
  12088. };
  12089. /**
  12090. * Proxy iOS `webkitbeginfullscreen` and `webkitendfullscreen` into
  12091. * `fullscreenchange` event.
  12092. *
  12093. * @private
  12094. * @fires fullscreenchange
  12095. * @listens webkitendfullscreen
  12096. * @listens webkitbeginfullscreen
  12097. * @listens webkitbeginfullscreen
  12098. */
  12099. Html5.prototype.proxyWebkitFullscreen_ = function proxyWebkitFullscreen_() {
  12100. var _this5 = this;
  12101. if (!('webkitDisplayingFullscreen' in this.el_)) {
  12102. return;
  12103. }
  12104. var endFn = function endFn() {
  12105. this.trigger('fullscreenchange', { isFullscreen: false });
  12106. };
  12107. var beginFn = function beginFn() {
  12108. this.one('webkitendfullscreen', endFn);
  12109. this.trigger('fullscreenchange', { isFullscreen: true });
  12110. };
  12111. this.on('webkitbeginfullscreen', beginFn);
  12112. this.on('dispose', function () {
  12113. _this5.off('webkitbeginfullscreen', beginFn);
  12114. _this5.off('webkitendfullscreen', endFn);
  12115. });
  12116. };
  12117. /**
  12118. * Check if fullscreen is supported on the current playback device.
  12119. *
  12120. * @return {boolean}
  12121. * - True if fullscreen is supported.
  12122. * - False if fullscreen is not supported.
  12123. */
  12124. Html5.prototype.supportsFullScreen = function supportsFullScreen() {
  12125. if (typeof this.el_.webkitEnterFullScreen === 'function') {
  12126. var userAgent = _window2['default'].navigator && _window2['default'].navigator.userAgent || '';
  12127. // Seems to be broken in Chromium/Chrome && Safari in Leopard
  12128. if (/Android/.test(userAgent) || !/Chrome|Mac OS X 10.5/.test(userAgent)) {
  12129. return true;
  12130. }
  12131. }
  12132. return false;
  12133. };
  12134. /**
  12135. * Request that the `HTML5` Tech enter fullscreen.
  12136. */
  12137. Html5.prototype.enterFullScreen = function enterFullScreen() {
  12138. var video = this.el_;
  12139. if (video.paused && video.networkState <= video.HAVE_METADATA) {
  12140. // attempt to prime the video element for programmatic access
  12141. // this isn't necessary on the desktop but shouldn't hurt
  12142. this.el_.play();
  12143. // playing and pausing synchronously during the transition to fullscreen
  12144. // can get iOS ~6.1 devices into a play/pause loop
  12145. this.setTimeout(function () {
  12146. video.pause();
  12147. video.webkitEnterFullScreen();
  12148. }, 0);
  12149. } else {
  12150. video.webkitEnterFullScreen();
  12151. }
  12152. };
  12153. /**
  12154. * Request that the `HTML5` Tech exit fullscreen.
  12155. */
  12156. Html5.prototype.exitFullScreen = function exitFullScreen() {
  12157. this.el_.webkitExitFullScreen();
  12158. };
  12159. /**
  12160. * A getter/setter for the `Html5` Tech's source object.
  12161. * > Note: Please use {@link Html5#setSource}
  12162. *
  12163. * @param {Tech~SourceObject} [src]
  12164. * The source object you want to set on the `HTML5` techs element.
  12165. *
  12166. * @return {Tech~SourceObject|undefined}
  12167. * - The current source object when a source is not passed in.
  12168. * - undefined when setting
  12169. *
  12170. * @deprecated Since version 5.
  12171. */
  12172. Html5.prototype.src = function src(_src) {
  12173. if (_src === undefined) {
  12174. return this.el_.src;
  12175. }
  12176. // Setting src through `src` instead of `setSrc` will be deprecated
  12177. this.setSrc(_src);
  12178. };
  12179. /**
  12180. * Reset the tech by removing all sources and then calling
  12181. * {@link Html5.resetMediaElement}.
  12182. */
  12183. Html5.prototype.reset = function reset() {
  12184. Html5.resetMediaElement(this.el_);
  12185. };
  12186. /**
  12187. * Get the current source on the `HTML5` Tech. Falls back to returning the source from
  12188. * the HTML5 media element.
  12189. *
  12190. * @return {Tech~SourceObject}
  12191. * The current source object from the HTML5 tech. With a fallback to the
  12192. * elements source.
  12193. */
  12194. Html5.prototype.currentSrc = function currentSrc() {
  12195. if (this.currentSource_) {
  12196. return this.currentSource_.src;
  12197. }
  12198. return this.el_.currentSrc;
  12199. };
  12200. /**
  12201. * Set controls attribute for the HTML5 media Element.
  12202. *
  12203. * @param {string} val
  12204. * Value to set the controls attribute to
  12205. */
  12206. Html5.prototype.setControls = function setControls(val) {
  12207. this.el_.controls = !!val;
  12208. };
  12209. /**
  12210. * Create and returns a remote {@link TextTrack} object.
  12211. *
  12212. * @param {string} kind
  12213. * `TextTrack` kind (subtitles, captions, descriptions, chapters, or metadata)
  12214. *
  12215. * @param {string} [label]
  12216. * Label to identify the text track
  12217. *
  12218. * @param {string} [language]
  12219. * Two letter language abbreviation
  12220. *
  12221. * @return {TextTrack}
  12222. * The TextTrack that gets created.
  12223. */
  12224. Html5.prototype.addTextTrack = function addTextTrack(kind, label, language) {
  12225. if (!this.featuresNativeTextTracks) {
  12226. return _Tech.prototype.addTextTrack.call(this, kind, label, language);
  12227. }
  12228. return this.el_.addTextTrack(kind, label, language);
  12229. };
  12230. /**
  12231. * Creates either native TextTrack or an emulated TextTrack depending
  12232. * on the value of `featuresNativeTextTracks`
  12233. *
  12234. * @param {Object} options
  12235. * The object should contain the options to intialize the TextTrack with.
  12236. *
  12237. * @param {string} [options.kind]
  12238. * `TextTrack` kind (subtitles, captions, descriptions, chapters, or metadata).
  12239. *
  12240. * @param {string} [options.label].
  12241. * Label to identify the text track
  12242. *
  12243. * @param {string} [options.language]
  12244. * Two letter language abbreviation.
  12245. *
  12246. * @param {boolean} [options.default]
  12247. * Default this track to on.
  12248. *
  12249. * @param {string} [options.id]
  12250. * The internal id to assign this track.
  12251. *
  12252. * @param {string} [options.src]
  12253. * A source url for the track.
  12254. *
  12255. * @return {HTMLTrackElement}
  12256. * The track element that gets created.
  12257. */
  12258. Html5.prototype.createRemoteTextTrack = function createRemoteTextTrack(options) {
  12259. if (!this.featuresNativeTextTracks) {
  12260. return _Tech.prototype.createRemoteTextTrack.call(this, options);
  12261. }
  12262. var htmlTrackElement = _document2['default'].createElement('track');
  12263. if (options.kind) {
  12264. htmlTrackElement.kind = options.kind;
  12265. }
  12266. if (options.label) {
  12267. htmlTrackElement.label = options.label;
  12268. }
  12269. if (options.language || options.srclang) {
  12270. htmlTrackElement.srclang = options.language || options.srclang;
  12271. }
  12272. if (options['default']) {
  12273. htmlTrackElement['default'] = options['default'];
  12274. }
  12275. if (options.id) {
  12276. htmlTrackElement.id = options.id;
  12277. }
  12278. if (options.src) {
  12279. htmlTrackElement.src = options.src;
  12280. }
  12281. return htmlTrackElement;
  12282. };
  12283. /**
  12284. * Creates a remote text track object and returns an html track element.
  12285. *
  12286. * @param {Object} options The object should contain values for
  12287. * kind, language, label, and src (location of the WebVTT file)
  12288. * @param {Boolean} [manualCleanup=true] if set to false, the TextTrack will be
  12289. * automatically removed from the video element whenever the source changes
  12290. * @return {HTMLTrackElement} An Html Track Element.
  12291. * This can be an emulated {@link HTMLTrackElement} or a native one.
  12292. * @deprecated The default value of the "manualCleanup" parameter will default
  12293. * to "false" in upcoming versions of Video.js
  12294. */
  12295. Html5.prototype.addRemoteTextTrack = function addRemoteTextTrack(options, manualCleanup) {
  12296. var htmlTrackElement = _Tech.prototype.addRemoteTextTrack.call(this, options, manualCleanup);
  12297. if (this.featuresNativeTextTracks) {
  12298. this.el().appendChild(htmlTrackElement);
  12299. }
  12300. return htmlTrackElement;
  12301. };
  12302. /**
  12303. * Remove remote `TextTrack` from `TextTrackList` object
  12304. *
  12305. * @param {TextTrack} track
  12306. * `TextTrack` object to remove
  12307. */
  12308. Html5.prototype.removeRemoteTextTrack = function removeRemoteTextTrack(track) {
  12309. _Tech.prototype.removeRemoteTextTrack.call(this, track);
  12310. if (this.featuresNativeTextTracks) {
  12311. var tracks = this.$$('track');
  12312. var i = tracks.length;
  12313. while (i--) {
  12314. if (track === tracks[i] || track === tracks[i].track) {
  12315. this.el().removeChild(tracks[i]);
  12316. }
  12317. }
  12318. }
  12319. };
  12320. return Html5;
  12321. }(_tech2['default']);
  12322. /* HTML5 Support Testing ---------------------------------------------------- */
  12323. if (Dom.isReal()) {
  12324. /**
  12325. * Element for testing browser HTML5 media capabilities
  12326. *
  12327. * @type {Element}
  12328. * @constant
  12329. * @private
  12330. */
  12331. Html5.TEST_VID = _document2['default'].createElement('video');
  12332. var track = _document2['default'].createElement('track');
  12333. track.kind = 'captions';
  12334. track.srclang = 'en';
  12335. track.label = 'English';
  12336. Html5.TEST_VID.appendChild(track);
  12337. }
  12338. /**
  12339. * Check if HTML5 media is supported by this browser/device.
  12340. *
  12341. * @return {boolean}
  12342. * - True if HTML5 media is supported.
  12343. * - False if HTML5 media is not supported.
  12344. */
  12345. Html5.isSupported = function () {
  12346. // IE9 with no Media Player is a LIAR! (#984)
  12347. try {
  12348. Html5.TEST_VID.volume = 0.5;
  12349. } catch (e) {
  12350. return false;
  12351. }
  12352. return !!(Html5.TEST_VID && Html5.TEST_VID.canPlayType);
  12353. };
  12354. /**
  12355. * Check if the volume can be changed in this browser/device.
  12356. * Volume cannot be changed in a lot of mobile devices.
  12357. * Specifically, it can't be changed from 1 on iOS.
  12358. *
  12359. * @return {boolean}
  12360. * - True if volume can be controlled
  12361. * - False otherwise
  12362. */
  12363. Html5.canControlVolume = function () {
  12364. // IE will error if Windows Media Player not installed #3315
  12365. try {
  12366. var volume = Html5.TEST_VID.volume;
  12367. Html5.TEST_VID.volume = volume / 2 + 0.1;
  12368. return volume !== Html5.TEST_VID.volume;
  12369. } catch (e) {
  12370. return false;
  12371. }
  12372. };
  12373. /**
  12374. * Check if the playback rate can be changed in this browser/device.
  12375. *
  12376. * @return {boolean}
  12377. * - True if playback rate can be controlled
  12378. * - False otherwise
  12379. */
  12380. Html5.canControlPlaybackRate = function () {
  12381. // Playback rate API is implemented in Android Chrome, but doesn't do anything
  12382. // https://github.com/videojs/video.js/issues/3180
  12383. if (browser.IS_ANDROID && browser.IS_CHROME) {
  12384. return false;
  12385. }
  12386. // IE will error if Windows Media Player not installed #3315
  12387. try {
  12388. var playbackRate = Html5.TEST_VID.playbackRate;
  12389. Html5.TEST_VID.playbackRate = playbackRate / 2 + 0.1;
  12390. return playbackRate !== Html5.TEST_VID.playbackRate;
  12391. } catch (e) {
  12392. return false;
  12393. }
  12394. };
  12395. /**
  12396. * Check to see if native `TextTrack`s are supported by this browser/device.
  12397. *
  12398. * @return {boolean}
  12399. * - True if native `TextTrack`s are supported.
  12400. * - False otherwise
  12401. */
  12402. Html5.supportsNativeTextTracks = function () {
  12403. return browser.IS_ANY_SAFARI;
  12404. };
  12405. /**
  12406. * Check to see if native `VideoTrack`s are supported by this browser/device
  12407. *
  12408. * @return {boolean}
  12409. * - True if native `VideoTrack`s are supported.
  12410. * - False otherwise
  12411. */
  12412. Html5.supportsNativeVideoTracks = function () {
  12413. return !!(Html5.TEST_VID && Html5.TEST_VID.videoTracks);
  12414. };
  12415. /**
  12416. * Check to see if native `AudioTrack`s are supported by this browser/device
  12417. *
  12418. * @return {boolean}
  12419. * - True if native `AudioTrack`s are supported.
  12420. * - False otherwise
  12421. */
  12422. Html5.supportsNativeAudioTracks = function () {
  12423. return !!(Html5.TEST_VID && Html5.TEST_VID.audioTracks);
  12424. };
  12425. /**
  12426. * An array of events available on the Html5 tech.
  12427. *
  12428. * @private
  12429. * @type {Array}
  12430. */
  12431. Html5.Events = ['loadstart', 'suspend', 'abort', 'error', 'emptied', 'stalled', 'loadedmetadata', 'loadeddata', 'canplay', 'canplaythrough', 'playing', 'waiting', 'seeking', 'seeked', 'ended', 'durationchange', 'timeupdate', 'progress', 'play', 'pause', 'ratechange', 'volumechange'];
  12432. /**
  12433. * Boolean indicating whether the `Tech` supports volume control.
  12434. *
  12435. * @type {boolean}
  12436. * @default {@link Html5.canControlVolume}
  12437. */
  12438. Html5.prototype.featuresVolumeControl = Html5.canControlVolume();
  12439. /**
  12440. * Boolean indicating whether the `Tech` supports changing the speed at which the media
  12441. * plays. Examples:
  12442. * - Set player to play 2x (twice) as fast
  12443. * - Set player to play 0.5x (half) as fast
  12444. *
  12445. * @type {boolean}
  12446. * @default {@link Html5.canControlPlaybackRate}
  12447. */
  12448. Html5.prototype.featuresPlaybackRate = Html5.canControlPlaybackRate();
  12449. /**
  12450. * Boolean indicating whether the `HTML5` tech currently supports the media element
  12451. * moving in the DOM. iOS breaks if you move the media element, so this is set this to
  12452. * false there. Everywhere else this should be true.
  12453. *
  12454. * @type {boolean}
  12455. * @default
  12456. */
  12457. Html5.prototype.movingMediaElementInDOM = !browser.IS_IOS;
  12458. // TODO: Previous comment: No longer appears to be used. Can probably be removed.
  12459. // Is this true?
  12460. /**
  12461. * Boolean indicating whether the `HTML5` tech currently supports automatic media resize
  12462. * when going into fullscreen.
  12463. *
  12464. * @type {boolean}
  12465. * @default
  12466. */
  12467. Html5.prototype.featuresFullscreenResize = true;
  12468. /**
  12469. * Boolean indicating whether the `HTML5` tech currently supports the progress event.
  12470. * If this is false, manual `progress` events will be triggred instead.
  12471. *
  12472. * @type {boolean}
  12473. * @default
  12474. */
  12475. Html5.prototype.featuresProgressEvents = true;
  12476. /**
  12477. * Boolean indicating whether the `HTML5` tech currently supports the timeupdate event.
  12478. * If this is false, manual `timeupdate` events will be triggred instead.
  12479. *
  12480. * @default
  12481. */
  12482. Html5.prototype.featuresTimeupdateEvents = true;
  12483. /**
  12484. * Boolean indicating whether the `HTML5` tech currently supports native `TextTrack`s.
  12485. *
  12486. * @type {boolean}
  12487. * @default {@link Html5.supportsNativeTextTracks}
  12488. */
  12489. Html5.prototype.featuresNativeTextTracks = Html5.supportsNativeTextTracks();
  12490. /**
  12491. * Boolean indicating whether the `HTML5` tech currently supports native `VideoTrack`s.
  12492. *
  12493. * @type {boolean}
  12494. * @default {@link Html5.supportsNativeVideoTracks}
  12495. */
  12496. Html5.prototype.featuresNativeVideoTracks = Html5.supportsNativeVideoTracks();
  12497. /**
  12498. * Boolean indicating whether the `HTML5` tech currently supports native `AudioTrack`s.
  12499. *
  12500. * @type {boolean}
  12501. * @default {@link Html5.supportsNativeAudioTracks}
  12502. */
  12503. Html5.prototype.featuresNativeAudioTracks = Html5.supportsNativeAudioTracks();
  12504. // HTML5 Feature detection and Device Fixes --------------------------------- //
  12505. var canPlayType = Html5.TEST_VID && Html5.TEST_VID.constructor.prototype.canPlayType;
  12506. var mpegurlRE = /^application\/(?:x-|vnd\.apple\.)mpegurl/i;
  12507. var mp4RE = /^video\/mp4/i;
  12508. Html5.patchCanPlayType = function () {
  12509. // Android 4.0 and above can play HLS to some extent but it reports being unable to do so
  12510. if (browser.ANDROID_VERSION >= 4.0 && !browser.IS_FIREFOX) {
  12511. Html5.TEST_VID.constructor.prototype.canPlayType = function (type) {
  12512. if (type && mpegurlRE.test(type)) {
  12513. return 'maybe';
  12514. }
  12515. return canPlayType.call(this, type);
  12516. };
  12517. // Override Android 2.2 and less canPlayType method which is broken
  12518. } else if (browser.IS_OLD_ANDROID) {
  12519. Html5.TEST_VID.constructor.prototype.canPlayType = function (type) {
  12520. if (type && mp4RE.test(type)) {
  12521. return 'maybe';
  12522. }
  12523. return canPlayType.call(this, type);
  12524. };
  12525. }
  12526. };
  12527. Html5.unpatchCanPlayType = function () {
  12528. var r = Html5.TEST_VID.constructor.prototype.canPlayType;
  12529. Html5.TEST_VID.constructor.prototype.canPlayType = canPlayType;
  12530. return r;
  12531. };
  12532. // by default, patch the media element
  12533. Html5.patchCanPlayType();
  12534. Html5.disposeMediaElement = function (el) {
  12535. if (!el) {
  12536. return;
  12537. }
  12538. if (el.parentNode) {
  12539. el.parentNode.removeChild(el);
  12540. }
  12541. // remove any child track or source nodes to prevent their loading
  12542. while (el.hasChildNodes()) {
  12543. el.removeChild(el.firstChild);
  12544. }
  12545. // remove any src reference. not setting `src=''` because that causes a warning
  12546. // in firefox
  12547. el.removeAttribute('src');
  12548. // force the media element to update its loading state by calling load()
  12549. // however IE on Windows 7N has a bug that throws an error so need a try/catch (#793)
  12550. if (typeof el.load === 'function') {
  12551. // wrapping in an iife so it's not deoptimized (#1060#discussion_r10324473)
  12552. (function () {
  12553. try {
  12554. el.load();
  12555. } catch (e) {
  12556. // not supported
  12557. }
  12558. })();
  12559. }
  12560. };
  12561. Html5.resetMediaElement = function (el) {
  12562. if (!el) {
  12563. return;
  12564. }
  12565. var sources = el.querySelectorAll('source');
  12566. var i = sources.length;
  12567. while (i--) {
  12568. el.removeChild(sources[i]);
  12569. }
  12570. // remove any src reference.
  12571. // not setting `src=''` because that throws an error
  12572. el.removeAttribute('src');
  12573. if (typeof el.load === 'function') {
  12574. // wrapping in an iife so it's not deoptimized (#1060#discussion_r10324473)
  12575. (function () {
  12576. try {
  12577. el.load();
  12578. } catch (e) {
  12579. // satisfy linter
  12580. }
  12581. })();
  12582. }
  12583. };
  12584. /* Native HTML5 element property wrapping ----------------------------------- */
  12585. // Wrap native properties with a getter
  12586. [
  12587. /**
  12588. * Get the value of `paused` from the media element. `paused` indicates whether the media element
  12589. * is currently paused or not.
  12590. *
  12591. * @method Html5#paused
  12592. * @return {boolean}
  12593. * The value of `paused` from the media element.
  12594. *
  12595. * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-paused}
  12596. */
  12597. 'paused',
  12598. /**
  12599. * Get the value of `currentTime` from the media element. `currentTime` indicates
  12600. * the current second that the media is at in playback.
  12601. *
  12602. * @method Html5#currentTime
  12603. * @return {number}
  12604. * The value of `currentTime` from the media element.
  12605. *
  12606. * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-currenttime}
  12607. */
  12608. 'currentTime',
  12609. /**
  12610. * Get the value of `buffered` from the media element. `buffered` is a `TimeRange`
  12611. * object that represents the parts of the media that are already downloaded and
  12612. * available for playback.
  12613. *
  12614. * @method Html5#buffered
  12615. * @return {TimeRange}
  12616. * The value of `buffered` from the media element.
  12617. *
  12618. * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-buffered}
  12619. */
  12620. 'buffered',
  12621. /**
  12622. * Get the value of `volume` from the media element. `volume` indicates
  12623. * the current playback volume of audio for a media. `volume` will be a value from 0
  12624. * (silent) to 1 (loudest and default).
  12625. *
  12626. * @method Html5#volume
  12627. * @return {number}
  12628. * The value of `volume` from the media element. Value will be between 0-1.
  12629. *
  12630. * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-a-volume}
  12631. */
  12632. 'volume',
  12633. /**
  12634. * Get the value of `muted` from the media element. `muted` indicates
  12635. * that the volume for the media should be set to silent. This does not actually change
  12636. * the `volume` attribute.
  12637. *
  12638. * @method Html5#muted
  12639. * @return {boolean}
  12640. * - True if the value of `volume` should be ignored and the audio set to silent.
  12641. * - False if the value of `volume` should be used.
  12642. *
  12643. * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-muted}
  12644. */
  12645. 'muted',
  12646. /**
  12647. * Get the value of `poster` from the media element. `poster` indicates
  12648. * that the url of an image file that can/will be shown when no media data is available.
  12649. *
  12650. * @method Html5#poster
  12651. * @return {string}
  12652. * The value of `poster` from the media element. Value will be a url to an
  12653. * image.
  12654. *
  12655. * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-video-poster}
  12656. */
  12657. 'poster',
  12658. /**
  12659. * Get the value of `preload` from the media element. `preload` indicates
  12660. * what should download before the media is interacted with. It can have the following
  12661. * values:
  12662. * - none: nothing should be downloaded
  12663. * - metadata: poster and the first few frames of the media may be downloaded to get
  12664. * media dimensions and other metadata
  12665. * - auto: allow the media and metadata for the media to be downloaded before
  12666. * interaction
  12667. *
  12668. * @method Html5#preload
  12669. * @return {string}
  12670. * The value of `preload` from the media element. Will be 'none', 'metadata',
  12671. * or 'auto'.
  12672. *
  12673. * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-preload}
  12674. */
  12675. 'preload',
  12676. /**
  12677. * Get the value of `autoplay` from the media element. `autoplay` indicates
  12678. * that the media should start to play as soon as the page is ready.
  12679. *
  12680. * @method Html5#autoplay
  12681. * @return {boolean}
  12682. * - The value of `autoplay` from the media element.
  12683. * - True indicates that the media should start as soon as the page loads.
  12684. * - False indicates that the media should not start as soon as the page loads.
  12685. *
  12686. * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-autoplay}
  12687. */
  12688. 'autoplay',
  12689. /**
  12690. * Get the value of `controls` from the media element. `controls` indicates
  12691. * whether the native media controls should be shown or hidden.
  12692. *
  12693. * @method Html5#controls
  12694. * @return {boolean}
  12695. * - The value of `controls` from the media element.
  12696. * - True indicates that native controls should be showing.
  12697. * - False indicates that native controls should be hidden.
  12698. *
  12699. * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-controls}
  12700. */
  12701. 'controls',
  12702. /**
  12703. * Get the value of `loop` from the media element. `loop` indicates
  12704. * that the media should return to the start of the media and continue playing once
  12705. * it reaches the end.
  12706. *
  12707. * @method Html5#loop
  12708. * @return {boolean}
  12709. * - The value of `loop` from the media element.
  12710. * - True indicates that playback should seek back to start once
  12711. * the end of a media is reached.
  12712. * - False indicates that playback should not loop back to the start when the
  12713. * end of the media is reached.
  12714. *
  12715. * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-loop}
  12716. */
  12717. 'loop',
  12718. /**
  12719. * Get the value of the `error` from the media element. `error` indicates any
  12720. * MediaError that may have occured during playback. If error returns null there is no
  12721. * current error.
  12722. *
  12723. * @method Html5#error
  12724. * @return {MediaError|null}
  12725. * The value of `error` from the media element. Will be `MediaError` if there
  12726. * is a current error and null otherwise.
  12727. *
  12728. * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-error}
  12729. */
  12730. 'error',
  12731. /**
  12732. * Get the value of `seeking` from the media element. `seeking` indicates whether the
  12733. * media is currently seeking to a new position or not.
  12734. *
  12735. * @method Html5#seeking
  12736. * @return {boolean}
  12737. * - The value of `seeking` from the media element.
  12738. * - True indicates that the media is currently seeking to a new position.
  12739. * - Flase indicates that the media is not seeking to a new position at this time.
  12740. *
  12741. * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-seeking}
  12742. */
  12743. 'seeking',
  12744. /**
  12745. * Get the value of `seekable` from the media element. `seekable` returns a
  12746. * `TimeRange` object indicating ranges of time that can currently be `seeked` to.
  12747. *
  12748. * @method Html5#seekable
  12749. * @return {TimeRange}
  12750. * The value of `seekable` from the media element. A `TimeRange` object
  12751. * indicating the current ranges of time that can be seeked to.
  12752. *
  12753. * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-seekable}
  12754. */
  12755. 'seekable',
  12756. /**
  12757. * Get the value of `ended` from the media element. `ended` indicates whether
  12758. * the media has reached the end or not.
  12759. *
  12760. * @method Html5#ended
  12761. * @return {boolean}
  12762. * - The value of `ended` from the media element.
  12763. * - True indicates that the media has ended.
  12764. * - False indicates that the media has not ended.
  12765. *
  12766. * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-ended}
  12767. */
  12768. 'ended',
  12769. /**
  12770. * Get the value of `defaultMuted` from the media element. `defaultMuted` indicates
  12771. * whether the media should start muted or not. Only changes the default state of the
  12772. * media. `muted` and `defaultMuted` can have different values. `muted` indicates the
  12773. * current state.
  12774. *
  12775. * @method Html5#defaultMuted
  12776. * @return {boolean}
  12777. * - The value of `defaultMuted` from the media element.
  12778. * - True indicates that the media should start muted.
  12779. * - False indicates that the media should not start muted
  12780. *
  12781. * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-defaultmuted}
  12782. */
  12783. 'defaultMuted',
  12784. /**
  12785. * Get the value of `playbackRate` from the media element. `playbackRate` indicates
  12786. * the rate at which the media is currently playing back. Examples:
  12787. * - if playbackRate is set to 2, media will play twice as fast.
  12788. * - if playbackRate is set to 0.5, media will play half as fast.
  12789. *
  12790. * @method Html5#playbackRate
  12791. * @return {number}
  12792. * The value of `playbackRate` from the media element. A number indicating
  12793. * the current playback speed of the media, where 1 is normal speed.
  12794. *
  12795. * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-playbackrate}
  12796. */
  12797. 'playbackRate',
  12798. /**
  12799. * Get the value of `played` from the media element. `played` returns a `TimeRange`
  12800. * object representing points in the media timeline that have been played.
  12801. *
  12802. * @method Html5#played
  12803. * @return {TimeRange}
  12804. * The value of `played` from the media element. A `TimeRange` object indicating
  12805. * the ranges of time that have been played.
  12806. *
  12807. * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-played}
  12808. */
  12809. 'played',
  12810. /**
  12811. * Get the value of `networkState` from the media element. `networkState` indicates
  12812. * the current network state. It returns an enumeration from the following list:
  12813. * - 0: NETWORK_EMPTY
  12814. * - 1: NEWORK_IDLE
  12815. * - 2: NETWORK_LOADING
  12816. * - 3: NETWORK_NO_SOURCE
  12817. *
  12818. * @method Html5#networkState
  12819. * @return {number}
  12820. * The value of `networkState` from the media element. This will be a number
  12821. * from the list in the description.
  12822. *
  12823. * @see [Spec] {@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-networkstate}
  12824. */
  12825. 'networkState',
  12826. /**
  12827. * Get the value of `readyState` from the media element. `readyState` indicates
  12828. * the current state of the media element. It returns an enumeration from the
  12829. * following list:
  12830. * - 0: HAVE_NOTHING
  12831. * - 1: HAVE_METADATA
  12832. * - 2: HAVE_CURRENT_DATA
  12833. * - 3: HAVE_FUTURE_DATA
  12834. * - 4: HAVE_ENOUGH_DATA
  12835. *
  12836. * @method Html5#readyState
  12837. * @return {number}
  12838. * The value of `readyState` from the media element. This will be a number
  12839. * from the list in the description.
  12840. *
  12841. * @see [Spec] {@link https://www.w3.org/TR/html5/embedded-content-0.html#ready-states}
  12842. */
  12843. 'readyState',
  12844. /**
  12845. * Get the value of `videoWidth` from the video element. `videoWidth` indicates
  12846. * the current width of the video in css pixels.
  12847. *
  12848. * @method Html5#videoWidth
  12849. * @return {number}
  12850. * The value of `videoWidth` from the video element. This will be a number
  12851. * in css pixels.
  12852. *
  12853. * @see [Spec] {@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-video-videowidth}
  12854. */
  12855. 'videoWidth',
  12856. /**
  12857. * Get the value of `videoHeight` from the video element. `videoHeigth` indicates
  12858. * the current height of the video in css pixels.
  12859. *
  12860. * @method Html5#videoHeight
  12861. * @return {number}
  12862. * The value of `videoHeight` from the video element. This will be a number
  12863. * in css pixels.
  12864. *
  12865. * @see [Spec] {@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-video-videowidth}
  12866. */
  12867. 'videoHeight'].forEach(function (prop) {
  12868. Html5.prototype[prop] = function () {
  12869. return this.el_[prop];
  12870. };
  12871. });
  12872. // Wrap native properties with a setter in this format:
  12873. // set + toTitleCase(name)
  12874. [
  12875. /**
  12876. * Set the value of `volume` on the media element. `volume` indicates the current
  12877. * audio level as a percentage in decimal form. This means that 1 is 100%, 0.5 is 50%, and
  12878. * so on.
  12879. *
  12880. * @method Html5#setVolume
  12881. * @param {number} percentAsDecimal
  12882. * The volume percent as a decimal. Valid range is from 0-1.
  12883. *
  12884. * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-a-volume}
  12885. */
  12886. 'volume',
  12887. /**
  12888. * Set the value of `muted` on the media element. `muted` indicates the current
  12889. * audio level should be silent.
  12890. *
  12891. * @method Html5#setMuted
  12892. * @param {boolean} muted
  12893. * - True if the audio should be set to silent
  12894. * - False otherwise
  12895. *
  12896. * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-muted}
  12897. */
  12898. 'muted',
  12899. /**
  12900. * Set the value of `src` on the media element. `src` indicates the current
  12901. * {@link Tech~SourceObject} for the media.
  12902. *
  12903. * @method Html5#setSrc
  12904. * @param {Tech~SourceObject} src
  12905. * The source object to set as the current source.
  12906. *
  12907. * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-src}
  12908. */
  12909. 'src',
  12910. /**
  12911. * Set the value of `poster` on the media element. `poster` is the url to
  12912. * an image file that can/will be shown when no media data is available.
  12913. *
  12914. * @method Html5#setPoster
  12915. * @param {string} poster
  12916. * The url to an image that should be used as the `poster` for the media
  12917. * element.
  12918. *
  12919. * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-poster}
  12920. */
  12921. 'poster',
  12922. /**
  12923. * Set the value of `preload` on the media element. `preload` indicates
  12924. * what should download before the media is interacted with. It can have the following
  12925. * values:
  12926. * - none: nothing should be downloaded
  12927. * - metadata: poster and the first few frames of the media may be downloaded to get
  12928. * media dimensions and other metadata
  12929. * - auto: allow the media and metadata for the media to be downloaded before
  12930. * interaction
  12931. *
  12932. * @method Html5#setPreload
  12933. * @param {string} preload
  12934. * The value of `preload` to set on the media element. Must be 'none', 'metadata',
  12935. * or 'auto'.
  12936. *
  12937. * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-preload}
  12938. */
  12939. 'preload',
  12940. /**
  12941. * Set the value of `autoplay` on the media element. `autoplay` indicates
  12942. * that the media should start to play as soon as the page is ready.
  12943. *
  12944. * @method Html5#setAutoplay
  12945. * @param {boolean} autoplay
  12946. * - True indicates that the media should start as soon as the page loads.
  12947. * - False indicates that the media should not start as soon as the page loads.
  12948. *
  12949. * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-autoplay}
  12950. */
  12951. 'autoplay',
  12952. /**
  12953. * Set the value of `loop` on the media element. `loop` indicates
  12954. * that the media should return to the start of the media and continue playing once
  12955. * it reaches the end.
  12956. *
  12957. * @method Html5#setLoop
  12958. * @param {boolean} loop
  12959. * - True indicates that playback should seek back to start once
  12960. * the end of a media is reached.
  12961. * - False indicates that playback should not loop back to the start when the
  12962. * end of the media is reached.
  12963. *
  12964. * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#attr-media-loop}
  12965. */
  12966. 'loop',
  12967. /**
  12968. * Set the value of `playbackRate` on the media element. `playbackRate` indicates
  12969. * the rate at which the media should play back. Examples:
  12970. * - if playbackRate is set to 2, media will play twice as fast.
  12971. * - if playbackRate is set to 0.5, media will play half as fast.
  12972. *
  12973. * @method Html5#setPlaybackRate
  12974. * @return {number}
  12975. * The value of `playbackRate` from the media element. A number indicating
  12976. * the current playback speed of the media, where 1 is normal speed.
  12977. *
  12978. * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-playbackrate}
  12979. */
  12980. 'playbackRate'].forEach(function (prop) {
  12981. Html5.prototype['set' + (0, _toTitleCase2['default'])(prop)] = function (v) {
  12982. this.el_[prop] = v;
  12983. };
  12984. });
  12985. // wrap native functions with a function
  12986. [
  12987. /**
  12988. * A wrapper around the media elements `pause` function. This will call the `HTML5`
  12989. * media elements `pause` function.
  12990. *
  12991. * @method Html5#pause
  12992. * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-pause}
  12993. */
  12994. 'pause',
  12995. /**
  12996. * A wrapper around the media elements `load` function. This will call the `HTML5`s
  12997. * media element `load` function.
  12998. *
  12999. * @method Html5#load
  13000. * @see [Spec]{@link https://www.w3.org/TR/html5/embedded-content-0.html#dom-media-load}
  13001. */
  13002. 'load'].forEach(function (prop) {
  13003. Html5.prototype[prop] = function () {
  13004. return this.el_[prop]();
  13005. };
  13006. });
  13007. _tech2['default'].withSourceHandlers(Html5);
  13008. /**
  13009. * Native source handler for Html5, simply passes the source to the media element.
  13010. *
  13011. * @proprety {Tech~SourceObject} source
  13012. * The source object
  13013. *
  13014. * @proprety {Html5} tech
  13015. * The instance of the HTML5 tech.
  13016. */
  13017. Html5.nativeSourceHandler = {};
  13018. /**
  13019. * Check if the media element can play the given mime type.
  13020. *
  13021. * @param {string} type
  13022. * The mimetype to check
  13023. *
  13024. * @return {string}
  13025. * 'probably', 'maybe', or '' (empty string)
  13026. */
  13027. Html5.nativeSourceHandler.canPlayType = function (type) {
  13028. // IE9 on Windows 7 without MediaPlayer throws an error here
  13029. // https://github.com/videojs/video.js/issues/519
  13030. try {
  13031. return Html5.TEST_VID.canPlayType(type);
  13032. } catch (e) {
  13033. return '';
  13034. }
  13035. };
  13036. /**
  13037. * Check if the media element can handle a source natively.
  13038. *
  13039. * @param {Tech~SourceObject} source
  13040. * The source object
  13041. *
  13042. * @param {Object} [options]
  13043. * Options to be passed to the tech.
  13044. *
  13045. * @return {string}
  13046. * 'probably', 'maybe', or '' (empty string).
  13047. */
  13048. Html5.nativeSourceHandler.canHandleSource = function (source, options) {
  13049. // If a type was provided we should rely on that
  13050. if (source.type) {
  13051. return Html5.nativeSourceHandler.canPlayType(source.type);
  13052. // If no type, fall back to checking 'video/[EXTENSION]'
  13053. } else if (source.src) {
  13054. var ext = Url.getFileExtension(source.src);
  13055. return Html5.nativeSourceHandler.canPlayType('video/' + ext);
  13056. }
  13057. return '';
  13058. };
  13059. /**
  13060. * Pass the source to the native media element.
  13061. *
  13062. * @param {Tech~SourceObject} source
  13063. * The source object
  13064. *
  13065. * @param {Html5} tech
  13066. * The instance of the Html5 tech
  13067. *
  13068. * @param {Object} [options]
  13069. * The options to pass to the source
  13070. */
  13071. Html5.nativeSourceHandler.handleSource = function (source, tech, options) {
  13072. tech.setSrc(source.src);
  13073. };
  13074. /**
  13075. * A noop for the native dispose function, as cleanup is not needed.
  13076. */
  13077. Html5.nativeSourceHandler.dispose = function () {};
  13078. // Register the native source handler
  13079. Html5.registerSourceHandler(Html5.nativeSourceHandler);
  13080. _component2['default'].registerComponent('Html5', Html5);
  13081. _tech2['default'].registerTech('Html5', Html5);
  13082. exports['default'] = Html5;
  13083. },{"5":5,"62":62,"78":78,"81":81,"83":83,"86":86,"87":87,"88":88,"91":91,"92":92,"94":94,"95":95,"98":98}],61:[function(_dereq_,module,exports){
  13084. 'use strict';
  13085. exports.__esModule = true;
  13086. var _component = _dereq_(5);
  13087. var _component2 = _interopRequireDefault(_component);
  13088. var _tech = _dereq_(62);
  13089. var _tech2 = _interopRequireDefault(_tech);
  13090. var _toTitleCase = _dereq_(91);
  13091. var _toTitleCase2 = _interopRequireDefault(_toTitleCase);
  13092. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  13093. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  13094. 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; }
  13095. 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; } /**
  13096. * @file loader.js
  13097. */
  13098. /**
  13099. * The `MediaLoader` is the `Component` that decides which playback technology to load
  13100. * when a player is initialized.
  13101. *
  13102. * @extends Component
  13103. */
  13104. var MediaLoader = function (_Component) {
  13105. _inherits(MediaLoader, _Component);
  13106. /**
  13107. * Create an instance of this class.
  13108. *
  13109. * @param {Player} player
  13110. * The `Player` that this class should attach to.
  13111. *
  13112. * @param {Object} [options]
  13113. * The key/value stroe of player options.
  13114. *
  13115. * @param {Component~ReadyCallback} [ready]
  13116. * The function that is run when this component is ready.
  13117. */
  13118. function MediaLoader(player, options, ready) {
  13119. _classCallCheck(this, MediaLoader);
  13120. // If there are no sources when the player is initialized,
  13121. // load the first supported playback technology.
  13122. var _this = _possibleConstructorReturn(this, _Component.call(this, player, options, ready));
  13123. if (!options.playerOptions.sources || options.playerOptions.sources.length === 0) {
  13124. for (var i = 0, j = options.playerOptions.techOrder; i < j.length; i++) {
  13125. var techName = (0, _toTitleCase2['default'])(j[i]);
  13126. var tech = _tech2['default'].getTech(techName);
  13127. // Support old behavior of techs being registered as components.
  13128. // Remove once that deprecated behavior is removed.
  13129. if (!techName) {
  13130. tech = _component2['default'].getComponent(techName);
  13131. }
  13132. // Check if the browser supports this technology
  13133. if (tech && tech.isSupported()) {
  13134. player.loadTech_(techName);
  13135. break;
  13136. }
  13137. }
  13138. } else {
  13139. // Loop through playback technologies (HTML5, Flash) and check for support.
  13140. // Then load the best source.
  13141. // A few assumptions here:
  13142. // All playback technologies respect preload false.
  13143. player.src(options.playerOptions.sources);
  13144. }
  13145. return _this;
  13146. }
  13147. return MediaLoader;
  13148. }(_component2['default']);
  13149. _component2['default'].registerComponent('MediaLoader', MediaLoader);
  13150. exports['default'] = MediaLoader;
  13151. },{"5":5,"62":62,"91":91}],62:[function(_dereq_,module,exports){
  13152. 'use strict';
  13153. exports.__esModule = true;
  13154. 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; };
  13155. var _component = _dereq_(5);
  13156. var _component2 = _interopRequireDefault(_component);
  13157. var _htmlTrackElement = _dereq_(66);
  13158. var _htmlTrackElement2 = _interopRequireDefault(_htmlTrackElement);
  13159. var _htmlTrackElementList = _dereq_(65);
  13160. var _htmlTrackElementList2 = _interopRequireDefault(_htmlTrackElementList);
  13161. var _mergeOptions = _dereq_(87);
  13162. var _mergeOptions2 = _interopRequireDefault(_mergeOptions);
  13163. var _textTrack = _dereq_(72);
  13164. var _textTrack2 = _interopRequireDefault(_textTrack);
  13165. var _textTrackList = _dereq_(70);
  13166. var _textTrackList2 = _interopRequireDefault(_textTrackList);
  13167. var _videoTrackList = _dereq_(76);
  13168. var _videoTrackList2 = _interopRequireDefault(_videoTrackList);
  13169. var _audioTrackList = _dereq_(63);
  13170. var _audioTrackList2 = _interopRequireDefault(_audioTrackList);
  13171. var _fn = _dereq_(83);
  13172. var Fn = _interopRequireWildcard(_fn);
  13173. var _log = _dereq_(86);
  13174. var _log2 = _interopRequireDefault(_log);
  13175. var _timeRanges = _dereq_(90);
  13176. var _buffer = _dereq_(79);
  13177. var _mediaError = _dereq_(46);
  13178. var _mediaError2 = _interopRequireDefault(_mediaError);
  13179. var _window = _dereq_(95);
  13180. var _window2 = _interopRequireDefault(_window);
  13181. var _document = _dereq_(94);
  13182. var _document2 = _interopRequireDefault(_document);
  13183. var _obj = _dereq_(88);
  13184. 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; } }
  13185. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  13186. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  13187. 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; }
  13188. 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; } /**
  13189. * @file tech.js
  13190. */
  13191. /**
  13192. * An Object containing a structure like: `{src: 'url', type: 'mimetype'}` or string
  13193. * that just contains the src url alone.
  13194. * * `var SourceObject = {src: 'http://ex.com/video.mp4', type: 'video/mp4'};`
  13195. * `var SourceString = 'http://example.com/some-video.mp4';`
  13196. *
  13197. * @typedef {Object|string} Tech~SourceObject
  13198. *
  13199. * @property {string} src
  13200. * The url to the source
  13201. *
  13202. * @property {string} type
  13203. * The mime type of the source
  13204. */
  13205. /**
  13206. * A function used by {@link Tech} to create a new {@link TextTrack}.
  13207. *
  13208. * @param {Tech} self
  13209. * An instance of the Tech class.
  13210. *
  13211. * @param {string} kind
  13212. * `TextTrack` kind (subtitles, captions, descriptions, chapters, or metadata)
  13213. *
  13214. * @param {string} [label]
  13215. * Label to identify the text track
  13216. *
  13217. * @param {string} [language]
  13218. * Two letter language abbreviation
  13219. *
  13220. * @param {Object} [options={}]
  13221. * An object with additional text track options
  13222. *
  13223. * @return {TextTrack}
  13224. * The text track that was created.
  13225. */
  13226. function createTrackHelper(self, kind, label, language) {
  13227. var options = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {};
  13228. var tracks = self.textTracks();
  13229. options.kind = kind;
  13230. if (label) {
  13231. options.label = label;
  13232. }
  13233. if (language) {
  13234. options.language = language;
  13235. }
  13236. options.tech = self;
  13237. var track = new _textTrack2['default'](options);
  13238. tracks.addTrack_(track);
  13239. return track;
  13240. }
  13241. /**
  13242. * This is the base class for media playback technology controllers, such as
  13243. * {@link Flash} and {@link HTML5}
  13244. *
  13245. * @extends Component
  13246. */
  13247. var Tech = function (_Component) {
  13248. _inherits(Tech, _Component);
  13249. /**
  13250. * Create an instance of this Tech.
  13251. *
  13252. * @param {Object} [options]
  13253. * The key/value store of player options.
  13254. *
  13255. * @param {Component~ReadyCallback} ready
  13256. * Callback function to call when the `HTML5` Tech is ready.
  13257. */
  13258. function Tech() {
  13259. var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  13260. var ready = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : function () {};
  13261. _classCallCheck(this, Tech);
  13262. // we don't want the tech to report user activity automatically.
  13263. // This is done manually in addControlsListeners
  13264. options.reportTouchActivity = false;
  13265. // keep track of whether the current source has played at all to
  13266. // implement a very limited played()
  13267. var _this = _possibleConstructorReturn(this, _Component.call(this, null, options, ready));
  13268. _this.hasStarted_ = false;
  13269. _this.on('playing', function () {
  13270. this.hasStarted_ = true;
  13271. });
  13272. _this.on('loadstart', function () {
  13273. this.hasStarted_ = false;
  13274. });
  13275. _this.textTracks_ = options.textTracks;
  13276. _this.videoTracks_ = options.videoTracks;
  13277. _this.audioTracks_ = options.audioTracks;
  13278. // Manually track progress in cases where the browser/flash player doesn't report it.
  13279. if (!_this.featuresProgressEvents) {
  13280. _this.manualProgressOn();
  13281. }
  13282. // Manually track timeupdates in cases where the browser/flash player doesn't report it.
  13283. if (!_this.featuresTimeupdateEvents) {
  13284. _this.manualTimeUpdatesOn();
  13285. }
  13286. ['Text', 'Audio', 'Video'].forEach(function (track) {
  13287. if (options['native' + track + 'Tracks'] === false) {
  13288. _this['featuresNative' + track + 'Tracks'] = false;
  13289. }
  13290. });
  13291. if (options.nativeCaptions === false) {
  13292. _this.featuresNativeTextTracks = false;
  13293. }
  13294. if (!_this.featuresNativeTextTracks) {
  13295. _this.emulateTextTracks();
  13296. }
  13297. _this.autoRemoteTextTracks_ = new _textTrackList2['default']();
  13298. _this.initTextTrackListeners();
  13299. _this.initTrackListeners();
  13300. // Turn on component tap events only if not using native controls
  13301. if (!options.nativeControlsForTouch) {
  13302. _this.emitTapEvents();
  13303. }
  13304. if (_this.constructor) {
  13305. _this.name_ = _this.constructor.name || 'Unknown Tech';
  13306. }
  13307. return _this;
  13308. }
  13309. /* Fallbacks for unsupported event types
  13310. ================================================================================ */
  13311. /**
  13312. * Polyfill the `progress` event for browsers that don't support it natively.
  13313. *
  13314. * @see {@link Tech#trackProgress}
  13315. */
  13316. Tech.prototype.manualProgressOn = function manualProgressOn() {
  13317. this.on('durationchange', this.onDurationChange);
  13318. this.manualProgress = true;
  13319. // Trigger progress watching when a source begins loading
  13320. this.one('ready', this.trackProgress);
  13321. };
  13322. /**
  13323. * Turn off the polyfill for `progress` events that was created in
  13324. * {@link Tech#manualProgressOn}
  13325. */
  13326. Tech.prototype.manualProgressOff = function manualProgressOff() {
  13327. this.manualProgress = false;
  13328. this.stopTrackingProgress();
  13329. this.off('durationchange', this.onDurationChange);
  13330. };
  13331. /**
  13332. * This is used to trigger a `progress` event when the buffered percent changes. It
  13333. * sets an interval function that will be called every 500 milliseconds to check if the
  13334. * buffer end percent has changed.
  13335. *
  13336. * > This function is called by {@link Tech#manualProgressOn}
  13337. *
  13338. * @param {EventTarget~Event} event
  13339. * The `ready` event that caused this to run.
  13340. *
  13341. * @listens Tech#ready
  13342. * @fires Tech#progress
  13343. */
  13344. Tech.prototype.trackProgress = function trackProgress(event) {
  13345. this.stopTrackingProgress();
  13346. this.progressInterval = this.setInterval(Fn.bind(this, function () {
  13347. // Don't trigger unless buffered amount is greater than last time
  13348. var numBufferedPercent = this.bufferedPercent();
  13349. if (this.bufferedPercent_ !== numBufferedPercent) {
  13350. /**
  13351. * See {@link Player#progress}
  13352. *
  13353. * @event Tech#progress
  13354. * @type {EventTarget~Event}
  13355. */
  13356. this.trigger('progress');
  13357. }
  13358. this.bufferedPercent_ = numBufferedPercent;
  13359. if (numBufferedPercent === 1) {
  13360. this.stopTrackingProgress();
  13361. }
  13362. }), 500);
  13363. };
  13364. /**
  13365. * Update our internal duration on a `durationchange` event by calling
  13366. * {@link Tech#duration}.
  13367. *
  13368. * @param {EventTarget~Event} event
  13369. * The `durationchange` event that caused this to run.
  13370. *
  13371. * @listens Tech#durationchange
  13372. */
  13373. Tech.prototype.onDurationChange = function onDurationChange(event) {
  13374. this.duration_ = this.duration();
  13375. };
  13376. /**
  13377. * Get and create a `TimeRange` object for buffering.
  13378. *
  13379. * @return {TimeRange}
  13380. * The time range object that was created.
  13381. */
  13382. Tech.prototype.buffered = function buffered() {
  13383. return (0, _timeRanges.createTimeRange)(0, 0);
  13384. };
  13385. /**
  13386. * Get the percentage of the current video that is currently buffered.
  13387. *
  13388. * @return {number}
  13389. * A number from 0 to 1 that represents the decimal percentage of the
  13390. * video that is buffered.
  13391. *
  13392. */
  13393. Tech.prototype.bufferedPercent = function bufferedPercent() {
  13394. return (0, _buffer.bufferedPercent)(this.buffered(), this.duration_);
  13395. };
  13396. /**
  13397. * Turn off the polyfill for `progress` events that was created in
  13398. * {@link Tech#manualProgressOn}
  13399. * Stop manually tracking progress events by clearing the interval that was set in
  13400. * {@link Tech#trackProgress}.
  13401. */
  13402. Tech.prototype.stopTrackingProgress = function stopTrackingProgress() {
  13403. this.clearInterval(this.progressInterval);
  13404. };
  13405. /**
  13406. * Polyfill the `timeupdate` event for browsers that don't support it.
  13407. *
  13408. * @see {@link Tech#trackCurrentTime}
  13409. */
  13410. Tech.prototype.manualTimeUpdatesOn = function manualTimeUpdatesOn() {
  13411. this.manualTimeUpdates = true;
  13412. this.on('play', this.trackCurrentTime);
  13413. this.on('pause', this.stopTrackingCurrentTime);
  13414. };
  13415. /**
  13416. * Turn off the polyfill for `timeupdate` events that was created in
  13417. * {@link Tech#manualTimeUpdatesOn}
  13418. */
  13419. Tech.prototype.manualTimeUpdatesOff = function manualTimeUpdatesOff() {
  13420. this.manualTimeUpdates = false;
  13421. this.stopTrackingCurrentTime();
  13422. this.off('play', this.trackCurrentTime);
  13423. this.off('pause', this.stopTrackingCurrentTime);
  13424. };
  13425. /**
  13426. * Sets up an interval function to track current time and trigger `timeupdate` every
  13427. * 250 milliseconds.
  13428. *
  13429. * @listens Tech#play
  13430. * @triggers Tech#timeupdate
  13431. */
  13432. Tech.prototype.trackCurrentTime = function trackCurrentTime() {
  13433. if (this.currentTimeInterval) {
  13434. this.stopTrackingCurrentTime();
  13435. }
  13436. this.currentTimeInterval = this.setInterval(function () {
  13437. /**
  13438. * Triggered at an interval of 250ms to indicated that time is passing in the video.
  13439. *
  13440. * @event Tech#timeupdate
  13441. * @type {EventTarget~Event}
  13442. */
  13443. this.trigger({ type: 'timeupdate', target: this, manuallyTriggered: true });
  13444. // 42 = 24 fps // 250 is what Webkit uses // FF uses 15
  13445. }, 250);
  13446. };
  13447. /**
  13448. * Stop the interval function created in {@link Tech#trackCurrentTime} so that the
  13449. * `timeupdate` event is no longer triggered.
  13450. *
  13451. * @listens {Tech#pause}
  13452. */
  13453. Tech.prototype.stopTrackingCurrentTime = function stopTrackingCurrentTime() {
  13454. this.clearInterval(this.currentTimeInterval);
  13455. // #1002 - if the video ends right before the next timeupdate would happen,
  13456. // the progress bar won't make it all the way to the end
  13457. this.trigger({ type: 'timeupdate', target: this, manuallyTriggered: true });
  13458. };
  13459. /**
  13460. * Turn off all event polyfills, clear the `Tech`s {@link AudioTrackList},
  13461. * {@link VideoTrackList}, and {@link TextTrackList}, and dispose of this Tech.
  13462. *
  13463. * @fires Component#dispose
  13464. */
  13465. Tech.prototype.dispose = function dispose() {
  13466. // clear out all tracks because we can't reuse them between techs
  13467. this.clearTracks(['audio', 'video', 'text']);
  13468. // Turn off any manual progress or timeupdate tracking
  13469. if (this.manualProgress) {
  13470. this.manualProgressOff();
  13471. }
  13472. if (this.manualTimeUpdates) {
  13473. this.manualTimeUpdatesOff();
  13474. }
  13475. _Component.prototype.dispose.call(this);
  13476. };
  13477. /**
  13478. * Clear out a single `TrackList` or an array of `TrackLists` given their names.
  13479. *
  13480. * > Note: Techs without source handlers should call this between sources for `video`
  13481. * & `audio` tracks. You don't want to use them between tracks!
  13482. *
  13483. * @param {string[]|string} types
  13484. * TrackList names to clear, valid names are `video`, `audio`, and
  13485. * `text`.
  13486. */
  13487. Tech.prototype.clearTracks = function clearTracks(types) {
  13488. var _this2 = this;
  13489. types = [].concat(types);
  13490. // clear out all tracks because we can't reuse them between techs
  13491. types.forEach(function (type) {
  13492. var list = _this2[type + 'Tracks']() || [];
  13493. var i = list.length;
  13494. while (i--) {
  13495. var track = list[i];
  13496. if (type === 'text') {
  13497. _this2.removeRemoteTextTrack(track);
  13498. }
  13499. list.removeTrack_(track);
  13500. }
  13501. });
  13502. };
  13503. /**
  13504. * Remove any TextTracks added via addRemoteTextTrack that are
  13505. * flagged for automatic garbage collection
  13506. */
  13507. Tech.prototype.cleanupAutoTextTracks = function cleanupAutoTextTracks() {
  13508. var list = this.autoRemoteTextTracks_ || [];
  13509. var i = list.length;
  13510. while (i--) {
  13511. var track = list[i];
  13512. this.removeRemoteTextTrack(track);
  13513. }
  13514. };
  13515. /**
  13516. * Reset the tech, which will removes all sources and reset the internal readyState.
  13517. *
  13518. * @abstract
  13519. */
  13520. Tech.prototype.reset = function reset() {};
  13521. /**
  13522. * Get or set an error on the Tech.
  13523. *
  13524. * @param {MediaError} [err]
  13525. * Error to set on the Tech
  13526. *
  13527. * @return {MediaError|null}
  13528. * The current error object on the tech, or null if there isn't one.
  13529. */
  13530. Tech.prototype.error = function error(err) {
  13531. if (err !== undefined) {
  13532. this.error_ = new _mediaError2['default'](err);
  13533. this.trigger('error');
  13534. }
  13535. return this.error_;
  13536. };
  13537. /**
  13538. * Returns the `TimeRange`s that have been played through for the current source.
  13539. *
  13540. * > NOTE: This implementation is incomplete. It does not track the played `TimeRange`.
  13541. * It only checks wether the source has played at all or not.
  13542. *
  13543. * @return {TimeRange}
  13544. * - A single time range if this video has played
  13545. * - An empty set of ranges if not.
  13546. */
  13547. Tech.prototype.played = function played() {
  13548. if (this.hasStarted_) {
  13549. return (0, _timeRanges.createTimeRange)(0, 0);
  13550. }
  13551. return (0, _timeRanges.createTimeRange)();
  13552. };
  13553. /**
  13554. * Causes a manual time update to occur if {@link Tech#manualTimeUpdatesOn} was
  13555. * previously called.
  13556. *
  13557. * @fires Tech#timeupdate
  13558. */
  13559. Tech.prototype.setCurrentTime = function setCurrentTime() {
  13560. // improve the accuracy of manual timeupdates
  13561. if (this.manualTimeUpdates) {
  13562. /**
  13563. * A manual `timeupdate` event.
  13564. *
  13565. * @event Tech#timeupdate
  13566. * @type {EventTarget~Event}
  13567. */
  13568. this.trigger({ type: 'timeupdate', target: this, manuallyTriggered: true });
  13569. }
  13570. };
  13571. /**
  13572. * Turn on listeners for {@link TextTrackList} events. This adds
  13573. * {@link EventTarget~EventListeners} for `texttrackchange`, `addtrack` and
  13574. * `removetrack`.
  13575. *
  13576. * @fires Tech#texttrackchange
  13577. */
  13578. Tech.prototype.initTextTrackListeners = function initTextTrackListeners() {
  13579. var textTrackListChanges = Fn.bind(this, function () {
  13580. /**
  13581. * Triggered when tracks are added or removed on the Tech {@link TextTrackList}
  13582. *
  13583. * @event Tech#texttrackchange
  13584. * @type {EventTarget~Event}
  13585. */
  13586. this.trigger('texttrackchange');
  13587. });
  13588. var tracks = this.textTracks();
  13589. if (!tracks) {
  13590. return;
  13591. }
  13592. tracks.addEventListener('removetrack', textTrackListChanges);
  13593. tracks.addEventListener('addtrack', textTrackListChanges);
  13594. this.on('dispose', Fn.bind(this, function () {
  13595. tracks.removeEventListener('removetrack', textTrackListChanges);
  13596. tracks.removeEventListener('addtrack', textTrackListChanges);
  13597. }));
  13598. };
  13599. /**
  13600. * Turn on listeners for {@link VideoTrackList} and {@link {AudioTrackList} events.
  13601. * This adds {@link EventTarget~EventListeners} for `addtrack`, and `removetrack`.
  13602. *
  13603. * @fires Tech#audiotrackchange
  13604. * @fires Tech#videotrackchange
  13605. */
  13606. Tech.prototype.initTrackListeners = function initTrackListeners() {
  13607. var _this3 = this;
  13608. var trackTypes = ['video', 'audio'];
  13609. trackTypes.forEach(function (type) {
  13610. /**
  13611. * Triggered when tracks are added or removed on the Tech {@link AudioTrackList}
  13612. *
  13613. * @event Tech#audiotrackchange
  13614. * @type {EventTarget~Event}
  13615. */
  13616. /**
  13617. * Triggered when tracks are added or removed on the Tech {@link VideoTrackList}
  13618. *
  13619. * @event Tech#videotrackchange
  13620. * @type {EventTarget~Event}
  13621. */
  13622. var trackListChanges = function trackListChanges() {
  13623. _this3.trigger(type + 'trackchange');
  13624. };
  13625. var tracks = _this3[type + 'Tracks']();
  13626. tracks.addEventListener('removetrack', trackListChanges);
  13627. tracks.addEventListener('addtrack', trackListChanges);
  13628. _this3.on('dispose', function () {
  13629. tracks.removeEventListener('removetrack', trackListChanges);
  13630. tracks.removeEventListener('addtrack', trackListChanges);
  13631. });
  13632. });
  13633. };
  13634. /**
  13635. * Emulate TextTracks using vtt.js if necessary
  13636. *
  13637. * @fires Tech#vttjsloaded
  13638. * @fires Tech#vttjserror
  13639. */
  13640. Tech.prototype.addWebVttScript_ = function addWebVttScript_() {
  13641. var _this4 = this;
  13642. if (!_window2['default'].WebVTT && this.el().parentNode !== null && this.el().parentNode !== undefined) {
  13643. var _ret = function () {
  13644. var vtt = _dereq_(99);
  13645. // load via require if available and vtt.js script location was not passed in
  13646. // as an option. novtt builds will turn the above require call into an empty object
  13647. // which will cause this if check to always fail.
  13648. if (!_this4.options_['vtt.js'] && (0, _obj.isPlain)(vtt) && Object.keys(vtt).length > 0) {
  13649. Object.keys(vtt).forEach(function (k) {
  13650. _window2['default'][k] = vtt[k];
  13651. });
  13652. _this4.trigger('vttjsloaded');
  13653. return {
  13654. v: void 0
  13655. };
  13656. }
  13657. // load vtt.js via the script location option or the cdn of no location was
  13658. // passed in
  13659. var script = _document2['default'].createElement('script');
  13660. script.src = _this4.options_['vtt.js'] || 'https://cdn.rawgit.com/gkatsev/vtt.js/vjs-v0.12.1/dist/vtt.min.js';
  13661. script.onload = function () {
  13662. /**
  13663. * Fired when vtt.js is loaded.
  13664. *
  13665. * @event Tech#vttjsloaded
  13666. * @type {EventTarget~Event}
  13667. */
  13668. _this4.trigger('vttjsloaded');
  13669. };
  13670. script.onerror = function () {
  13671. /**
  13672. * Fired when vtt.js was not loaded due to an error
  13673. *
  13674. * @event Tech#vttjsloaded
  13675. * @type {EventTarget~Event}
  13676. */
  13677. _this4.trigger('vttjserror');
  13678. };
  13679. _this4.on('dispose', function () {
  13680. script.onload = null;
  13681. script.onerror = null;
  13682. });
  13683. // but have not loaded yet and we set it to true before the inject so that
  13684. // we don't overwrite the injected window.WebVTT if it loads right away
  13685. _window2['default'].WebVTT = true;
  13686. _this4.el().parentNode.appendChild(script);
  13687. }();
  13688. if ((typeof _ret === 'undefined' ? 'undefined' : _typeof(_ret)) === "object") return _ret.v;
  13689. }
  13690. };
  13691. /**
  13692. * Emulate texttracks
  13693. *
  13694. * @method emulateTextTracks
  13695. */
  13696. Tech.prototype.emulateTextTracks = function emulateTextTracks() {
  13697. var _this5 = this;
  13698. var tracks = this.textTracks();
  13699. if (!tracks) {
  13700. return;
  13701. }
  13702. this.remoteTextTracks().on('addtrack', function (e) {
  13703. _this5.textTracks().addTrack_(e.track);
  13704. });
  13705. this.remoteTextTracks().on('removetrack', function (e) {
  13706. _this5.textTracks().removeTrack_(e.track);
  13707. });
  13708. // Initially, Tech.el_ is a child of a dummy-div wait until the Component system
  13709. // signals that the Tech is ready at which point Tech.el_ is part of the DOM
  13710. // before inserting the WebVTT script
  13711. this.on('ready', this.addWebVttScript_);
  13712. var updateDisplay = function updateDisplay() {
  13713. return _this5.trigger('texttrackchange');
  13714. };
  13715. var textTracksChanges = function textTracksChanges() {
  13716. updateDisplay();
  13717. for (var i = 0; i < tracks.length; i++) {
  13718. var track = tracks[i];
  13719. track.removeEventListener('cuechange', updateDisplay);
  13720. if (track.mode === 'showing') {
  13721. track.addEventListener('cuechange', updateDisplay);
  13722. }
  13723. }
  13724. };
  13725. textTracksChanges();
  13726. tracks.addEventListener('change', textTracksChanges);
  13727. this.on('dispose', function () {
  13728. tracks.removeEventListener('change', textTracksChanges);
  13729. });
  13730. };
  13731. /**
  13732. * Get the `Tech`s {@link VideoTrackList}.
  13733. *
  13734. * @return {VideoTrackList}
  13735. * The video track list that the Tech is currently using.
  13736. */
  13737. Tech.prototype.videoTracks = function videoTracks() {
  13738. this.videoTracks_ = this.videoTracks_ || new _videoTrackList2['default']();
  13739. return this.videoTracks_;
  13740. };
  13741. /**
  13742. * Get the `Tech`s {@link AudioTrackList}.
  13743. *
  13744. * @return {AudioTrackList}
  13745. * The audio track list that the Tech is currently using.
  13746. */
  13747. Tech.prototype.audioTracks = function audioTracks() {
  13748. this.audioTracks_ = this.audioTracks_ || new _audioTrackList2['default']();
  13749. return this.audioTracks_;
  13750. };
  13751. /**
  13752. * Get the `Tech`s {@link TextTrackList}.
  13753. *
  13754. * @return {TextTrackList}
  13755. * The text track list that the Tech is currently using.
  13756. */
  13757. Tech.prototype.textTracks = function textTracks() {
  13758. this.textTracks_ = this.textTracks_ || new _textTrackList2['default']();
  13759. return this.textTracks_;
  13760. };
  13761. /**
  13762. * Get the `Tech`s remote {@link TextTrackList}, which is created from elements
  13763. * that were added to the DOM.
  13764. *
  13765. * @return {TextTrackList}
  13766. * The remote text track list that the Tech is currently using.
  13767. */
  13768. Tech.prototype.remoteTextTracks = function remoteTextTracks() {
  13769. this.remoteTextTracks_ = this.remoteTextTracks_ || new _textTrackList2['default']();
  13770. return this.remoteTextTracks_;
  13771. };
  13772. /**
  13773. * Get The `Tech`s {HTMLTrackElementList}, which are the elements in the DOM that are
  13774. * being used as TextTracks.
  13775. *
  13776. * @return {HTMLTrackElementList}
  13777. * The current HTML track elements that exist for the tech.
  13778. */
  13779. Tech.prototype.remoteTextTrackEls = function remoteTextTrackEls() {
  13780. this.remoteTextTrackEls_ = this.remoteTextTrackEls_ || new _htmlTrackElementList2['default']();
  13781. return this.remoteTextTrackEls_;
  13782. };
  13783. /**
  13784. * Create and returns a remote {@link TextTrack} object.
  13785. *
  13786. * @param {string} kind
  13787. * `TextTrack` kind (subtitles, captions, descriptions, chapters, or metadata)
  13788. *
  13789. * @param {string} [label]
  13790. * Label to identify the text track
  13791. *
  13792. * @param {string} [language]
  13793. * Two letter language abbreviation
  13794. *
  13795. * @return {TextTrack}
  13796. * The TextTrack that gets created.
  13797. */
  13798. Tech.prototype.addTextTrack = function addTextTrack(kind, label, language) {
  13799. if (!kind) {
  13800. throw new Error('TextTrack kind is required but was not provided');
  13801. }
  13802. return createTrackHelper(this, kind, label, language);
  13803. };
  13804. /**
  13805. * Create an emulated TextTrack for use by addRemoteTextTrack
  13806. *
  13807. * This is intended to be overridden by classes that inherit from
  13808. * Tech in order to create native or custom TextTracks.
  13809. *
  13810. * @param {Object} options
  13811. * The object should contain the options to initialize the TextTrack with.
  13812. *
  13813. * @param {string} [options.kind]
  13814. * `TextTrack` kind (subtitles, captions, descriptions, chapters, or metadata).
  13815. *
  13816. * @param {string} [options.label].
  13817. * Label to identify the text track
  13818. *
  13819. * @param {string} [options.language]
  13820. * Two letter language abbreviation.
  13821. *
  13822. * @return {HTMLTrackElement}
  13823. * The track element that gets created.
  13824. */
  13825. Tech.prototype.createRemoteTextTrack = function createRemoteTextTrack(options) {
  13826. var track = (0, _mergeOptions2['default'])(options, {
  13827. tech: this
  13828. });
  13829. return new _htmlTrackElement2['default'](track);
  13830. };
  13831. /**
  13832. * Creates a remote text track object and returns an html track element.
  13833. *
  13834. * > Note: This can be an emulated {@link HTMLTrackElement} or a native one.
  13835. *
  13836. * @param {Object} options
  13837. * See {@link Tech#createRemoteTextTrack} for more detailed properties.
  13838. *
  13839. * @param {boolean} [manualCleanup=true]
  13840. * - When false: the TextTrack will be automatically removed from the video
  13841. * element whenever the source changes
  13842. * - When True: The TextTrack will have to be cleaned up manually
  13843. *
  13844. * @return {HTMLTrackElement}
  13845. * An Html Track Element.
  13846. *
  13847. * @deprecated The default functionality for this function will be equivalent
  13848. * to "manualCleanup=false" in the future. The manualCleanup parameter will
  13849. * also be removed.
  13850. */
  13851. Tech.prototype.addRemoteTextTrack = function addRemoteTextTrack() {
  13852. var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  13853. var manualCleanup = arguments[1];
  13854. var htmlTrackElement = this.createRemoteTextTrack(options);
  13855. if (manualCleanup !== true && manualCleanup !== false) {
  13856. // deprecation warning
  13857. _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');
  13858. manualCleanup = true;
  13859. }
  13860. // store HTMLTrackElement and TextTrack to remote list
  13861. this.remoteTextTrackEls().addTrackElement_(htmlTrackElement);
  13862. this.remoteTextTracks().addTrack_(htmlTrackElement.track);
  13863. if (manualCleanup !== true) {
  13864. // create the TextTrackList if it doesn't exist
  13865. this.autoRemoteTextTracks_.addTrack_(htmlTrackElement.track);
  13866. }
  13867. return htmlTrackElement;
  13868. };
  13869. /**
  13870. * Remove a remote text track from the remote `TextTrackList`.
  13871. *
  13872. * @param {TextTrack} track
  13873. * `TextTrack` to remove from the `TextTrackList`
  13874. */
  13875. Tech.prototype.removeRemoteTextTrack = function removeRemoteTextTrack(track) {
  13876. var trackElement = this.remoteTextTrackEls().getTrackElementByTrack_(track);
  13877. // remove HTMLTrackElement and TextTrack from remote list
  13878. this.remoteTextTrackEls().removeTrackElement_(trackElement);
  13879. this.remoteTextTracks().removeTrack_(track);
  13880. this.autoRemoteTextTracks_.removeTrack_(track);
  13881. };
  13882. /**
  13883. * A method to set a poster from a `Tech`.
  13884. *
  13885. * @abstract
  13886. */
  13887. Tech.prototype.setPoster = function setPoster() {};
  13888. /*
  13889. * Check if the tech can support the given mime-type.
  13890. *
  13891. * The base tech does not support any type, but source handlers might
  13892. * overwrite this.
  13893. *
  13894. * @param {string} type
  13895. * The mimetype to check for support
  13896. *
  13897. * @return {string}
  13898. * 'probably', 'maybe', or empty string
  13899. *
  13900. * @see [Spec]{@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/canPlayType}
  13901. *
  13902. * @abstract
  13903. */
  13904. Tech.prototype.canPlayType = function canPlayType() {
  13905. return '';
  13906. };
  13907. /*
  13908. * Return whether the argument is a Tech or not.
  13909. * Can be passed either a Class like `Html5` or a instance like `player.tech_`
  13910. *
  13911. * @param {Object} component
  13912. * The item to check
  13913. *
  13914. * @return {boolean}
  13915. * Whether it is a tech or not
  13916. * - True if it is a tech
  13917. * - False if it is not
  13918. */
  13919. Tech.isTech = function isTech(component) {
  13920. return component.prototype instanceof Tech || component instanceof Tech || component === Tech;
  13921. };
  13922. /**
  13923. * Registers a `Tech` into a shared list for videojs.
  13924. *
  13925. * @param {string} name
  13926. * Name of the `Tech` to register.
  13927. *
  13928. * @param {Object} tech
  13929. * The `Tech` class to register.
  13930. */
  13931. Tech.registerTech = function registerTech(name, tech) {
  13932. if (!Tech.techs_) {
  13933. Tech.techs_ = {};
  13934. }
  13935. if (!Tech.isTech(tech)) {
  13936. throw new Error('Tech ' + name + ' must be a Tech');
  13937. }
  13938. Tech.techs_[name] = tech;
  13939. return tech;
  13940. };
  13941. /**
  13942. * Get a `Tech` from the shared list by name.
  13943. *
  13944. * @param {string} name
  13945. * Name of the component to get
  13946. *
  13947. * @return {Tech|undefined}
  13948. * The `Tech` or undefined if there was no tech with the name requsted.
  13949. */
  13950. Tech.getTech = function getTech(name) {
  13951. if (Tech.techs_ && Tech.techs_[name]) {
  13952. return Tech.techs_[name];
  13953. }
  13954. if (_window2['default'] && _window2['default'].videojs && _window2['default'].videojs[name]) {
  13955. _log2['default'].warn('The ' + name + ' tech was added to the videojs object when it should be registered using videojs.registerTech(name, tech)');
  13956. return _window2['default'].videojs[name];
  13957. }
  13958. };
  13959. return Tech;
  13960. }(_component2['default']);
  13961. /**
  13962. * List of associated text tracks.
  13963. *
  13964. * @type {TextTrackList}
  13965. * @private
  13966. */
  13967. Tech.prototype.textTracks_; // eslint-disable-line
  13968. /**
  13969. * List of associated audio tracks.
  13970. *
  13971. * @type {AudioTrackList}
  13972. * @private
  13973. */
  13974. Tech.prototype.audioTracks_; // eslint-disable-line
  13975. /**
  13976. * List of associated video tracks.
  13977. *
  13978. * @type {VideoTrackList}
  13979. * @private
  13980. */
  13981. Tech.prototype.videoTracks_; // eslint-disable-line
  13982. /**
  13983. * Boolean indicating wether the `Tech` supports volume control.
  13984. *
  13985. * @type {boolean}
  13986. * @default
  13987. */
  13988. Tech.prototype.featuresVolumeControl = true;
  13989. /**
  13990. * Boolean indicating wether the `Tech` support fullscreen resize control.
  13991. * Resizing plugins using request fullscreen reloads the plugin
  13992. *
  13993. * @type {boolean}
  13994. * @default
  13995. */
  13996. Tech.prototype.featuresFullscreenResize = false;
  13997. /**
  13998. * Boolean indicating wether the `Tech` supports changing the speed at which the video
  13999. * plays. Examples:
  14000. * - Set player to play 2x (twice) as fast
  14001. * - Set player to play 0.5x (half) as fast
  14002. *
  14003. * @type {boolean}
  14004. * @default
  14005. */
  14006. Tech.prototype.featuresPlaybackRate = false;
  14007. /**
  14008. * Boolean indicating wether the `Tech` supports the `progress` event. This is currently
  14009. * not triggered by video-js-swf. This will be used to determine if
  14010. * {@link Tech#manualProgressOn} should be called.
  14011. *
  14012. * @type {boolean}
  14013. * @default
  14014. */
  14015. Tech.prototype.featuresProgressEvents = false;
  14016. /**
  14017. * Boolean indicating wether the `Tech` supports the `timeupdate` event. This is currently
  14018. * not triggered by video-js-swf. This will be used to determine if
  14019. * {@link Tech#manualTimeUpdates} should be called.
  14020. *
  14021. * @type {boolean}
  14022. * @default
  14023. */
  14024. Tech.prototype.featuresTimeupdateEvents = false;
  14025. /**
  14026. * Boolean indicating wether the `Tech` supports the native `TextTrack`s.
  14027. * This will help us integrate with native `TextTrack`s if the browser supports them.
  14028. *
  14029. * @type {boolean}
  14030. * @default
  14031. */
  14032. Tech.prototype.featuresNativeTextTracks = false;
  14033. /**
  14034. * A functional mixin for techs that want to use the Source Handler pattern.
  14035. * Source handlers are scripts for handling specific formats.
  14036. * The source handler pattern is used for adaptive formats (HLS, DASH) that
  14037. * manually load video data and feed it into a Source Buffer (Media Source Extensions)
  14038. * Example: `Tech.withSourceHandlers.call(MyTech);`
  14039. *
  14040. * @param {Tech} _Tech
  14041. * The tech to add source handler functions to.
  14042. *
  14043. * @mixes Tech~SourceHandlerAdditions
  14044. */
  14045. Tech.withSourceHandlers = function (_Tech) {
  14046. /**
  14047. * Register a source handler
  14048. *
  14049. * @param {Function} handler
  14050. * The source handler class
  14051. *
  14052. * @param {number} [index]
  14053. * Register it at the following index
  14054. */
  14055. _Tech.registerSourceHandler = function (handler, index) {
  14056. var handlers = _Tech.sourceHandlers;
  14057. if (!handlers) {
  14058. handlers = _Tech.sourceHandlers = [];
  14059. }
  14060. if (index === undefined) {
  14061. // add to the end of the list
  14062. index = handlers.length;
  14063. }
  14064. handlers.splice(index, 0, handler);
  14065. };
  14066. /**
  14067. * Check if the tech can support the given type. Also checks the
  14068. * Techs sourceHandlers.
  14069. *
  14070. * @param {string} type
  14071. * The mimetype to check.
  14072. *
  14073. * @return {string}
  14074. * 'probably', 'maybe', or '' (empty string)
  14075. */
  14076. _Tech.canPlayType = function (type) {
  14077. var handlers = _Tech.sourceHandlers || [];
  14078. var can = void 0;
  14079. for (var i = 0; i < handlers.length; i++) {
  14080. can = handlers[i].canPlayType(type);
  14081. if (can) {
  14082. return can;
  14083. }
  14084. }
  14085. return '';
  14086. };
  14087. /**
  14088. * Returns the first source handler that supports the source.
  14089. *
  14090. * TODO: Answer question: should 'probably' be prioritized over 'maybe'
  14091. *
  14092. * @param {Tech~SourceObject} source
  14093. * The source object
  14094. *
  14095. * @param {Object} options
  14096. * The options passed to the tech
  14097. *
  14098. * @return {SourceHandler|null}
  14099. * The first source handler that supports the source or null if
  14100. * no SourceHandler supports the source
  14101. */
  14102. _Tech.selectSourceHandler = function (source, options) {
  14103. var handlers = _Tech.sourceHandlers || [];
  14104. var can = void 0;
  14105. for (var i = 0; i < handlers.length; i++) {
  14106. can = handlers[i].canHandleSource(source, options);
  14107. if (can) {
  14108. return handlers[i];
  14109. }
  14110. }
  14111. return null;
  14112. };
  14113. /**
  14114. * Check if the tech can support the given source.
  14115. *
  14116. * @param {Tech~SourceObject} srcObj
  14117. * The source object
  14118. *
  14119. * @param {Object} options
  14120. * The options passed to the tech
  14121. *
  14122. * @return {string}
  14123. * 'probably', 'maybe', or '' (empty string)
  14124. */
  14125. _Tech.canPlaySource = function (srcObj, options) {
  14126. var sh = _Tech.selectSourceHandler(srcObj, options);
  14127. if (sh) {
  14128. return sh.canHandleSource(srcObj, options);
  14129. }
  14130. return '';
  14131. };
  14132. /**
  14133. * When using a source handler, prefer its implementation of
  14134. * any function normally provided by the tech.
  14135. */
  14136. var deferrable = ['seekable', 'duration'];
  14137. /**
  14138. * A wrapper around {@link Tech#seekable} that will call a `SourceHandler`s seekable
  14139. * function if it exists, with a fallback to the Techs seekable function.
  14140. *
  14141. * @method _Tech.seekable
  14142. */
  14143. /**
  14144. * A wrapper around {@link Tech#duration} that will call a `SourceHandler`s duration
  14145. * function if it exists, otherwise it will fallback to the techs duration function.
  14146. *
  14147. * @method _Tech.duration
  14148. */
  14149. deferrable.forEach(function (fnName) {
  14150. var originalFn = this[fnName];
  14151. if (typeof originalFn !== 'function') {
  14152. return;
  14153. }
  14154. this[fnName] = function () {
  14155. if (this.sourceHandler_ && this.sourceHandler_[fnName]) {
  14156. return this.sourceHandler_[fnName].apply(this.sourceHandler_, arguments);
  14157. }
  14158. return originalFn.apply(this, arguments);
  14159. };
  14160. }, _Tech.prototype);
  14161. /**
  14162. * Create a function for setting the source using a source object
  14163. * and source handlers.
  14164. * Should never be called unless a source handler was found.
  14165. *
  14166. * @param {Tech~SourceObject} source
  14167. * A source object with src and type keys
  14168. *
  14169. * @return {Tech}
  14170. * Returns itself; this method is chainable
  14171. */
  14172. _Tech.prototype.setSource = function (source) {
  14173. var sh = _Tech.selectSourceHandler(source, this.options_);
  14174. if (!sh) {
  14175. // Fall back to a native source hander when unsupported sources are
  14176. // deliberately set
  14177. if (_Tech.nativeSourceHandler) {
  14178. sh = _Tech.nativeSourceHandler;
  14179. } else {
  14180. _log2['default'].error('No source hander found for the current source.');
  14181. }
  14182. }
  14183. // Dispose any existing source handler
  14184. this.disposeSourceHandler();
  14185. this.off('dispose', this.disposeSourceHandler);
  14186. if (sh !== _Tech.nativeSourceHandler) {
  14187. this.currentSource_ = source;
  14188. // Catch if someone replaced the src without calling setSource.
  14189. // If they do, set currentSource_ to null and dispose our source handler.
  14190. this.off(this.el_, 'loadstart', _Tech.prototype.firstLoadStartListener_);
  14191. this.off(this.el_, 'loadstart', _Tech.prototype.successiveLoadStartListener_);
  14192. this.one(this.el_, 'loadstart', _Tech.prototype.firstLoadStartListener_);
  14193. }
  14194. this.sourceHandler_ = sh.handleSource(source, this, this.options_);
  14195. this.on('dispose', this.disposeSourceHandler);
  14196. return this;
  14197. };
  14198. /**
  14199. * Called once for the first loadstart of a video.
  14200. *
  14201. * @listens Tech#loadstart
  14202. */
  14203. _Tech.prototype.firstLoadStartListener_ = function () {
  14204. this.one(this.el_, 'loadstart', _Tech.prototype.successiveLoadStartListener_);
  14205. };
  14206. // On successive loadstarts when setSource has not been called again
  14207. /**
  14208. * Called after the first loadstart for a video occurs.
  14209. *
  14210. * @listens Tech#loadstart
  14211. */
  14212. _Tech.prototype.successiveLoadStartListener_ = function () {
  14213. this.disposeSourceHandler();
  14214. this.one(this.el_, 'loadstart', _Tech.prototype.successiveLoadStartListener_);
  14215. };
  14216. /**
  14217. * Clean up any existing SourceHandlers and listeners when the Tech is disposed.
  14218. *
  14219. * @listens Tech#dispose
  14220. */
  14221. _Tech.prototype.disposeSourceHandler = function () {
  14222. // if we have a source and get another one
  14223. // then we are loading something new
  14224. // than clear all of our current tracks
  14225. if (this.currentSource_) {
  14226. this.clearTracks(['audio', 'video']);
  14227. this.currentSource_ = null;
  14228. }
  14229. // always clean up auto-text tracks
  14230. this.cleanupAutoTextTracks();
  14231. if (this.sourceHandler_) {
  14232. this.off(this.el_, 'loadstart', _Tech.prototype.firstLoadStartListener_);
  14233. this.off(this.el_, 'loadstart', _Tech.prototype.successiveLoadStartListener_);
  14234. if (this.sourceHandler_.dispose) {
  14235. this.sourceHandler_.dispose();
  14236. }
  14237. this.sourceHandler_ = null;
  14238. }
  14239. };
  14240. };
  14241. _component2['default'].registerComponent('Tech', Tech);
  14242. // Old name for Tech
  14243. // @deprecated
  14244. _component2['default'].registerComponent('MediaTechController', Tech);
  14245. Tech.registerTech('Tech', Tech);
  14246. exports['default'] = Tech;
  14247. },{"46":46,"5":5,"63":63,"65":65,"66":66,"70":70,"72":72,"76":76,"79":79,"83":83,"86":86,"87":87,"88":88,"90":90,"94":94,"95":95,"99":99}],63:[function(_dereq_,module,exports){
  14248. 'use strict';
  14249. exports.__esModule = true;
  14250. var _trackList = _dereq_(74);
  14251. var _trackList2 = _interopRequireDefault(_trackList);
  14252. var _browser = _dereq_(78);
  14253. var browser = _interopRequireWildcard(_browser);
  14254. var _document = _dereq_(94);
  14255. var _document2 = _interopRequireDefault(_document);
  14256. 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; } }
  14257. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  14258. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  14259. 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; }
  14260. 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; } /**
  14261. * @file audio-track-list.js
  14262. */
  14263. /**
  14264. * Anywhere we call this function we diverge from the spec
  14265. * as we only support one enabled audiotrack at a time
  14266. *
  14267. * @param {AudioTrackList} list
  14268. * list to work on
  14269. *
  14270. * @param {AudioTrack} track
  14271. * The track to skip
  14272. *
  14273. * @private
  14274. */
  14275. var disableOthers = function disableOthers(list, track) {
  14276. for (var i = 0; i < list.length; i++) {
  14277. if (track.id === list[i].id) {
  14278. continue;
  14279. }
  14280. // another audio track is enabled, disable it
  14281. list[i].enabled = false;
  14282. }
  14283. };
  14284. /**
  14285. * The current list of {@link AudioTrack} for a media file.
  14286. *
  14287. * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#audiotracklist}
  14288. * @extends TrackList
  14289. */
  14290. var AudioTrackList = function (_TrackList) {
  14291. _inherits(AudioTrackList, _TrackList);
  14292. /**
  14293. * Create an instance of this class.
  14294. *
  14295. * @param {AudioTrack[]} [tracks=[]]
  14296. * A list of `AudioTrack` to instantiate the list with.
  14297. */
  14298. function AudioTrackList() {
  14299. var _this, _ret;
  14300. var tracks = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
  14301. _classCallCheck(this, AudioTrackList);
  14302. var list = void 0;
  14303. // make sure only 1 track is enabled
  14304. // sorted from last index to first index
  14305. for (var i = tracks.length - 1; i >= 0; i--) {
  14306. if (tracks[i].enabled) {
  14307. disableOthers(tracks, tracks[i]);
  14308. break;
  14309. }
  14310. }
  14311. // IE8 forces us to implement inheritance ourselves
  14312. // as it does not support Object.defineProperty properly
  14313. if (browser.IS_IE8) {
  14314. list = _document2['default'].createElement('custom');
  14315. for (var prop in _trackList2['default'].prototype) {
  14316. if (prop !== 'constructor') {
  14317. list[prop] = _trackList2['default'].prototype[prop];
  14318. }
  14319. }
  14320. for (var _prop in AudioTrackList.prototype) {
  14321. if (_prop !== 'constructor') {
  14322. list[_prop] = AudioTrackList.prototype[_prop];
  14323. }
  14324. }
  14325. }
  14326. list = (_this = _possibleConstructorReturn(this, _TrackList.call(this, tracks, list)), _this);
  14327. list.changing_ = false;
  14328. return _ret = list, _possibleConstructorReturn(_this, _ret);
  14329. }
  14330. /**
  14331. * Add an {@link AudioTrack} to the `AudioTrackList`.
  14332. *
  14333. * @param {AudioTrack} track
  14334. * The AudioTrack to add to the list
  14335. *
  14336. * @fires Track#addtrack
  14337. * @private
  14338. */
  14339. AudioTrackList.prototype.addTrack_ = function addTrack_(track) {
  14340. var _this2 = this;
  14341. if (track.enabled) {
  14342. disableOthers(this, track);
  14343. }
  14344. _TrackList.prototype.addTrack_.call(this, track);
  14345. // native tracks don't have this
  14346. if (!track.addEventListener) {
  14347. return;
  14348. }
  14349. /**
  14350. * @listens AudioTrack#enabledchange
  14351. * @fires TrackList#change
  14352. */
  14353. track.addEventListener('enabledchange', function () {
  14354. // when we are disabling other tracks (since we don't support
  14355. // more than one track at a time) we will set changing_
  14356. // to true so that we don't trigger additional change events
  14357. if (_this2.changing_) {
  14358. return;
  14359. }
  14360. _this2.changing_ = true;
  14361. disableOthers(_this2, track);
  14362. _this2.changing_ = false;
  14363. _this2.trigger('change');
  14364. });
  14365. };
  14366. /**
  14367. * Add an {@link AudioTrack} to the `AudioTrackList`.
  14368. *
  14369. * @param {AudioTrack} track
  14370. * The AudioTrack to add to the list
  14371. *
  14372. * @fires Track#addtrack
  14373. */
  14374. AudioTrackList.prototype.addTrack = function addTrack(track) {
  14375. this.addTrack_(track);
  14376. };
  14377. /**
  14378. * Remove an {@link AudioTrack} from the `AudioTrackList`.
  14379. *
  14380. * @param {AudioTrack} track
  14381. * The AudioTrack to remove from the list
  14382. *
  14383. * @fires Track#removetrack
  14384. */
  14385. AudioTrackList.prototype.removeTrack = function removeTrack(track) {
  14386. _TrackList.prototype.removeTrack_.call(this, track);
  14387. };
  14388. return AudioTrackList;
  14389. }(_trackList2['default']);
  14390. exports['default'] = AudioTrackList;
  14391. },{"74":74,"78":78,"94":94}],64:[function(_dereq_,module,exports){
  14392. 'use strict';
  14393. exports.__esModule = true;
  14394. var _trackEnums = _dereq_(73);
  14395. var _track = _dereq_(75);
  14396. var _track2 = _interopRequireDefault(_track);
  14397. var _mergeOptions = _dereq_(87);
  14398. var _mergeOptions2 = _interopRequireDefault(_mergeOptions);
  14399. var _browser = _dereq_(78);
  14400. var browser = _interopRequireWildcard(_browser);
  14401. 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; } }
  14402. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  14403. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  14404. 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; }
  14405. 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; }
  14406. /**
  14407. * A representation of a single `AudioTrack`. If it is part of an {@link AudioTrackList}
  14408. * only one `AudioTrack` in the list will be enabled at a time.
  14409. *
  14410. * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#audiotrack}
  14411. * @extends Track
  14412. */
  14413. var AudioTrack = function (_Track) {
  14414. _inherits(AudioTrack, _Track);
  14415. /**
  14416. * Create an instance of this class.
  14417. *
  14418. * @param {Object} [options={}]
  14419. * Object of option names and values
  14420. *
  14421. * @param {AudioTrack~Kind} [options.kind='']
  14422. * A valid audio track kind
  14423. *
  14424. * @param {string} [options.id='vjs_track_' + Guid.newGUID()]
  14425. * A unique id for this AudioTrack.
  14426. *
  14427. * @param {string} [options.label='']
  14428. * The menu label for this track.
  14429. *
  14430. * @param {string} [options.language='']
  14431. * A valid two character language code.
  14432. *
  14433. * @param {boolean} [options.enabled]
  14434. * If this track is the one that is currently playing. If this track is part of
  14435. * an {@link AudioTrackList}, only one {@link AudioTrack} will be enabled.
  14436. */
  14437. function AudioTrack() {
  14438. var _this, _ret;
  14439. var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  14440. _classCallCheck(this, AudioTrack);
  14441. var settings = (0, _mergeOptions2['default'])(options, {
  14442. kind: _trackEnums.AudioTrackKind[options.kind] || ''
  14443. });
  14444. // on IE8 this will be a document element
  14445. // for every other browser this will be a normal object
  14446. var track = (_this = _possibleConstructorReturn(this, _Track.call(this, settings)), _this);
  14447. var enabled = false;
  14448. if (browser.IS_IE8) {
  14449. for (var prop in AudioTrack.prototype) {
  14450. if (prop !== 'constructor') {
  14451. track[prop] = AudioTrack.prototype[prop];
  14452. }
  14453. }
  14454. }
  14455. /**
  14456. * @member {boolean} enabled
  14457. * If this `AudioTrack` is enabled or not. When setting this will
  14458. * fire {@link AudioTrack#enabledchange} if the state of enabled is changed.
  14459. *
  14460. * @fires VideoTrack#selectedchange
  14461. */
  14462. Object.defineProperty(track, 'enabled', {
  14463. get: function get() {
  14464. return enabled;
  14465. },
  14466. set: function set(newEnabled) {
  14467. // an invalid or unchanged value
  14468. if (typeof newEnabled !== 'boolean' || newEnabled === enabled) {
  14469. return;
  14470. }
  14471. enabled = newEnabled;
  14472. /**
  14473. * An event that fires when enabled changes on this track. This allows
  14474. * the AudioTrackList that holds this track to act accordingly.
  14475. *
  14476. * > Note: This is not part of the spec! Native tracks will do
  14477. * this internally without an event.
  14478. *
  14479. * @event AudioTrack#enabledchange
  14480. * @type {EventTarget~Event}
  14481. */
  14482. this.trigger('enabledchange');
  14483. }
  14484. });
  14485. // if the user sets this track to selected then
  14486. // set selected to that true value otherwise
  14487. // we keep it false
  14488. if (settings.enabled) {
  14489. track.enabled = settings.enabled;
  14490. }
  14491. track.loaded_ = true;
  14492. return _ret = track, _possibleConstructorReturn(_this, _ret);
  14493. }
  14494. return AudioTrack;
  14495. }(_track2['default']);
  14496. exports['default'] = AudioTrack;
  14497. },{"73":73,"75":75,"78":78,"87":87}],65:[function(_dereq_,module,exports){
  14498. 'use strict';
  14499. exports.__esModule = true;
  14500. var _browser = _dereq_(78);
  14501. var browser = _interopRequireWildcard(_browser);
  14502. var _document = _dereq_(94);
  14503. var _document2 = _interopRequireDefault(_document);
  14504. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  14505. 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; } }
  14506. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } /**
  14507. * @file html-track-element-list.js
  14508. */
  14509. /**
  14510. * The current list of {@link HtmlTrackElement}s.
  14511. */
  14512. var HtmlTrackElementList = function () {
  14513. /**
  14514. * Create an instance of this class.
  14515. *
  14516. * @param {HtmlTrackElement[]} [tracks=[]]
  14517. * A list of `HtmlTrackElement` to instantiate the list with.
  14518. */
  14519. function HtmlTrackElementList() {
  14520. var trackElements = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
  14521. _classCallCheck(this, HtmlTrackElementList);
  14522. var list = this; // eslint-disable-line
  14523. if (browser.IS_IE8) {
  14524. list = _document2['default'].createElement('custom');
  14525. for (var prop in HtmlTrackElementList.prototype) {
  14526. if (prop !== 'constructor') {
  14527. list[prop] = HtmlTrackElementList.prototype[prop];
  14528. }
  14529. }
  14530. }
  14531. list.trackElements_ = [];
  14532. /**
  14533. * @member {number} length
  14534. * The current number of `Track`s in the this Trackist.
  14535. */
  14536. Object.defineProperty(list, 'length', {
  14537. get: function get() {
  14538. return this.trackElements_.length;
  14539. }
  14540. });
  14541. for (var i = 0, length = trackElements.length; i < length; i++) {
  14542. list.addTrackElement_(trackElements[i]);
  14543. }
  14544. if (browser.IS_IE8) {
  14545. return list;
  14546. }
  14547. }
  14548. /**
  14549. * Add an {@link HtmlTrackElement} to the `HtmlTrackElementList`
  14550. *
  14551. * @param {HtmlTrackElement} trackElement
  14552. * The track element to add to the list.
  14553. *
  14554. * @private
  14555. */
  14556. HtmlTrackElementList.prototype.addTrackElement_ = function addTrackElement_(trackElement) {
  14557. var index = this.trackElements_.length;
  14558. if (!('' + index in this)) {
  14559. Object.defineProperty(this, index, {
  14560. get: function get() {
  14561. return this.trackElements_[index];
  14562. }
  14563. });
  14564. }
  14565. // Do not add duplicate elements
  14566. if (this.trackElements_.indexOf(trackElement) === -1) {
  14567. this.trackElements_.push(trackElement);
  14568. }
  14569. };
  14570. /**
  14571. * Get an {@link HtmlTrackElement} from the `HtmlTrackElementList` given an
  14572. * {@link TextTrack}.
  14573. *
  14574. * @param {TextTrack} track
  14575. * The track associated with a track element.
  14576. *
  14577. * @return {HtmlTrackElement|undefined}
  14578. * The track element that was found or undefined.
  14579. *
  14580. * @private
  14581. */
  14582. HtmlTrackElementList.prototype.getTrackElementByTrack_ = function getTrackElementByTrack_(track) {
  14583. var trackElement_ = void 0;
  14584. for (var i = 0, length = this.trackElements_.length; i < length; i++) {
  14585. if (track === this.trackElements_[i].track) {
  14586. trackElement_ = this.trackElements_[i];
  14587. break;
  14588. }
  14589. }
  14590. return trackElement_;
  14591. };
  14592. /**
  14593. * Remove a {@link HtmlTrackElement} from the `HtmlTrackElementList`
  14594. *
  14595. * @param {HtmlTrackElement} trackElement
  14596. * The track element to remove from the list.
  14597. *
  14598. * @private
  14599. */
  14600. HtmlTrackElementList.prototype.removeTrackElement_ = function removeTrackElement_(trackElement) {
  14601. for (var i = 0, length = this.trackElements_.length; i < length; i++) {
  14602. if (trackElement === this.trackElements_[i]) {
  14603. this.trackElements_.splice(i, 1);
  14604. break;
  14605. }
  14606. }
  14607. };
  14608. return HtmlTrackElementList;
  14609. }();
  14610. exports['default'] = HtmlTrackElementList;
  14611. },{"78":78,"94":94}],66:[function(_dereq_,module,exports){
  14612. 'use strict';
  14613. exports.__esModule = true;
  14614. var _browser = _dereq_(78);
  14615. var browser = _interopRequireWildcard(_browser);
  14616. var _document = _dereq_(94);
  14617. var _document2 = _interopRequireDefault(_document);
  14618. var _eventTarget = _dereq_(42);
  14619. var _eventTarget2 = _interopRequireDefault(_eventTarget);
  14620. var _textTrack = _dereq_(72);
  14621. var _textTrack2 = _interopRequireDefault(_textTrack);
  14622. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  14623. 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; } }
  14624. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  14625. 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; }
  14626. 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; } /**
  14627. * @file html-track-element.js
  14628. */
  14629. /**
  14630. * @typedef {HTMLTrackElement~ReadyState}
  14631. * @enum {number}
  14632. */
  14633. var NONE = 0;
  14634. var LOADING = 1;
  14635. var LOADED = 2;
  14636. var ERROR = 3;
  14637. /**
  14638. * A single track represented in the DOM.
  14639. *
  14640. * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#htmltrackelement}
  14641. * @extends EventTarget
  14642. */
  14643. var HTMLTrackElement = function (_EventTarget) {
  14644. _inherits(HTMLTrackElement, _EventTarget);
  14645. /**
  14646. * Create an instance of this class.
  14647. *
  14648. * @param {Object} options={}
  14649. * Object of option names and values
  14650. *
  14651. * @param {Tech} options.tech
  14652. * A reference to the tech that owns this HTMLTrackElement.
  14653. *
  14654. * @param {TextTrack~Kind} [options.kind='subtitles']
  14655. * A valid text track kind.
  14656. *
  14657. * @param {TextTrack~Mode} [options.mode='disabled']
  14658. * A valid text track mode.
  14659. *
  14660. * @param {string} [options.id='vjs_track_' + Guid.newGUID()]
  14661. * A unique id for this TextTrack.
  14662. *
  14663. * @param {string} [options.label='']
  14664. * The menu label for this track.
  14665. *
  14666. * @param {string} [options.language='']
  14667. * A valid two character language code.
  14668. *
  14669. * @param {string} [options.srclang='']
  14670. * A valid two character language code. An alternative, but deprioritized
  14671. * vesion of `options.language`
  14672. *
  14673. * @param {string} [options.src]
  14674. * A url to TextTrack cues.
  14675. *
  14676. * @param {boolean} [options.default]
  14677. * If this track should default to on or off.
  14678. */
  14679. function HTMLTrackElement() {
  14680. var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  14681. _classCallCheck(this, HTMLTrackElement);
  14682. var _this = _possibleConstructorReturn(this, _EventTarget.call(this));
  14683. var readyState = void 0;
  14684. var trackElement = _this; // eslint-disable-line
  14685. if (browser.IS_IE8) {
  14686. trackElement = _document2['default'].createElement('custom');
  14687. for (var prop in HTMLTrackElement.prototype) {
  14688. if (prop !== 'constructor') {
  14689. trackElement[prop] = HTMLTrackElement.prototype[prop];
  14690. }
  14691. }
  14692. }
  14693. var track = new _textTrack2['default'](options);
  14694. trackElement.kind = track.kind;
  14695. trackElement.src = track.src;
  14696. trackElement.srclang = track.language;
  14697. trackElement.label = track.label;
  14698. trackElement['default'] = track['default'];
  14699. /**
  14700. * @member {HTMLTrackElement~ReadyState} readyState
  14701. * The current ready state of the track element.
  14702. */
  14703. Object.defineProperty(trackElement, 'readyState', {
  14704. get: function get() {
  14705. return readyState;
  14706. }
  14707. });
  14708. /**
  14709. * @member {TextTrack} track
  14710. * The underlying TextTrack object.
  14711. */
  14712. Object.defineProperty(trackElement, 'track', {
  14713. get: function get() {
  14714. return track;
  14715. }
  14716. });
  14717. readyState = NONE;
  14718. /**
  14719. * @listens TextTrack#loadeddata
  14720. * @fires HTMLTrackElement#load
  14721. */
  14722. track.addEventListener('loadeddata', function () {
  14723. readyState = LOADED;
  14724. trackElement.trigger({
  14725. type: 'load',
  14726. target: trackElement
  14727. });
  14728. });
  14729. if (browser.IS_IE8) {
  14730. var _ret;
  14731. return _ret = trackElement, _possibleConstructorReturn(_this, _ret);
  14732. }
  14733. return _this;
  14734. }
  14735. return HTMLTrackElement;
  14736. }(_eventTarget2['default']);
  14737. HTMLTrackElement.prototype.allowedEvents_ = {
  14738. load: 'load'
  14739. };
  14740. HTMLTrackElement.NONE = NONE;
  14741. HTMLTrackElement.LOADING = LOADING;
  14742. HTMLTrackElement.LOADED = LOADED;
  14743. HTMLTrackElement.ERROR = ERROR;
  14744. exports['default'] = HTMLTrackElement;
  14745. },{"42":42,"72":72,"78":78,"94":94}],67:[function(_dereq_,module,exports){
  14746. 'use strict';
  14747. exports.__esModule = true;
  14748. var _browser = _dereq_(78);
  14749. var browser = _interopRequireWildcard(_browser);
  14750. var _document = _dereq_(94);
  14751. var _document2 = _interopRequireDefault(_document);
  14752. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  14753. 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; } }
  14754. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } /**
  14755. * @file text-track-cue-list.js
  14756. */
  14757. /**
  14758. * @typedef {Object} TextTrackCue
  14759. *
  14760. * @property {string} id
  14761. * The unique id for this text track cue
  14762. *
  14763. * @property {number} startTime
  14764. * The start time for this text track cue
  14765. *
  14766. * @property {number} endTime
  14767. * The end time for this text track cue
  14768. *
  14769. * @property {boolean} pauseOnExit
  14770. * Pause when the end time is reached if true.
  14771. *
  14772. * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#texttrackcue}
  14773. */
  14774. /**
  14775. * A List of TextTrackCues.
  14776. *
  14777. * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#texttrackcuelist}
  14778. */
  14779. var TextTrackCueList = function () {
  14780. /**
  14781. * Create an instance of this class..
  14782. *
  14783. * @param {Array} cues
  14784. * A list of cues to be initialized with
  14785. */
  14786. function TextTrackCueList(cues) {
  14787. _classCallCheck(this, TextTrackCueList);
  14788. var list = this; // eslint-disable-line
  14789. if (browser.IS_IE8) {
  14790. list = _document2['default'].createElement('custom');
  14791. for (var prop in TextTrackCueList.prototype) {
  14792. if (prop !== 'constructor') {
  14793. list[prop] = TextTrackCueList.prototype[prop];
  14794. }
  14795. }
  14796. }
  14797. TextTrackCueList.prototype.setCues_.call(list, cues);
  14798. /**
  14799. * @member {number} length
  14800. * The current number of `TextTrackCue`s in the TextTrackCueList.
  14801. */
  14802. Object.defineProperty(list, 'length', {
  14803. get: function get() {
  14804. return this.length_;
  14805. }
  14806. });
  14807. if (browser.IS_IE8) {
  14808. return list;
  14809. }
  14810. }
  14811. /**
  14812. * A setter for cues in this list. Creates getters
  14813. * an an index for the cues.
  14814. *
  14815. * @param {Array} cues
  14816. * An array of cues to set
  14817. *
  14818. * @private
  14819. */
  14820. TextTrackCueList.prototype.setCues_ = function setCues_(cues) {
  14821. var oldLength = this.length || 0;
  14822. var i = 0;
  14823. var l = cues.length;
  14824. this.cues_ = cues;
  14825. this.length_ = cues.length;
  14826. var defineProp = function defineProp(index) {
  14827. if (!('' + index in this)) {
  14828. Object.defineProperty(this, '' + index, {
  14829. get: function get() {
  14830. return this.cues_[index];
  14831. }
  14832. });
  14833. }
  14834. };
  14835. if (oldLength < l) {
  14836. i = oldLength;
  14837. for (; i < l; i++) {
  14838. defineProp.call(this, i);
  14839. }
  14840. }
  14841. };
  14842. /**
  14843. * Get a `TextTrackCue` that is currently in the `TextTrackCueList` by id.
  14844. *
  14845. * @param {string} id
  14846. * The id of the cue that should be searched for.
  14847. *
  14848. * @return {TextTrackCue|null}
  14849. * A single cue or null if none was found.
  14850. */
  14851. TextTrackCueList.prototype.getCueById = function getCueById(id) {
  14852. var result = null;
  14853. for (var i = 0, l = this.length; i < l; i++) {
  14854. var cue = this[i];
  14855. if (cue.id === id) {
  14856. result = cue;
  14857. break;
  14858. }
  14859. }
  14860. return result;
  14861. };
  14862. return TextTrackCueList;
  14863. }();
  14864. exports['default'] = TextTrackCueList;
  14865. },{"78":78,"94":94}],68:[function(_dereq_,module,exports){
  14866. 'use strict';
  14867. exports.__esModule = true;
  14868. var _component = _dereq_(5);
  14869. var _component2 = _interopRequireDefault(_component);
  14870. var _fn = _dereq_(83);
  14871. var Fn = _interopRequireWildcard(_fn);
  14872. var _window = _dereq_(95);
  14873. var _window2 = _interopRequireDefault(_window);
  14874. 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; } }
  14875. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  14876. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  14877. 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; }
  14878. 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; } /**
  14879. * @file text-track-display.js
  14880. */
  14881. var darkGray = '#222';
  14882. var lightGray = '#ccc';
  14883. var fontMap = {
  14884. monospace: 'monospace',
  14885. sansSerif: 'sans-serif',
  14886. serif: 'serif',
  14887. monospaceSansSerif: '"Andale Mono", "Lucida Console", monospace',
  14888. monospaceSerif: '"Courier New", monospace',
  14889. proportionalSansSerif: 'sans-serif',
  14890. proportionalSerif: 'serif',
  14891. casual: '"Comic Sans MS", Impact, fantasy',
  14892. script: '"Monotype Corsiva", cursive',
  14893. smallcaps: '"Andale Mono", "Lucida Console", monospace, sans-serif'
  14894. };
  14895. /**
  14896. * Construct an rgba color from a given hex color code.
  14897. *
  14898. * @param {number} color
  14899. * Hex number for color, like #f0e.
  14900. *
  14901. * @param {number} opacity
  14902. * Value for opacity, 0.0 - 1.0.
  14903. *
  14904. * @return {string}
  14905. * The rgba color that was created, like 'rgba(255, 0, 0, 0.3)'.
  14906. *
  14907. * @private
  14908. */
  14909. function constructColor(color, opacity) {
  14910. return 'rgba(' +
  14911. // color looks like "#f0e"
  14912. parseInt(color[1] + color[1], 16) + ',' + parseInt(color[2] + color[2], 16) + ',' + parseInt(color[3] + color[3], 16) + ',' + opacity + ')';
  14913. }
  14914. /**
  14915. * Try to update the style of a DOM element. Some style changes will throw an error,
  14916. * particularly in IE8. Those should be noops.
  14917. *
  14918. * @param {Element} el
  14919. * The DOM element to be styled.
  14920. *
  14921. * @param {string} style
  14922. * The CSS property on the element that should be styled.
  14923. *
  14924. * @param {string} rule
  14925. * The style rule that should be applied to the property.
  14926. */
  14927. function tryUpdateStyle(el, style, rule) {
  14928. try {
  14929. el.style[style] = rule;
  14930. } catch (e) {
  14931. // Satisfies linter.
  14932. return;
  14933. }
  14934. }
  14935. /**
  14936. * The component for displaying text track cues.
  14937. *
  14938. * @extends Component
  14939. */
  14940. var TextTrackDisplay = function (_Component) {
  14941. _inherits(TextTrackDisplay, _Component);
  14942. /**
  14943. * Creates an instance of this class.
  14944. *
  14945. * @param {Player} player
  14946. * The `Player` that this class should be attached to.
  14947. *
  14948. * @param {Object} [options]
  14949. * The key/value store of player options.
  14950. *
  14951. * @param {Component~ReadyCallback} [ready]
  14952. * The function to call when `TextTrackDisplay` is ready.
  14953. */
  14954. function TextTrackDisplay(player, options, ready) {
  14955. _classCallCheck(this, TextTrackDisplay);
  14956. var _this = _possibleConstructorReturn(this, _Component.call(this, player, options, ready));
  14957. player.on('loadstart', Fn.bind(_this, _this.toggleDisplay));
  14958. player.on('texttrackchange', Fn.bind(_this, _this.updateDisplay));
  14959. // This used to be called during player init, but was causing an error
  14960. // if a track should show by default and the display hadn't loaded yet.
  14961. // Should probably be moved to an external track loader when we support
  14962. // tracks that don't need a display.
  14963. player.ready(Fn.bind(_this, function () {
  14964. if (player.tech_ && player.tech_.featuresNativeTextTracks) {
  14965. this.hide();
  14966. return;
  14967. }
  14968. player.on('fullscreenchange', Fn.bind(this, this.updateDisplay));
  14969. var tracks = this.options_.playerOptions.tracks || [];
  14970. for (var i = 0; i < tracks.length; i++) {
  14971. this.player_.addRemoteTextTrack(tracks[i], true);
  14972. }
  14973. var modes = { captions: 1, subtitles: 1 };
  14974. var trackList = this.player_.textTracks();
  14975. var firstDesc = void 0;
  14976. var firstCaptions = void 0;
  14977. if (trackList) {
  14978. for (var _i = 0; _i < trackList.length; _i++) {
  14979. var track = trackList[_i];
  14980. if (track['default']) {
  14981. if (track.kind === 'descriptions' && !firstDesc) {
  14982. firstDesc = track;
  14983. } else if (track.kind in modes && !firstCaptions) {
  14984. firstCaptions = track;
  14985. }
  14986. }
  14987. }
  14988. // We want to show the first default track but captions and subtitles
  14989. // take precedence over descriptions.
  14990. // So, display the first default captions or subtitles track
  14991. // and otherwise the first default descriptions track.
  14992. if (firstCaptions) {
  14993. firstCaptions.mode = 'showing';
  14994. } else if (firstDesc) {
  14995. firstDesc.mode = 'showing';
  14996. }
  14997. }
  14998. }));
  14999. return _this;
  15000. }
  15001. /**
  15002. * Turn display of {@link TextTrack}'s from the current state into the other state.
  15003. * There are only two states:
  15004. * - 'shown'
  15005. * - 'hidden'
  15006. *
  15007. * @listens Player#loadstart
  15008. */
  15009. TextTrackDisplay.prototype.toggleDisplay = function toggleDisplay() {
  15010. if (this.player_.tech_ && this.player_.tech_.featuresNativeTextTracks) {
  15011. this.hide();
  15012. } else {
  15013. this.show();
  15014. }
  15015. };
  15016. /**
  15017. * Create the {@link Component}'s DOM element.
  15018. *
  15019. * @return {Element}
  15020. * The element that was created.
  15021. */
  15022. TextTrackDisplay.prototype.createEl = function createEl() {
  15023. return _Component.prototype.createEl.call(this, 'div', {
  15024. className: 'vjs-text-track-display'
  15025. }, {
  15026. 'aria-live': 'off',
  15027. 'aria-atomic': 'true'
  15028. });
  15029. };
  15030. /**
  15031. * Clear all displayed {@link TextTrack}s.
  15032. */
  15033. TextTrackDisplay.prototype.clearDisplay = function clearDisplay() {
  15034. if (typeof _window2['default'].WebVTT === 'function') {
  15035. _window2['default'].WebVTT.processCues(_window2['default'], [], this.el_);
  15036. }
  15037. };
  15038. /**
  15039. * Update the displayed TextTrack when a either a {@link Player#texttrackchange} or
  15040. * a {@link Player#fullscreenchange} is fired.
  15041. *
  15042. * @listens Player#texttrackchange
  15043. * @listens Player#fullscreenchange
  15044. */
  15045. TextTrackDisplay.prototype.updateDisplay = function updateDisplay() {
  15046. var tracks = this.player_.textTracks();
  15047. this.clearDisplay();
  15048. if (!tracks) {
  15049. return;
  15050. }
  15051. // Track display prioritization model: if multiple tracks are 'showing',
  15052. // display the first 'subtitles' or 'captions' track which is 'showing',
  15053. // otherwise display the first 'descriptions' track which is 'showing'
  15054. var descriptionsTrack = null;
  15055. var captionsSubtitlesTrack = null;
  15056. var i = tracks.length;
  15057. while (i--) {
  15058. var track = tracks[i];
  15059. if (track.mode === 'showing') {
  15060. if (track.kind === 'descriptions') {
  15061. descriptionsTrack = track;
  15062. } else {
  15063. captionsSubtitlesTrack = track;
  15064. }
  15065. }
  15066. }
  15067. if (captionsSubtitlesTrack) {
  15068. if (this.getAttribute('aria-live') !== 'off') {
  15069. this.setAttribute('aria-live', 'off');
  15070. }
  15071. this.updateForTrack(captionsSubtitlesTrack);
  15072. } else if (descriptionsTrack) {
  15073. if (this.getAttribute('aria-live') !== 'assertive') {
  15074. this.setAttribute('aria-live', 'assertive');
  15075. }
  15076. this.updateForTrack(descriptionsTrack);
  15077. }
  15078. };
  15079. /**
  15080. * Add an {@link Texttrack} to to the {@link Tech}s {@link TextTrackList}.
  15081. *
  15082. * @param {TextTrack} track
  15083. * Text track object to be added to the list.
  15084. */
  15085. TextTrackDisplay.prototype.updateForTrack = function updateForTrack(track) {
  15086. if (typeof _window2['default'].WebVTT !== 'function' || !track.activeCues) {
  15087. return;
  15088. }
  15089. var overrides = this.player_.textTrackSettings.getValues();
  15090. var cues = [];
  15091. for (var _i2 = 0; _i2 < track.activeCues.length; _i2++) {
  15092. cues.push(track.activeCues[_i2]);
  15093. }
  15094. _window2['default'].WebVTT.processCues(_window2['default'], cues, this.el_);
  15095. var i = cues.length;
  15096. while (i--) {
  15097. var cue = cues[i];
  15098. if (!cue) {
  15099. continue;
  15100. }
  15101. var cueDiv = cue.displayState;
  15102. if (overrides.color) {
  15103. cueDiv.firstChild.style.color = overrides.color;
  15104. }
  15105. if (overrides.textOpacity) {
  15106. tryUpdateStyle(cueDiv.firstChild, 'color', constructColor(overrides.color || '#fff', overrides.textOpacity));
  15107. }
  15108. if (overrides.backgroundColor) {
  15109. cueDiv.firstChild.style.backgroundColor = overrides.backgroundColor;
  15110. }
  15111. if (overrides.backgroundOpacity) {
  15112. tryUpdateStyle(cueDiv.firstChild, 'backgroundColor', constructColor(overrides.backgroundColor || '#000', overrides.backgroundOpacity));
  15113. }
  15114. if (overrides.windowColor) {
  15115. if (overrides.windowOpacity) {
  15116. tryUpdateStyle(cueDiv, 'backgroundColor', constructColor(overrides.windowColor, overrides.windowOpacity));
  15117. } else {
  15118. cueDiv.style.backgroundColor = overrides.windowColor;
  15119. }
  15120. }
  15121. if (overrides.edgeStyle) {
  15122. if (overrides.edgeStyle === 'dropshadow') {
  15123. cueDiv.firstChild.style.textShadow = '2px 2px 3px ' + darkGray + ', 2px 2px 4px ' + darkGray + ', 2px 2px 5px ' + darkGray;
  15124. } else if (overrides.edgeStyle === 'raised') {
  15125. cueDiv.firstChild.style.textShadow = '1px 1px ' + darkGray + ', 2px 2px ' + darkGray + ', 3px 3px ' + darkGray;
  15126. } else if (overrides.edgeStyle === 'depressed') {
  15127. cueDiv.firstChild.style.textShadow = '1px 1px ' + lightGray + ', 0 1px ' + lightGray + ', -1px -1px ' + darkGray + ', 0 -1px ' + darkGray;
  15128. } else if (overrides.edgeStyle === 'uniform') {
  15129. cueDiv.firstChild.style.textShadow = '0 0 4px ' + darkGray + ', 0 0 4px ' + darkGray + ', 0 0 4px ' + darkGray + ', 0 0 4px ' + darkGray;
  15130. }
  15131. }
  15132. if (overrides.fontPercent && overrides.fontPercent !== 1) {
  15133. var fontSize = _window2['default'].parseFloat(cueDiv.style.fontSize);
  15134. cueDiv.style.fontSize = fontSize * overrides.fontPercent + 'px';
  15135. cueDiv.style.height = 'auto';
  15136. cueDiv.style.top = 'auto';
  15137. cueDiv.style.bottom = '2px';
  15138. }
  15139. if (overrides.fontFamily && overrides.fontFamily !== 'default') {
  15140. if (overrides.fontFamily === 'small-caps') {
  15141. cueDiv.firstChild.style.fontVariant = 'small-caps';
  15142. } else {
  15143. cueDiv.firstChild.style.fontFamily = fontMap[overrides.fontFamily];
  15144. }
  15145. }
  15146. }
  15147. };
  15148. return TextTrackDisplay;
  15149. }(_component2['default']);
  15150. _component2['default'].registerComponent('TextTrackDisplay', TextTrackDisplay);
  15151. exports['default'] = TextTrackDisplay;
  15152. },{"5":5,"83":83,"95":95}],69:[function(_dereq_,module,exports){
  15153. 'use strict';
  15154. exports.__esModule = true;
  15155. /**
  15156. * @file text-track-list-converter.js Utilities for capturing text track state and
  15157. * re-creating tracks based on a capture.
  15158. *
  15159. * @module text-track-list-converter
  15160. */
  15161. /**
  15162. * Examine a single {@link TextTrack} and return a JSON-compatible javascript object that
  15163. * represents the {@link TextTrack}'s state.
  15164. *
  15165. * @param {TextTrack} track
  15166. * The text track to query.
  15167. *
  15168. * @return {Object}
  15169. * A serializable javascript representation of the TextTrack.
  15170. * @private
  15171. */
  15172. var trackToJson_ = function trackToJson_(track) {
  15173. var ret = ['kind', 'label', 'language', 'id', 'inBandMetadataTrackDispatchType', 'mode', 'src'].reduce(function (acc, prop, i) {
  15174. if (track[prop]) {
  15175. acc[prop] = track[prop];
  15176. }
  15177. return acc;
  15178. }, {
  15179. cues: track.cues && Array.prototype.map.call(track.cues, function (cue) {
  15180. return {
  15181. startTime: cue.startTime,
  15182. endTime: cue.endTime,
  15183. text: cue.text,
  15184. id: cue.id
  15185. };
  15186. })
  15187. });
  15188. return ret;
  15189. };
  15190. /**
  15191. * Examine a {@link Tech} and return a JSON-compatible javascript array that represents the
  15192. * state of all {@link TextTrack}s currently configured. The return array is compatible with
  15193. * {@link text-track-list-converter:jsonToTextTracks}.
  15194. *
  15195. * @param {Tech} tech
  15196. * The tech object to query
  15197. *
  15198. * @return {Array}
  15199. * A serializable javascript representation of the {@link Tech}s
  15200. * {@link TextTrackList}.
  15201. */
  15202. var textTracksToJson = function textTracksToJson(tech) {
  15203. var trackEls = tech.$$('track');
  15204. var trackObjs = Array.prototype.map.call(trackEls, function (t) {
  15205. return t.track;
  15206. });
  15207. var tracks = Array.prototype.map.call(trackEls, function (trackEl) {
  15208. var json = trackToJson_(trackEl.track);
  15209. if (trackEl.src) {
  15210. json.src = trackEl.src;
  15211. }
  15212. return json;
  15213. });
  15214. return tracks.concat(Array.prototype.filter.call(tech.textTracks(), function (track) {
  15215. return trackObjs.indexOf(track) === -1;
  15216. }).map(trackToJson_));
  15217. };
  15218. /**
  15219. * Create a set of remote {@link TextTrack}s on a {@link Tech} based on an array of javascript
  15220. * object {@link TextTrack} representations.
  15221. *
  15222. * @param {Array} json
  15223. * An array of `TextTrack` representation objects, like those that would be
  15224. * produced by `textTracksToJson`.
  15225. *
  15226. * @param {Tech} tech
  15227. * The `Tech` to create the `TextTrack`s on.
  15228. */
  15229. var jsonToTextTracks = function jsonToTextTracks(json, tech) {
  15230. json.forEach(function (track) {
  15231. var addedTrack = tech.addRemoteTextTrack(track).track;
  15232. if (!track.src && track.cues) {
  15233. track.cues.forEach(function (cue) {
  15234. return addedTrack.addCue(cue);
  15235. });
  15236. }
  15237. });
  15238. return tech.textTracks();
  15239. };
  15240. exports['default'] = { textTracksToJson: textTracksToJson, jsonToTextTracks: jsonToTextTracks, trackToJson_: trackToJson_ };
  15241. },{}],70:[function(_dereq_,module,exports){
  15242. 'use strict';
  15243. exports.__esModule = true;
  15244. var _trackList = _dereq_(74);
  15245. var _trackList2 = _interopRequireDefault(_trackList);
  15246. var _fn = _dereq_(83);
  15247. var Fn = _interopRequireWildcard(_fn);
  15248. var _browser = _dereq_(78);
  15249. var browser = _interopRequireWildcard(_browser);
  15250. var _document = _dereq_(94);
  15251. var _document2 = _interopRequireDefault(_document);
  15252. 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; } }
  15253. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  15254. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  15255. 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; }
  15256. 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; } /**
  15257. * @file text-track-list.js
  15258. */
  15259. /**
  15260. * The current list of {@link TextTrack} for a media file.
  15261. *
  15262. * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#texttracklist}
  15263. * @extends TrackList
  15264. */
  15265. var TextTrackList = function (_TrackList) {
  15266. _inherits(TextTrackList, _TrackList);
  15267. /**
  15268. * Create an instance of this class.
  15269. *
  15270. * @param {TextTrack[]} [tracks=[]]
  15271. * A list of `TextTrack` to instantiate the list with.
  15272. */
  15273. function TextTrackList() {
  15274. var _this, _ret;
  15275. var tracks = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
  15276. _classCallCheck(this, TextTrackList);
  15277. var list = void 0;
  15278. // IE8 forces us to implement inheritance ourselves
  15279. // as it does not support Object.defineProperty properly
  15280. if (browser.IS_IE8) {
  15281. list = _document2['default'].createElement('custom');
  15282. for (var prop in _trackList2['default'].prototype) {
  15283. if (prop !== 'constructor') {
  15284. list[prop] = _trackList2['default'].prototype[prop];
  15285. }
  15286. }
  15287. for (var _prop in TextTrackList.prototype) {
  15288. if (_prop !== 'constructor') {
  15289. list[_prop] = TextTrackList.prototype[_prop];
  15290. }
  15291. }
  15292. }
  15293. list = (_this = _possibleConstructorReturn(this, _TrackList.call(this, tracks, list)), _this);
  15294. return _ret = list, _possibleConstructorReturn(_this, _ret);
  15295. }
  15296. /**
  15297. * Add a {@link TextTrack} to the `TextTrackList`
  15298. *
  15299. * @param {TextTrack} track
  15300. * The text track to add to the list.
  15301. *
  15302. * @fires TrackList#addtrack
  15303. * @private
  15304. */
  15305. TextTrackList.prototype.addTrack_ = function addTrack_(track) {
  15306. _TrackList.prototype.addTrack_.call(this, track);
  15307. /**
  15308. * @listens TextTrack#modechange
  15309. * @fires TrackList#change
  15310. */
  15311. track.addEventListener('modechange', Fn.bind(this, function () {
  15312. this.trigger('change');
  15313. }));
  15314. };
  15315. return TextTrackList;
  15316. }(_trackList2['default']);
  15317. exports['default'] = TextTrackList;
  15318. },{"74":74,"78":78,"83":83,"94":94}],71:[function(_dereq_,module,exports){
  15319. 'use strict';
  15320. exports.__esModule = true;
  15321. var _window = _dereq_(95);
  15322. var _window2 = _interopRequireDefault(_window);
  15323. var _component = _dereq_(5);
  15324. var _component2 = _interopRequireDefault(_component);
  15325. var _dom = _dereq_(81);
  15326. var _fn = _dereq_(83);
  15327. var Fn = _interopRequireWildcard(_fn);
  15328. var _obj = _dereq_(88);
  15329. var Obj = _interopRequireWildcard(_obj);
  15330. var _log = _dereq_(86);
  15331. var _log2 = _interopRequireDefault(_log);
  15332. 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; } }
  15333. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  15334. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  15335. 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; }
  15336. 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; } /**
  15337. * @file text-track-settings.js
  15338. */
  15339. var LOCAL_STORAGE_KEY = 'vjs-text-track-settings';
  15340. var COLOR_BLACK = ['#000', 'Black'];
  15341. var COLOR_BLUE = ['#00F', 'Blue'];
  15342. var COLOR_CYAN = ['#0FF', 'Cyan'];
  15343. var COLOR_GREEN = ['#0F0', 'Green'];
  15344. var COLOR_MAGENTA = ['#F0F', 'Magenta'];
  15345. var COLOR_RED = ['#F00', 'Red'];
  15346. var COLOR_WHITE = ['#FFF', 'White'];
  15347. var COLOR_YELLOW = ['#FF0', 'Yellow'];
  15348. var OPACITY_OPAQUE = ['1', 'Opaque'];
  15349. var OPACITY_SEMI = ['0.5', 'Semi-Transparent'];
  15350. var OPACITY_TRANS = ['0', 'Transparent'];
  15351. // Configuration for the various <select> elements in the DOM of this component.
  15352. //
  15353. // Possible keys include:
  15354. //
  15355. // `default`:
  15356. // The default option index. Only needs to be provided if not zero.
  15357. // `parser`:
  15358. // A function which is used to parse the value from the selected option in
  15359. // a customized way.
  15360. // `selector`:
  15361. // The selector used to find the associated <select> element.
  15362. var selectConfigs = {
  15363. backgroundColor: {
  15364. selector: '.vjs-bg-color > select',
  15365. id: 'captions-background-color-%s',
  15366. label: 'Color',
  15367. options: [COLOR_BLACK, COLOR_WHITE, COLOR_RED, COLOR_GREEN, COLOR_BLUE, COLOR_YELLOW, COLOR_MAGENTA, COLOR_CYAN]
  15368. },
  15369. backgroundOpacity: {
  15370. selector: '.vjs-bg-opacity > select',
  15371. id: 'captions-background-opacity-%s',
  15372. label: 'Transparency',
  15373. options: [OPACITY_OPAQUE, OPACITY_SEMI, OPACITY_TRANS]
  15374. },
  15375. color: {
  15376. selector: '.vjs-fg-color > select',
  15377. id: 'captions-foreground-color-%s',
  15378. label: 'Color',
  15379. options: [COLOR_WHITE, COLOR_BLACK, COLOR_RED, COLOR_GREEN, COLOR_BLUE, COLOR_YELLOW, COLOR_MAGENTA, COLOR_CYAN]
  15380. },
  15381. edgeStyle: {
  15382. selector: '.vjs-edge-style > select',
  15383. id: '%s',
  15384. label: 'Text Edge Style',
  15385. options: [['none', 'None'], ['raised', 'Raised'], ['depressed', 'Depressed'], ['uniform', 'Uniform'], ['dropshadow', 'Dropshadow']]
  15386. },
  15387. fontFamily: {
  15388. selector: '.vjs-font-family > select',
  15389. id: 'captions-font-family-%s',
  15390. label: 'Font Family',
  15391. options: [['proportionalSansSerif', 'Proportional Sans-Serif'], ['monospaceSansSerif', 'Monospace Sans-Serif'], ['proportionalSerif', 'Proportional Serif'], ['monospaceSerif', 'Monospace Serif'], ['casual', 'Casual'], ['script', 'Script'], ['small-caps', 'Small Caps']]
  15392. },
  15393. fontPercent: {
  15394. selector: '.vjs-font-percent > select',
  15395. id: 'captions-font-size-%s',
  15396. label: 'Font Size',
  15397. 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%']],
  15398. 'default': 2,
  15399. parser: function parser(v) {
  15400. return v === '1.00' ? null : Number(v);
  15401. }
  15402. },
  15403. textOpacity: {
  15404. selector: '.vjs-text-opacity > select',
  15405. id: 'captions-foreground-opacity-%s',
  15406. label: 'Transparency',
  15407. options: [OPACITY_OPAQUE, OPACITY_SEMI]
  15408. },
  15409. // Options for this object are defined below.
  15410. windowColor: {
  15411. selector: '.vjs-window-color > select',
  15412. id: 'captions-window-color-%s',
  15413. label: 'Color'
  15414. },
  15415. // Options for this object are defined below.
  15416. windowOpacity: {
  15417. selector: '.vjs-window-opacity > select',
  15418. id: 'captions-window-opacity-%s',
  15419. label: 'Transparency',
  15420. options: [OPACITY_TRANS, OPACITY_SEMI, OPACITY_OPAQUE]
  15421. }
  15422. };
  15423. selectConfigs.windowColor.options = selectConfigs.backgroundColor.options;
  15424. /**
  15425. * Get the actual value of an option.
  15426. *
  15427. * @param {string} value
  15428. * The value to get
  15429. *
  15430. * @param {Function} [parser]
  15431. * Optional function to adjust the value.
  15432. *
  15433. * @return {Mixed}
  15434. * - Will be `undefined` if no value exists
  15435. * - Will be `undefined` if the given value is "none".
  15436. * - Will be the actual value otherwise.
  15437. *
  15438. * @private
  15439. */
  15440. function parseOptionValue(value, parser) {
  15441. if (parser) {
  15442. value = parser(value);
  15443. }
  15444. if (value && value !== 'none') {
  15445. return value;
  15446. }
  15447. }
  15448. /**
  15449. * Gets the value of the selected <option> element within a <select> element.
  15450. *
  15451. * @param {Element} el
  15452. * the element to look in
  15453. *
  15454. * @param {Function} [parser]
  15455. * Optional function to adjust the value.
  15456. *
  15457. * @return {Mixed}
  15458. * - Will be `undefined` if no value exists
  15459. * - Will be `undefined` if the given value is "none".
  15460. * - Will be the actual value otherwise.
  15461. *
  15462. * @private
  15463. */
  15464. function getSelectedOptionValue(el, parser) {
  15465. var value = el.options[el.options.selectedIndex].value;
  15466. return parseOptionValue(value, parser);
  15467. }
  15468. /**
  15469. * Sets the selected <option> element within a <select> element based on a
  15470. * given value.
  15471. *
  15472. * @param {Element} el
  15473. * The element to look in.
  15474. *
  15475. * @param {string} value
  15476. * the property to look on.
  15477. *
  15478. * @param {Function} [parser]
  15479. * Optional function to adjust the value before comparing.
  15480. *
  15481. * @private
  15482. */
  15483. function setSelectedOption(el, value, parser) {
  15484. if (!value) {
  15485. return;
  15486. }
  15487. for (var i = 0; i < el.options.length; i++) {
  15488. if (parseOptionValue(el.options[i].value, parser) === value) {
  15489. el.selectedIndex = i;
  15490. break;
  15491. }
  15492. }
  15493. }
  15494. /**
  15495. * Manipulate Text Tracks settings.
  15496. *
  15497. * @extends Component
  15498. */
  15499. var TextTrackSettings = function (_Component) {
  15500. _inherits(TextTrackSettings, _Component);
  15501. /**
  15502. * Creates an instance of this class.
  15503. *
  15504. * @param {Player} player
  15505. * The `Player` that this class should be attached to.
  15506. *
  15507. * @param {Object} [options]
  15508. * The key/value store of player options.
  15509. */
  15510. function TextTrackSettings(player, options) {
  15511. _classCallCheck(this, TextTrackSettings);
  15512. var _this = _possibleConstructorReturn(this, _Component.call(this, player, options));
  15513. _this.setDefaults();
  15514. _this.hide();
  15515. _this.updateDisplay = Fn.bind(_this, _this.updateDisplay);
  15516. // Grab `persistTextTrackSettings` from the player options if not passed in child options
  15517. if (options.persistTextTrackSettings === undefined) {
  15518. _this.options_.persistTextTrackSettings = _this.options_.playerOptions.persistTextTrackSettings;
  15519. }
  15520. _this.on(_this.$('.vjs-done-button'), 'click', function () {
  15521. _this.saveSettings();
  15522. _this.hide();
  15523. });
  15524. _this.on(_this.$('.vjs-default-button'), 'click', function () {
  15525. _this.setDefaults();
  15526. _this.updateDisplay();
  15527. });
  15528. Obj.each(selectConfigs, function (config) {
  15529. _this.on(_this.$(config.selector), 'change', _this.updateDisplay);
  15530. });
  15531. if (_this.options_.persistTextTrackSettings) {
  15532. _this.restoreSettings();
  15533. }
  15534. return _this;
  15535. }
  15536. /**
  15537. * Create a <select> element with configured options.
  15538. *
  15539. * @param {string} key
  15540. * Configuration key to use during creation.
  15541. *
  15542. * @return {Element}
  15543. * The DOM element that gets created.
  15544. * @private
  15545. */
  15546. TextTrackSettings.prototype.createElSelect_ = function createElSelect_(key) {
  15547. var _this2 = this;
  15548. var config = selectConfigs[key];
  15549. var id = config.id.replace('%s', this.id_);
  15550. return [(0, _dom.createEl)('label', {
  15551. className: 'vjs-label',
  15552. textContent: config.label
  15553. }, {
  15554. 'for': id
  15555. }), (0, _dom.createEl)('select', { id: id }, undefined, config.options.map(function (o) {
  15556. return (0, _dom.createEl)('option', {
  15557. textContent: _this2.localize(o[1]),
  15558. value: o[0]
  15559. });
  15560. }))];
  15561. };
  15562. /**
  15563. * Create foreground color element for the component
  15564. *
  15565. * @return {Element}
  15566. * The element that was created.
  15567. *
  15568. * @private
  15569. */
  15570. TextTrackSettings.prototype.createElFgColor_ = function createElFgColor_() {
  15571. var legend = (0, _dom.createEl)('legend', {
  15572. textContent: this.localize('Text')
  15573. });
  15574. var select = this.createElSelect_('color');
  15575. var opacity = (0, _dom.createEl)('span', {
  15576. className: 'vjs-text-opacity vjs-opacity'
  15577. }, undefined, this.createElSelect_('textOpacity'));
  15578. return (0, _dom.createEl)('fieldset', {
  15579. className: 'vjs-fg-color vjs-tracksetting'
  15580. }, undefined, [legend].concat(select, opacity));
  15581. };
  15582. /**
  15583. * Create background color element for the component
  15584. *
  15585. * @return {Element}
  15586. * The element that was created
  15587. *
  15588. * @private
  15589. */
  15590. TextTrackSettings.prototype.createElBgColor_ = function createElBgColor_() {
  15591. var legend = (0, _dom.createEl)('legend', {
  15592. textContent: this.localize('Background')
  15593. });
  15594. var select = this.createElSelect_('backgroundColor');
  15595. var opacity = (0, _dom.createEl)('span', {
  15596. className: 'vjs-bg-opacity vjs-opacity'
  15597. }, undefined, this.createElSelect_('backgroundOpacity'));
  15598. return (0, _dom.createEl)('fieldset', {
  15599. className: 'vjs-bg-color vjs-tracksetting'
  15600. }, undefined, [legend].concat(select, opacity));
  15601. };
  15602. /**
  15603. * Create window color element for the component
  15604. *
  15605. * @return {Element}
  15606. * The element that was created
  15607. *
  15608. * @private
  15609. */
  15610. TextTrackSettings.prototype.createElWinColor_ = function createElWinColor_() {
  15611. var legend = (0, _dom.createEl)('legend', {
  15612. textContent: this.localize('Window')
  15613. });
  15614. var select = this.createElSelect_('windowColor');
  15615. var opacity = (0, _dom.createEl)('span', {
  15616. className: 'vjs-window-opacity vjs-opacity'
  15617. }, undefined, this.createElSelect_('windowOpacity'));
  15618. return (0, _dom.createEl)('fieldset', {
  15619. className: 'vjs-window-color vjs-tracksetting'
  15620. }, undefined, [legend].concat(select, opacity));
  15621. };
  15622. /**
  15623. * Create color elements for the component
  15624. *
  15625. * @return {Element}
  15626. * The element that was created
  15627. *
  15628. * @private
  15629. */
  15630. TextTrackSettings.prototype.createElColors_ = function createElColors_() {
  15631. return (0, _dom.createEl)('div', {
  15632. className: 'vjs-tracksettings-colors'
  15633. }, undefined, [this.createElFgColor_(), this.createElBgColor_(), this.createElWinColor_()]);
  15634. };
  15635. /**
  15636. * Create font elements for the component
  15637. *
  15638. * @return {Element}
  15639. * The element that was created.
  15640. *
  15641. * @private
  15642. */
  15643. TextTrackSettings.prototype.createElFont_ = function createElFont_() {
  15644. var fontPercent = (0, _dom.createEl)('div', {
  15645. className: 'vjs-font-percent vjs-tracksetting'
  15646. }, undefined, this.createElSelect_('fontPercent'));
  15647. var edgeStyle = (0, _dom.createEl)('div', {
  15648. className: 'vjs-edge-style vjs-tracksetting'
  15649. }, undefined, this.createElSelect_('edgeStyle'));
  15650. var fontFamily = (0, _dom.createEl)('div', {
  15651. className: 'vjs-font-family vjs-tracksetting'
  15652. }, undefined, this.createElSelect_('fontFamily'));
  15653. return (0, _dom.createEl)('div', {
  15654. className: 'vjs-tracksettings-font'
  15655. }, undefined, [fontPercent, edgeStyle, fontFamily]);
  15656. };
  15657. /**
  15658. * Create controls for the component
  15659. *
  15660. * @return {Element}
  15661. * The element that was created.
  15662. *
  15663. * @private
  15664. */
  15665. TextTrackSettings.prototype.createElControls_ = function createElControls_() {
  15666. var defaultsButton = (0, _dom.createEl)('button', {
  15667. className: 'vjs-default-button',
  15668. textContent: this.localize('Defaults')
  15669. });
  15670. var doneButton = (0, _dom.createEl)('button', {
  15671. className: 'vjs-done-button',
  15672. textContent: 'Done'
  15673. });
  15674. return (0, _dom.createEl)('div', {
  15675. className: 'vjs-tracksettings-controls'
  15676. }, undefined, [defaultsButton, doneButton]);
  15677. };
  15678. /**
  15679. * Create the component's DOM element
  15680. *
  15681. * @return {Element}
  15682. * The element that was created.
  15683. */
  15684. TextTrackSettings.prototype.createEl = function createEl() {
  15685. var settings = (0, _dom.createEl)('div', {
  15686. className: 'vjs-tracksettings'
  15687. }, undefined, [this.createElColors_(), this.createElFont_(), this.createElControls_()]);
  15688. var heading = (0, _dom.createEl)('div', {
  15689. className: 'vjs-control-text',
  15690. id: 'TTsettingsDialogLabel-' + this.id_,
  15691. textContent: 'Caption Settings Dialog'
  15692. }, {
  15693. 'aria-level': '1',
  15694. 'role': 'heading'
  15695. });
  15696. var description = (0, _dom.createEl)('div', {
  15697. className: 'vjs-control-text',
  15698. id: 'TTsettingsDialogDescription-' + this.id_,
  15699. textContent: 'Beginning of dialog window. Escape will cancel and close the window.'
  15700. });
  15701. var doc = (0, _dom.createEl)('div', undefined, {
  15702. role: 'document'
  15703. }, [heading, description, settings]);
  15704. return (0, _dom.createEl)('div', {
  15705. className: 'vjs-caption-settings vjs-modal-overlay',
  15706. tabIndex: -1
  15707. }, {
  15708. 'role': 'dialog',
  15709. 'aria-labelledby': heading.id,
  15710. 'aria-describedby': description.id
  15711. }, doc);
  15712. };
  15713. /**
  15714. * Gets an object of text track settings (or null).
  15715. *
  15716. * @return {Object}
  15717. * An object with config values parsed from the DOM or localStorage.
  15718. */
  15719. TextTrackSettings.prototype.getValues = function getValues() {
  15720. var _this3 = this;
  15721. return Obj.reduce(selectConfigs, function (accum, config, key) {
  15722. var value = getSelectedOptionValue(_this3.$(config.selector), config.parser);
  15723. if (value !== undefined) {
  15724. accum[key] = value;
  15725. }
  15726. return accum;
  15727. }, {});
  15728. };
  15729. /**
  15730. * Sets text track settings from an object of values.
  15731. *
  15732. * @param {Object} values
  15733. * An object with config values parsed from the DOM or localStorage.
  15734. */
  15735. TextTrackSettings.prototype.setValues = function setValues(values) {
  15736. var _this4 = this;
  15737. Obj.each(selectConfigs, function (config, key) {
  15738. setSelectedOption(_this4.$(config.selector), values[key], config.parser);
  15739. });
  15740. };
  15741. /**
  15742. * Sets all <select> elements to their default values.
  15743. */
  15744. TextTrackSettings.prototype.setDefaults = function setDefaults() {
  15745. var _this5 = this;
  15746. Obj.each(selectConfigs, function (config) {
  15747. var index = config.hasOwnProperty('default') ? config['default'] : 0;
  15748. _this5.$(config.selector).selectedIndex = index;
  15749. });
  15750. };
  15751. /**
  15752. * Restore texttrack settings from localStorage
  15753. */
  15754. TextTrackSettings.prototype.restoreSettings = function restoreSettings() {
  15755. var values = void 0;
  15756. try {
  15757. values = JSON.parse(_window2['default'].localStorage.getItem(LOCAL_STORAGE_KEY));
  15758. } catch (err) {
  15759. _log2['default'].warn(err);
  15760. }
  15761. if (values) {
  15762. this.setValues(values);
  15763. }
  15764. };
  15765. /**
  15766. * Save text track settings to localStorage
  15767. */
  15768. TextTrackSettings.prototype.saveSettings = function saveSettings() {
  15769. if (!this.options_.persistTextTrackSettings) {
  15770. return;
  15771. }
  15772. var values = this.getValues();
  15773. try {
  15774. if (Object.keys(values).length) {
  15775. _window2['default'].localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(values));
  15776. } else {
  15777. _window2['default'].localStorage.removeItem(LOCAL_STORAGE_KEY);
  15778. }
  15779. } catch (err) {
  15780. _log2['default'].warn(err);
  15781. }
  15782. };
  15783. /**
  15784. * Update display of text track settings
  15785. */
  15786. TextTrackSettings.prototype.updateDisplay = function updateDisplay() {
  15787. var ttDisplay = this.player_.getChild('textTrackDisplay');
  15788. if (ttDisplay) {
  15789. ttDisplay.updateDisplay();
  15790. }
  15791. };
  15792. return TextTrackSettings;
  15793. }(_component2['default']);
  15794. _component2['default'].registerComponent('TextTrackSettings', TextTrackSettings);
  15795. exports['default'] = TextTrackSettings;
  15796. },{"5":5,"81":81,"83":83,"86":86,"88":88,"95":95}],72:[function(_dereq_,module,exports){
  15797. 'use strict';
  15798. exports.__esModule = true;
  15799. var _textTrackCueList = _dereq_(67);
  15800. var _textTrackCueList2 = _interopRequireDefault(_textTrackCueList);
  15801. var _fn = _dereq_(83);
  15802. var Fn = _interopRequireWildcard(_fn);
  15803. var _trackEnums = _dereq_(73);
  15804. var _log = _dereq_(86);
  15805. var _log2 = _interopRequireDefault(_log);
  15806. var _window = _dereq_(95);
  15807. var _window2 = _interopRequireDefault(_window);
  15808. var _track = _dereq_(75);
  15809. var _track2 = _interopRequireDefault(_track);
  15810. var _url = _dereq_(92);
  15811. var _xhr = _dereq_(105);
  15812. var _xhr2 = _interopRequireDefault(_xhr);
  15813. var _mergeOptions = _dereq_(87);
  15814. var _mergeOptions2 = _interopRequireDefault(_mergeOptions);
  15815. var _browser = _dereq_(78);
  15816. var browser = _interopRequireWildcard(_browser);
  15817. 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; } }
  15818. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  15819. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  15820. 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; }
  15821. 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; } /**
  15822. * @file text-track.js
  15823. */
  15824. /**
  15825. * Takes a webvtt file contents and parses it into cues
  15826. *
  15827. * @param {string} srcContent
  15828. * webVTT file contents
  15829. *
  15830. * @param {TextTrack} track
  15831. * TextTrack to add cues to. Cues come from the srcContent.
  15832. *
  15833. * @private
  15834. */
  15835. var parseCues = function parseCues(srcContent, track) {
  15836. var parser = new _window2['default'].WebVTT.Parser(_window2['default'], _window2['default'].vttjs, _window2['default'].WebVTT.StringDecoder());
  15837. var errors = [];
  15838. parser.oncue = function (cue) {
  15839. track.addCue(cue);
  15840. };
  15841. parser.onparsingerror = function (error) {
  15842. errors.push(error);
  15843. };
  15844. parser.onflush = function () {
  15845. track.trigger({
  15846. type: 'loadeddata',
  15847. target: track
  15848. });
  15849. };
  15850. parser.parse(srcContent);
  15851. if (errors.length > 0) {
  15852. if (_window2['default'].console && _window2['default'].console.groupCollapsed) {
  15853. _window2['default'].console.groupCollapsed('Text Track parsing errors for ' + track.src);
  15854. }
  15855. errors.forEach(function (error) {
  15856. return _log2['default'].error(error);
  15857. });
  15858. if (_window2['default'].console && _window2['default'].console.groupEnd) {
  15859. _window2['default'].console.groupEnd();
  15860. }
  15861. }
  15862. parser.flush();
  15863. };
  15864. /**
  15865. * Load a `TextTrack` from a specifed url.
  15866. *
  15867. * @param {string} src
  15868. * Url to load track from.
  15869. *
  15870. * @param {TextTrack} track
  15871. * Track to add cues to. Comes from the content at the end of `url`.
  15872. *
  15873. * @private
  15874. */
  15875. var loadTrack = function loadTrack(src, track) {
  15876. var opts = {
  15877. uri: src
  15878. };
  15879. var crossOrigin = (0, _url.isCrossOrigin)(src);
  15880. if (crossOrigin) {
  15881. opts.cors = crossOrigin;
  15882. }
  15883. (0, _xhr2['default'])(opts, Fn.bind(this, function (err, response, responseBody) {
  15884. if (err) {
  15885. return _log2['default'].error(err, response);
  15886. }
  15887. track.loaded_ = true;
  15888. // Make sure that vttjs has loaded, otherwise, wait till it finished loading
  15889. // NOTE: this is only used for the alt/video.novtt.js build
  15890. if (typeof _window2['default'].WebVTT !== 'function') {
  15891. if (track.tech_) {
  15892. (function () {
  15893. var loadHandler = function loadHandler() {
  15894. return parseCues(responseBody, track);
  15895. };
  15896. track.tech_.on('vttjsloaded', loadHandler);
  15897. track.tech_.on('vttjserror', function () {
  15898. _log2['default'].error('vttjs failed to load, stopping trying to process ' + track.src);
  15899. track.tech_.off('vttjsloaded', loadHandler);
  15900. });
  15901. })();
  15902. }
  15903. } else {
  15904. parseCues(responseBody, track);
  15905. }
  15906. }));
  15907. };
  15908. /**
  15909. * A representation of a single `TextTrack`.
  15910. *
  15911. * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#texttrack}
  15912. * @extends Track
  15913. */
  15914. var TextTrack = function (_Track) {
  15915. _inherits(TextTrack, _Track);
  15916. /**
  15917. * Create an instance of this class.
  15918. *
  15919. * @param {Object} options={}
  15920. * Object of option names and values
  15921. *
  15922. * @param {Tech} options.tech
  15923. * A reference to the tech that owns this TextTrack.
  15924. *
  15925. * @param {TextTrack~Kind} [options.kind='subtitles']
  15926. * A valid text track kind.
  15927. *
  15928. * @param {TextTrack~Mode} [options.mode='disabled']
  15929. * A valid text track mode.
  15930. *
  15931. * @param {string} [options.id='vjs_track_' + Guid.newGUID()]
  15932. * A unique id for this TextTrack.
  15933. *
  15934. * @param {string} [options.label='']
  15935. * The menu label for this track.
  15936. *
  15937. * @param {string} [options.language='']
  15938. * A valid two character language code.
  15939. *
  15940. * @param {string} [options.srclang='']
  15941. * A valid two character language code. An alternative, but deprioritized
  15942. * vesion of `options.language`
  15943. *
  15944. * @param {string} [options.src]
  15945. * A url to TextTrack cues.
  15946. *
  15947. * @param {boolean} [options.default]
  15948. * If this track should default to on or off.
  15949. */
  15950. function TextTrack() {
  15951. var _this, _ret2;
  15952. var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  15953. _classCallCheck(this, TextTrack);
  15954. if (!options.tech) {
  15955. throw new Error('A tech was not provided.');
  15956. }
  15957. var settings = (0, _mergeOptions2['default'])(options, {
  15958. kind: _trackEnums.TextTrackKind[options.kind] || 'subtitles',
  15959. language: options.language || options.srclang || ''
  15960. });
  15961. var mode = _trackEnums.TextTrackMode[settings.mode] || 'disabled';
  15962. var default_ = settings['default'];
  15963. if (settings.kind === 'metadata' || settings.kind === 'chapters') {
  15964. mode = 'hidden';
  15965. }
  15966. // on IE8 this will be a document element
  15967. // for every other browser this will be a normal object
  15968. var tt = (_this = _possibleConstructorReturn(this, _Track.call(this, settings)), _this);
  15969. tt.tech_ = settings.tech;
  15970. if (browser.IS_IE8) {
  15971. for (var prop in TextTrack.prototype) {
  15972. if (prop !== 'constructor') {
  15973. tt[prop] = TextTrack.prototype[prop];
  15974. }
  15975. }
  15976. }
  15977. tt.cues_ = [];
  15978. tt.activeCues_ = [];
  15979. var cues = new _textTrackCueList2['default'](tt.cues_);
  15980. var activeCues = new _textTrackCueList2['default'](tt.activeCues_);
  15981. var changed = false;
  15982. var timeupdateHandler = Fn.bind(tt, function () {
  15983. // Accessing this.activeCues for the side-effects of updating itself
  15984. // due to it's nature as a getter function. Do not remove or cues will
  15985. // stop updating!
  15986. /* eslint-disable no-unused-expressions */
  15987. this.activeCues;
  15988. /* eslint-enable no-unused-expressions */
  15989. if (changed) {
  15990. this.trigger('cuechange');
  15991. changed = false;
  15992. }
  15993. });
  15994. if (mode !== 'disabled') {
  15995. tt.tech_.on('timeupdate', timeupdateHandler);
  15996. }
  15997. /**
  15998. * @member {boolean} default
  15999. * If this track was set to be on or off by default. Cannot be changed after
  16000. * creation.
  16001. *
  16002. * @readonly
  16003. */
  16004. Object.defineProperty(tt, 'default', {
  16005. get: function get() {
  16006. return default_;
  16007. },
  16008. set: function set() {}
  16009. });
  16010. /**
  16011. * @member {string} mode
  16012. * Set the mode of this TextTrack to a valid {@link TextTrack~Mode}. Will
  16013. * not be set if setting to an invalid mode.
  16014. *
  16015. * @fires TextTrack#modechange
  16016. */
  16017. Object.defineProperty(tt, 'mode', {
  16018. get: function get() {
  16019. return mode;
  16020. },
  16021. set: function set(newMode) {
  16022. if (!_trackEnums.TextTrackMode[newMode]) {
  16023. return;
  16024. }
  16025. mode = newMode;
  16026. if (mode === 'showing') {
  16027. this.tech_.on('timeupdate', timeupdateHandler);
  16028. }
  16029. /**
  16030. * An event that fires when mode changes on this track. This allows
  16031. * the TextTrackList that holds this track to act accordingly.
  16032. *
  16033. * > Note: This is not part of the spec!
  16034. *
  16035. * @event TextTrack#modechange
  16036. * @type {EventTarget~Event}
  16037. */
  16038. this.trigger('modechange');
  16039. }
  16040. });
  16041. /**
  16042. * @member {TextTrackCueList} cues
  16043. * The text track cue list for this TextTrack.
  16044. */
  16045. Object.defineProperty(tt, 'cues', {
  16046. get: function get() {
  16047. if (!this.loaded_) {
  16048. return null;
  16049. }
  16050. return cues;
  16051. },
  16052. set: function set() {}
  16053. });
  16054. /**
  16055. * @member {TextTrackCueList} activeCues
  16056. * The list text track cues that are currently active for this TextTrack.
  16057. */
  16058. Object.defineProperty(tt, 'activeCues', {
  16059. get: function get() {
  16060. if (!this.loaded_) {
  16061. return null;
  16062. }
  16063. // nothing to do
  16064. if (this.cues.length === 0) {
  16065. return activeCues;
  16066. }
  16067. var ct = this.tech_.currentTime();
  16068. var active = [];
  16069. for (var i = 0, l = this.cues.length; i < l; i++) {
  16070. var cue = this.cues[i];
  16071. if (cue.startTime <= ct && cue.endTime >= ct) {
  16072. active.push(cue);
  16073. } else if (cue.startTime === cue.endTime && cue.startTime <= ct && cue.startTime + 0.5 >= ct) {
  16074. active.push(cue);
  16075. }
  16076. }
  16077. changed = false;
  16078. if (active.length !== this.activeCues_.length) {
  16079. changed = true;
  16080. } else {
  16081. for (var _i = 0; _i < active.length; _i++) {
  16082. if (this.activeCues_.indexOf(active[_i]) === -1) {
  16083. changed = true;
  16084. }
  16085. }
  16086. }
  16087. this.activeCues_ = active;
  16088. activeCues.setCues_(this.activeCues_);
  16089. return activeCues;
  16090. },
  16091. set: function set() {}
  16092. });
  16093. if (settings.src) {
  16094. tt.src = settings.src;
  16095. loadTrack(settings.src, tt);
  16096. } else {
  16097. tt.loaded_ = true;
  16098. }
  16099. return _ret2 = tt, _possibleConstructorReturn(_this, _ret2);
  16100. }
  16101. /**
  16102. * Add a cue to the internal list of cues.
  16103. *
  16104. * @param {TextTrack~Cue} cue
  16105. * The cue to add to our internal list
  16106. */
  16107. TextTrack.prototype.addCue = function addCue(cue) {
  16108. var tracks = this.tech_.textTracks();
  16109. if (tracks) {
  16110. for (var i = 0; i < tracks.length; i++) {
  16111. if (tracks[i] !== this) {
  16112. tracks[i].removeCue(cue);
  16113. }
  16114. }
  16115. }
  16116. this.cues_.push(cue);
  16117. this.cues.setCues_(this.cues_);
  16118. };
  16119. /**
  16120. * Remove a cue from our internal list
  16121. *
  16122. * @param {TextTrack~Cue} removeCue
  16123. * The cue to remove from our internal list
  16124. */
  16125. TextTrack.prototype.removeCue = function removeCue(_removeCue) {
  16126. var removed = false;
  16127. for (var i = 0, l = this.cues_.length; i < l; i++) {
  16128. var cue = this.cues_[i];
  16129. if (cue === _removeCue) {
  16130. this.cues_.splice(i, 1);
  16131. removed = true;
  16132. }
  16133. }
  16134. if (removed) {
  16135. this.cues.setCues_(this.cues_);
  16136. }
  16137. };
  16138. return TextTrack;
  16139. }(_track2['default']);
  16140. /**
  16141. * cuechange - One or more cues in the track have become active or stopped being active.
  16142. */
  16143. TextTrack.prototype.allowedEvents_ = {
  16144. cuechange: 'cuechange'
  16145. };
  16146. exports['default'] = TextTrack;
  16147. },{"105":105,"67":67,"73":73,"75":75,"78":78,"83":83,"86":86,"87":87,"92":92,"95":95}],73:[function(_dereq_,module,exports){
  16148. 'use strict';
  16149. exports.__esModule = true;
  16150. /**
  16151. * @file track-kinds.js
  16152. */
  16153. /**
  16154. * All possible `VideoTrackKind`s
  16155. *
  16156. * @see https://html.spec.whatwg.org/multipage/embedded-content.html#dom-videotrack-kind
  16157. * @typedef VideoTrack~Kind
  16158. * @enum
  16159. */
  16160. var VideoTrackKind = exports.VideoTrackKind = {
  16161. alternative: 'alternative',
  16162. captions: 'captions',
  16163. main: 'main',
  16164. sign: 'sign',
  16165. subtitles: 'subtitles',
  16166. commentary: 'commentary'
  16167. };
  16168. /**
  16169. * All possible `AudioTrackKind`s
  16170. *
  16171. * @see https://html.spec.whatwg.org/multipage/embedded-content.html#dom-audiotrack-kind
  16172. * @typedef AudioTrack~Kind
  16173. * @enum
  16174. */
  16175. var AudioTrackKind = exports.AudioTrackKind = {
  16176. 'alternative': 'alternative',
  16177. 'descriptions': 'descriptions',
  16178. 'main': 'main',
  16179. 'main-desc': 'main-desc',
  16180. 'translation': 'translation',
  16181. 'commentary': 'commentary'
  16182. };
  16183. /**
  16184. * All possible `TextTrackKind`s
  16185. *
  16186. * @see https://html.spec.whatwg.org/multipage/embedded-content.html#dom-texttrack-kind
  16187. * @typedef TextTrack~Kind
  16188. * @enum
  16189. */
  16190. var TextTrackKind = exports.TextTrackKind = {
  16191. subtitles: 'subtitles',
  16192. captions: 'captions',
  16193. descriptions: 'descriptions',
  16194. chapters: 'chapters',
  16195. metadata: 'metadata'
  16196. };
  16197. /**
  16198. * All possible `TextTrackMode`s
  16199. *
  16200. * @see https://html.spec.whatwg.org/multipage/embedded-content.html#texttrackmode
  16201. * @typedef TextTrack~Mode
  16202. * @enum
  16203. */
  16204. var TextTrackMode = exports.TextTrackMode = {
  16205. disabled: 'disabled',
  16206. hidden: 'hidden',
  16207. showing: 'showing'
  16208. };
  16209. },{}],74:[function(_dereq_,module,exports){
  16210. 'use strict';
  16211. exports.__esModule = true;
  16212. var _eventTarget = _dereq_(42);
  16213. var _eventTarget2 = _interopRequireDefault(_eventTarget);
  16214. var _browser = _dereq_(78);
  16215. var browser = _interopRequireWildcard(_browser);
  16216. var _document = _dereq_(94);
  16217. var _document2 = _interopRequireDefault(_document);
  16218. 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; } }
  16219. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  16220. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  16221. 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; }
  16222. 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; } /**
  16223. * @file track-list.js
  16224. */
  16225. /**
  16226. * Common functionaliy between {@link TextTrackList}, {@link AudioTrackList}, and
  16227. * {@link VideoTrackList}
  16228. *
  16229. * @extends EventTarget
  16230. */
  16231. var TrackList = function (_EventTarget) {
  16232. _inherits(TrackList, _EventTarget);
  16233. /**
  16234. * Create an instance of this class
  16235. *
  16236. * @param {Track[]} tracks
  16237. * A list of tracks to initialize the list with.
  16238. *
  16239. * @param {Object} [list]
  16240. * The child object with inheritance done manually for ie8.
  16241. *
  16242. * @abstract
  16243. */
  16244. function TrackList() {
  16245. var tracks = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
  16246. var _ret;
  16247. var list = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
  16248. _classCallCheck(this, TrackList);
  16249. var _this = _possibleConstructorReturn(this, _EventTarget.call(this));
  16250. if (!list) {
  16251. list = _this; // eslint-disable-line
  16252. if (browser.IS_IE8) {
  16253. list = _document2['default'].createElement('custom');
  16254. for (var prop in TrackList.prototype) {
  16255. if (prop !== 'constructor') {
  16256. list[prop] = TrackList.prototype[prop];
  16257. }
  16258. }
  16259. }
  16260. }
  16261. list.tracks_ = [];
  16262. /**
  16263. * @member {number} length
  16264. * The current number of `Track`s in the this Trackist.
  16265. */
  16266. Object.defineProperty(list, 'length', {
  16267. get: function get() {
  16268. return this.tracks_.length;
  16269. }
  16270. });
  16271. for (var i = 0; i < tracks.length; i++) {
  16272. list.addTrack_(tracks[i]);
  16273. }
  16274. // must return the object, as for ie8 it will not be this
  16275. // but a reference to a document object
  16276. return _ret = list, _possibleConstructorReturn(_this, _ret);
  16277. }
  16278. /**
  16279. * Add a {@link Track} to the `TrackList`
  16280. *
  16281. * @param {Track} track
  16282. * The audio, video, or text track to add to the list.
  16283. *
  16284. * @fires TrackList#addtrack
  16285. * @private
  16286. */
  16287. TrackList.prototype.addTrack_ = function addTrack_(track) {
  16288. var index = this.tracks_.length;
  16289. if (!('' + index in this)) {
  16290. Object.defineProperty(this, index, {
  16291. get: function get() {
  16292. return this.tracks_[index];
  16293. }
  16294. });
  16295. }
  16296. // Do not add duplicate tracks
  16297. if (this.tracks_.indexOf(track) === -1) {
  16298. this.tracks_.push(track);
  16299. /**
  16300. * Triggered when a track is added to a track list.
  16301. *
  16302. * @event TrackList#addtrack
  16303. * @type {EventTarget~Event}
  16304. * @property {Track} track
  16305. * A reference to track that was added.
  16306. */
  16307. this.trigger({
  16308. track: track,
  16309. type: 'addtrack'
  16310. });
  16311. }
  16312. };
  16313. /**
  16314. * Remove a {@link Track} from the `TrackList`
  16315. *
  16316. * @param {Track} track
  16317. * The audio, video, or text track to remove from the list.
  16318. *
  16319. * @fires TrackList#removetrack
  16320. * @private
  16321. */
  16322. TrackList.prototype.removeTrack_ = function removeTrack_(rtrack) {
  16323. var track = void 0;
  16324. for (var i = 0, l = this.length; i < l; i++) {
  16325. if (this[i] === rtrack) {
  16326. track = this[i];
  16327. if (track.off) {
  16328. track.off();
  16329. }
  16330. this.tracks_.splice(i, 1);
  16331. break;
  16332. }
  16333. }
  16334. if (!track) {
  16335. return;
  16336. }
  16337. /**
  16338. * Triggered when a track is removed from track list.
  16339. *
  16340. * @event TrackList#removetrack
  16341. * @type {EventTarget~Event}
  16342. * @property {Track} track
  16343. * A reference to track that was removed.
  16344. */
  16345. this.trigger({
  16346. track: track,
  16347. type: 'removetrack'
  16348. });
  16349. };
  16350. /**
  16351. * Get a Track from the TrackList by a tracks id
  16352. *
  16353. * @param {String} id - the id of the track to get
  16354. * @method getTrackById
  16355. * @return {Track}
  16356. * @private
  16357. */
  16358. TrackList.prototype.getTrackById = function getTrackById(id) {
  16359. var result = null;
  16360. for (var i = 0, l = this.length; i < l; i++) {
  16361. var track = this[i];
  16362. if (track.id === id) {
  16363. result = track;
  16364. break;
  16365. }
  16366. }
  16367. return result;
  16368. };
  16369. return TrackList;
  16370. }(_eventTarget2['default']);
  16371. /**
  16372. * Triggered when a different track is selected/enabled.
  16373. *
  16374. * @event TrackList#change
  16375. * @type {EventTarget~Event}
  16376. */
  16377. /**
  16378. * Events that can be called with on + eventName. See {@link EventHandler}.
  16379. *
  16380. * @property {Object} TrackList#allowedEvents_
  16381. * @private
  16382. */
  16383. TrackList.prototype.allowedEvents_ = {
  16384. change: 'change',
  16385. addtrack: 'addtrack',
  16386. removetrack: 'removetrack'
  16387. };
  16388. // emulate attribute EventHandler support to allow for feature detection
  16389. for (var event in TrackList.prototype.allowedEvents_) {
  16390. TrackList.prototype['on' + event] = null;
  16391. }
  16392. exports['default'] = TrackList;
  16393. },{"42":42,"78":78,"94":94}],75:[function(_dereq_,module,exports){
  16394. 'use strict';
  16395. exports.__esModule = true;
  16396. var _browser = _dereq_(78);
  16397. var browser = _interopRequireWildcard(_browser);
  16398. var _document = _dereq_(94);
  16399. var _document2 = _interopRequireDefault(_document);
  16400. var _guid = _dereq_(85);
  16401. var Guid = _interopRequireWildcard(_guid);
  16402. var _eventTarget = _dereq_(42);
  16403. var _eventTarget2 = _interopRequireDefault(_eventTarget);
  16404. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  16405. 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; } }
  16406. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  16407. 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; }
  16408. 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; } /**
  16409. * @file track.js
  16410. */
  16411. /**
  16412. * A Track class that contains all of the common functionality for {@link AudioTrack},
  16413. * {@link VideoTrack}, and {@link TextTrack}.
  16414. *
  16415. * > Note: This class should not be used directly
  16416. *
  16417. * @see {@link https://html.spec.whatwg.org/multipage/embedded-content.html}
  16418. * @extends EventTarget
  16419. * @abstract
  16420. */
  16421. var Track = function (_EventTarget) {
  16422. _inherits(Track, _EventTarget);
  16423. /**
  16424. * Create an instance of this class.
  16425. *
  16426. * @param {Object} [options={}]
  16427. * Object of option names and values
  16428. *
  16429. * @param {string} [options.kind='']
  16430. * A valid kind for the track type you are creating.
  16431. *
  16432. * @param {string} [options.id='vjs_track_' + Guid.newGUID()]
  16433. * A unique id for this AudioTrack.
  16434. *
  16435. * @param {string} [options.label='']
  16436. * The menu label for this track.
  16437. *
  16438. * @param {string} [options.language='']
  16439. * A valid two character language code.
  16440. *
  16441. * @abstract
  16442. */
  16443. function Track() {
  16444. var _ret;
  16445. var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  16446. _classCallCheck(this, Track);
  16447. var _this = _possibleConstructorReturn(this, _EventTarget.call(this));
  16448. var track = _this; // eslint-disable-line
  16449. if (browser.IS_IE8) {
  16450. track = _document2['default'].createElement('custom');
  16451. for (var prop in Track.prototype) {
  16452. if (prop !== 'constructor') {
  16453. track[prop] = Track.prototype[prop];
  16454. }
  16455. }
  16456. }
  16457. var trackProps = {
  16458. id: options.id || 'vjs_track_' + Guid.newGUID(),
  16459. kind: options.kind || '',
  16460. label: options.label || '',
  16461. language: options.language || ''
  16462. };
  16463. /**
  16464. * @member {string} id
  16465. * The id of this track. Cannot be changed after creation.
  16466. *
  16467. * @readonly
  16468. */
  16469. /**
  16470. * @member {string} kind
  16471. * The kind of track that this is. Cannot be changed after creation.
  16472. *
  16473. * @readonly
  16474. */
  16475. /**
  16476. * @member {string} label
  16477. * The label of this track. Cannot be changed after creation.
  16478. *
  16479. * @readonly
  16480. */
  16481. /**
  16482. * @member {string} language
  16483. * The two letter language code for this track. Cannot be changed after
  16484. * creation.
  16485. *
  16486. * @readonly
  16487. */
  16488. var _loop = function _loop(key) {
  16489. Object.defineProperty(track, key, {
  16490. get: function get() {
  16491. return trackProps[key];
  16492. },
  16493. set: function set() {}
  16494. });
  16495. };
  16496. for (var key in trackProps) {
  16497. _loop(key);
  16498. }
  16499. return _ret = track, _possibleConstructorReturn(_this, _ret);
  16500. }
  16501. return Track;
  16502. }(_eventTarget2['default']);
  16503. exports['default'] = Track;
  16504. },{"42":42,"78":78,"85":85,"94":94}],76:[function(_dereq_,module,exports){
  16505. 'use strict';
  16506. exports.__esModule = true;
  16507. var _trackList = _dereq_(74);
  16508. var _trackList2 = _interopRequireDefault(_trackList);
  16509. var _browser = _dereq_(78);
  16510. var browser = _interopRequireWildcard(_browser);
  16511. var _document = _dereq_(94);
  16512. var _document2 = _interopRequireDefault(_document);
  16513. 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; } }
  16514. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  16515. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  16516. 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; }
  16517. 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; } /**
  16518. * @file video-track-list.js
  16519. */
  16520. /**
  16521. * Un-select all other {@link VideoTrack}s that are selected.
  16522. *
  16523. * @param {VideoTrackList} list
  16524. * list to work on
  16525. *
  16526. * @param {VideoTrack} track
  16527. * The track to skip
  16528. *
  16529. * @private
  16530. */
  16531. var disableOthers = function disableOthers(list, track) {
  16532. for (var i = 0; i < list.length; i++) {
  16533. if (track.id === list[i].id) {
  16534. continue;
  16535. }
  16536. // another video track is enabled, disable it
  16537. list[i].selected = false;
  16538. }
  16539. };
  16540. /**
  16541. * The current list of {@link VideoTrack} for a video.
  16542. *
  16543. * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#videotracklist}
  16544. * @extends TrackList
  16545. */
  16546. var VideoTrackList = function (_TrackList) {
  16547. _inherits(VideoTrackList, _TrackList);
  16548. /**
  16549. * Create an instance of this class.
  16550. *
  16551. * @param {VideoTrack[]} [tracks=[]]
  16552. * A list of `VideoTrack` to instantiate the list with.
  16553. */
  16554. function VideoTrackList() {
  16555. var _this, _ret;
  16556. var tracks = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
  16557. _classCallCheck(this, VideoTrackList);
  16558. var list = void 0;
  16559. // make sure only 1 track is enabled
  16560. // sorted from last index to first index
  16561. for (var i = tracks.length - 1; i >= 0; i--) {
  16562. if (tracks[i].selected) {
  16563. disableOthers(tracks, tracks[i]);
  16564. break;
  16565. }
  16566. }
  16567. // IE8 forces us to implement inheritance ourselves
  16568. // as it does not support Object.defineProperty properly
  16569. if (browser.IS_IE8) {
  16570. list = _document2['default'].createElement('custom');
  16571. for (var prop in _trackList2['default'].prototype) {
  16572. if (prop !== 'constructor') {
  16573. list[prop] = _trackList2['default'].prototype[prop];
  16574. }
  16575. }
  16576. for (var _prop in VideoTrackList.prototype) {
  16577. if (_prop !== 'constructor') {
  16578. list[_prop] = VideoTrackList.prototype[_prop];
  16579. }
  16580. }
  16581. }
  16582. list = (_this = _possibleConstructorReturn(this, _TrackList.call(this, tracks, list)), _this);
  16583. list.changing_ = false;
  16584. /**
  16585. * @member {number} VideoTrackList#selectedIndex
  16586. * The current index of the selected {@link VideoTrack`}.
  16587. */
  16588. Object.defineProperty(list, 'selectedIndex', {
  16589. get: function get() {
  16590. for (var _i = 0; _i < this.length; _i++) {
  16591. if (this[_i].selected) {
  16592. return _i;
  16593. }
  16594. }
  16595. return -1;
  16596. },
  16597. set: function set() {}
  16598. });
  16599. return _ret = list, _possibleConstructorReturn(_this, _ret);
  16600. }
  16601. /**
  16602. * Add a {@link VideoTrack} to the `VideoTrackList`.
  16603. *
  16604. * @param {VideoTrack} track
  16605. * The VideoTrack to add to the list
  16606. *
  16607. * @fires TrackList#addtrack
  16608. * @private
  16609. */
  16610. VideoTrackList.prototype.addTrack_ = function addTrack_(track) {
  16611. var _this2 = this;
  16612. if (track.selected) {
  16613. disableOthers(this, track);
  16614. }
  16615. _TrackList.prototype.addTrack_.call(this, track);
  16616. // native tracks don't have this
  16617. if (!track.addEventListener) {
  16618. return;
  16619. }
  16620. /**
  16621. * @listens VideoTrack#selectedchange
  16622. * @fires TrackList#change
  16623. */
  16624. track.addEventListener('selectedchange', function () {
  16625. if (_this2.changing_) {
  16626. return;
  16627. }
  16628. _this2.changing_ = true;
  16629. disableOthers(_this2, track);
  16630. _this2.changing_ = false;
  16631. _this2.trigger('change');
  16632. });
  16633. };
  16634. /**
  16635. * Add a {@link VideoTrack} to the `VideoTrackList`.
  16636. *
  16637. * @param {VideoTrack} track
  16638. * The VideoTrack to add to the list
  16639. *
  16640. * @fires TrackList#addtrack
  16641. */
  16642. VideoTrackList.prototype.addTrack = function addTrack(track) {
  16643. this.addTrack_(track);
  16644. };
  16645. /**
  16646. * Remove a {@link VideoTrack} to the `VideoTrackList`.
  16647. *
  16648. * @param {VideoTrack} track
  16649. * The VideoTrack to remove from the list.
  16650. *
  16651. * @fires TrackList#removetrack
  16652. */
  16653. VideoTrackList.prototype.removeTrack = function removeTrack(track) {
  16654. _TrackList.prototype.removeTrack_.call(this, track);
  16655. };
  16656. return VideoTrackList;
  16657. }(_trackList2['default']);
  16658. exports['default'] = VideoTrackList;
  16659. },{"74":74,"78":78,"94":94}],77:[function(_dereq_,module,exports){
  16660. 'use strict';
  16661. exports.__esModule = true;
  16662. var _trackEnums = _dereq_(73);
  16663. var _track = _dereq_(75);
  16664. var _track2 = _interopRequireDefault(_track);
  16665. var _mergeOptions = _dereq_(87);
  16666. var _mergeOptions2 = _interopRequireDefault(_mergeOptions);
  16667. var _browser = _dereq_(78);
  16668. var browser = _interopRequireWildcard(_browser);
  16669. 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; } }
  16670. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  16671. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  16672. 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; }
  16673. 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; }
  16674. /**
  16675. * A representation of a single `VideoTrack`.
  16676. *
  16677. * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#videotrack}
  16678. * @extends Track
  16679. */
  16680. var VideoTrack = function (_Track) {
  16681. _inherits(VideoTrack, _Track);
  16682. /**
  16683. * Create an instance of this class.
  16684. *
  16685. * @param {Object} [options={}]
  16686. * Object of option names and values
  16687. *
  16688. * @param {string} [options.kind='']
  16689. * A valid {@link VideoTrack~Kind}
  16690. *
  16691. * @param {string} [options.id='vjs_track_' + Guid.newGUID()]
  16692. * A unique id for this AudioTrack.
  16693. *
  16694. * @param {string} [options.label='']
  16695. * The menu label for this track.
  16696. *
  16697. * @param {string} [options.language='']
  16698. * A valid two character language code.
  16699. *
  16700. * @param {boolean} [options.selected]
  16701. * If this track is the one that is currently playing.
  16702. */
  16703. function VideoTrack() {
  16704. var _this, _ret;
  16705. var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  16706. _classCallCheck(this, VideoTrack);
  16707. var settings = (0, _mergeOptions2['default'])(options, {
  16708. kind: _trackEnums.VideoTrackKind[options.kind] || ''
  16709. });
  16710. // on IE8 this will be a document element
  16711. // for every other browser this will be a normal object
  16712. var track = (_this = _possibleConstructorReturn(this, _Track.call(this, settings)), _this);
  16713. var selected = false;
  16714. if (browser.IS_IE8) {
  16715. for (var prop in VideoTrack.prototype) {
  16716. if (prop !== 'constructor') {
  16717. track[prop] = VideoTrack.prototype[prop];
  16718. }
  16719. }
  16720. }
  16721. /**
  16722. * @member {boolean} selected
  16723. * If this `VideoTrack` is selected or not. When setting this will
  16724. * fire {@link VideoTrack#selectedchange} if the state of selected changed.
  16725. *
  16726. * @fires VideoTrack#selectedchange
  16727. */
  16728. Object.defineProperty(track, 'selected', {
  16729. get: function get() {
  16730. return selected;
  16731. },
  16732. set: function set(newSelected) {
  16733. // an invalid or unchanged value
  16734. if (typeof newSelected !== 'boolean' || newSelected === selected) {
  16735. return;
  16736. }
  16737. selected = newSelected;
  16738. /**
  16739. * An event that fires when selected changes on this track. This allows
  16740. * the VideoTrackList that holds this track to act accordingly.
  16741. *
  16742. * > Note: This is not part of the spec! Native tracks will do
  16743. * this internally without an event.
  16744. *
  16745. * @event VideoTrack#selectedchange
  16746. * @type {EventTarget~Event}
  16747. */
  16748. this.trigger('selectedchange');
  16749. }
  16750. });
  16751. // if the user sets this track to selected then
  16752. // set selected to that true value otherwise
  16753. // we keep it false
  16754. if (settings.selected) {
  16755. track.selected = settings.selected;
  16756. }
  16757. return _ret = track, _possibleConstructorReturn(_this, _ret);
  16758. }
  16759. return VideoTrack;
  16760. }(_track2['default']);
  16761. exports['default'] = VideoTrack;
  16762. },{"73":73,"75":75,"78":78,"87":87}],78:[function(_dereq_,module,exports){
  16763. 'use strict';
  16764. exports.__esModule = true;
  16765. 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;
  16766. var _dom = _dereq_(81);
  16767. var Dom = _interopRequireWildcard(_dom);
  16768. var _window = _dereq_(95);
  16769. var _window2 = _interopRequireDefault(_window);
  16770. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  16771. 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; } }
  16772. /**
  16773. * @file browser.js
  16774. * @module browser
  16775. */
  16776. var USER_AGENT = _window2['default'].navigator && _window2['default'].navigator.userAgent || '';
  16777. var webkitVersionMap = /AppleWebKit\/([\d.]+)/i.exec(USER_AGENT);
  16778. var appleWebkitVersion = webkitVersionMap ? parseFloat(webkitVersionMap.pop()) : null;
  16779. /*
  16780. * Device is an iPhone
  16781. *
  16782. * @type {Boolean}
  16783. * @constant
  16784. * @private
  16785. */
  16786. var IS_IPAD = exports.IS_IPAD = /iPad/i.test(USER_AGENT);
  16787. // The Facebook app's UIWebView identifies as both an iPhone and iPad, so
  16788. // to identify iPhones, we need to exclude iPads.
  16789. // http://artsy.github.io/blog/2012/10/18/the-perils-of-ios-user-agent-sniffing/
  16790. var IS_IPHONE = exports.IS_IPHONE = /iPhone/i.test(USER_AGENT) && !IS_IPAD;
  16791. var IS_IPOD = exports.IS_IPOD = /iPod/i.test(USER_AGENT);
  16792. var IS_IOS = exports.IS_IOS = IS_IPHONE || IS_IPAD || IS_IPOD;
  16793. var IOS_VERSION = exports.IOS_VERSION = function () {
  16794. var match = USER_AGENT.match(/OS (\d+)_/i);
  16795. if (match && match[1]) {
  16796. return match[1];
  16797. }
  16798. return null;
  16799. }();
  16800. var IS_ANDROID = exports.IS_ANDROID = /Android/i.test(USER_AGENT);
  16801. var ANDROID_VERSION = exports.ANDROID_VERSION = function () {
  16802. // This matches Android Major.Minor.Patch versions
  16803. // ANDROID_VERSION is Major.Minor as a Number, if Minor isn't available, then only Major is returned
  16804. var match = USER_AGENT.match(/Android (\d+)(?:\.(\d+))?(?:\.(\d+))*/i);
  16805. if (!match) {
  16806. return null;
  16807. }
  16808. var major = match[1] && parseFloat(match[1]);
  16809. var minor = match[2] && parseFloat(match[2]);
  16810. if (major && minor) {
  16811. return parseFloat(match[1] + '.' + match[2]);
  16812. } else if (major) {
  16813. return major;
  16814. }
  16815. return null;
  16816. }();
  16817. // Old Android is defined as Version older than 2.3, and requiring a webkit version of the android browser
  16818. var IS_OLD_ANDROID = exports.IS_OLD_ANDROID = IS_ANDROID && /webkit/i.test(USER_AGENT) && ANDROID_VERSION < 2.3;
  16819. var IS_NATIVE_ANDROID = exports.IS_NATIVE_ANDROID = IS_ANDROID && ANDROID_VERSION < 5 && appleWebkitVersion < 537;
  16820. var IS_FIREFOX = exports.IS_FIREFOX = /Firefox/i.test(USER_AGENT);
  16821. var IS_EDGE = exports.IS_EDGE = /Edge/i.test(USER_AGENT);
  16822. var IS_CHROME = exports.IS_CHROME = !IS_EDGE && /Chrome/i.test(USER_AGENT);
  16823. var IS_IE8 = exports.IS_IE8 = /MSIE\s8\.0/.test(USER_AGENT);
  16824. var IE_VERSION = exports.IE_VERSION = function (result) {
  16825. return result && parseFloat(result[1]);
  16826. }(/MSIE\s(\d+)\.\d/.exec(USER_AGENT));
  16827. var IS_SAFARI = exports.IS_SAFARI = /Safari/i.test(USER_AGENT) && !IS_CHROME && !IS_ANDROID && !IS_EDGE;
  16828. var IS_ANY_SAFARI = exports.IS_ANY_SAFARI = IS_SAFARI || IS_IOS;
  16829. var TOUCH_ENABLED = exports.TOUCH_ENABLED = Dom.isReal() && ('ontouchstart' in _window2['default'] || _window2['default'].DocumentTouch && _window2['default'].document instanceof _window2['default'].DocumentTouch);
  16830. var BACKGROUND_SIZE_SUPPORTED = exports.BACKGROUND_SIZE_SUPPORTED = Dom.isReal() && 'backgroundSize' in _window2['default'].document.createElement('video').style;
  16831. },{"81":81,"95":95}],79:[function(_dereq_,module,exports){
  16832. 'use strict';
  16833. exports.__esModule = true;
  16834. exports.bufferedPercent = bufferedPercent;
  16835. var _timeRanges = _dereq_(90);
  16836. /**
  16837. * Compute the percentage of the media that has been buffered.
  16838. *
  16839. * @param {TimeRange} buffered
  16840. * The current `TimeRange` object representing buffered time ranges
  16841. *
  16842. * @param {number} duration
  16843. * Total duration of the media
  16844. *
  16845. * @return {number}
  16846. * Percent buffered of the total duration in decimal form.
  16847. */
  16848. function bufferedPercent(buffered, duration) {
  16849. var bufferedDuration = 0;
  16850. var start = void 0;
  16851. var end = void 0;
  16852. if (!duration) {
  16853. return 0;
  16854. }
  16855. if (!buffered || !buffered.length) {
  16856. buffered = (0, _timeRanges.createTimeRange)(0, 0);
  16857. }
  16858. for (var i = 0; i < buffered.length; i++) {
  16859. start = buffered.start(i);
  16860. end = buffered.end(i);
  16861. // buffered end can be bigger than duration by a very small fraction
  16862. if (end > duration) {
  16863. end = duration;
  16864. }
  16865. bufferedDuration += end - start;
  16866. }
  16867. return bufferedDuration / duration;
  16868. } /**
  16869. * @file buffer.js
  16870. * @module buffer
  16871. */
  16872. },{"90":90}],80:[function(_dereq_,module,exports){
  16873. 'use strict';
  16874. exports.__esModule = true;
  16875. exports['default'] = computedStyle;
  16876. var _window = _dereq_(95);
  16877. var _window2 = _interopRequireDefault(_window);
  16878. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  16879. /**
  16880. * A safe getComputedStyle with an IE8 fallback.
  16881. *
  16882. * This is needed because in Firefox, if the player is loaded in an iframe with
  16883. * `display:none`, then `getComputedStyle` returns `null`, so, we do a null-check to
  16884. * make sure that the player doesn't break in these cases.
  16885. *
  16886. * @param {Element} el
  16887. * The element you want the computed style of
  16888. *
  16889. * @param {string} prop
  16890. * The property name you want
  16891. *
  16892. * @see https://bugzilla.mozilla.org/show_bug.cgi?id=548397
  16893. */
  16894. function computedStyle(el, prop) {
  16895. if (!el || !prop) {
  16896. return '';
  16897. }
  16898. if (typeof _window2['default'].getComputedStyle === 'function') {
  16899. var cs = _window2['default'].getComputedStyle(el);
  16900. return cs ? cs[prop] : '';
  16901. }
  16902. return el.currentStyle[prop] || '';
  16903. } /**
  16904. * @file computed-style.js
  16905. * @module computed-style
  16906. */
  16907. },{"95":95}],81:[function(_dereq_,module,exports){
  16908. 'use strict';
  16909. exports.__esModule = true;
  16910. exports.$$ = exports.$ = undefined;
  16911. 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 ', '.']);
  16912. exports.isReal = isReal;
  16913. exports.isEl = isEl;
  16914. exports.getEl = getEl;
  16915. exports.createEl = createEl;
  16916. exports.textContent = textContent;
  16917. exports.insertElFirst = insertElFirst;
  16918. exports.getElData = getElData;
  16919. exports.hasElData = hasElData;
  16920. exports.removeElData = removeElData;
  16921. exports.hasElClass = hasElClass;
  16922. exports.addElClass = addElClass;
  16923. exports.removeElClass = removeElClass;
  16924. exports.toggleElClass = toggleElClass;
  16925. exports.setElAttributes = setElAttributes;
  16926. exports.getElAttributes = getElAttributes;
  16927. exports.getAttribute = getAttribute;
  16928. exports.setAttribute = setAttribute;
  16929. exports.removeAttribute = removeAttribute;
  16930. exports.blockTextSelection = blockTextSelection;
  16931. exports.unblockTextSelection = unblockTextSelection;
  16932. exports.findElPosition = findElPosition;
  16933. exports.getPointerPosition = getPointerPosition;
  16934. exports.isTextNode = isTextNode;
  16935. exports.emptyEl = emptyEl;
  16936. exports.normalizeContent = normalizeContent;
  16937. exports.appendContent = appendContent;
  16938. exports.insertContent = insertContent;
  16939. var _document = _dereq_(94);
  16940. var _document2 = _interopRequireDefault(_document);
  16941. var _window = _dereq_(95);
  16942. var _window2 = _interopRequireDefault(_window);
  16943. var _guid = _dereq_(85);
  16944. var Guid = _interopRequireWildcard(_guid);
  16945. var _log = _dereq_(86);
  16946. var _log2 = _interopRequireDefault(_log);
  16947. var _tsml = _dereq_(98);
  16948. var _tsml2 = _interopRequireDefault(_tsml);
  16949. var _obj = _dereq_(88);
  16950. 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; } }
  16951. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  16952. function _taggedTemplateLiteralLoose(strings, raw) { strings.raw = raw; return strings; } /**
  16953. * @file dom.js
  16954. * @module dom
  16955. */
  16956. /**
  16957. * Detect if a value is a string with any non-whitespace characters.
  16958. *
  16959. * @param {string} str
  16960. * The string to check
  16961. *
  16962. * @return {boolean}
  16963. * - True if the string is non-blank
  16964. * - False otherwise
  16965. *
  16966. */
  16967. function isNonBlankString(str) {
  16968. return typeof str === 'string' && /\S/.test(str);
  16969. }
  16970. /**
  16971. * Throws an error if the passed string has whitespace. This is used by
  16972. * class methods to be relatively consistent with the classList API.
  16973. *
  16974. * @param {string} str
  16975. * The string to check for whitespace.
  16976. *
  16977. * @throws {Error}
  16978. * Throws an error if there is whitespace in the string.
  16979. *
  16980. */
  16981. function throwIfWhitespace(str) {
  16982. if (/\s/.test(str)) {
  16983. throw new Error('class has illegal whitespace characters');
  16984. }
  16985. }
  16986. /**
  16987. * Produce a regular expression for matching a className within an elements className.
  16988. *
  16989. * @param {string} className
  16990. * The className to generate the RegExp for.
  16991. *
  16992. * @return {RegExp}
  16993. * The RegExp that will check for a specific `className` in an elements
  16994. * className.
  16995. */
  16996. function classRegExp(className) {
  16997. return new RegExp('(^|\\s)' + className + '($|\\s)');
  16998. }
  16999. /**
  17000. * Whether the current DOM interface appears to be real.
  17001. *
  17002. * @return {Boolean}
  17003. */
  17004. function isReal() {
  17005. return (
  17006. // Both document and window will never be undefined thanks to `global`.
  17007. _document2['default'] === _window2['default'].document &&
  17008. // In IE < 9, DOM methods return "object" as their type, so all we can
  17009. // confidently check is that it exists.
  17010. typeof _document2['default'].createElement !== 'undefined'
  17011. );
  17012. }
  17013. /**
  17014. * Determines, via duck typing, whether or not a value is a DOM element.
  17015. *
  17016. * @param {Mixed} value
  17017. * The thing to check
  17018. *
  17019. * @return {boolean}
  17020. * - True if it is a DOM element
  17021. * - False otherwise
  17022. */
  17023. function isEl(value) {
  17024. return (0, _obj.isObject)(value) && value.nodeType === 1;
  17025. }
  17026. /**
  17027. * Creates functions to query the DOM using a given method.
  17028. *
  17029. * @param {string} method
  17030. * The method to create the query with.
  17031. *
  17032. * @return {Function}
  17033. * The query method
  17034. */
  17035. function createQuerier(method) {
  17036. return function (selector, context) {
  17037. if (!isNonBlankString(selector)) {
  17038. return _document2['default'][method](null);
  17039. }
  17040. if (isNonBlankString(context)) {
  17041. context = _document2['default'].querySelector(context);
  17042. }
  17043. var ctx = isEl(context) ? context : _document2['default'];
  17044. return ctx[method] && ctx[method](selector);
  17045. };
  17046. }
  17047. /**
  17048. * Shorthand for document.getElementById()
  17049. * Also allows for CSS (jQuery) ID syntax. But nothing other than IDs.
  17050. *
  17051. * @param {string} id
  17052. * The id of the element to get
  17053. *
  17054. * @return {Element|null}
  17055. * Element with supplied ID or null if there wasn't one.
  17056. */
  17057. function getEl(id) {
  17058. if (id.indexOf('#') === 0) {
  17059. id = id.slice(1);
  17060. }
  17061. return _document2['default'].getElementById(id);
  17062. }
  17063. /**
  17064. * Creates an element and applies properties.
  17065. *
  17066. * @param {string} [tagName='div']
  17067. * Name of tag to be created.
  17068. *
  17069. * @param {Object} [properties={}]
  17070. * Element properties to be applied.
  17071. *
  17072. * @param {Object} [attributes={}]
  17073. * Element attributes to be applied.
  17074. *
  17075. * @param {String|Element|TextNode|Array|Function} [content]
  17076. * Contents for the element (see: {@link dom:normalizeContent})
  17077. *
  17078. * @return {Element}
  17079. * The element that was created.
  17080. */
  17081. function createEl() {
  17082. var tagName = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'div';
  17083. var properties = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  17084. var attributes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
  17085. var content = arguments[3];
  17086. var el = _document2['default'].createElement(tagName);
  17087. Object.getOwnPropertyNames(properties).forEach(function (propName) {
  17088. var val = properties[propName];
  17089. // See #2176
  17090. // We originally were accepting both properties and attributes in the
  17091. // same object, but that doesn't work so well.
  17092. if (propName.indexOf('aria-') !== -1 || propName === 'role' || propName === 'type') {
  17093. _log2['default'].warn((0, _tsml2['default'])(_templateObject, propName, val));
  17094. el.setAttribute(propName, val);
  17095. // Handle textContent since it's not supported everywhere and we have a
  17096. // method for it.
  17097. } else if (propName === 'textContent') {
  17098. textContent(el, val);
  17099. } else {
  17100. el[propName] = val;
  17101. }
  17102. });
  17103. Object.getOwnPropertyNames(attributes).forEach(function (attrName) {
  17104. el.setAttribute(attrName, attributes[attrName]);
  17105. });
  17106. if (content) {
  17107. appendContent(el, content);
  17108. }
  17109. return el;
  17110. }
  17111. /**
  17112. * Injects text into an element, replacing any existing contents entirely.
  17113. *
  17114. * @param {Element} el
  17115. * The element to add text content into
  17116. *
  17117. * @param {string} text
  17118. * The text content to add.
  17119. *
  17120. * @return {Element}
  17121. * The element with added text content.
  17122. */
  17123. function textContent(el, text) {
  17124. if (typeof el.textContent === 'undefined') {
  17125. el.innerText = text;
  17126. } else {
  17127. el.textContent = text;
  17128. }
  17129. return el;
  17130. }
  17131. /**
  17132. * Insert an element as the first child node of another
  17133. *
  17134. * @param {Element} child
  17135. * Element to insert
  17136. *
  17137. * @param {Element} parent
  17138. * Element to insert child into
  17139. *
  17140. */
  17141. function insertElFirst(child, parent) {
  17142. if (parent.firstChild) {
  17143. parent.insertBefore(child, parent.firstChild);
  17144. } else {
  17145. parent.appendChild(child);
  17146. }
  17147. }
  17148. /**
  17149. * Element Data Store. Allows for binding data to an element without putting it directly on the element.
  17150. * Ex. Event listeners are stored here.
  17151. * (also from jsninja.com, slightly modified and updated for closure compiler)
  17152. *
  17153. * @type {Object}
  17154. * @private
  17155. */
  17156. var elData = {};
  17157. /*
  17158. * Unique attribute name to store an element's guid in
  17159. *
  17160. * @type {string}
  17161. * @constant
  17162. * @private
  17163. */
  17164. var elIdAttr = 'vdata' + new Date().getTime();
  17165. /**
  17166. * Returns the cache object where data for an element is stored
  17167. *
  17168. * @param {Element} el
  17169. * Element to store data for.
  17170. *
  17171. * @return {Object}
  17172. * The cache object for that el that was passed in.
  17173. */
  17174. function getElData(el) {
  17175. var id = el[elIdAttr];
  17176. if (!id) {
  17177. id = el[elIdAttr] = Guid.newGUID();
  17178. }
  17179. if (!elData[id]) {
  17180. elData[id] = {};
  17181. }
  17182. return elData[id];
  17183. }
  17184. /**
  17185. * Returns whether or not an element has cached data
  17186. *
  17187. * @param {Element} el
  17188. * Check if this element has cached data.
  17189. *
  17190. * @return {boolean}
  17191. * - True if the DOM element has cached data.
  17192. * - False otherwise.
  17193. */
  17194. function hasElData(el) {
  17195. var id = el[elIdAttr];
  17196. if (!id) {
  17197. return false;
  17198. }
  17199. return !!Object.getOwnPropertyNames(elData[id]).length;
  17200. }
  17201. /**
  17202. * Delete data for the element from the cache and the guid attr from getElementById
  17203. *
  17204. * @param {Element} el
  17205. * Remove cached data for this element.
  17206. */
  17207. function removeElData(el) {
  17208. var id = el[elIdAttr];
  17209. if (!id) {
  17210. return;
  17211. }
  17212. // Remove all stored data
  17213. delete elData[id];
  17214. // Remove the elIdAttr property from the DOM node
  17215. try {
  17216. delete el[elIdAttr];
  17217. } catch (e) {
  17218. if (el.removeAttribute) {
  17219. el.removeAttribute(elIdAttr);
  17220. } else {
  17221. // IE doesn't appear to support removeAttribute on the document element
  17222. el[elIdAttr] = null;
  17223. }
  17224. }
  17225. }
  17226. /**
  17227. * Check if an element has a CSS class
  17228. *
  17229. * @param {Element} element
  17230. * Element to check
  17231. *
  17232. * @param {string} classToCheck
  17233. * Class name to check for
  17234. *
  17235. * @return {boolean}
  17236. * - True if the element had the class
  17237. * - False otherwise.
  17238. *
  17239. * @throws {Error}
  17240. * Throws an error if `classToCheck` has white space.
  17241. */
  17242. function hasElClass(element, classToCheck) {
  17243. throwIfWhitespace(classToCheck);
  17244. if (element.classList) {
  17245. return element.classList.contains(classToCheck);
  17246. }
  17247. return classRegExp(classToCheck).test(element.className);
  17248. }
  17249. /**
  17250. * Add a CSS class name to an element
  17251. *
  17252. * @param {Element} element
  17253. * Element to add class name to.
  17254. *
  17255. * @param {string} classToAdd
  17256. * Class name to add.
  17257. *
  17258. * @return {Element}
  17259. * The dom element with the added class name.
  17260. */
  17261. function addElClass(element, classToAdd) {
  17262. if (element.classList) {
  17263. element.classList.add(classToAdd);
  17264. // Don't need to `throwIfWhitespace` here because `hasElClass` will do it
  17265. // in the case of classList not being supported.
  17266. } else if (!hasElClass(element, classToAdd)) {
  17267. element.className = (element.className + ' ' + classToAdd).trim();
  17268. }
  17269. return element;
  17270. }
  17271. /**
  17272. * Remove a CSS class name from an element
  17273. *
  17274. * @param {Element} element
  17275. * Element to remove a class name from.
  17276. *
  17277. * @param {string} classToRemove
  17278. * Class name to remove
  17279. *
  17280. * @return {Element}
  17281. * The dom element with class name removed.
  17282. */
  17283. function removeElClass(element, classToRemove) {
  17284. if (element.classList) {
  17285. element.classList.remove(classToRemove);
  17286. } else {
  17287. throwIfWhitespace(classToRemove);
  17288. element.className = element.className.split(/\s+/).filter(function (c) {
  17289. return c !== classToRemove;
  17290. }).join(' ');
  17291. }
  17292. return element;
  17293. }
  17294. /**
  17295. * The callback definition for toggleElClass.
  17296. *
  17297. * @callback Dom~PredicateCallback
  17298. * @param {Element} element
  17299. * The DOM element of the Component.
  17300. *
  17301. * @param {string} classToToggle
  17302. * The `className` that wants to be toggled
  17303. *
  17304. * @return {boolean|undefined}
  17305. * - If true the `classToToggle` will get added to `element`.
  17306. * - If false the `classToToggle` will get removed from `element`.
  17307. * - If undefined this callback will be ignored
  17308. */
  17309. /**
  17310. * Adds or removes a CSS class name on an element depending on an optional
  17311. * condition or the presence/absence of the class name.
  17312. *
  17313. * @param {Element} element
  17314. * The element to toggle a class name on.
  17315. *
  17316. * @param {string} classToToggle
  17317. * The class that should be toggled
  17318. *
  17319. * @param {boolean|PredicateCallback} [predicate]
  17320. * See the return value for {@link Dom~PredicateCallback}
  17321. *
  17322. * @return {Element}
  17323. * The element with a class that has been toggled.
  17324. */
  17325. function toggleElClass(element, classToToggle, predicate) {
  17326. // This CANNOT use `classList` internally because IE does not support the
  17327. // second parameter to the `classList.toggle()` method! Which is fine because
  17328. // `classList` will be used by the add/remove functions.
  17329. var has = hasElClass(element, classToToggle);
  17330. if (typeof predicate === 'function') {
  17331. predicate = predicate(element, classToToggle);
  17332. }
  17333. if (typeof predicate !== 'boolean') {
  17334. predicate = !has;
  17335. }
  17336. // If the necessary class operation matches the current state of the
  17337. // element, no action is required.
  17338. if (predicate === has) {
  17339. return;
  17340. }
  17341. if (predicate) {
  17342. addElClass(element, classToToggle);
  17343. } else {
  17344. removeElClass(element, classToToggle);
  17345. }
  17346. return element;
  17347. }
  17348. /**
  17349. * Apply attributes to an HTML element.
  17350. *
  17351. * @param {Element} el
  17352. * Element to add attributes to.
  17353. *
  17354. * @param {Object} [attributes]
  17355. * Attributes to be applied.
  17356. */
  17357. function setElAttributes(el, attributes) {
  17358. Object.getOwnPropertyNames(attributes).forEach(function (attrName) {
  17359. var attrValue = attributes[attrName];
  17360. if (attrValue === null || typeof attrValue === 'undefined' || attrValue === false) {
  17361. el.removeAttribute(attrName);
  17362. } else {
  17363. el.setAttribute(attrName, attrValue === true ? '' : attrValue);
  17364. }
  17365. });
  17366. }
  17367. /**
  17368. * Get an element's attribute values, as defined on the HTML tag
  17369. * Attributes are not the same as properties. They're defined on the tag
  17370. * or with setAttribute (which shouldn't be used with HTML)
  17371. * This will return true or false for boolean attributes.
  17372. *
  17373. * @param {Element} tag
  17374. * Element from which to get tag attributes.
  17375. *
  17376. * @return {Object}
  17377. * All attributes of the element.
  17378. */
  17379. function getElAttributes(tag) {
  17380. var obj = {};
  17381. // known boolean attributes
  17382. // we can check for matching boolean properties, but older browsers
  17383. // won't know about HTML5 boolean attributes that we still read from
  17384. var knownBooleans = ',' + 'autoplay,controls,loop,muted,default' + ',';
  17385. if (tag && tag.attributes && tag.attributes.length > 0) {
  17386. var attrs = tag.attributes;
  17387. for (var i = attrs.length - 1; i >= 0; i--) {
  17388. var attrName = attrs[i].name;
  17389. var attrVal = attrs[i].value;
  17390. // check for known booleans
  17391. // the matching element property will return a value for typeof
  17392. if (typeof tag[attrName] === 'boolean' || knownBooleans.indexOf(',' + attrName + ',') !== -1) {
  17393. // the value of an included boolean attribute is typically an empty
  17394. // string ('') which would equal false if we just check for a false value.
  17395. // we also don't want support bad code like autoplay='false'
  17396. attrVal = attrVal !== null ? true : false;
  17397. }
  17398. obj[attrName] = attrVal;
  17399. }
  17400. }
  17401. return obj;
  17402. }
  17403. /**
  17404. * Get the value of an element's attribute
  17405. *
  17406. * @param {Element} el
  17407. * A DOM element
  17408. *
  17409. * @param {string} attribute
  17410. * Attribute to get the value of
  17411. *
  17412. * @return {string}
  17413. * value of the attribute
  17414. */
  17415. function getAttribute(el, attribute) {
  17416. return el.getAttribute(attribute);
  17417. }
  17418. /**
  17419. * Set the value of an element's attribute
  17420. *
  17421. * @param {Element} el
  17422. * A DOM element
  17423. *
  17424. * @param {string} attribute
  17425. * Attribute to set
  17426. *
  17427. * @param {string} value
  17428. * Value to set the attribute to
  17429. */
  17430. function setAttribute(el, attribute, value) {
  17431. el.setAttribute(attribute, value);
  17432. }
  17433. /**
  17434. * Remove an element's attribute
  17435. *
  17436. * @param {Element} el
  17437. * A DOM element
  17438. *
  17439. * @param {string} attribute
  17440. * Attribute to remove
  17441. */
  17442. function removeAttribute(el, attribute) {
  17443. el.removeAttribute(attribute);
  17444. }
  17445. /**
  17446. * Attempt to block the ability to select text while dragging controls
  17447. */
  17448. function blockTextSelection() {
  17449. _document2['default'].body.focus();
  17450. _document2['default'].onselectstart = function () {
  17451. return false;
  17452. };
  17453. }
  17454. /**
  17455. * Turn off text selection blocking
  17456. */
  17457. function unblockTextSelection() {
  17458. _document2['default'].onselectstart = function () {
  17459. return true;
  17460. };
  17461. }
  17462. /**
  17463. * The postion of a DOM element on the page.
  17464. *
  17465. * @typedef {Object} Dom~Position
  17466. *
  17467. * @property {number} left
  17468. * Pixels to the left
  17469. *
  17470. * @property {number} top
  17471. * Pixels on top
  17472. */
  17473. /**
  17474. * Offset Left.
  17475. * getBoundingClientRect technique from
  17476. * John Resig
  17477. *
  17478. * @see http://ejohn.org/blog/getboundingclientrect-is-awesome/
  17479. *
  17480. * @param {Element} el
  17481. * Element from which to get offset
  17482. *
  17483. * @return {Dom~Position}
  17484. * The position of the element that was passed in.
  17485. */
  17486. function findElPosition(el) {
  17487. var box = void 0;
  17488. if (el.getBoundingClientRect && el.parentNode) {
  17489. box = el.getBoundingClientRect();
  17490. }
  17491. if (!box) {
  17492. return {
  17493. left: 0,
  17494. top: 0
  17495. };
  17496. }
  17497. var docEl = _document2['default'].documentElement;
  17498. var body = _document2['default'].body;
  17499. var clientLeft = docEl.clientLeft || body.clientLeft || 0;
  17500. var scrollLeft = _window2['default'].pageXOffset || body.scrollLeft;
  17501. var left = box.left + scrollLeft - clientLeft;
  17502. var clientTop = docEl.clientTop || body.clientTop || 0;
  17503. var scrollTop = _window2['default'].pageYOffset || body.scrollTop;
  17504. var top = box.top + scrollTop - clientTop;
  17505. // Android sometimes returns slightly off decimal values, so need to round
  17506. return {
  17507. left: Math.round(left),
  17508. top: Math.round(top)
  17509. };
  17510. }
  17511. /**
  17512. * x and y coordinates for a dom element or mouse pointer
  17513. *
  17514. * @typedef {Object} Dom~Coordinates
  17515. *
  17516. * @property {number} x
  17517. * x coordinate in pixels
  17518. *
  17519. * @property {number} y
  17520. * y coordinate in pixels
  17521. */
  17522. /**
  17523. * Get pointer position in element
  17524. * Returns an object with x and y coordinates.
  17525. * The base on the coordinates are the bottom left of the element.
  17526. *
  17527. * @param {Element} el
  17528. * Element on which to get the pointer position on
  17529. *
  17530. * @param {EventTarget~Event} event
  17531. * Event object
  17532. *
  17533. * @return {Dom~Coordinates}
  17534. * A Coordinates object corresponding to the mouse position.
  17535. *
  17536. */
  17537. function getPointerPosition(el, event) {
  17538. var position = {};
  17539. var box = findElPosition(el);
  17540. var boxW = el.offsetWidth;
  17541. var boxH = el.offsetHeight;
  17542. var boxY = box.top;
  17543. var boxX = box.left;
  17544. var pageY = event.pageY;
  17545. var pageX = event.pageX;
  17546. if (event.changedTouches) {
  17547. pageX = event.changedTouches[0].pageX;
  17548. pageY = event.changedTouches[0].pageY;
  17549. }
  17550. position.y = Math.max(0, Math.min(1, (boxY - pageY + boxH) / boxH));
  17551. position.x = Math.max(0, Math.min(1, (pageX - boxX) / boxW));
  17552. return position;
  17553. }
  17554. /**
  17555. * Determines, via duck typing, whether or not a value is a text node.
  17556. *
  17557. * @param {Mixed} value
  17558. * Check if this value is a text node.
  17559. *
  17560. * @return {boolean}
  17561. * - True if it is a text node
  17562. * - False otherwise
  17563. */
  17564. function isTextNode(value) {
  17565. return (0, _obj.isObject)(value) && value.nodeType === 3;
  17566. }
  17567. /**
  17568. * Empties the contents of an element.
  17569. *
  17570. * @param {Element} el
  17571. * The element to empty children from
  17572. *
  17573. * @return {Element}
  17574. * The element with no children
  17575. */
  17576. function emptyEl(el) {
  17577. while (el.firstChild) {
  17578. el.removeChild(el.firstChild);
  17579. }
  17580. return el;
  17581. }
  17582. /**
  17583. * Normalizes content for eventual insertion into the DOM.
  17584. *
  17585. * This allows a wide range of content definition methods, but protects
  17586. * from falling into the trap of simply writing to `innerHTML`, which is
  17587. * an XSS concern.
  17588. *
  17589. * The content for an element can be passed in multiple types and
  17590. * combinations, whose behavior is as follows:
  17591. *
  17592. * @param {String|Element|TextNode|Array|Function} content
  17593. * - String: Normalized into a text node.
  17594. * - Element/TextNode: Passed through.
  17595. * - Array: A one-dimensional array of strings, elements, nodes, or functions
  17596. * (which return single strings, elements, or nodes).
  17597. * - Function: If the sole argument, is expected to produce a string, element,
  17598. * node, or array as defined above.
  17599. *
  17600. * @return {Array}
  17601. * All of the content that was passed in normalized.
  17602. */
  17603. function normalizeContent(content) {
  17604. // First, invoke content if it is a function. If it produces an array,
  17605. // that needs to happen before normalization.
  17606. if (typeof content === 'function') {
  17607. content = content();
  17608. }
  17609. // Next up, normalize to an array, so one or many items can be normalized,
  17610. // filtered, and returned.
  17611. return (Array.isArray(content) ? content : [content]).map(function (value) {
  17612. // First, invoke value if it is a function to produce a new value,
  17613. // which will be subsequently normalized to a Node of some kind.
  17614. if (typeof value === 'function') {
  17615. value = value();
  17616. }
  17617. if (isEl(value) || isTextNode(value)) {
  17618. return value;
  17619. }
  17620. if (typeof value === 'string' && /\S/.test(value)) {
  17621. return _document2['default'].createTextNode(value);
  17622. }
  17623. }).filter(function (value) {
  17624. return value;
  17625. });
  17626. }
  17627. /**
  17628. * Normalizes and appends content to an element.
  17629. *
  17630. * @param {Element} el
  17631. * Element to append normalized content to.
  17632. *
  17633. *
  17634. * @param {String|Element|TextNode|Array|Function} content
  17635. * See the `content` argument of {@link dom:normalizeContent}
  17636. *
  17637. * @return {Element}
  17638. * The element with appended normalized content.
  17639. */
  17640. function appendContent(el, content) {
  17641. normalizeContent(content).forEach(function (node) {
  17642. return el.appendChild(node);
  17643. });
  17644. return el;
  17645. }
  17646. /**
  17647. * Normalizes and inserts content into an element; this is identical to
  17648. * `appendContent()`, except it empties the element first.
  17649. *
  17650. * @param {Element} el
  17651. * Element to insert normalized content into.
  17652. *
  17653. * @param {String|Element|TextNode|Array|Function} content
  17654. * See the `content` argument of {@link dom:normalizeContent}
  17655. *
  17656. * @return {Element}
  17657. * The element with inserted normalized content.
  17658. *
  17659. */
  17660. function insertContent(el, content) {
  17661. return appendContent(emptyEl(el), content);
  17662. }
  17663. /**
  17664. * Finds a single DOM element matching `selector` within the optional
  17665. * `context` of another DOM element (defaulting to `document`).
  17666. *
  17667. * @param {string} selector
  17668. * A valid CSS selector, which will be passed to `querySelector`.
  17669. *
  17670. * @param {Element|String} [context=document]
  17671. * A DOM element within which to query. Can also be a selector
  17672. * string in which case the first matching element will be used
  17673. * as context. If missing (or no element matches selector), falls
  17674. * back to `document`.
  17675. *
  17676. * @return {Element|null}
  17677. * The element that was found or null.
  17678. */
  17679. var $ = exports.$ = createQuerier('querySelector');
  17680. /**
  17681. * Finds a all DOM elements matching `selector` within the optional
  17682. * `context` of another DOM element (defaulting to `document`).
  17683. *
  17684. * @param {string} selector
  17685. * A valid CSS selector, which will be passed to `querySelectorAll`.
  17686. *
  17687. * @param {Element|String} [context=document]
  17688. * A DOM element within which to query. Can also be a selector
  17689. * string in which case the first matching element will be used
  17690. * as context. If missing (or no element matches selector), falls
  17691. * back to `document`.
  17692. *
  17693. * @return {NodeList}
  17694. * A element list of elements that were found. Will be empty if none were found.
  17695. *
  17696. */
  17697. var $$ = exports.$$ = createQuerier('querySelectorAll');
  17698. },{"85":85,"86":86,"88":88,"94":94,"95":95,"98":98}],82:[function(_dereq_,module,exports){
  17699. 'use strict';
  17700. exports.__esModule = true;
  17701. exports.fixEvent = fixEvent;
  17702. exports.on = on;
  17703. exports.off = off;
  17704. exports.trigger = trigger;
  17705. exports.one = one;
  17706. var _dom = _dereq_(81);
  17707. var Dom = _interopRequireWildcard(_dom);
  17708. var _guid = _dereq_(85);
  17709. var Guid = _interopRequireWildcard(_guid);
  17710. var _log = _dereq_(86);
  17711. var _log2 = _interopRequireDefault(_log);
  17712. var _window = _dereq_(95);
  17713. var _window2 = _interopRequireDefault(_window);
  17714. var _document = _dereq_(94);
  17715. var _document2 = _interopRequireDefault(_document);
  17716. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  17717. 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; } }
  17718. /**
  17719. * Clean up the listener cache and dispatchers
  17720. *
  17721. * @param {Element|Object} elem
  17722. * Element to clean up
  17723. *
  17724. * @param {string} type
  17725. * Type of event to clean up
  17726. */
  17727. function _cleanUpEvents(elem, type) {
  17728. var data = Dom.getElData(elem);
  17729. // Remove the events of a particular type if there are none left
  17730. if (data.handlers[type].length === 0) {
  17731. delete data.handlers[type];
  17732. // data.handlers[type] = null;
  17733. // Setting to null was causing an error with data.handlers
  17734. // Remove the meta-handler from the element
  17735. if (elem.removeEventListener) {
  17736. elem.removeEventListener(type, data.dispatcher, false);
  17737. } else if (elem.detachEvent) {
  17738. elem.detachEvent('on' + type, data.dispatcher);
  17739. }
  17740. }
  17741. // Remove the events object if there are no types left
  17742. if (Object.getOwnPropertyNames(data.handlers).length <= 0) {
  17743. delete data.handlers;
  17744. delete data.dispatcher;
  17745. delete data.disabled;
  17746. }
  17747. // Finally remove the element data if there is no data left
  17748. if (Object.getOwnPropertyNames(data).length === 0) {
  17749. Dom.removeElData(elem);
  17750. }
  17751. }
  17752. /**
  17753. * Loops through an array of event types and calls the requested method for each type.
  17754. *
  17755. * @param {Function} fn
  17756. * The event method we want to use.
  17757. *
  17758. * @param {Element|Object} elem
  17759. * Element or object to bind listeners to
  17760. *
  17761. * @param {string} type
  17762. * Type of event to bind to.
  17763. *
  17764. * @param {EventTarget~EventListener} callback
  17765. * Event listener.
  17766. */
  17767. /**
  17768. * @file events.js. An Event System (John Resig - Secrets of a JS Ninja http://jsninja.com/)
  17769. * (Original book version wasn't completely usable, so fixed some things and made Closure Compiler compatible)
  17770. * This should work very similarly to jQuery's events, however it's based off the book version which isn't as
  17771. * robust as jquery's, so there's probably some differences.
  17772. *
  17773. * @module events
  17774. */
  17775. function _handleMultipleEvents(fn, elem, types, callback) {
  17776. types.forEach(function (type) {
  17777. // Call the event method for each one of the types
  17778. fn(elem, type, callback);
  17779. });
  17780. }
  17781. /**
  17782. * Fix a native event to have standard property values
  17783. *
  17784. * @param {Object} event
  17785. * Event object to fix.
  17786. *
  17787. * @return {Object}
  17788. * Fixed event object.
  17789. */
  17790. function fixEvent(event) {
  17791. function returnTrue() {
  17792. return true;
  17793. }
  17794. function returnFalse() {
  17795. return false;
  17796. }
  17797. // Test if fixing up is needed
  17798. // Used to check if !event.stopPropagation instead of isPropagationStopped
  17799. // But native events return true for stopPropagation, but don't have
  17800. // other expected methods like isPropagationStopped. Seems to be a problem
  17801. // with the Javascript Ninja code. So we're just overriding all events now.
  17802. if (!event || !event.isPropagationStopped) {
  17803. (function () {
  17804. var old = event || _window2['default'].event;
  17805. event = {};
  17806. // Clone the old object so that we can modify the values event = {};
  17807. // IE8 Doesn't like when you mess with native event properties
  17808. // Firefox returns false for event.hasOwnProperty('type') and other props
  17809. // which makes copying more difficult.
  17810. // TODO: Probably best to create a whitelist of event props
  17811. for (var key in old) {
  17812. // Safari 6.0.3 warns you if you try to copy deprecated layerX/Y
  17813. // Chrome warns you if you try to copy deprecated keyboardEvent.keyLocation
  17814. // and webkitMovementX/Y
  17815. if (key !== 'layerX' && key !== 'layerY' && key !== 'keyLocation' && key !== 'webkitMovementX' && key !== 'webkitMovementY') {
  17816. // Chrome 32+ warns if you try to copy deprecated returnValue, but
  17817. // we still want to if preventDefault isn't supported (IE8).
  17818. if (!(key === 'returnValue' && old.preventDefault)) {
  17819. event[key] = old[key];
  17820. }
  17821. }
  17822. }
  17823. // The event occurred on this element
  17824. if (!event.target) {
  17825. event.target = event.srcElement || _document2['default'];
  17826. }
  17827. // Handle which other element the event is related to
  17828. if (!event.relatedTarget) {
  17829. event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement;
  17830. }
  17831. // Stop the default browser action
  17832. event.preventDefault = function () {
  17833. if (old.preventDefault) {
  17834. old.preventDefault();
  17835. }
  17836. event.returnValue = false;
  17837. old.returnValue = false;
  17838. event.defaultPrevented = true;
  17839. };
  17840. event.defaultPrevented = false;
  17841. // Stop the event from bubbling
  17842. event.stopPropagation = function () {
  17843. if (old.stopPropagation) {
  17844. old.stopPropagation();
  17845. }
  17846. event.cancelBubble = true;
  17847. old.cancelBubble = true;
  17848. event.isPropagationStopped = returnTrue;
  17849. };
  17850. event.isPropagationStopped = returnFalse;
  17851. // Stop the event from bubbling and executing other handlers
  17852. event.stopImmediatePropagation = function () {
  17853. if (old.stopImmediatePropagation) {
  17854. old.stopImmediatePropagation();
  17855. }
  17856. event.isImmediatePropagationStopped = returnTrue;
  17857. event.stopPropagation();
  17858. };
  17859. event.isImmediatePropagationStopped = returnFalse;
  17860. // Handle mouse position
  17861. if (event.clientX !== null && event.clientX !== undefined) {
  17862. var doc = _document2['default'].documentElement;
  17863. var body = _document2['default'].body;
  17864. event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
  17865. event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0);
  17866. }
  17867. // Handle key presses
  17868. event.which = event.charCode || event.keyCode;
  17869. // Fix button for mouse clicks:
  17870. // 0 == left; 1 == middle; 2 == right
  17871. if (event.button !== null && event.button !== undefined) {
  17872. // The following is disabled because it does not pass videojs-standard
  17873. // and... yikes.
  17874. /* eslint-disable */
  17875. event.button = event.button & 1 ? 0 : event.button & 4 ? 1 : event.button & 2 ? 2 : 0;
  17876. /* eslint-enable */
  17877. }
  17878. })();
  17879. }
  17880. // Returns fixed-up instance
  17881. return event;
  17882. }
  17883. /**
  17884. * Add an event listener to element
  17885. * It stores the handler function in a separate cache object
  17886. * and adds a generic handler to the element's event,
  17887. * along with a unique id (guid) to the element.
  17888. *
  17889. * @param {Element|Object} elem
  17890. * Element or object to bind listeners to
  17891. *
  17892. * @param {string|string[]} type
  17893. * Type of event to bind to.
  17894. *
  17895. * @param {EventTarget~EventListener} fn
  17896. * Event listener.
  17897. */
  17898. function on(elem, type, fn) {
  17899. if (Array.isArray(type)) {
  17900. return _handleMultipleEvents(on, elem, type, fn);
  17901. }
  17902. var data = Dom.getElData(elem);
  17903. // We need a place to store all our handler data
  17904. if (!data.handlers) {
  17905. data.handlers = {};
  17906. }
  17907. if (!data.handlers[type]) {
  17908. data.handlers[type] = [];
  17909. }
  17910. if (!fn.guid) {
  17911. fn.guid = Guid.newGUID();
  17912. }
  17913. data.handlers[type].push(fn);
  17914. if (!data.dispatcher) {
  17915. data.disabled = false;
  17916. data.dispatcher = function (event, hash) {
  17917. if (data.disabled) {
  17918. return;
  17919. }
  17920. event = fixEvent(event);
  17921. var handlers = data.handlers[event.type];
  17922. if (handlers) {
  17923. // Copy handlers so if handlers are added/removed during the process it doesn't throw everything off.
  17924. var handlersCopy = handlers.slice(0);
  17925. for (var m = 0, n = handlersCopy.length; m < n; m++) {
  17926. if (event.isImmediatePropagationStopped()) {
  17927. break;
  17928. } else {
  17929. try {
  17930. handlersCopy[m].call(elem, event, hash);
  17931. } catch (e) {
  17932. _log2['default'].error(e);
  17933. }
  17934. }
  17935. }
  17936. }
  17937. };
  17938. }
  17939. if (data.handlers[type].length === 1) {
  17940. if (elem.addEventListener) {
  17941. elem.addEventListener(type, data.dispatcher, false);
  17942. } else if (elem.attachEvent) {
  17943. elem.attachEvent('on' + type, data.dispatcher);
  17944. }
  17945. }
  17946. }
  17947. /**
  17948. * Removes event listeners from an element
  17949. *
  17950. * @param {Element|Object} elem
  17951. * Object to remove listeners from.
  17952. *
  17953. * @param {string|string[]} [type]
  17954. * Type of listener to remove. Don't include to remove all events from element.
  17955. *
  17956. * @param {EventTarget~EventListener} [fn]
  17957. * Specific listener to remove. Don't include to remove listeners for an event
  17958. * type.
  17959. */
  17960. function off(elem, type, fn) {
  17961. // Don't want to add a cache object through getElData if not needed
  17962. if (!Dom.hasElData(elem)) {
  17963. return;
  17964. }
  17965. var data = Dom.getElData(elem);
  17966. // If no events exist, nothing to unbind
  17967. if (!data.handlers) {
  17968. return;
  17969. }
  17970. if (Array.isArray(type)) {
  17971. return _handleMultipleEvents(off, elem, type, fn);
  17972. }
  17973. // Utility function
  17974. var removeType = function removeType(t) {
  17975. data.handlers[t] = [];
  17976. _cleanUpEvents(elem, t);
  17977. };
  17978. // Are we removing all bound events?
  17979. if (!type) {
  17980. for (var t in data.handlers) {
  17981. removeType(t);
  17982. }
  17983. return;
  17984. }
  17985. var handlers = data.handlers[type];
  17986. // If no handlers exist, nothing to unbind
  17987. if (!handlers) {
  17988. return;
  17989. }
  17990. // If no listener was provided, remove all listeners for type
  17991. if (!fn) {
  17992. removeType(type);
  17993. return;
  17994. }
  17995. // We're only removing a single handler
  17996. if (fn.guid) {
  17997. for (var n = 0; n < handlers.length; n++) {
  17998. if (handlers[n].guid === fn.guid) {
  17999. handlers.splice(n--, 1);
  18000. }
  18001. }
  18002. }
  18003. _cleanUpEvents(elem, type);
  18004. }
  18005. /**
  18006. * Trigger an event for an element
  18007. *
  18008. * @param {Element|Object} elem
  18009. * Element to trigger an event on
  18010. *
  18011. * @param {EventTarget~Event|string} event
  18012. * A string (the type) or an event object with a type attribute
  18013. *
  18014. * @param {Object} [hash]
  18015. * data hash to pass along with the event
  18016. *
  18017. * @return {boolean|undefined}
  18018. * - Returns the opposite of `defaultPrevented` if default was prevented
  18019. * - Otherwise returns undefined
  18020. */
  18021. function trigger(elem, event, hash) {
  18022. // Fetches element data and a reference to the parent (for bubbling).
  18023. // Don't want to add a data object to cache for every parent,
  18024. // so checking hasElData first.
  18025. var elemData = Dom.hasElData(elem) ? Dom.getElData(elem) : {};
  18026. var parent = elem.parentNode || elem.ownerDocument;
  18027. // type = event.type || event,
  18028. // handler;
  18029. // If an event name was passed as a string, creates an event out of it
  18030. if (typeof event === 'string') {
  18031. event = { type: event, target: elem };
  18032. }
  18033. // Normalizes the event properties.
  18034. event = fixEvent(event);
  18035. // If the passed element has a dispatcher, executes the established handlers.
  18036. if (elemData.dispatcher) {
  18037. elemData.dispatcher.call(elem, event, hash);
  18038. }
  18039. // Unless explicitly stopped or the event does not bubble (e.g. media events)
  18040. // recursively calls this function to bubble the event up the DOM.
  18041. if (parent && !event.isPropagationStopped() && event.bubbles === true) {
  18042. trigger.call(null, parent, event, hash);
  18043. // If at the top of the DOM, triggers the default action unless disabled.
  18044. } else if (!parent && !event.defaultPrevented) {
  18045. var targetData = Dom.getElData(event.target);
  18046. // Checks if the target has a default action for this event.
  18047. if (event.target[event.type]) {
  18048. // Temporarily disables event dispatching on the target as we have already executed the handler.
  18049. targetData.disabled = true;
  18050. // Executes the default action.
  18051. if (typeof event.target[event.type] === 'function') {
  18052. event.target[event.type]();
  18053. }
  18054. // Re-enables event dispatching.
  18055. targetData.disabled = false;
  18056. }
  18057. }
  18058. // Inform the triggerer if the default was prevented by returning false
  18059. return !event.defaultPrevented;
  18060. }
  18061. /**
  18062. * Trigger a listener only once for an event
  18063. *
  18064. * @param {Element|Object} elem
  18065. * Element or object to bind to.
  18066. *
  18067. * @param {string|string[]} type
  18068. * Name/type of event
  18069. *
  18070. * @param {Event~EventListener} fn
  18071. * Event Listener function
  18072. */
  18073. function one(elem, type, fn) {
  18074. if (Array.isArray(type)) {
  18075. return _handleMultipleEvents(one, elem, type, fn);
  18076. }
  18077. var func = function func() {
  18078. off(elem, type, func);
  18079. fn.apply(this, arguments);
  18080. };
  18081. // copy the guid to the new function so it can removed using the original function's ID
  18082. func.guid = fn.guid = fn.guid || Guid.newGUID();
  18083. on(elem, type, func);
  18084. }
  18085. },{"81":81,"85":85,"86":86,"94":94,"95":95}],83:[function(_dereq_,module,exports){
  18086. 'use strict';
  18087. exports.__esModule = true;
  18088. exports.throttle = exports.bind = undefined;
  18089. var _guid = _dereq_(85);
  18090. /**
  18091. * Bind (a.k.a proxy or Context). A simple method for changing the context of a function
  18092. * It also stores a unique id on the function so it can be easily removed from events.
  18093. *
  18094. * @param {Mixed} context
  18095. * The object to bind as scope.
  18096. *
  18097. * @param {Function} fn
  18098. * The function to be bound to a scope.
  18099. *
  18100. * @param {number} [uid]
  18101. * An optional unique ID for the function to be set
  18102. *
  18103. * @return {Function}
  18104. * The new function that will be bound into the context given
  18105. */
  18106. var bind = exports.bind = function bind(context, fn, uid) {
  18107. // Make sure the function has a unique ID
  18108. if (!fn.guid) {
  18109. fn.guid = (0, _guid.newGUID)();
  18110. }
  18111. // Create the new function that changes the context
  18112. var bound = function bound() {
  18113. return fn.apply(context, arguments);
  18114. };
  18115. // Allow for the ability to individualize this function
  18116. // Needed in the case where multiple objects might share the same prototype
  18117. // IF both items add an event listener with the same function, then you try to remove just one
  18118. // it will remove both because they both have the same guid.
  18119. // when using this, you need to use the bind method when you remove the listener as well.
  18120. // currently used in text tracks
  18121. bound.guid = uid ? uid + '_' + fn.guid : fn.guid;
  18122. return bound;
  18123. };
  18124. /**
  18125. * Wraps the given function, `fn`, with a new function that only invokes `fn`
  18126. * at most once per every `wait` milliseconds.
  18127. *
  18128. * @param {Function} fn
  18129. * The function to be throttled.
  18130. *
  18131. * @param {Number} wait
  18132. * The number of milliseconds by which to throttle.
  18133. *
  18134. * @return {Function}
  18135. */
  18136. /**
  18137. * @file fn.js
  18138. * @module fn
  18139. */
  18140. var throttle = exports.throttle = function throttle(fn, wait) {
  18141. var last = Date.now();
  18142. var throttled = function throttled() {
  18143. var now = Date.now();
  18144. if (now - last >= wait) {
  18145. fn.apply(undefined, arguments);
  18146. last = now;
  18147. }
  18148. };
  18149. return throttled;
  18150. };
  18151. },{"85":85}],84:[function(_dereq_,module,exports){
  18152. 'use strict';
  18153. exports.__esModule = true;
  18154. /**
  18155. * @file format-time.js
  18156. * @module Format-time
  18157. */
  18158. /**
  18159. * Format seconds as a time string, H:MM:SS or M:SS. Supplying a guide (in seconds)
  18160. * will force a number of leading zeros to cover the length of the guide.
  18161. *
  18162. * @param {number} seconds
  18163. * Number of seconds to be turned into a string
  18164. *
  18165. * @param {number} guide
  18166. * Number (in seconds) to model the string after
  18167. *
  18168. * @return {string}
  18169. * Time formatted as H:MM:SS or M:SS
  18170. */
  18171. function formatTime(seconds) {
  18172. var guide = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : seconds;
  18173. seconds = seconds < 0 ? 0 : seconds;
  18174. var s = Math.floor(seconds % 60);
  18175. var m = Math.floor(seconds / 60 % 60);
  18176. var h = Math.floor(seconds / 3600);
  18177. var gm = Math.floor(guide / 60 % 60);
  18178. var gh = Math.floor(guide / 3600);
  18179. // handle invalid times
  18180. if (isNaN(seconds) || seconds === Infinity) {
  18181. // '-' is false for all relational operators (e.g. <, >=) so this setting
  18182. // will add the minimum number of fields specified by the guide
  18183. h = m = s = '-';
  18184. }
  18185. // Check if we need to show hours
  18186. h = h > 0 || gh > 0 ? h + ':' : '';
  18187. // If hours are showing, we may need to add a leading zero.
  18188. // Always show at least one digit of minutes.
  18189. m = ((h || gm >= 10) && m < 10 ? '0' + m : m) + ':';
  18190. // Check if leading zero is need for seconds
  18191. s = s < 10 ? '0' + s : s;
  18192. return h + m + s;
  18193. }
  18194. exports['default'] = formatTime;
  18195. },{}],85:[function(_dereq_,module,exports){
  18196. "use strict";
  18197. exports.__esModule = true;
  18198. exports.newGUID = newGUID;
  18199. /**
  18200. * @file guid.js
  18201. * @module guid
  18202. */
  18203. /**
  18204. * Unique ID for an element or function
  18205. * @type {Number}
  18206. */
  18207. var _guid = 1;
  18208. /**
  18209. * Get a unique auto-incrementing ID by number that has not been returned before.
  18210. *
  18211. * @return {number}
  18212. * A new unique ID.
  18213. */
  18214. function newGUID() {
  18215. return _guid++;
  18216. }
  18217. },{}],86:[function(_dereq_,module,exports){
  18218. 'use strict';
  18219. exports.__esModule = true;
  18220. exports.logByType = undefined;
  18221. var _window = _dereq_(95);
  18222. var _window2 = _interopRequireDefault(_window);
  18223. var _browser = _dereq_(78);
  18224. var _obj = _dereq_(88);
  18225. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  18226. var log = void 0;
  18227. /**
  18228. * Log messages to the console and history based on the type of message
  18229. *
  18230. * @param {string} type
  18231. * The name of the console method to use.
  18232. *
  18233. * @param {Array} args
  18234. * The arguments to be passed to the matching console method.
  18235. *
  18236. * @param {boolean} [stringify]
  18237. * By default, only old IEs should get console argument stringification,
  18238. * but this is exposed as a parameter to facilitate testing.
  18239. */
  18240. /**
  18241. * @file log.js
  18242. * @module log
  18243. */
  18244. var logByType = exports.logByType = function logByType(type, args) {
  18245. var stringify = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : !!_browser.IE_VERSION && _browser.IE_VERSION < 11;
  18246. if (type !== 'log') {
  18247. // add the type to the front of the message when it's not "log"
  18248. args.unshift(type.toUpperCase() + ':');
  18249. }
  18250. // add to history
  18251. log.history.push(args);
  18252. // add console prefix after adding to history
  18253. args.unshift('VIDEOJS:');
  18254. // If there's no console then don't try to output messages, but they will
  18255. // still be stored in `log.history`.
  18256. //
  18257. // Was setting these once outside of this function, but containing them
  18258. // in the function makes it easier to test cases where console doesn't exist
  18259. // when the module is executed.
  18260. var fn = _window2['default'].console && _window2['default'].console[type];
  18261. // Bail out if there's no console.
  18262. if (!fn) {
  18263. return;
  18264. }
  18265. // IEs previous to 11 log objects uselessly as "[object Object]"; so, JSONify
  18266. // objects and arrays for those less-capable browsers.
  18267. if (stringify) {
  18268. args = args.map(function (a) {
  18269. if ((0, _obj.isObject)(a) || Array.isArray(a)) {
  18270. try {
  18271. return JSON.stringify(a);
  18272. } catch (x) {
  18273. return String(a);
  18274. }
  18275. }
  18276. // Cast to string before joining, so we get null and undefined explicitly
  18277. // included in output (as we would in a modern console).
  18278. return String(a);
  18279. }).join(' ');
  18280. }
  18281. // Old IE versions do not allow .apply() for console methods (they are
  18282. // reported as objects rather than functions).
  18283. if (!fn.apply) {
  18284. fn(args);
  18285. } else {
  18286. fn[Array.isArray(args) ? 'apply' : 'call'](_window2['default'].console, args);
  18287. }
  18288. };
  18289. /**
  18290. * Log plain debug messages
  18291. *
  18292. * @param {Mixed[]} args
  18293. * One or more messages or objects that should be logged.
  18294. */
  18295. log = function log() {
  18296. for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
  18297. args[_key] = arguments[_key];
  18298. }
  18299. logByType('log', args);
  18300. };
  18301. /**
  18302. * Keep a history of log messages
  18303. *
  18304. * @type {Array}
  18305. */
  18306. log.history = [];
  18307. /**
  18308. * Log error messages
  18309. *
  18310. * @param {Mixed[]} args
  18311. * One or more messages or objects that should be logged as an error
  18312. */
  18313. log.error = function () {
  18314. for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
  18315. args[_key2] = arguments[_key2];
  18316. }
  18317. return logByType('error', args);
  18318. };
  18319. /**
  18320. * Log warning messages
  18321. *
  18322. * @param {Mixed[]} args
  18323. * One or more messages or objects that should be logged as a warning.
  18324. */
  18325. log.warn = function () {
  18326. for (var _len3 = arguments.length, args = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
  18327. args[_key3] = arguments[_key3];
  18328. }
  18329. return logByType('warn', args);
  18330. };
  18331. exports['default'] = log;
  18332. },{"78":78,"88":88,"95":95}],87:[function(_dereq_,module,exports){
  18333. 'use strict';
  18334. exports.__esModule = true;
  18335. exports['default'] = mergeOptions;
  18336. var _obj = _dereq_(88);
  18337. /**
  18338. * Deep-merge one or more options objects, recursively merging **only** plain
  18339. * object properties.
  18340. *
  18341. * @param {Object[]} sources
  18342. * One or more objects to merge into a new object.
  18343. *
  18344. * @returns {Object}
  18345. * A new object that is the merged result of all sources.
  18346. */
  18347. function mergeOptions() {
  18348. var result = {};
  18349. for (var _len = arguments.length, sources = Array(_len), _key = 0; _key < _len; _key++) {
  18350. sources[_key] = arguments[_key];
  18351. }
  18352. sources.forEach(function (source) {
  18353. if (!source) {
  18354. return;
  18355. }
  18356. (0, _obj.each)(source, function (value, key) {
  18357. if (!(0, _obj.isPlain)(value)) {
  18358. result[key] = value;
  18359. return;
  18360. }
  18361. if (!(0, _obj.isPlain)(result[key])) {
  18362. result[key] = {};
  18363. }
  18364. result[key] = mergeOptions(result[key], value);
  18365. });
  18366. });
  18367. return result;
  18368. } /**
  18369. * @file merge-options.js
  18370. * @module merge-options
  18371. */
  18372. },{"88":88}],88:[function(_dereq_,module,exports){
  18373. 'use strict';
  18374. exports.__esModule = true;
  18375. 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; };
  18376. exports.each = each;
  18377. exports.reduce = reduce;
  18378. exports.assign = assign;
  18379. exports.isObject = isObject;
  18380. exports.isPlain = isPlain;
  18381. /**
  18382. * @file obj.js
  18383. * @module obj
  18384. */
  18385. /**
  18386. * @callback obj:EachCallback
  18387. *
  18388. * @param {Mixed} value
  18389. * The current key for the object that is being iterated over.
  18390. *
  18391. * @param {string} key
  18392. * The current key-value for object that is being iterated over
  18393. */
  18394. /**
  18395. * @callback obj:ReduceCallback
  18396. *
  18397. * @param {Mixed} accum
  18398. * The value that is accumulating over the reduce loop.
  18399. *
  18400. * @param {Mixed} value
  18401. * The current key for the object that is being iterated over.
  18402. *
  18403. * @param {string} key
  18404. * The current key-value for object that is being iterated over
  18405. *
  18406. * @return {Mixed}
  18407. * The new accumulated value.
  18408. */
  18409. var toString = Object.prototype.toString;
  18410. /**
  18411. * Array-like iteration for objects.
  18412. *
  18413. * @param {Object} object
  18414. * The object to iterate over
  18415. *
  18416. * @param {obj:EachCallback} fn
  18417. * The callback function which is called for each key in the object.
  18418. */
  18419. function each(object, fn) {
  18420. Object.keys(object).forEach(function (key) {
  18421. return fn(object[key], key);
  18422. });
  18423. }
  18424. /**
  18425. * Array-like reduce for objects.
  18426. *
  18427. * @param {Object} object
  18428. * The Object that you want to reduce.
  18429. *
  18430. * @param {Function} fn
  18431. * A callback function which is called for each key in the object. It
  18432. * receives the accumulated value and the per-iteration value and key
  18433. * as arguments.
  18434. *
  18435. * @param {Mixed} [initial = 0]
  18436. * Starting value
  18437. *
  18438. * @return {Mixed}
  18439. * The final accumulated value.
  18440. */
  18441. function reduce(object, fn) {
  18442. var initial = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
  18443. return Object.keys(object).reduce(function (accum, key) {
  18444. return fn(accum, object[key], key);
  18445. }, initial);
  18446. }
  18447. /**
  18448. * Object.assign-style object shallow merge/extend.
  18449. *
  18450. * @param {Object} target
  18451. * @param {Object} ...sources
  18452. * @return {Object}
  18453. */
  18454. function assign(target) {
  18455. for (var _len = arguments.length, sources = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
  18456. sources[_key - 1] = arguments[_key];
  18457. }
  18458. if (Object.assign) {
  18459. return Object.assign.apply(Object, [target].concat(sources));
  18460. }
  18461. sources.forEach(function (source) {
  18462. if (!source) {
  18463. return;
  18464. }
  18465. each(source, function (value, key) {
  18466. target[key] = value;
  18467. });
  18468. });
  18469. return target;
  18470. }
  18471. /**
  18472. * Returns whether a value is an object of any kind - including DOM nodes,
  18473. * arrays, regular expressions, etc. Not functions, though.
  18474. *
  18475. * This avoids the gotcha where using `typeof` on a `null` value
  18476. * results in `'object'`.
  18477. *
  18478. * @param {Object} value
  18479. * @return {Boolean}
  18480. */
  18481. function isObject(value) {
  18482. return !!value && (typeof value === 'undefined' ? 'undefined' : _typeof(value)) === 'object';
  18483. }
  18484. /**
  18485. * Returns whether an object appears to be a "plain" object - that is, a
  18486. * direct instance of `Object`.
  18487. *
  18488. * @param {Object} value
  18489. * @return {Boolean}
  18490. */
  18491. function isPlain(value) {
  18492. return isObject(value) && toString.call(value) === '[object Object]' && value.constructor === Object;
  18493. }
  18494. },{}],89:[function(_dereq_,module,exports){
  18495. 'use strict';
  18496. exports.__esModule = true;
  18497. exports.setTextContent = exports.createStyleElement = undefined;
  18498. var _document = _dereq_(94);
  18499. var _document2 = _interopRequireDefault(_document);
  18500. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  18501. /**
  18502. * Create a DOM syle element given a className for it.
  18503. *
  18504. * @param {string} className
  18505. * The className to add to the created style element.
  18506. *
  18507. * @return {Element}
  18508. * The element that was created.
  18509. */
  18510. var createStyleElement = exports.createStyleElement = function createStyleElement(className) {
  18511. var style = _document2['default'].createElement('style');
  18512. style.className = className;
  18513. return style;
  18514. };
  18515. /**
  18516. * Add text to a DOM element.
  18517. *
  18518. * @param {Element} el
  18519. * The Element to add text content to.
  18520. *
  18521. * @param {string} content
  18522. * The text to add to the element.
  18523. */
  18524. /**
  18525. * @file stylesheet.js
  18526. * @module stylesheet
  18527. */
  18528. var setTextContent = exports.setTextContent = function setTextContent(el, content) {
  18529. if (el.styleSheet) {
  18530. el.styleSheet.cssText = content;
  18531. } else {
  18532. el.textContent = content;
  18533. }
  18534. };
  18535. },{"94":94}],90:[function(_dereq_,module,exports){
  18536. 'use strict';
  18537. exports.__esModule = true;
  18538. exports.createTimeRange = undefined;
  18539. exports.createTimeRanges = createTimeRanges;
  18540. var _log = _dereq_(86);
  18541. var _log2 = _interopRequireDefault(_log);
  18542. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  18543. /**
  18544. * Returns the time for the specified index at the start or end
  18545. * of a TimeRange object.
  18546. *
  18547. * @function time-ranges:indexFunction
  18548. *
  18549. * @param {number} [index=0]
  18550. * The range number to return the time for.
  18551. *
  18552. * @return {number}
  18553. * The time that offset at the specified index.
  18554. *
  18555. * @depricated index must be set to a value, in the future this will throw an error.
  18556. */
  18557. /**
  18558. * An object that contains ranges of time for various reasons.
  18559. *
  18560. * @typedef {Object} TimeRange
  18561. *
  18562. * @property {number} length
  18563. * The number of time ranges represented by this Object
  18564. *
  18565. * @property {time-ranges:indexFunction} start
  18566. * Returns the time offset at which a specified time range begins.
  18567. *
  18568. * @property {time-ranges:indexFunction} end
  18569. * Returns the time offset at which a specified time range begins.
  18570. *
  18571. * @see https://developer.mozilla.org/en-US/docs/Web/API/TimeRanges
  18572. */
  18573. /**
  18574. * Check if any of the time ranges are over the maximum index.
  18575. *
  18576. * @param {string} fnName
  18577. * The function name to use for logging
  18578. *
  18579. * @param {number} index
  18580. * The index to check
  18581. *
  18582. * @param {number} maxIndex
  18583. * The maximum possible index
  18584. *
  18585. * @throws {Error} if the timeRanges provided are over the maxIndex
  18586. */
  18587. function rangeCheck(fnName, index, maxIndex) {
  18588. if (index < 0 || index > maxIndex) {
  18589. throw new Error('Failed to execute \'' + fnName + '\' on \'TimeRanges\': The index provided (' + index + ') is greater than or equal to the maximum bound (' + maxIndex + ').');
  18590. }
  18591. }
  18592. /**
  18593. * Check if any of the time ranges are over the maximum index.
  18594. *
  18595. * @param {string} fnName
  18596. * The function name to use for logging
  18597. *
  18598. * @param {string} valueIndex
  18599. * The proprety that should be used to get the time. should be 'start' or 'end'
  18600. *
  18601. * @param {Array} ranges
  18602. * An array of time ranges
  18603. *
  18604. * @param {Array} [rangeIndex=0]
  18605. * The index to start the search at
  18606. *
  18607. * @return {number}
  18608. * The time that offset at the specified index.
  18609. *
  18610. *
  18611. * @depricated rangeIndex must be set to a value, in the future this will throw an error.
  18612. * @throws {Error} if rangeIndex is more than the length of ranges
  18613. */
  18614. /**
  18615. * @file time-ranges.js
  18616. * @module time-ranges
  18617. */
  18618. function getRange(fnName, valueIndex, ranges, rangeIndex) {
  18619. if (rangeIndex === undefined) {
  18620. _log2['default'].warn('DEPRECATED: Function \'' + fnName + '\' on \'TimeRanges\' called without an index argument.');
  18621. rangeIndex = 0;
  18622. }
  18623. rangeCheck(fnName, rangeIndex, ranges.length - 1);
  18624. return ranges[rangeIndex][valueIndex];
  18625. }
  18626. /**
  18627. * Create a time range object givent ranges of time.
  18628. *
  18629. * @param {Array} [ranges]
  18630. * An array of time ranges.
  18631. */
  18632. function createTimeRangesObj(ranges) {
  18633. if (ranges === undefined || ranges.length === 0) {
  18634. return {
  18635. length: 0,
  18636. start: function start() {
  18637. throw new Error('This TimeRanges object is empty');
  18638. },
  18639. end: function end() {
  18640. throw new Error('This TimeRanges object is empty');
  18641. }
  18642. };
  18643. }
  18644. return {
  18645. length: ranges.length,
  18646. start: getRange.bind(null, 'start', 0, ranges),
  18647. end: getRange.bind(null, 'end', 1, ranges)
  18648. };
  18649. }
  18650. /**
  18651. * Should create a fake `TimeRange` object which mimics an HTML5 time range instance.
  18652. *
  18653. * @param {number|Array} start
  18654. * The start of a single range or an array of ranges
  18655. *
  18656. * @param {number} end
  18657. * The end of a single range.
  18658. *
  18659. * @private
  18660. */
  18661. function createTimeRanges(start, end) {
  18662. if (Array.isArray(start)) {
  18663. return createTimeRangesObj(start);
  18664. } else if (start === undefined || end === undefined) {
  18665. return createTimeRangesObj();
  18666. }
  18667. return createTimeRangesObj([[start, end]]);
  18668. }
  18669. exports.createTimeRange = createTimeRanges;
  18670. },{"86":86}],91:[function(_dereq_,module,exports){
  18671. 'use strict';
  18672. exports.__esModule = true;
  18673. /**
  18674. * @file to-title-case.js
  18675. * @module to-title-case
  18676. */
  18677. /**
  18678. * Uppercase the first letter of a string.
  18679. *
  18680. * @param {string} string
  18681. * String to be uppercased
  18682. *
  18683. * @return {string}
  18684. * The string with an uppercased first letter
  18685. */
  18686. function toTitleCase(string) {
  18687. if (typeof string !== 'string') {
  18688. return string;
  18689. }
  18690. return string.charAt(0).toUpperCase() + string.slice(1);
  18691. }
  18692. exports['default'] = toTitleCase;
  18693. },{}],92:[function(_dereq_,module,exports){
  18694. 'use strict';
  18695. exports.__esModule = true;
  18696. exports.isCrossOrigin = exports.getFileExtension = exports.getAbsoluteURL = exports.parseUrl = undefined;
  18697. var _document = _dereq_(94);
  18698. var _document2 = _interopRequireDefault(_document);
  18699. var _window = _dereq_(95);
  18700. var _window2 = _interopRequireDefault(_window);
  18701. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  18702. /**
  18703. * @typedef {Object} url:URLObject
  18704. *
  18705. * @property {string} protocol
  18706. * The protocol of the url that was parsed.
  18707. *
  18708. * @property {string} hostname
  18709. * The hostname of the url that was parsed.
  18710. *
  18711. * @property {string} port
  18712. * The port of the url that was parsed.
  18713. *
  18714. * @property {string} pathname
  18715. * The pathname of the url that was parsed.
  18716. *
  18717. * @property {string} search
  18718. * The search query of the url that was parsed.
  18719. *
  18720. * @property {string} hash
  18721. * The hash of the url that was parsed.
  18722. *
  18723. * @property {string} host
  18724. * The host of the url that was parsed.
  18725. */
  18726. /**
  18727. * Resolve and parse the elements of a URL.
  18728. *
  18729. * @param {String} url
  18730. * The url to parse
  18731. *
  18732. * @return {url:URLObject}
  18733. * An object of url details
  18734. */
  18735. /**
  18736. * @file url.js
  18737. * @module url
  18738. */
  18739. var parseUrl = exports.parseUrl = function parseUrl(url) {
  18740. var props = ['protocol', 'hostname', 'port', 'pathname', 'search', 'hash', 'host'];
  18741. // add the url to an anchor and let the browser parse the URL
  18742. var a = _document2['default'].createElement('a');
  18743. a.href = url;
  18744. // IE8 (and 9?) Fix
  18745. // ie8 doesn't parse the URL correctly until the anchor is actually
  18746. // added to the body, and an innerHTML is needed to trigger the parsing
  18747. var addToBody = a.host === '' && a.protocol !== 'file:';
  18748. var div = void 0;
  18749. if (addToBody) {
  18750. div = _document2['default'].createElement('div');
  18751. div.innerHTML = '<a href="' + url + '"></a>';
  18752. a = div.firstChild;
  18753. // prevent the div from affecting layout
  18754. div.setAttribute('style', 'display:none; position:absolute;');
  18755. _document2['default'].body.appendChild(div);
  18756. }
  18757. // Copy the specific URL properties to a new object
  18758. // This is also needed for IE8 because the anchor loses its
  18759. // properties when it's removed from the dom
  18760. var details = {};
  18761. for (var i = 0; i < props.length; i++) {
  18762. details[props[i]] = a[props[i]];
  18763. }
  18764. // IE9 adds the port to the host property unlike everyone else. If
  18765. // a port identifier is added for standard ports, strip it.
  18766. if (details.protocol === 'http:') {
  18767. details.host = details.host.replace(/:80$/, '');
  18768. }
  18769. if (details.protocol === 'https:') {
  18770. details.host = details.host.replace(/:443$/, '');
  18771. }
  18772. if (addToBody) {
  18773. _document2['default'].body.removeChild(div);
  18774. }
  18775. return details;
  18776. };
  18777. /**
  18778. * Get absolute version of relative URL. Used to tell flash correct URL.
  18779. *
  18780. *
  18781. * @param {string} url
  18782. * URL to make absolute
  18783. *
  18784. * @return {string}
  18785. * Absolute URL
  18786. *
  18787. * @see http://stackoverflow.com/questions/470832/getting-an-absolute-url-from-a-relative-one-ie6-issue
  18788. */
  18789. var getAbsoluteURL = exports.getAbsoluteURL = function getAbsoluteURL(url) {
  18790. // Check if absolute URL
  18791. if (!url.match(/^https?:\/\//)) {
  18792. // Convert to absolute URL. Flash hosted off-site needs an absolute URL.
  18793. var div = _document2['default'].createElement('div');
  18794. div.innerHTML = '<a href="' + url + '">x</a>';
  18795. url = div.firstChild.href;
  18796. }
  18797. return url;
  18798. };
  18799. /**
  18800. * Returns the extension of the passed file name. It will return an empty string
  18801. * if passed an invalid path.
  18802. *
  18803. * @param {string} path
  18804. * The fileName path like '/path/to/file.mp4'
  18805. *
  18806. * @returns {string}
  18807. * The extension in lower case or an empty string if no
  18808. * extension could be found.
  18809. */
  18810. var getFileExtension = exports.getFileExtension = function getFileExtension(path) {
  18811. if (typeof path === 'string') {
  18812. var splitPathRe = /^(\/?)([\s\S]*?)((?:\.{1,2}|[^\/]+?)(\.([^\.\/\?]+)))(?:[\/]*|[\?].*)$/i;
  18813. var pathParts = splitPathRe.exec(path);
  18814. if (pathParts) {
  18815. return pathParts.pop().toLowerCase();
  18816. }
  18817. }
  18818. return '';
  18819. };
  18820. /**
  18821. * Returns whether the url passed is a cross domain request or not.
  18822. *
  18823. * @param {string} url
  18824. * The url to check.
  18825. *
  18826. * @return {boolean}
  18827. * Whether it is a cross domain request or not.
  18828. */
  18829. var isCrossOrigin = exports.isCrossOrigin = function isCrossOrigin(url) {
  18830. var winLoc = _window2['default'].location;
  18831. var urlInfo = parseUrl(url);
  18832. // IE8 protocol relative urls will return ':' for protocol
  18833. var srcProtocol = urlInfo.protocol === ':' ? winLoc.protocol : urlInfo.protocol;
  18834. // Check if url is for another domain/origin
  18835. // IE8 doesn't know location.origin, so we won't rely on it here
  18836. var crossOrigin = srcProtocol + urlInfo.host !== winLoc.protocol + winLoc.host;
  18837. return crossOrigin;
  18838. };
  18839. },{"94":94,"95":95}],93:[function(_dereq_,module,exports){
  18840. 'use strict';
  18841. exports.__esModule = true;
  18842. 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; }; /**
  18843. * @file video.js
  18844. * @module videojs
  18845. */
  18846. /* global define */
  18847. // Include the built-in techs
  18848. var _window = _dereq_(95);
  18849. var _window2 = _interopRequireDefault(_window);
  18850. var _document = _dereq_(94);
  18851. var _document2 = _interopRequireDefault(_document);
  18852. var _setup = _dereq_(56);
  18853. var setup = _interopRequireWildcard(_setup);
  18854. var _stylesheet = _dereq_(89);
  18855. var stylesheet = _interopRequireWildcard(_stylesheet);
  18856. var _component = _dereq_(5);
  18857. var _component2 = _interopRequireDefault(_component);
  18858. var _eventTarget = _dereq_(42);
  18859. var _eventTarget2 = _interopRequireDefault(_eventTarget);
  18860. var _events = _dereq_(82);
  18861. var Events = _interopRequireWildcard(_events);
  18862. var _player = _dereq_(51);
  18863. var _player2 = _interopRequireDefault(_player);
  18864. var _plugins = _dereq_(52);
  18865. var _plugins2 = _interopRequireDefault(_plugins);
  18866. var _mergeOptions2 = _dereq_(87);
  18867. var _mergeOptions3 = _interopRequireDefault(_mergeOptions2);
  18868. var _fn = _dereq_(83);
  18869. var Fn = _interopRequireWildcard(_fn);
  18870. var _textTrack = _dereq_(72);
  18871. var _textTrack2 = _interopRequireDefault(_textTrack);
  18872. var _audioTrack = _dereq_(64);
  18873. var _audioTrack2 = _interopRequireDefault(_audioTrack);
  18874. var _videoTrack = _dereq_(77);
  18875. var _videoTrack2 = _interopRequireDefault(_videoTrack);
  18876. var _timeRanges = _dereq_(90);
  18877. var _formatTime = _dereq_(84);
  18878. var _formatTime2 = _interopRequireDefault(_formatTime);
  18879. var _log = _dereq_(86);
  18880. var _log2 = _interopRequireDefault(_log);
  18881. var _dom = _dereq_(81);
  18882. var Dom = _interopRequireWildcard(_dom);
  18883. var _browser = _dereq_(78);
  18884. var browser = _interopRequireWildcard(_browser);
  18885. var _url = _dereq_(92);
  18886. var Url = _interopRequireWildcard(_url);
  18887. var _obj = _dereq_(88);
  18888. var _computedStyle = _dereq_(80);
  18889. var _computedStyle2 = _interopRequireDefault(_computedStyle);
  18890. var _extend = _dereq_(43);
  18891. var _extend2 = _interopRequireDefault(_extend);
  18892. var _xhr = _dereq_(105);
  18893. var _xhr2 = _interopRequireDefault(_xhr);
  18894. var _tech = _dereq_(62);
  18895. var _tech2 = _interopRequireDefault(_tech);
  18896. 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; } }
  18897. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  18898. // HTML5 Element Shim for IE8
  18899. if (typeof HTMLVideoElement === 'undefined' && Dom.isReal()) {
  18900. _document2['default'].createElement('video');
  18901. _document2['default'].createElement('audio');
  18902. _document2['default'].createElement('track');
  18903. }
  18904. /**
  18905. * Doubles as the main function for users to create a player instance and also
  18906. * the main library object.
  18907. * The `videojs` function can be used to initialize or retrieve a player.
  18908. *
  18909. * @param {string|Element} id
  18910. * Video element or video element ID
  18911. *
  18912. * @param {Object} [options]
  18913. * Optional options object for config/settings
  18914. *
  18915. * @param {Component~ReadyCallback} [ready]
  18916. * Optional ready callback
  18917. *
  18918. * @return {Player}
  18919. * A player instance
  18920. *
  18921. * @mixes videojs
  18922. */
  18923. function videojs(id, options, ready) {
  18924. var tag = void 0;
  18925. // Allow for element or ID to be passed in
  18926. // String ID
  18927. if (typeof id === 'string') {
  18928. // Adjust for jQuery ID syntax
  18929. if (id.indexOf('#') === 0) {
  18930. id = id.slice(1);
  18931. }
  18932. // If a player instance has already been created for this ID return it.
  18933. if (videojs.getPlayers()[id]) {
  18934. // If options or ready funtion are passed, warn
  18935. if (options) {
  18936. _log2['default'].warn('Player "' + id + '" is already initialised. Options will not be applied.');
  18937. }
  18938. if (ready) {
  18939. videojs.getPlayers()[id].ready(ready);
  18940. }
  18941. return videojs.getPlayers()[id];
  18942. }
  18943. // Otherwise get element for ID
  18944. tag = Dom.getEl(id);
  18945. // ID is a media element
  18946. } else {
  18947. tag = id;
  18948. }
  18949. // Check for a useable element
  18950. // re: nodeName, could be a box div also
  18951. if (!tag || !tag.nodeName) {
  18952. throw new TypeError('The element or ID supplied is not valid. (videojs)');
  18953. }
  18954. // Element may have a player attr referring to an already created player instance.
  18955. // If so return that otherwise set up a new player below
  18956. if (tag.player || _player2['default'].players[tag.playerId]) {
  18957. return tag.player || _player2['default'].players[tag.playerId];
  18958. }
  18959. options = options || {};
  18960. videojs.hooks('beforesetup').forEach(function (hookFunction) {
  18961. var opts = hookFunction(tag, (0, _mergeOptions3['default'])(options));
  18962. if (!(0, _obj.isObject)(opts) || Array.isArray(opts)) {
  18963. _log2['default'].error('please return an object in beforesetup hooks');
  18964. return;
  18965. }
  18966. options = (0, _mergeOptions3['default'])(options, opts);
  18967. });
  18968. var PlayerComponent = _component2['default'].getComponent('Player');
  18969. // If not, set up a new player
  18970. var player = new PlayerComponent(tag, options, ready);
  18971. videojs.hooks('setup').forEach(function (hookFunction) {
  18972. return hookFunction(player);
  18973. });
  18974. return player;
  18975. }
  18976. /**
  18977. * An Object that contains lifecycle hooks as keys which point to an array
  18978. * of functions that are run when a lifecycle is triggered
  18979. */
  18980. videojs.hooks_ = {};
  18981. /**
  18982. * Get a list of hooks for a specific lifecycle
  18983. *
  18984. * @param {string} type
  18985. * the lifecyle to get hooks from
  18986. *
  18987. * @param {Function} [fn]
  18988. * Optionally add a hook to the lifecycle that your are getting.
  18989. *
  18990. * @return {Array}
  18991. * an array of hooks, or an empty array if there are none.
  18992. */
  18993. videojs.hooks = function (type, fn) {
  18994. videojs.hooks_[type] = videojs.hooks_[type] || [];
  18995. if (fn) {
  18996. videojs.hooks_[type] = videojs.hooks_[type].concat(fn);
  18997. }
  18998. return videojs.hooks_[type];
  18999. };
  19000. /**
  19001. * Add a function hook to a specific videojs lifecycle.
  19002. *
  19003. * @param {string} type
  19004. * the lifecycle to hook the function to.
  19005. *
  19006. * @param {Function|Function[]}
  19007. * The function or array of functions to attach.
  19008. */
  19009. videojs.hook = function (type, fn) {
  19010. videojs.hooks(type, fn);
  19011. };
  19012. /**
  19013. * Remove a hook from a specific videojs lifecycle.
  19014. *
  19015. * @param {string} type
  19016. * the lifecycle that the function hooked to
  19017. *
  19018. * @param {Function} fn
  19019. * The hooked function to remove
  19020. *
  19021. * @return {boolean}
  19022. * The function that was removed or undef
  19023. */
  19024. videojs.removeHook = function (type, fn) {
  19025. var index = videojs.hooks(type).indexOf(fn);
  19026. if (index <= -1) {
  19027. return false;
  19028. }
  19029. videojs.hooks_[type] = videojs.hooks_[type].slice();
  19030. videojs.hooks_[type].splice(index, 1);
  19031. return true;
  19032. };
  19033. // Add default styles
  19034. if (_window2['default'].VIDEOJS_NO_DYNAMIC_STYLE !== true && Dom.isReal()) {
  19035. var style = Dom.$('.vjs-styles-defaults');
  19036. if (!style) {
  19037. style = stylesheet.createStyleElement('vjs-styles-defaults');
  19038. var head = Dom.$('head');
  19039. if (head) {
  19040. head.insertBefore(style, head.firstChild);
  19041. }
  19042. stylesheet.setTextContent(style, '\n .video-js {\n width: 300px;\n height: 150px;\n }\n\n .vjs-fluid {\n padding-top: 56.25%\n }\n ');
  19043. }
  19044. }
  19045. // Run Auto-load players
  19046. // You have to wait at least once in case this script is loaded after your
  19047. // video in the DOM (weird behavior only with minified version)
  19048. setup.autoSetupTimeout(1, videojs);
  19049. /**
  19050. * Current software version. Follows semver.
  19051. *
  19052. * @type {string}
  19053. */
  19054. videojs.VERSION = '5.16.0';
  19055. /**
  19056. * The global options object. These are the settings that take effect
  19057. * if no overrides are specified when the player is created.
  19058. *
  19059. * @type {Object}
  19060. */
  19061. videojs.options = _player2['default'].prototype.options_;
  19062. /**
  19063. * Get an object with the currently created players, keyed by player ID
  19064. *
  19065. * @return {Object}
  19066. * The created players
  19067. */
  19068. videojs.getPlayers = function () {
  19069. return _player2['default'].players;
  19070. };
  19071. /**
  19072. * Expose players object.
  19073. *
  19074. * @memberOf videojs
  19075. * @property {Object} players
  19076. */
  19077. videojs.players = _player2['default'].players;
  19078. /**
  19079. * Get a component class object by name
  19080. *
  19081. * @borrows Component.getComponent as videojs.getComponent
  19082. */
  19083. videojs.getComponent = _component2['default'].getComponent;
  19084. /**
  19085. * Register a component so it can referred to by name. Used when adding to other
  19086. * components, either through addChild `component.addChild('myComponent')` or through
  19087. * default children options `{ children: ['myComponent'] }`.
  19088. *
  19089. * > NOTE: You could also just initialize the component before adding.
  19090. * `component.addChild(new MyComponent());`
  19091. *
  19092. * @param {string} name
  19093. * The class name of the component
  19094. *
  19095. * @param {Component} comp
  19096. * The component class
  19097. *
  19098. * @return {Component}
  19099. * The newly registered component
  19100. */
  19101. videojs.registerComponent = function (name, comp) {
  19102. if (_tech2['default'].isTech(comp)) {
  19103. _log2['default'].warn('The ' + name + ' tech was registered as a component. It should instead be registered using videojs.registerTech(name, tech)');
  19104. }
  19105. _component2['default'].registerComponent.call(_component2['default'], name, comp);
  19106. };
  19107. /**
  19108. * Get a Tech class object by name
  19109. *
  19110. * @borrows Tech.getTech as videojs.getTech
  19111. */
  19112. videojs.getTech = _tech2['default'].getTech;
  19113. /**
  19114. * Register a Tech so it can referred to by name.
  19115. * This is used in the tech order for the player.
  19116. *
  19117. * @borrows Tech.registerTech as videojs.registerTech
  19118. */
  19119. videojs.registerTech = _tech2['default'].registerTech;
  19120. /**
  19121. * A suite of browser and device tests from {@link browser}.
  19122. *
  19123. * @type {Object}
  19124. * @private
  19125. */
  19126. videojs.browser = browser;
  19127. /**
  19128. * Whether or not the browser supports touch events. Included for backward
  19129. * compatibility with 4.x, but deprecated. Use `videojs.browser.TOUCH_ENABLED`
  19130. * instead going forward.
  19131. *
  19132. * @deprecated since version 5.0
  19133. * @type {boolean}
  19134. */
  19135. videojs.TOUCH_ENABLED = browser.TOUCH_ENABLED;
  19136. /**
  19137. * Subclass an existing class
  19138. * Mimics ES6 subclassing with the `extend` keyword
  19139. *
  19140. * @borrows extend:extendFn as videojs.extend
  19141. */
  19142. videojs.extend = _extend2['default'];
  19143. /**
  19144. * Merge two options objects recursively
  19145. * Performs a deep merge like lodash.merge but **only merges plain objects**
  19146. * (not arrays, elements, anything else)
  19147. * Other values will be copied directly from the second object.
  19148. *
  19149. * @borrows merge-options:mergeOptions as videojs.mergeOptions
  19150. */
  19151. videojs.mergeOptions = _mergeOptions3['default'];
  19152. /**
  19153. * Change the context (this) of a function
  19154. *
  19155. * > NOTE: as of v5.0 we require an ES5 shim, so you should use the native
  19156. * `function() {}.bind(newContext);` instead of this.
  19157. *
  19158. * @borrows fn:bind as videojs.bind
  19159. */
  19160. videojs.bind = Fn.bind;
  19161. /**
  19162. * Create a Video.js player plugin.
  19163. * Plugins are only initialized when options for the plugin are included
  19164. * in the player options, or the plugin function on the player instance is
  19165. * called.
  19166. *
  19167. * @borrows plugin:plugin as videojs.plugin
  19168. */
  19169. videojs.plugin = _plugins2['default'];
  19170. /**
  19171. * Adding languages so that they're available to all players.
  19172. * Example: `videojs.addLanguage('es', { 'Hello': 'Hola' });`
  19173. *
  19174. * @param {string} code
  19175. * The language code or dictionary property
  19176. *
  19177. * @param {Object} data
  19178. * The data values to be translated
  19179. *
  19180. * @return {Object}
  19181. * The resulting language dictionary object
  19182. */
  19183. videojs.addLanguage = function (code, data) {
  19184. var _mergeOptions;
  19185. code = ('' + code).toLowerCase();
  19186. videojs.options.languages = (0, _mergeOptions3['default'])(videojs.options.languages, (_mergeOptions = {}, _mergeOptions[code] = data, _mergeOptions));
  19187. return videojs.options.languages[code];
  19188. };
  19189. /**
  19190. * Log messages
  19191. *
  19192. * @borrows log:log as videojs.log
  19193. */
  19194. videojs.log = _log2['default'];
  19195. /**
  19196. * Creates an emulated TimeRange object.
  19197. *
  19198. * @borrows time-ranges:createTimeRanges as videojs.createTimeRange
  19199. */
  19200. /**
  19201. * @borrows time-ranges:createTimeRanges as videojs.createTimeRanges
  19202. */
  19203. videojs.createTimeRange = videojs.createTimeRanges = _timeRanges.createTimeRanges;
  19204. /**
  19205. * Format seconds as a time string, H:MM:SS or M:SS
  19206. * Supplying a guide (in seconds) will force a number of leading zeros
  19207. * to cover the length of the guide
  19208. *
  19209. * @borrows format-time:formatTime as videojs.formatTime
  19210. */
  19211. videojs.formatTime = _formatTime2['default'];
  19212. /**
  19213. * Resolve and parse the elements of a URL
  19214. *
  19215. * @borrows url:parseUrl as videojs.parseUrl
  19216. */
  19217. videojs.parseUrl = Url.parseUrl;
  19218. /**
  19219. * Returns whether the url passed is a cross domain request or not.
  19220. *
  19221. * @borrows url:isCrossOrigin as videojs.isCrossOrigin
  19222. */
  19223. videojs.isCrossOrigin = Url.isCrossOrigin;
  19224. /**
  19225. * Event target class.
  19226. *
  19227. * @borrows EventTarget as videojs.EventTarget
  19228. */
  19229. videojs.EventTarget = _eventTarget2['default'];
  19230. /**
  19231. * Add an event listener to element
  19232. * It stores the handler function in a separate cache object
  19233. * and adds a generic handler to the element's event,
  19234. * along with a unique id (guid) to the element.
  19235. *
  19236. * @borrows events:on as videojs.on
  19237. */
  19238. videojs.on = Events.on;
  19239. /**
  19240. * Trigger a listener only once for an event
  19241. *
  19242. * @borrows events:one as videojs.one
  19243. */
  19244. videojs.one = Events.one;
  19245. /**
  19246. * Removes event listeners from an element
  19247. *
  19248. * @borrows events:off as videojs.off
  19249. */
  19250. videojs.off = Events.off;
  19251. /**
  19252. * Trigger an event for an element
  19253. *
  19254. * @borrows events:trigger as videojs.trigger
  19255. */
  19256. videojs.trigger = Events.trigger;
  19257. /**
  19258. * A cross-browser XMLHttpRequest wrapper. Here's a simple example:
  19259. *
  19260. * @param {Object} options
  19261. * settings for the request.
  19262. *
  19263. * @return {XMLHttpRequest|XDomainRequest}
  19264. * The request object.
  19265. *
  19266. * @see https://github.com/Raynos/xhr
  19267. */
  19268. videojs.xhr = _xhr2['default'];
  19269. /**
  19270. * TextTrack class
  19271. *
  19272. * @borrows TextTrack as videojs.TextTrack
  19273. */
  19274. videojs.TextTrack = _textTrack2['default'];
  19275. /**
  19276. * export the AudioTrack class so that source handlers can create
  19277. * AudioTracks and then add them to the players AudioTrackList
  19278. *
  19279. * @borrows AudioTrack as videojs.AudioTrack
  19280. */
  19281. videojs.AudioTrack = _audioTrack2['default'];
  19282. /**
  19283. * export the VideoTrack class so that source handlers can create
  19284. * VideoTracks and then add them to the players VideoTrackList
  19285. *
  19286. * @borrows VideoTrack as videojs.VideoTrack
  19287. */
  19288. videojs.VideoTrack = _videoTrack2['default'];
  19289. /**
  19290. * Determines, via duck typing, whether or not a value is a DOM element.
  19291. *
  19292. * @borrows dom:isEl as videojs.isEl
  19293. */
  19294. videojs.isEl = Dom.isEl;
  19295. /**
  19296. * Determines, via duck typing, whether or not a value is a text node.
  19297. *
  19298. * @borrows dom:isTextNode as videojs.isTextNode
  19299. */
  19300. videojs.isTextNode = Dom.isTextNode;
  19301. /**
  19302. * Creates an element and applies properties.
  19303. *
  19304. * @borrows dom:createEl as videojs.createEl
  19305. */
  19306. videojs.createEl = Dom.createEl;
  19307. /**
  19308. * Check if an element has a CSS class
  19309. *
  19310. * @borrows dom:hasElClass as videojs.hasClass
  19311. */
  19312. videojs.hasClass = Dom.hasElClass;
  19313. /**
  19314. * Add a CSS class name to an element
  19315. *
  19316. * @borrows dom:addElClass as videojs.addClass
  19317. */
  19318. videojs.addClass = Dom.addElClass;
  19319. /**
  19320. * Remove a CSS class name from an element
  19321. *
  19322. * @borrows dom:removeElClass as videojs.removeClass
  19323. */
  19324. videojs.removeClass = Dom.removeElClass;
  19325. /**
  19326. * Adds or removes a CSS class name on an element depending on an optional
  19327. * condition or the presence/absence of the class name.
  19328. *
  19329. * @borrows dom:toggleElClass as videojs.toggleClass
  19330. */
  19331. videojs.toggleClass = Dom.toggleElClass;
  19332. /**
  19333. * Apply attributes to an HTML element.
  19334. *
  19335. * @borrows dom:setElAttributes as videojs.setAttribute
  19336. */
  19337. videojs.setAttributes = Dom.setElAttributes;
  19338. /**
  19339. * Get an element's attribute values, as defined on the HTML tag
  19340. * Attributes are not the same as properties. They're defined on the tag
  19341. * or with setAttribute (which shouldn't be used with HTML)
  19342. * This will return true or false for boolean attributes.
  19343. *
  19344. * @borrows dom:getElAttributes as videojs.getAttributes
  19345. */
  19346. videojs.getAttributes = Dom.getElAttributes;
  19347. /**
  19348. * Empties the contents of an element.
  19349. *
  19350. * @borrows dom:emptyEl as videojs.emptyEl
  19351. */
  19352. videojs.emptyEl = Dom.emptyEl;
  19353. /**
  19354. * Normalizes and appends content to an element.
  19355. *
  19356. * The content for an element can be passed in multiple types and
  19357. * combinations, whose behavior is as follows:
  19358. *
  19359. * - String
  19360. * Normalized into a text node.
  19361. *
  19362. * - Element, TextNode
  19363. * Passed through.
  19364. *
  19365. * - Array
  19366. * A one-dimensional array of strings, elements, nodes, or functions (which
  19367. * return single strings, elements, or nodes).
  19368. *
  19369. * - Function
  19370. * If the sole argument, is expected to produce a string, element,
  19371. * node, or array.
  19372. *
  19373. * @borrows dom:appendContents as videojs.appendContet
  19374. */
  19375. videojs.appendContent = Dom.appendContent;
  19376. /**
  19377. * Normalizes and inserts content into an element; this is identical to
  19378. * `appendContent()`, except it empties the element first.
  19379. *
  19380. * The content for an element can be passed in multiple types and
  19381. * combinations, whose behavior is as follows:
  19382. *
  19383. * - String
  19384. * Normalized into a text node.
  19385. *
  19386. * - Element, TextNode
  19387. * Passed through.
  19388. *
  19389. * - Array
  19390. * A one-dimensional array of strings, elements, nodes, or functions (which
  19391. * return single strings, elements, or nodes).
  19392. *
  19393. * - Function
  19394. * If the sole argument, is expected to produce a string, element,
  19395. * node, or array.
  19396. *
  19397. * @borrows dom:insertContent as videojs.insertContent
  19398. */
  19399. videojs.insertContent = Dom.insertContent;
  19400. /**
  19401. * A safe getComputedStyle with an IE8 fallback.
  19402. *
  19403. * This is because in Firefox, if the player is loaded in an iframe with `display:none`,
  19404. * then `getComputedStyle` returns `null`, so, we do a null-check to make sure
  19405. * that the player doesn't break in these cases.
  19406. * See https://bugzilla.mozilla.org/show_bug.cgi?id=548397 for more details.
  19407. *
  19408. * @borrows computed-style:computedStyle as videojs.computedStyle
  19409. */
  19410. videojs.computedStyle = _computedStyle2['default'];
  19411. /*
  19412. * Custom Universal Module Definition (UMD)
  19413. *
  19414. * Video.js will never be a non-browser lib so we can simplify UMD a bunch and
  19415. * still support requirejs and browserify. This also needs to be closure
  19416. * compiler compatible, so string keys are used.
  19417. */
  19418. if (typeof define === 'function' && define.amd) {
  19419. define('videojs', [], function () {
  19420. return videojs;
  19421. });
  19422. // checking that module is an object too because of umdjs/umd#35
  19423. } else if ((typeof exports === 'undefined' ? 'undefined' : _typeof(exports)) === 'object' && (typeof module === 'undefined' ? 'undefined' : _typeof(module)) === 'object') {
  19424. module.exports = videojs;
  19425. }
  19426. exports['default'] = videojs;
  19427. },{"105":105,"42":42,"43":43,"5":5,"51":51,"52":52,"56":56,"62":62,"64":64,"72":72,"77":77,"78":78,"80":80,"81":81,"82":82,"83":83,"84":84,"86":86,"87":87,"88":88,"89":89,"90":90,"92":92,"94":94,"95":95}],94:[function(_dereq_,module,exports){
  19428. (function (global){
  19429. var topLevel = typeof global !== 'undefined' ? global :
  19430. typeof window !== 'undefined' ? window : {}
  19431. var minDoc = _dereq_(96);
  19432. if (typeof document !== 'undefined') {
  19433. module.exports = document;
  19434. } else {
  19435. var doccy = topLevel['__GLOBAL_DOCUMENT_CACHE@4'];
  19436. if (!doccy) {
  19437. doccy = topLevel['__GLOBAL_DOCUMENT_CACHE@4'] = minDoc;
  19438. }
  19439. module.exports = doccy;
  19440. }
  19441. }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
  19442. },{"96":96}],95:[function(_dereq_,module,exports){
  19443. (function (global){
  19444. if (typeof window !== "undefined") {
  19445. module.exports = window;
  19446. } else if (typeof global !== "undefined") {
  19447. module.exports = global;
  19448. } else if (typeof self !== "undefined"){
  19449. module.exports = self;
  19450. } else {
  19451. module.exports = {};
  19452. }
  19453. }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
  19454. },{}],96:[function(_dereq_,module,exports){
  19455. },{}],97:[function(_dereq_,module,exports){
  19456. module.exports = SafeParseTuple
  19457. function SafeParseTuple(obj, reviver) {
  19458. var json
  19459. var error = null
  19460. try {
  19461. json = JSON.parse(obj, reviver)
  19462. } catch (err) {
  19463. error = err
  19464. }
  19465. return [error, json]
  19466. }
  19467. },{}],98:[function(_dereq_,module,exports){
  19468. function clean (s) {
  19469. return s.replace(/\n\r?\s*/g, '')
  19470. }
  19471. module.exports = function tsml (sa) {
  19472. var s = ''
  19473. , i = 0
  19474. for (; i < arguments.length; i++)
  19475. s += clean(sa[i]) + (arguments[i + 1] || '')
  19476. return s
  19477. }
  19478. },{}],99:[function(_dereq_,module,exports){
  19479. /**
  19480. * Copyright 2013 vtt.js Contributors
  19481. *
  19482. * Licensed under the Apache License, Version 2.0 (the "License");
  19483. * you may not use this file except in compliance with the License.
  19484. * You may obtain a copy of the License at
  19485. *
  19486. * http://www.apache.org/licenses/LICENSE-2.0
  19487. *
  19488. * Unless required by applicable law or agreed to in writing, software
  19489. * distributed under the License is distributed on an "AS IS" BASIS,
  19490. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  19491. * See the License for the specific language governing permissions and
  19492. * limitations under the License.
  19493. */
  19494. // Default exports for Node. Export the extended versions of VTTCue and
  19495. // VTTRegion in Node since we likely want the capability to convert back and
  19496. // forth between JSON. If we don't then it's not that big of a deal since we're
  19497. // off browser.
  19498. module.exports = {
  19499. WebVTT: _dereq_(100).WebVTT,
  19500. VTTCue: _dereq_(101).VTTCue,
  19501. VTTRegion: _dereq_(103).VTTRegion
  19502. };
  19503. },{"100":100,"101":101,"103":103}],100:[function(_dereq_,module,exports){
  19504. /**
  19505. * Copyright 2013 vtt.js Contributors
  19506. *
  19507. * Licensed under the Apache License, Version 2.0 (the "License");
  19508. * you may not use this file except in compliance with the License.
  19509. * You may obtain a copy of the License at
  19510. *
  19511. * http://www.apache.org/licenses/LICENSE-2.0
  19512. *
  19513. * Unless required by applicable law or agreed to in writing, software
  19514. * distributed under the License is distributed on an "AS IS" BASIS,
  19515. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  19516. * See the License for the specific language governing permissions and
  19517. * limitations under the License.
  19518. */
  19519. /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  19520. /* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
  19521. (function(global) {
  19522. var _objCreate = Object.create || (function() {
  19523. function F() {}
  19524. return function(o) {
  19525. if (arguments.length !== 1) {
  19526. throw new Error('Object.create shim only accepts one parameter.');
  19527. }
  19528. F.prototype = o;
  19529. return new F();
  19530. };
  19531. })();
  19532. // Creates a new ParserError object from an errorData object. The errorData
  19533. // object should have default code and message properties. The default message
  19534. // property can be overriden by passing in a message parameter.
  19535. // See ParsingError.Errors below for acceptable errors.
  19536. function ParsingError(errorData, message) {
  19537. this.name = "ParsingError";
  19538. this.code = errorData.code;
  19539. this.message = message || errorData.message;
  19540. }
  19541. ParsingError.prototype = _objCreate(Error.prototype);
  19542. ParsingError.prototype.constructor = ParsingError;
  19543. // ParsingError metadata for acceptable ParsingErrors.
  19544. ParsingError.Errors = {
  19545. BadSignature: {
  19546. code: 0,
  19547. message: "Malformed WebVTT signature."
  19548. },
  19549. BadTimeStamp: {
  19550. code: 1,
  19551. message: "Malformed time stamp."
  19552. }
  19553. };
  19554. // Try to parse input as a time stamp.
  19555. function parseTimeStamp(input) {
  19556. function computeSeconds(h, m, s, f) {
  19557. return (h | 0) * 3600 + (m | 0) * 60 + (s | 0) + (f | 0) / 1000;
  19558. }
  19559. var m = input.match(/^(\d+):(\d{2})(:\d{2})?\.(\d{3})/);
  19560. if (!m) {
  19561. return null;
  19562. }
  19563. if (m[3]) {
  19564. // Timestamp takes the form of [hours]:[minutes]:[seconds].[milliseconds]
  19565. return computeSeconds(m[1], m[2], m[3].replace(":", ""), m[4]);
  19566. } else if (m[1] > 59) {
  19567. // Timestamp takes the form of [hours]:[minutes].[milliseconds]
  19568. // First position is hours as it's over 59.
  19569. return computeSeconds(m[1], m[2], 0, m[4]);
  19570. } else {
  19571. // Timestamp takes the form of [minutes]:[seconds].[milliseconds]
  19572. return computeSeconds(0, m[1], m[2], m[4]);
  19573. }
  19574. }
  19575. // A settings object holds key/value pairs and will ignore anything but the first
  19576. // assignment to a specific key.
  19577. function Settings() {
  19578. this.values = _objCreate(null);
  19579. }
  19580. Settings.prototype = {
  19581. // Only accept the first assignment to any key.
  19582. set: function(k, v) {
  19583. if (!this.get(k) && v !== "") {
  19584. this.values[k] = v;
  19585. }
  19586. },
  19587. // Return the value for a key, or a default value.
  19588. // If 'defaultKey' is passed then 'dflt' is assumed to be an object with
  19589. // a number of possible default values as properties where 'defaultKey' is
  19590. // the key of the property that will be chosen; otherwise it's assumed to be
  19591. // a single value.
  19592. get: function(k, dflt, defaultKey) {
  19593. if (defaultKey) {
  19594. return this.has(k) ? this.values[k] : dflt[defaultKey];
  19595. }
  19596. return this.has(k) ? this.values[k] : dflt;
  19597. },
  19598. // Check whether we have a value for a key.
  19599. has: function(k) {
  19600. return k in this.values;
  19601. },
  19602. // Accept a setting if its one of the given alternatives.
  19603. alt: function(k, v, a) {
  19604. for (var n = 0; n < a.length; ++n) {
  19605. if (v === a[n]) {
  19606. this.set(k, v);
  19607. break;
  19608. }
  19609. }
  19610. },
  19611. // Accept a setting if its a valid (signed) integer.
  19612. integer: function(k, v) {
  19613. if (/^-?\d+$/.test(v)) { // integer
  19614. this.set(k, parseInt(v, 10));
  19615. }
  19616. },
  19617. // Accept a setting if its a valid percentage.
  19618. percent: function(k, v) {
  19619. var m;
  19620. if ((m = v.match(/^([\d]{1,3})(\.[\d]*)?%$/))) {
  19621. v = parseFloat(v);
  19622. if (v >= 0 && v <= 100) {
  19623. this.set(k, v);
  19624. return true;
  19625. }
  19626. }
  19627. return false;
  19628. }
  19629. };
  19630. // Helper function to parse input into groups separated by 'groupDelim', and
  19631. // interprete each group as a key/value pair separated by 'keyValueDelim'.
  19632. function parseOptions(input, callback, keyValueDelim, groupDelim) {
  19633. var groups = groupDelim ? input.split(groupDelim) : [input];
  19634. for (var i in groups) {
  19635. if (typeof groups[i] !== "string") {
  19636. continue;
  19637. }
  19638. var kv = groups[i].split(keyValueDelim);
  19639. if (kv.length !== 2) {
  19640. continue;
  19641. }
  19642. var k = kv[0];
  19643. var v = kv[1];
  19644. callback(k, v);
  19645. }
  19646. }
  19647. function parseCue(input, cue, regionList) {
  19648. // Remember the original input if we need to throw an error.
  19649. var oInput = input;
  19650. // 4.1 WebVTT timestamp
  19651. function consumeTimeStamp() {
  19652. var ts = parseTimeStamp(input);
  19653. if (ts === null) {
  19654. throw new ParsingError(ParsingError.Errors.BadTimeStamp,
  19655. "Malformed timestamp: " + oInput);
  19656. }
  19657. // Remove time stamp from input.
  19658. input = input.replace(/^[^\sa-zA-Z-]+/, "");
  19659. return ts;
  19660. }
  19661. // 4.4.2 WebVTT cue settings
  19662. function consumeCueSettings(input, cue) {
  19663. var settings = new Settings();
  19664. parseOptions(input, function (k, v) {
  19665. switch (k) {
  19666. case "region":
  19667. // Find the last region we parsed with the same region id.
  19668. for (var i = regionList.length - 1; i >= 0; i--) {
  19669. if (regionList[i].id === v) {
  19670. settings.set(k, regionList[i].region);
  19671. break;
  19672. }
  19673. }
  19674. break;
  19675. case "vertical":
  19676. settings.alt(k, v, ["rl", "lr"]);
  19677. break;
  19678. case "line":
  19679. var vals = v.split(","),
  19680. vals0 = vals[0];
  19681. settings.integer(k, vals0);
  19682. settings.percent(k, vals0) ? settings.set("snapToLines", false) : null;
  19683. settings.alt(k, vals0, ["auto"]);
  19684. if (vals.length === 2) {
  19685. settings.alt("lineAlign", vals[1], ["start", "middle", "end"]);
  19686. }
  19687. break;
  19688. case "position":
  19689. vals = v.split(",");
  19690. settings.percent(k, vals[0]);
  19691. if (vals.length === 2) {
  19692. settings.alt("positionAlign", vals[1], ["start", "middle", "end"]);
  19693. }
  19694. break;
  19695. case "size":
  19696. settings.percent(k, v);
  19697. break;
  19698. case "align":
  19699. settings.alt(k, v, ["start", "middle", "end", "left", "right"]);
  19700. break;
  19701. }
  19702. }, /:/, /\s/);
  19703. // Apply default values for any missing fields.
  19704. cue.region = settings.get("region", null);
  19705. cue.vertical = settings.get("vertical", "");
  19706. cue.line = settings.get("line", "auto");
  19707. cue.lineAlign = settings.get("lineAlign", "start");
  19708. cue.snapToLines = settings.get("snapToLines", true);
  19709. cue.size = settings.get("size", 100);
  19710. cue.align = settings.get("align", "middle");
  19711. cue.position = settings.get("position", {
  19712. start: 0,
  19713. left: 0,
  19714. middle: 50,
  19715. end: 100,
  19716. right: 100
  19717. }, cue.align);
  19718. cue.positionAlign = settings.get("positionAlign", {
  19719. start: "start",
  19720. left: "start",
  19721. middle: "middle",
  19722. end: "end",
  19723. right: "end"
  19724. }, cue.align);
  19725. }
  19726. function skipWhitespace() {
  19727. input = input.replace(/^\s+/, "");
  19728. }
  19729. // 4.1 WebVTT cue timings.
  19730. skipWhitespace();
  19731. cue.startTime = consumeTimeStamp(); // (1) collect cue start time
  19732. skipWhitespace();
  19733. if (input.substr(0, 3) !== "-->") { // (3) next characters must match "-->"
  19734. throw new ParsingError(ParsingError.Errors.BadTimeStamp,
  19735. "Malformed time stamp (time stamps must be separated by '-->'): " +
  19736. oInput);
  19737. }
  19738. input = input.substr(3);
  19739. skipWhitespace();
  19740. cue.endTime = consumeTimeStamp(); // (5) collect cue end time
  19741. // 4.1 WebVTT cue settings list.
  19742. skipWhitespace();
  19743. consumeCueSettings(input, cue);
  19744. }
  19745. var ESCAPE = {
  19746. "&amp;": "&",
  19747. "&lt;": "<",
  19748. "&gt;": ">",
  19749. "&lrm;": "\u200e",
  19750. "&rlm;": "\u200f",
  19751. "&nbsp;": "\u00a0"
  19752. };
  19753. var TAG_NAME = {
  19754. c: "span",
  19755. i: "i",
  19756. b: "b",
  19757. u: "u",
  19758. ruby: "ruby",
  19759. rt: "rt",
  19760. v: "span",
  19761. lang: "span"
  19762. };
  19763. var TAG_ANNOTATION = {
  19764. v: "title",
  19765. lang: "lang"
  19766. };
  19767. var NEEDS_PARENT = {
  19768. rt: "ruby"
  19769. };
  19770. // Parse content into a document fragment.
  19771. function parseContent(window, input) {
  19772. function nextToken() {
  19773. // Check for end-of-string.
  19774. if (!input) {
  19775. return null;
  19776. }
  19777. // Consume 'n' characters from the input.
  19778. function consume(result) {
  19779. input = input.substr(result.length);
  19780. return result;
  19781. }
  19782. var m = input.match(/^([^<]*)(<[^>]+>?)?/);
  19783. // If there is some text before the next tag, return it, otherwise return
  19784. // the tag.
  19785. return consume(m[1] ? m[1] : m[2]);
  19786. }
  19787. // Unescape a string 's'.
  19788. function unescape1(e) {
  19789. return ESCAPE[e];
  19790. }
  19791. function unescape(s) {
  19792. while ((m = s.match(/&(amp|lt|gt|lrm|rlm|nbsp);/))) {
  19793. s = s.replace(m[0], unescape1);
  19794. }
  19795. return s;
  19796. }
  19797. function shouldAdd(current, element) {
  19798. return !NEEDS_PARENT[element.localName] ||
  19799. NEEDS_PARENT[element.localName] === current.localName;
  19800. }
  19801. // Create an element for this tag.
  19802. function createElement(type, annotation) {
  19803. var tagName = TAG_NAME[type];
  19804. if (!tagName) {
  19805. return null;
  19806. }
  19807. var element = window.document.createElement(tagName);
  19808. element.localName = tagName;
  19809. var name = TAG_ANNOTATION[type];
  19810. if (name && annotation) {
  19811. element[name] = annotation.trim();
  19812. }
  19813. return element;
  19814. }
  19815. var rootDiv = window.document.createElement("div"),
  19816. current = rootDiv,
  19817. t,
  19818. tagStack = [];
  19819. while ((t = nextToken()) !== null) {
  19820. if (t[0] === '<') {
  19821. if (t[1] === "/") {
  19822. // If the closing tag matches, move back up to the parent node.
  19823. if (tagStack.length &&
  19824. tagStack[tagStack.length - 1] === t.substr(2).replace(">", "")) {
  19825. tagStack.pop();
  19826. current = current.parentNode;
  19827. }
  19828. // Otherwise just ignore the end tag.
  19829. continue;
  19830. }
  19831. var ts = parseTimeStamp(t.substr(1, t.length - 2));
  19832. var node;
  19833. if (ts) {
  19834. // Timestamps are lead nodes as well.
  19835. node = window.document.createProcessingInstruction("timestamp", ts);
  19836. current.appendChild(node);
  19837. continue;
  19838. }
  19839. var m = t.match(/^<([^.\s/0-9>]+)(\.[^\s\\>]+)?([^>\\]+)?(\\?)>?$/);
  19840. // If we can't parse the tag, skip to the next tag.
  19841. if (!m) {
  19842. continue;
  19843. }
  19844. // Try to construct an element, and ignore the tag if we couldn't.
  19845. node = createElement(m[1], m[3]);
  19846. if (!node) {
  19847. continue;
  19848. }
  19849. // Determine if the tag should be added based on the context of where it
  19850. // is placed in the cuetext.
  19851. if (!shouldAdd(current, node)) {
  19852. continue;
  19853. }
  19854. // Set the class list (as a list of classes, separated by space).
  19855. if (m[2]) {
  19856. node.className = m[2].substr(1).replace('.', ' ');
  19857. }
  19858. // Append the node to the current node, and enter the scope of the new
  19859. // node.
  19860. tagStack.push(m[1]);
  19861. current.appendChild(node);
  19862. current = node;
  19863. continue;
  19864. }
  19865. // Text nodes are leaf nodes.
  19866. current.appendChild(window.document.createTextNode(unescape(t)));
  19867. }
  19868. return rootDiv;
  19869. }
  19870. // This is a list of all the Unicode characters that have a strong
  19871. // right-to-left category. What this means is that these characters are
  19872. // written right-to-left for sure. It was generated by pulling all the strong
  19873. // right-to-left characters out of the Unicode data table. That table can
  19874. // found at: http://www.unicode.org/Public/UNIDATA/UnicodeData.txt
  19875. var strongRTLChars = [0x05BE, 0x05C0, 0x05C3, 0x05C6, 0x05D0, 0x05D1,
  19876. 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7, 0x05D8, 0x05D9, 0x05DA,
  19877. 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF, 0x05E0, 0x05E1, 0x05E2, 0x05E3,
  19878. 0x05E4, 0x05E5, 0x05E6, 0x05E7, 0x05E8, 0x05E9, 0x05EA, 0x05F0, 0x05F1,
  19879. 0x05F2, 0x05F3, 0x05F4, 0x0608, 0x060B, 0x060D, 0x061B, 0x061E, 0x061F,
  19880. 0x0620, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627, 0x0628,
  19881. 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F, 0x0630, 0x0631,
  19882. 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x0637, 0x0638, 0x0639, 0x063A,
  19883. 0x063B, 0x063C, 0x063D, 0x063E, 0x063F, 0x0640, 0x0641, 0x0642, 0x0643,
  19884. 0x0644, 0x0645, 0x0646, 0x0647, 0x0648, 0x0649, 0x064A, 0x066D, 0x066E,
  19885. 0x066F, 0x0671, 0x0672, 0x0673, 0x0674, 0x0675, 0x0676, 0x0677, 0x0678,
  19886. 0x0679, 0x067A, 0x067B, 0x067C, 0x067D, 0x067E, 0x067F, 0x0680, 0x0681,
  19887. 0x0682, 0x0683, 0x0684, 0x0685, 0x0686, 0x0687, 0x0688, 0x0689, 0x068A,
  19888. 0x068B, 0x068C, 0x068D, 0x068E, 0x068F, 0x0690, 0x0691, 0x0692, 0x0693,
  19889. 0x0694, 0x0695, 0x0696, 0x0697, 0x0698, 0x0699, 0x069A, 0x069B, 0x069C,
  19890. 0x069D, 0x069E, 0x069F, 0x06A0, 0x06A1, 0x06A2, 0x06A3, 0x06A4, 0x06A5,
  19891. 0x06A6, 0x06A7, 0x06A8, 0x06A9, 0x06AA, 0x06AB, 0x06AC, 0x06AD, 0x06AE,
  19892. 0x06AF, 0x06B0, 0x06B1, 0x06B2, 0x06B3, 0x06B4, 0x06B5, 0x06B6, 0x06B7,
  19893. 0x06B8, 0x06B9, 0x06BA, 0x06BB, 0x06BC, 0x06BD, 0x06BE, 0x06BF, 0x06C0,
  19894. 0x06C1, 0x06C2, 0x06C3, 0x06C4, 0x06C5, 0x06C6, 0x06C7, 0x06C8, 0x06C9,
  19895. 0x06CA, 0x06CB, 0x06CC, 0x06CD, 0x06CE, 0x06CF, 0x06D0, 0x06D1, 0x06D2,
  19896. 0x06D3, 0x06D4, 0x06D5, 0x06E5, 0x06E6, 0x06EE, 0x06EF, 0x06FA, 0x06FB,
  19897. 0x06FC, 0x06FD, 0x06FE, 0x06FF, 0x0700, 0x0701, 0x0702, 0x0703, 0x0704,
  19898. 0x0705, 0x0706, 0x0707, 0x0708, 0x0709, 0x070A, 0x070B, 0x070C, 0x070D,
  19899. 0x070F, 0x0710, 0x0712, 0x0713, 0x0714, 0x0715, 0x0716, 0x0717, 0x0718,
  19900. 0x0719, 0x071A, 0x071B, 0x071C, 0x071D, 0x071E, 0x071F, 0x0720, 0x0721,
  19901. 0x0722, 0x0723, 0x0724, 0x0725, 0x0726, 0x0727, 0x0728, 0x0729, 0x072A,
  19902. 0x072B, 0x072C, 0x072D, 0x072E, 0x072F, 0x074D, 0x074E, 0x074F, 0x0750,
  19903. 0x0751, 0x0752, 0x0753, 0x0754, 0x0755, 0x0756, 0x0757, 0x0758, 0x0759,
  19904. 0x075A, 0x075B, 0x075C, 0x075D, 0x075E, 0x075F, 0x0760, 0x0761, 0x0762,
  19905. 0x0763, 0x0764, 0x0765, 0x0766, 0x0767, 0x0768, 0x0769, 0x076A, 0x076B,
  19906. 0x076C, 0x076D, 0x076E, 0x076F, 0x0770, 0x0771, 0x0772, 0x0773, 0x0774,
  19907. 0x0775, 0x0776, 0x0777, 0x0778, 0x0779, 0x077A, 0x077B, 0x077C, 0x077D,
  19908. 0x077E, 0x077F, 0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0786,
  19909. 0x0787, 0x0788, 0x0789, 0x078A, 0x078B, 0x078C, 0x078D, 0x078E, 0x078F,
  19910. 0x0790, 0x0791, 0x0792, 0x0793, 0x0794, 0x0795, 0x0796, 0x0797, 0x0798,
  19911. 0x0799, 0x079A, 0x079B, 0x079C, 0x079D, 0x079E, 0x079F, 0x07A0, 0x07A1,
  19912. 0x07A2, 0x07A3, 0x07A4, 0x07A5, 0x07B1, 0x07C0, 0x07C1, 0x07C2, 0x07C3,
  19913. 0x07C4, 0x07C5, 0x07C6, 0x07C7, 0x07C8, 0x07C9, 0x07CA, 0x07CB, 0x07CC,
  19914. 0x07CD, 0x07CE, 0x07CF, 0x07D0, 0x07D1, 0x07D2, 0x07D3, 0x07D4, 0x07D5,
  19915. 0x07D6, 0x07D7, 0x07D8, 0x07D9, 0x07DA, 0x07DB, 0x07DC, 0x07DD, 0x07DE,
  19916. 0x07DF, 0x07E0, 0x07E1, 0x07E2, 0x07E3, 0x07E4, 0x07E5, 0x07E6, 0x07E7,
  19917. 0x07E8, 0x07E9, 0x07EA, 0x07F4, 0x07F5, 0x07FA, 0x0800, 0x0801, 0x0802,
  19918. 0x0803, 0x0804, 0x0805, 0x0806, 0x0807, 0x0808, 0x0809, 0x080A, 0x080B,
  19919. 0x080C, 0x080D, 0x080E, 0x080F, 0x0810, 0x0811, 0x0812, 0x0813, 0x0814,
  19920. 0x0815, 0x081A, 0x0824, 0x0828, 0x0830, 0x0831, 0x0832, 0x0833, 0x0834,
  19921. 0x0835, 0x0836, 0x0837, 0x0838, 0x0839, 0x083A, 0x083B, 0x083C, 0x083D,
  19922. 0x083E, 0x0840, 0x0841, 0x0842, 0x0843, 0x0844, 0x0845, 0x0846, 0x0847,
  19923. 0x0848, 0x0849, 0x084A, 0x084B, 0x084C, 0x084D, 0x084E, 0x084F, 0x0850,
  19924. 0x0851, 0x0852, 0x0853, 0x0854, 0x0855, 0x0856, 0x0857, 0x0858, 0x085E,
  19925. 0x08A0, 0x08A2, 0x08A3, 0x08A4, 0x08A5, 0x08A6, 0x08A7, 0x08A8, 0x08A9,
  19926. 0x08AA, 0x08AB, 0x08AC, 0x200F, 0xFB1D, 0xFB1F, 0xFB20, 0xFB21, 0xFB22,
  19927. 0xFB23, 0xFB24, 0xFB25, 0xFB26, 0xFB27, 0xFB28, 0xFB2A, 0xFB2B, 0xFB2C,
  19928. 0xFB2D, 0xFB2E, 0xFB2F, 0xFB30, 0xFB31, 0xFB32, 0xFB33, 0xFB34, 0xFB35,
  19929. 0xFB36, 0xFB38, 0xFB39, 0xFB3A, 0xFB3B, 0xFB3C, 0xFB3E, 0xFB40, 0xFB41,
  19930. 0xFB43, 0xFB44, 0xFB46, 0xFB47, 0xFB48, 0xFB49, 0xFB4A, 0xFB4B, 0xFB4C,
  19931. 0xFB4D, 0xFB4E, 0xFB4F, 0xFB50, 0xFB51, 0xFB52, 0xFB53, 0xFB54, 0xFB55,
  19932. 0xFB56, 0xFB57, 0xFB58, 0xFB59, 0xFB5A, 0xFB5B, 0xFB5C, 0xFB5D, 0xFB5E,
  19933. 0xFB5F, 0xFB60, 0xFB61, 0xFB62, 0xFB63, 0xFB64, 0xFB65, 0xFB66, 0xFB67,
  19934. 0xFB68, 0xFB69, 0xFB6A, 0xFB6B, 0xFB6C, 0xFB6D, 0xFB6E, 0xFB6F, 0xFB70,
  19935. 0xFB71, 0xFB72, 0xFB73, 0xFB74, 0xFB75, 0xFB76, 0xFB77, 0xFB78, 0xFB79,
  19936. 0xFB7A, 0xFB7B, 0xFB7C, 0xFB7D, 0xFB7E, 0xFB7F, 0xFB80, 0xFB81, 0xFB82,
  19937. 0xFB83, 0xFB84, 0xFB85, 0xFB86, 0xFB87, 0xFB88, 0xFB89, 0xFB8A, 0xFB8B,
  19938. 0xFB8C, 0xFB8D, 0xFB8E, 0xFB8F, 0xFB90, 0xFB91, 0xFB92, 0xFB93, 0xFB94,
  19939. 0xFB95, 0xFB96, 0xFB97, 0xFB98, 0xFB99, 0xFB9A, 0xFB9B, 0xFB9C, 0xFB9D,
  19940. 0xFB9E, 0xFB9F, 0xFBA0, 0xFBA1, 0xFBA2, 0xFBA3, 0xFBA4, 0xFBA5, 0xFBA6,
  19941. 0xFBA7, 0xFBA8, 0xFBA9, 0xFBAA, 0xFBAB, 0xFBAC, 0xFBAD, 0xFBAE, 0xFBAF,
  19942. 0xFBB0, 0xFBB1, 0xFBB2, 0xFBB3, 0xFBB4, 0xFBB5, 0xFBB6, 0xFBB7, 0xFBB8,
  19943. 0xFBB9, 0xFBBA, 0xFBBB, 0xFBBC, 0xFBBD, 0xFBBE, 0xFBBF, 0xFBC0, 0xFBC1,
  19944. 0xFBD3, 0xFBD4, 0xFBD5, 0xFBD6, 0xFBD7, 0xFBD8, 0xFBD9, 0xFBDA, 0xFBDB,
  19945. 0xFBDC, 0xFBDD, 0xFBDE, 0xFBDF, 0xFBE0, 0xFBE1, 0xFBE2, 0xFBE3, 0xFBE4,
  19946. 0xFBE5, 0xFBE6, 0xFBE7, 0xFBE8, 0xFBE9, 0xFBEA, 0xFBEB, 0xFBEC, 0xFBED,
  19947. 0xFBEE, 0xFBEF, 0xFBF0, 0xFBF1, 0xFBF2, 0xFBF3, 0xFBF4, 0xFBF5, 0xFBF6,
  19948. 0xFBF7, 0xFBF8, 0xFBF9, 0xFBFA, 0xFBFB, 0xFBFC, 0xFBFD, 0xFBFE, 0xFBFF,
  19949. 0xFC00, 0xFC01, 0xFC02, 0xFC03, 0xFC04, 0xFC05, 0xFC06, 0xFC07, 0xFC08,
  19950. 0xFC09, 0xFC0A, 0xFC0B, 0xFC0C, 0xFC0D, 0xFC0E, 0xFC0F, 0xFC10, 0xFC11,
  19951. 0xFC12, 0xFC13, 0xFC14, 0xFC15, 0xFC16, 0xFC17, 0xFC18, 0xFC19, 0xFC1A,
  19952. 0xFC1B, 0xFC1C, 0xFC1D, 0xFC1E, 0xFC1F, 0xFC20, 0xFC21, 0xFC22, 0xFC23,
  19953. 0xFC24, 0xFC25, 0xFC26, 0xFC27, 0xFC28, 0xFC29, 0xFC2A, 0xFC2B, 0xFC2C,
  19954. 0xFC2D, 0xFC2E, 0xFC2F, 0xFC30, 0xFC31, 0xFC32, 0xFC33, 0xFC34, 0xFC35,
  19955. 0xFC36, 0xFC37, 0xFC38, 0xFC39, 0xFC3A, 0xFC3B, 0xFC3C, 0xFC3D, 0xFC3E,
  19956. 0xFC3F, 0xFC40, 0xFC41, 0xFC42, 0xFC43, 0xFC44, 0xFC45, 0xFC46, 0xFC47,
  19957. 0xFC48, 0xFC49, 0xFC4A, 0xFC4B, 0xFC4C, 0xFC4D, 0xFC4E, 0xFC4F, 0xFC50,
  19958. 0xFC51, 0xFC52, 0xFC53, 0xFC54, 0xFC55, 0xFC56, 0xFC57, 0xFC58, 0xFC59,
  19959. 0xFC5A, 0xFC5B, 0xFC5C, 0xFC5D, 0xFC5E, 0xFC5F, 0xFC60, 0xFC61, 0xFC62,
  19960. 0xFC63, 0xFC64, 0xFC65, 0xFC66, 0xFC67, 0xFC68, 0xFC69, 0xFC6A, 0xFC6B,
  19961. 0xFC6C, 0xFC6D, 0xFC6E, 0xFC6F, 0xFC70, 0xFC71, 0xFC72, 0xFC73, 0xFC74,
  19962. 0xFC75, 0xFC76, 0xFC77, 0xFC78, 0xFC79, 0xFC7A, 0xFC7B, 0xFC7C, 0xFC7D,
  19963. 0xFC7E, 0xFC7F, 0xFC80, 0xFC81, 0xFC82, 0xFC83, 0xFC84, 0xFC85, 0xFC86,
  19964. 0xFC87, 0xFC88, 0xFC89, 0xFC8A, 0xFC8B, 0xFC8C, 0xFC8D, 0xFC8E, 0xFC8F,
  19965. 0xFC90, 0xFC91, 0xFC92, 0xFC93, 0xFC94, 0xFC95, 0xFC96, 0xFC97, 0xFC98,
  19966. 0xFC99, 0xFC9A, 0xFC9B, 0xFC9C, 0xFC9D, 0xFC9E, 0xFC9F, 0xFCA0, 0xFCA1,
  19967. 0xFCA2, 0xFCA3, 0xFCA4, 0xFCA5, 0xFCA6, 0xFCA7, 0xFCA8, 0xFCA9, 0xFCAA,
  19968. 0xFCAB, 0xFCAC, 0xFCAD, 0xFCAE, 0xFCAF, 0xFCB0, 0xFCB1, 0xFCB2, 0xFCB3,
  19969. 0xFCB4, 0xFCB5, 0xFCB6, 0xFCB7, 0xFCB8, 0xFCB9, 0xFCBA, 0xFCBB, 0xFCBC,
  19970. 0xFCBD, 0xFCBE, 0xFCBF, 0xFCC0, 0xFCC1, 0xFCC2, 0xFCC3, 0xFCC4, 0xFCC5,
  19971. 0xFCC6, 0xFCC7, 0xFCC8, 0xFCC9, 0xFCCA, 0xFCCB, 0xFCCC, 0xFCCD, 0xFCCE,
  19972. 0xFCCF, 0xFCD0, 0xFCD1, 0xFCD2, 0xFCD3, 0xFCD4, 0xFCD5, 0xFCD6, 0xFCD7,
  19973. 0xFCD8, 0xFCD9, 0xFCDA, 0xFCDB, 0xFCDC, 0xFCDD, 0xFCDE, 0xFCDF, 0xFCE0,
  19974. 0xFCE1, 0xFCE2, 0xFCE3, 0xFCE4, 0xFCE5, 0xFCE6, 0xFCE7, 0xFCE8, 0xFCE9,
  19975. 0xFCEA, 0xFCEB, 0xFCEC, 0xFCED, 0xFCEE, 0xFCEF, 0xFCF0, 0xFCF1, 0xFCF2,
  19976. 0xFCF3, 0xFCF4, 0xFCF5, 0xFCF6, 0xFCF7, 0xFCF8, 0xFCF9, 0xFCFA, 0xFCFB,
  19977. 0xFCFC, 0xFCFD, 0xFCFE, 0xFCFF, 0xFD00, 0xFD01, 0xFD02, 0xFD03, 0xFD04,
  19978. 0xFD05, 0xFD06, 0xFD07, 0xFD08, 0xFD09, 0xFD0A, 0xFD0B, 0xFD0C, 0xFD0D,
  19979. 0xFD0E, 0xFD0F, 0xFD10, 0xFD11, 0xFD12, 0xFD13, 0xFD14, 0xFD15, 0xFD16,
  19980. 0xFD17, 0xFD18, 0xFD19, 0xFD1A, 0xFD1B, 0xFD1C, 0xFD1D, 0xFD1E, 0xFD1F,
  19981. 0xFD20, 0xFD21, 0xFD22, 0xFD23, 0xFD24, 0xFD25, 0xFD26, 0xFD27, 0xFD28,
  19982. 0xFD29, 0xFD2A, 0xFD2B, 0xFD2C, 0xFD2D, 0xFD2E, 0xFD2F, 0xFD30, 0xFD31,
  19983. 0xFD32, 0xFD33, 0xFD34, 0xFD35, 0xFD36, 0xFD37, 0xFD38, 0xFD39, 0xFD3A,
  19984. 0xFD3B, 0xFD3C, 0xFD3D, 0xFD50, 0xFD51, 0xFD52, 0xFD53, 0xFD54, 0xFD55,
  19985. 0xFD56, 0xFD57, 0xFD58, 0xFD59, 0xFD5A, 0xFD5B, 0xFD5C, 0xFD5D, 0xFD5E,
  19986. 0xFD5F, 0xFD60, 0xFD61, 0xFD62, 0xFD63, 0xFD64, 0xFD65, 0xFD66, 0xFD67,
  19987. 0xFD68, 0xFD69, 0xFD6A, 0xFD6B, 0xFD6C, 0xFD6D, 0xFD6E, 0xFD6F, 0xFD70,
  19988. 0xFD71, 0xFD72, 0xFD73, 0xFD74, 0xFD75, 0xFD76, 0xFD77, 0xFD78, 0xFD79,
  19989. 0xFD7A, 0xFD7B, 0xFD7C, 0xFD7D, 0xFD7E, 0xFD7F, 0xFD80, 0xFD81, 0xFD82,
  19990. 0xFD83, 0xFD84, 0xFD85, 0xFD86, 0xFD87, 0xFD88, 0xFD89, 0xFD8A, 0xFD8B,
  19991. 0xFD8C, 0xFD8D, 0xFD8E, 0xFD8F, 0xFD92, 0xFD93, 0xFD94, 0xFD95, 0xFD96,
  19992. 0xFD97, 0xFD98, 0xFD99, 0xFD9A, 0xFD9B, 0xFD9C, 0xFD9D, 0xFD9E, 0xFD9F,
  19993. 0xFDA0, 0xFDA1, 0xFDA2, 0xFDA3, 0xFDA4, 0xFDA5, 0xFDA6, 0xFDA7, 0xFDA8,
  19994. 0xFDA9, 0xFDAA, 0xFDAB, 0xFDAC, 0xFDAD, 0xFDAE, 0xFDAF, 0xFDB0, 0xFDB1,
  19995. 0xFDB2, 0xFDB3, 0xFDB4, 0xFDB5, 0xFDB6, 0xFDB7, 0xFDB8, 0xFDB9, 0xFDBA,
  19996. 0xFDBB, 0xFDBC, 0xFDBD, 0xFDBE, 0xFDBF, 0xFDC0, 0xFDC1, 0xFDC2, 0xFDC3,
  19997. 0xFDC4, 0xFDC5, 0xFDC6, 0xFDC7, 0xFDF0, 0xFDF1, 0xFDF2, 0xFDF3, 0xFDF4,
  19998. 0xFDF5, 0xFDF6, 0xFDF7, 0xFDF8, 0xFDF9, 0xFDFA, 0xFDFB, 0xFDFC, 0xFE70,
  19999. 0xFE71, 0xFE72, 0xFE73, 0xFE74, 0xFE76, 0xFE77, 0xFE78, 0xFE79, 0xFE7A,
  20000. 0xFE7B, 0xFE7C, 0xFE7D, 0xFE7E, 0xFE7F, 0xFE80, 0xFE81, 0xFE82, 0xFE83,
  20001. 0xFE84, 0xFE85, 0xFE86, 0xFE87, 0xFE88, 0xFE89, 0xFE8A, 0xFE8B, 0xFE8C,
  20002. 0xFE8D, 0xFE8E, 0xFE8F, 0xFE90, 0xFE91, 0xFE92, 0xFE93, 0xFE94, 0xFE95,
  20003. 0xFE96, 0xFE97, 0xFE98, 0xFE99, 0xFE9A, 0xFE9B, 0xFE9C, 0xFE9D, 0xFE9E,
  20004. 0xFE9F, 0xFEA0, 0xFEA1, 0xFEA2, 0xFEA3, 0xFEA4, 0xFEA5, 0xFEA6, 0xFEA7,
  20005. 0xFEA8, 0xFEA9, 0xFEAA, 0xFEAB, 0xFEAC, 0xFEAD, 0xFEAE, 0xFEAF, 0xFEB0,
  20006. 0xFEB1, 0xFEB2, 0xFEB3, 0xFEB4, 0xFEB5, 0xFEB6, 0xFEB7, 0xFEB8, 0xFEB9,
  20007. 0xFEBA, 0xFEBB, 0xFEBC, 0xFEBD, 0xFEBE, 0xFEBF, 0xFEC0, 0xFEC1, 0xFEC2,
  20008. 0xFEC3, 0xFEC4, 0xFEC5, 0xFEC6, 0xFEC7, 0xFEC8, 0xFEC9, 0xFECA, 0xFECB,
  20009. 0xFECC, 0xFECD, 0xFECE, 0xFECF, 0xFED0, 0xFED1, 0xFED2, 0xFED3, 0xFED4,
  20010. 0xFED5, 0xFED6, 0xFED7, 0xFED8, 0xFED9, 0xFEDA, 0xFEDB, 0xFEDC, 0xFEDD,
  20011. 0xFEDE, 0xFEDF, 0xFEE0, 0xFEE1, 0xFEE2, 0xFEE3, 0xFEE4, 0xFEE5, 0xFEE6,
  20012. 0xFEE7, 0xFEE8, 0xFEE9, 0xFEEA, 0xFEEB, 0xFEEC, 0xFEED, 0xFEEE, 0xFEEF,
  20013. 0xFEF0, 0xFEF1, 0xFEF2, 0xFEF3, 0xFEF4, 0xFEF5, 0xFEF6, 0xFEF7, 0xFEF8,
  20014. 0xFEF9, 0xFEFA, 0xFEFB, 0xFEFC, 0x10800, 0x10801, 0x10802, 0x10803,
  20015. 0x10804, 0x10805, 0x10808, 0x1080A, 0x1080B, 0x1080C, 0x1080D, 0x1080E,
  20016. 0x1080F, 0x10810, 0x10811, 0x10812, 0x10813, 0x10814, 0x10815, 0x10816,
  20017. 0x10817, 0x10818, 0x10819, 0x1081A, 0x1081B, 0x1081C, 0x1081D, 0x1081E,
  20018. 0x1081F, 0x10820, 0x10821, 0x10822, 0x10823, 0x10824, 0x10825, 0x10826,
  20019. 0x10827, 0x10828, 0x10829, 0x1082A, 0x1082B, 0x1082C, 0x1082D, 0x1082E,
  20020. 0x1082F, 0x10830, 0x10831, 0x10832, 0x10833, 0x10834, 0x10835, 0x10837,
  20021. 0x10838, 0x1083C, 0x1083F, 0x10840, 0x10841, 0x10842, 0x10843, 0x10844,
  20022. 0x10845, 0x10846, 0x10847, 0x10848, 0x10849, 0x1084A, 0x1084B, 0x1084C,
  20023. 0x1084D, 0x1084E, 0x1084F, 0x10850, 0x10851, 0x10852, 0x10853, 0x10854,
  20024. 0x10855, 0x10857, 0x10858, 0x10859, 0x1085A, 0x1085B, 0x1085C, 0x1085D,
  20025. 0x1085E, 0x1085F, 0x10900, 0x10901, 0x10902, 0x10903, 0x10904, 0x10905,
  20026. 0x10906, 0x10907, 0x10908, 0x10909, 0x1090A, 0x1090B, 0x1090C, 0x1090D,
  20027. 0x1090E, 0x1090F, 0x10910, 0x10911, 0x10912, 0x10913, 0x10914, 0x10915,
  20028. 0x10916, 0x10917, 0x10918, 0x10919, 0x1091A, 0x1091B, 0x10920, 0x10921,
  20029. 0x10922, 0x10923, 0x10924, 0x10925, 0x10926, 0x10927, 0x10928, 0x10929,
  20030. 0x1092A, 0x1092B, 0x1092C, 0x1092D, 0x1092E, 0x1092F, 0x10930, 0x10931,
  20031. 0x10932, 0x10933, 0x10934, 0x10935, 0x10936, 0x10937, 0x10938, 0x10939,
  20032. 0x1093F, 0x10980, 0x10981, 0x10982, 0x10983, 0x10984, 0x10985, 0x10986,
  20033. 0x10987, 0x10988, 0x10989, 0x1098A, 0x1098B, 0x1098C, 0x1098D, 0x1098E,
  20034. 0x1098F, 0x10990, 0x10991, 0x10992, 0x10993, 0x10994, 0x10995, 0x10996,
  20035. 0x10997, 0x10998, 0x10999, 0x1099A, 0x1099B, 0x1099C, 0x1099D, 0x1099E,
  20036. 0x1099F, 0x109A0, 0x109A1, 0x109A2, 0x109A3, 0x109A4, 0x109A5, 0x109A6,
  20037. 0x109A7, 0x109A8, 0x109A9, 0x109AA, 0x109AB, 0x109AC, 0x109AD, 0x109AE,
  20038. 0x109AF, 0x109B0, 0x109B1, 0x109B2, 0x109B3, 0x109B4, 0x109B5, 0x109B6,
  20039. 0x109B7, 0x109BE, 0x109BF, 0x10A00, 0x10A10, 0x10A11, 0x10A12, 0x10A13,
  20040. 0x10A15, 0x10A16, 0x10A17, 0x10A19, 0x10A1A, 0x10A1B, 0x10A1C, 0x10A1D,
  20041. 0x10A1E, 0x10A1F, 0x10A20, 0x10A21, 0x10A22, 0x10A23, 0x10A24, 0x10A25,
  20042. 0x10A26, 0x10A27, 0x10A28, 0x10A29, 0x10A2A, 0x10A2B, 0x10A2C, 0x10A2D,
  20043. 0x10A2E, 0x10A2F, 0x10A30, 0x10A31, 0x10A32, 0x10A33, 0x10A40, 0x10A41,
  20044. 0x10A42, 0x10A43, 0x10A44, 0x10A45, 0x10A46, 0x10A47, 0x10A50, 0x10A51,
  20045. 0x10A52, 0x10A53, 0x10A54, 0x10A55, 0x10A56, 0x10A57, 0x10A58, 0x10A60,
  20046. 0x10A61, 0x10A62, 0x10A63, 0x10A64, 0x10A65, 0x10A66, 0x10A67, 0x10A68,
  20047. 0x10A69, 0x10A6A, 0x10A6B, 0x10A6C, 0x10A6D, 0x10A6E, 0x10A6F, 0x10A70,
  20048. 0x10A71, 0x10A72, 0x10A73, 0x10A74, 0x10A75, 0x10A76, 0x10A77, 0x10A78,
  20049. 0x10A79, 0x10A7A, 0x10A7B, 0x10A7C, 0x10A7D, 0x10A7E, 0x10A7F, 0x10B00,
  20050. 0x10B01, 0x10B02, 0x10B03, 0x10B04, 0x10B05, 0x10B06, 0x10B07, 0x10B08,
  20051. 0x10B09, 0x10B0A, 0x10B0B, 0x10B0C, 0x10B0D, 0x10B0E, 0x10B0F, 0x10B10,
  20052. 0x10B11, 0x10B12, 0x10B13, 0x10B14, 0x10B15, 0x10B16, 0x10B17, 0x10B18,
  20053. 0x10B19, 0x10B1A, 0x10B1B, 0x10B1C, 0x10B1D, 0x10B1E, 0x10B1F, 0x10B20,
  20054. 0x10B21, 0x10B22, 0x10B23, 0x10B24, 0x10B25, 0x10B26, 0x10B27, 0x10B28,
  20055. 0x10B29, 0x10B2A, 0x10B2B, 0x10B2C, 0x10B2D, 0x10B2E, 0x10B2F, 0x10B30,
  20056. 0x10B31, 0x10B32, 0x10B33, 0x10B34, 0x10B35, 0x10B40, 0x10B41, 0x10B42,
  20057. 0x10B43, 0x10B44, 0x10B45, 0x10B46, 0x10B47, 0x10B48, 0x10B49, 0x10B4A,
  20058. 0x10B4B, 0x10B4C, 0x10B4D, 0x10B4E, 0x10B4F, 0x10B50, 0x10B51, 0x10B52,
  20059. 0x10B53, 0x10B54, 0x10B55, 0x10B58, 0x10B59, 0x10B5A, 0x10B5B, 0x10B5C,
  20060. 0x10B5D, 0x10B5E, 0x10B5F, 0x10B60, 0x10B61, 0x10B62, 0x10B63, 0x10B64,
  20061. 0x10B65, 0x10B66, 0x10B67, 0x10B68, 0x10B69, 0x10B6A, 0x10B6B, 0x10B6C,
  20062. 0x10B6D, 0x10B6E, 0x10B6F, 0x10B70, 0x10B71, 0x10B72, 0x10B78, 0x10B79,
  20063. 0x10B7A, 0x10B7B, 0x10B7C, 0x10B7D, 0x10B7E, 0x10B7F, 0x10C00, 0x10C01,
  20064. 0x10C02, 0x10C03, 0x10C04, 0x10C05, 0x10C06, 0x10C07, 0x10C08, 0x10C09,
  20065. 0x10C0A, 0x10C0B, 0x10C0C, 0x10C0D, 0x10C0E, 0x10C0F, 0x10C10, 0x10C11,
  20066. 0x10C12, 0x10C13, 0x10C14, 0x10C15, 0x10C16, 0x10C17, 0x10C18, 0x10C19,
  20067. 0x10C1A, 0x10C1B, 0x10C1C, 0x10C1D, 0x10C1E, 0x10C1F, 0x10C20, 0x10C21,
  20068. 0x10C22, 0x10C23, 0x10C24, 0x10C25, 0x10C26, 0x10C27, 0x10C28, 0x10C29,
  20069. 0x10C2A, 0x10C2B, 0x10C2C, 0x10C2D, 0x10C2E, 0x10C2F, 0x10C30, 0x10C31,
  20070. 0x10C32, 0x10C33, 0x10C34, 0x10C35, 0x10C36, 0x10C37, 0x10C38, 0x10C39,
  20071. 0x10C3A, 0x10C3B, 0x10C3C, 0x10C3D, 0x10C3E, 0x10C3F, 0x10C40, 0x10C41,
  20072. 0x10C42, 0x10C43, 0x10C44, 0x10C45, 0x10C46, 0x10C47, 0x10C48, 0x1EE00,
  20073. 0x1EE01, 0x1EE02, 0x1EE03, 0x1EE05, 0x1EE06, 0x1EE07, 0x1EE08, 0x1EE09,
  20074. 0x1EE0A, 0x1EE0B, 0x1EE0C, 0x1EE0D, 0x1EE0E, 0x1EE0F, 0x1EE10, 0x1EE11,
  20075. 0x1EE12, 0x1EE13, 0x1EE14, 0x1EE15, 0x1EE16, 0x1EE17, 0x1EE18, 0x1EE19,
  20076. 0x1EE1A, 0x1EE1B, 0x1EE1C, 0x1EE1D, 0x1EE1E, 0x1EE1F, 0x1EE21, 0x1EE22,
  20077. 0x1EE24, 0x1EE27, 0x1EE29, 0x1EE2A, 0x1EE2B, 0x1EE2C, 0x1EE2D, 0x1EE2E,
  20078. 0x1EE2F, 0x1EE30, 0x1EE31, 0x1EE32, 0x1EE34, 0x1EE35, 0x1EE36, 0x1EE37,
  20079. 0x1EE39, 0x1EE3B, 0x1EE42, 0x1EE47, 0x1EE49, 0x1EE4B, 0x1EE4D, 0x1EE4E,
  20080. 0x1EE4F, 0x1EE51, 0x1EE52, 0x1EE54, 0x1EE57, 0x1EE59, 0x1EE5B, 0x1EE5D,
  20081. 0x1EE5F, 0x1EE61, 0x1EE62, 0x1EE64, 0x1EE67, 0x1EE68, 0x1EE69, 0x1EE6A,
  20082. 0x1EE6C, 0x1EE6D, 0x1EE6E, 0x1EE6F, 0x1EE70, 0x1EE71, 0x1EE72, 0x1EE74,
  20083. 0x1EE75, 0x1EE76, 0x1EE77, 0x1EE79, 0x1EE7A, 0x1EE7B, 0x1EE7C, 0x1EE7E,
  20084. 0x1EE80, 0x1EE81, 0x1EE82, 0x1EE83, 0x1EE84, 0x1EE85, 0x1EE86, 0x1EE87,
  20085. 0x1EE88, 0x1EE89, 0x1EE8B, 0x1EE8C, 0x1EE8D, 0x1EE8E, 0x1EE8F, 0x1EE90,
  20086. 0x1EE91, 0x1EE92, 0x1EE93, 0x1EE94, 0x1EE95, 0x1EE96, 0x1EE97, 0x1EE98,
  20087. 0x1EE99, 0x1EE9A, 0x1EE9B, 0x1EEA1, 0x1EEA2, 0x1EEA3, 0x1EEA5, 0x1EEA6,
  20088. 0x1EEA7, 0x1EEA8, 0x1EEA9, 0x1EEAB, 0x1EEAC, 0x1EEAD, 0x1EEAE, 0x1EEAF,
  20089. 0x1EEB0, 0x1EEB1, 0x1EEB2, 0x1EEB3, 0x1EEB4, 0x1EEB5, 0x1EEB6, 0x1EEB7,
  20090. 0x1EEB8, 0x1EEB9, 0x1EEBA, 0x1EEBB, 0x10FFFD];
  20091. function determineBidi(cueDiv) {
  20092. var nodeStack = [],
  20093. text = "",
  20094. charCode;
  20095. if (!cueDiv || !cueDiv.childNodes) {
  20096. return "ltr";
  20097. }
  20098. function pushNodes(nodeStack, node) {
  20099. for (var i = node.childNodes.length - 1; i >= 0; i--) {
  20100. nodeStack.push(node.childNodes[i]);
  20101. }
  20102. }
  20103. function nextTextNode(nodeStack) {
  20104. if (!nodeStack || !nodeStack.length) {
  20105. return null;
  20106. }
  20107. var node = nodeStack.pop(),
  20108. text = node.textContent || node.innerText;
  20109. if (text) {
  20110. // TODO: This should match all unicode type B characters (paragraph
  20111. // separator characters). See issue #115.
  20112. var m = text.match(/^.*(\n|\r)/);
  20113. if (m) {
  20114. nodeStack.length = 0;
  20115. return m[0];
  20116. }
  20117. return text;
  20118. }
  20119. if (node.tagName === "ruby") {
  20120. return nextTextNode(nodeStack);
  20121. }
  20122. if (node.childNodes) {
  20123. pushNodes(nodeStack, node);
  20124. return nextTextNode(nodeStack);
  20125. }
  20126. }
  20127. pushNodes(nodeStack, cueDiv);
  20128. while ((text = nextTextNode(nodeStack))) {
  20129. for (var i = 0; i < text.length; i++) {
  20130. charCode = text.charCodeAt(i);
  20131. for (var j = 0; j < strongRTLChars.length; j++) {
  20132. if (strongRTLChars[j] === charCode) {
  20133. return "rtl";
  20134. }
  20135. }
  20136. }
  20137. }
  20138. return "ltr";
  20139. }
  20140. function computeLinePos(cue) {
  20141. if (typeof cue.line === "number" &&
  20142. (cue.snapToLines || (cue.line >= 0 && cue.line <= 100))) {
  20143. return cue.line;
  20144. }
  20145. if (!cue.track || !cue.track.textTrackList ||
  20146. !cue.track.textTrackList.mediaElement) {
  20147. return -1;
  20148. }
  20149. var track = cue.track,
  20150. trackList = track.textTrackList,
  20151. count = 0;
  20152. for (var i = 0; i < trackList.length && trackList[i] !== track; i++) {
  20153. if (trackList[i].mode === "showing") {
  20154. count++;
  20155. }
  20156. }
  20157. return ++count * -1;
  20158. }
  20159. function StyleBox() {
  20160. }
  20161. // Apply styles to a div. If there is no div passed then it defaults to the
  20162. // div on 'this'.
  20163. StyleBox.prototype.applyStyles = function(styles, div) {
  20164. div = div || this.div;
  20165. for (var prop in styles) {
  20166. if (styles.hasOwnProperty(prop)) {
  20167. div.style[prop] = styles[prop];
  20168. }
  20169. }
  20170. };
  20171. StyleBox.prototype.formatStyle = function(val, unit) {
  20172. return val === 0 ? 0 : val + unit;
  20173. };
  20174. // Constructs the computed display state of the cue (a div). Places the div
  20175. // into the overlay which should be a block level element (usually a div).
  20176. function CueStyleBox(window, cue, styleOptions) {
  20177. var isIE8 = (/MSIE\s8\.0/).test(navigator.userAgent);
  20178. var color = "rgba(255, 255, 255, 1)";
  20179. var backgroundColor = "rgba(0, 0, 0, 0.8)";
  20180. if (isIE8) {
  20181. color = "rgb(255, 255, 255)";
  20182. backgroundColor = "rgb(0, 0, 0)";
  20183. }
  20184. StyleBox.call(this);
  20185. this.cue = cue;
  20186. // Parse our cue's text into a DOM tree rooted at 'cueDiv'. This div will
  20187. // have inline positioning and will function as the cue background box.
  20188. this.cueDiv = parseContent(window, cue.text);
  20189. var styles = {
  20190. color: color,
  20191. backgroundColor: backgroundColor,
  20192. position: "relative",
  20193. left: 0,
  20194. right: 0,
  20195. top: 0,
  20196. bottom: 0,
  20197. display: "inline"
  20198. };
  20199. if (!isIE8) {
  20200. styles.writingMode = cue.vertical === "" ? "horizontal-tb"
  20201. : cue.vertical === "lr" ? "vertical-lr"
  20202. : "vertical-rl";
  20203. styles.unicodeBidi = "plaintext";
  20204. }
  20205. this.applyStyles(styles, this.cueDiv);
  20206. // Create an absolutely positioned div that will be used to position the cue
  20207. // div. Note, all WebVTT cue-setting alignments are equivalent to the CSS
  20208. // mirrors of them except "middle" which is "center" in CSS.
  20209. this.div = window.document.createElement("div");
  20210. styles = {
  20211. textAlign: cue.align === "middle" ? "center" : cue.align,
  20212. font: styleOptions.font,
  20213. whiteSpace: "pre-line",
  20214. position: "absolute"
  20215. };
  20216. if (!isIE8) {
  20217. styles.direction = determineBidi(this.cueDiv);
  20218. styles.writingMode = cue.vertical === "" ? "horizontal-tb"
  20219. : cue.vertical === "lr" ? "vertical-lr"
  20220. : "vertical-rl".
  20221. stylesunicodeBidi = "plaintext";
  20222. }
  20223. this.applyStyles(styles);
  20224. this.div.appendChild(this.cueDiv);
  20225. // Calculate the distance from the reference edge of the viewport to the text
  20226. // position of the cue box. The reference edge will be resolved later when
  20227. // the box orientation styles are applied.
  20228. var textPos = 0;
  20229. switch (cue.positionAlign) {
  20230. case "start":
  20231. textPos = cue.position;
  20232. break;
  20233. case "middle":
  20234. textPos = cue.position - (cue.size / 2);
  20235. break;
  20236. case "end":
  20237. textPos = cue.position - cue.size;
  20238. break;
  20239. }
  20240. // Horizontal box orientation; textPos is the distance from the left edge of the
  20241. // area to the left edge of the box and cue.size is the distance extending to
  20242. // the right from there.
  20243. if (cue.vertical === "") {
  20244. this.applyStyles({
  20245. left: this.formatStyle(textPos, "%"),
  20246. width: this.formatStyle(cue.size, "%")
  20247. });
  20248. // Vertical box orientation; textPos is the distance from the top edge of the
  20249. // area to the top edge of the box and cue.size is the height extending
  20250. // downwards from there.
  20251. } else {
  20252. this.applyStyles({
  20253. top: this.formatStyle(textPos, "%"),
  20254. height: this.formatStyle(cue.size, "%")
  20255. });
  20256. }
  20257. this.move = function(box) {
  20258. this.applyStyles({
  20259. top: this.formatStyle(box.top, "px"),
  20260. bottom: this.formatStyle(box.bottom, "px"),
  20261. left: this.formatStyle(box.left, "px"),
  20262. right: this.formatStyle(box.right, "px"),
  20263. height: this.formatStyle(box.height, "px"),
  20264. width: this.formatStyle(box.width, "px")
  20265. });
  20266. };
  20267. }
  20268. CueStyleBox.prototype = _objCreate(StyleBox.prototype);
  20269. CueStyleBox.prototype.constructor = CueStyleBox;
  20270. // Represents the co-ordinates of an Element in a way that we can easily
  20271. // compute things with such as if it overlaps or intersects with another Element.
  20272. // Can initialize it with either a StyleBox or another BoxPosition.
  20273. function BoxPosition(obj) {
  20274. var isIE8 = (/MSIE\s8\.0/).test(navigator.userAgent);
  20275. // Either a BoxPosition was passed in and we need to copy it, or a StyleBox
  20276. // was passed in and we need to copy the results of 'getBoundingClientRect'
  20277. // as the object returned is readonly. All co-ordinate values are in reference
  20278. // to the viewport origin (top left).
  20279. var lh, height, width, top;
  20280. if (obj.div) {
  20281. height = obj.div.offsetHeight;
  20282. width = obj.div.offsetWidth;
  20283. top = obj.div.offsetTop;
  20284. var rects = (rects = obj.div.childNodes) && (rects = rects[0]) &&
  20285. rects.getClientRects && rects.getClientRects();
  20286. obj = obj.div.getBoundingClientRect();
  20287. // In certain cases the outter div will be slightly larger then the sum of
  20288. // the inner div's lines. This could be due to bold text, etc, on some platforms.
  20289. // In this case we should get the average line height and use that. This will
  20290. // result in the desired behaviour.
  20291. lh = rects ? Math.max((rects[0] && rects[0].height) || 0, obj.height / rects.length)
  20292. : 0;
  20293. }
  20294. this.left = obj.left;
  20295. this.right = obj.right;
  20296. this.top = obj.top || top;
  20297. this.height = obj.height || height;
  20298. this.bottom = obj.bottom || (top + (obj.height || height));
  20299. this.width = obj.width || width;
  20300. this.lineHeight = lh !== undefined ? lh : obj.lineHeight;
  20301. if (isIE8 && !this.lineHeight) {
  20302. this.lineHeight = 13;
  20303. }
  20304. }
  20305. // Move the box along a particular axis. Optionally pass in an amount to move
  20306. // the box. If no amount is passed then the default is the line height of the
  20307. // box.
  20308. BoxPosition.prototype.move = function(axis, toMove) {
  20309. toMove = toMove !== undefined ? toMove : this.lineHeight;
  20310. switch (axis) {
  20311. case "+x":
  20312. this.left += toMove;
  20313. this.right += toMove;
  20314. break;
  20315. case "-x":
  20316. this.left -= toMove;
  20317. this.right -= toMove;
  20318. break;
  20319. case "+y":
  20320. this.top += toMove;
  20321. this.bottom += toMove;
  20322. break;
  20323. case "-y":
  20324. this.top -= toMove;
  20325. this.bottom -= toMove;
  20326. break;
  20327. }
  20328. };
  20329. // Check if this box overlaps another box, b2.
  20330. BoxPosition.prototype.overlaps = function(b2) {
  20331. return this.left < b2.right &&
  20332. this.right > b2.left &&
  20333. this.top < b2.bottom &&
  20334. this.bottom > b2.top;
  20335. };
  20336. // Check if this box overlaps any other boxes in boxes.
  20337. BoxPosition.prototype.overlapsAny = function(boxes) {
  20338. for (var i = 0; i < boxes.length; i++) {
  20339. if (this.overlaps(boxes[i])) {
  20340. return true;
  20341. }
  20342. }
  20343. return false;
  20344. };
  20345. // Check if this box is within another box.
  20346. BoxPosition.prototype.within = function(container) {
  20347. return this.top >= container.top &&
  20348. this.bottom <= container.bottom &&
  20349. this.left >= container.left &&
  20350. this.right <= container.right;
  20351. };
  20352. // Check if this box is entirely within the container or it is overlapping
  20353. // on the edge opposite of the axis direction passed. For example, if "+x" is
  20354. // passed and the box is overlapping on the left edge of the container, then
  20355. // return true.
  20356. BoxPosition.prototype.overlapsOppositeAxis = function(container, axis) {
  20357. switch (axis) {
  20358. case "+x":
  20359. return this.left < container.left;
  20360. case "-x":
  20361. return this.right > container.right;
  20362. case "+y":
  20363. return this.top < container.top;
  20364. case "-y":
  20365. return this.bottom > container.bottom;
  20366. }
  20367. };
  20368. // Find the percentage of the area that this box is overlapping with another
  20369. // box.
  20370. BoxPosition.prototype.intersectPercentage = function(b2) {
  20371. var x = Math.max(0, Math.min(this.right, b2.right) - Math.max(this.left, b2.left)),
  20372. y = Math.max(0, Math.min(this.bottom, b2.bottom) - Math.max(this.top, b2.top)),
  20373. intersectArea = x * y;
  20374. return intersectArea / (this.height * this.width);
  20375. };
  20376. // Convert the positions from this box to CSS compatible positions using
  20377. // the reference container's positions. This has to be done because this
  20378. // box's positions are in reference to the viewport origin, whereas, CSS
  20379. // values are in referecne to their respective edges.
  20380. BoxPosition.prototype.toCSSCompatValues = function(reference) {
  20381. return {
  20382. top: this.top - reference.top,
  20383. bottom: reference.bottom - this.bottom,
  20384. left: this.left - reference.left,
  20385. right: reference.right - this.right,
  20386. height: this.height,
  20387. width: this.width
  20388. };
  20389. };
  20390. // Get an object that represents the box's position without anything extra.
  20391. // Can pass a StyleBox, HTMLElement, or another BoxPositon.
  20392. BoxPosition.getSimpleBoxPosition = function(obj) {
  20393. var height = obj.div ? obj.div.offsetHeight : obj.tagName ? obj.offsetHeight : 0;
  20394. var width = obj.div ? obj.div.offsetWidth : obj.tagName ? obj.offsetWidth : 0;
  20395. var top = obj.div ? obj.div.offsetTop : obj.tagName ? obj.offsetTop : 0;
  20396. obj = obj.div ? obj.div.getBoundingClientRect() :
  20397. obj.tagName ? obj.getBoundingClientRect() : obj;
  20398. var ret = {
  20399. left: obj.left,
  20400. right: obj.right,
  20401. top: obj.top || top,
  20402. height: obj.height || height,
  20403. bottom: obj.bottom || (top + (obj.height || height)),
  20404. width: obj.width || width
  20405. };
  20406. return ret;
  20407. };
  20408. // Move a StyleBox to its specified, or next best, position. The containerBox
  20409. // is the box that contains the StyleBox, such as a div. boxPositions are
  20410. // a list of other boxes that the styleBox can't overlap with.
  20411. function moveBoxToLinePosition(window, styleBox, containerBox, boxPositions) {
  20412. // Find the best position for a cue box, b, on the video. The axis parameter
  20413. // is a list of axis, the order of which, it will move the box along. For example:
  20414. // Passing ["+x", "-x"] will move the box first along the x axis in the positive
  20415. // direction. If it doesn't find a good position for it there it will then move
  20416. // it along the x axis in the negative direction.
  20417. function findBestPosition(b, axis) {
  20418. var bestPosition,
  20419. specifiedPosition = new BoxPosition(b),
  20420. percentage = 1; // Highest possible so the first thing we get is better.
  20421. for (var i = 0; i < axis.length; i++) {
  20422. while (b.overlapsOppositeAxis(containerBox, axis[i]) ||
  20423. (b.within(containerBox) && b.overlapsAny(boxPositions))) {
  20424. b.move(axis[i]);
  20425. }
  20426. // We found a spot where we aren't overlapping anything. This is our
  20427. // best position.
  20428. if (b.within(containerBox)) {
  20429. return b;
  20430. }
  20431. var p = b.intersectPercentage(containerBox);
  20432. // If we're outside the container box less then we were on our last try
  20433. // then remember this position as the best position.
  20434. if (percentage > p) {
  20435. bestPosition = new BoxPosition(b);
  20436. percentage = p;
  20437. }
  20438. // Reset the box position to the specified position.
  20439. b = new BoxPosition(specifiedPosition);
  20440. }
  20441. return bestPosition || specifiedPosition;
  20442. }
  20443. var boxPosition = new BoxPosition(styleBox),
  20444. cue = styleBox.cue,
  20445. linePos = computeLinePos(cue),
  20446. axis = [];
  20447. // If we have a line number to align the cue to.
  20448. if (cue.snapToLines) {
  20449. var size;
  20450. switch (cue.vertical) {
  20451. case "":
  20452. axis = [ "+y", "-y" ];
  20453. size = "height";
  20454. break;
  20455. case "rl":
  20456. axis = [ "+x", "-x" ];
  20457. size = "width";
  20458. break;
  20459. case "lr":
  20460. axis = [ "-x", "+x" ];
  20461. size = "width";
  20462. break;
  20463. }
  20464. var step = boxPosition.lineHeight,
  20465. position = step * Math.round(linePos),
  20466. maxPosition = containerBox[size] + step,
  20467. initialAxis = axis[0];
  20468. // If the specified intial position is greater then the max position then
  20469. // clamp the box to the amount of steps it would take for the box to
  20470. // reach the max position.
  20471. if (Math.abs(position) > maxPosition) {
  20472. position = position < 0 ? -1 : 1;
  20473. position *= Math.ceil(maxPosition / step) * step;
  20474. }
  20475. // If computed line position returns negative then line numbers are
  20476. // relative to the bottom of the video instead of the top. Therefore, we
  20477. // need to increase our initial position by the length or width of the
  20478. // video, depending on the writing direction, and reverse our axis directions.
  20479. if (linePos < 0) {
  20480. position += cue.vertical === "" ? containerBox.height : containerBox.width;
  20481. axis = axis.reverse();
  20482. }
  20483. // Move the box to the specified position. This may not be its best
  20484. // position.
  20485. boxPosition.move(initialAxis, position);
  20486. } else {
  20487. // If we have a percentage line value for the cue.
  20488. var calculatedPercentage = (boxPosition.lineHeight / containerBox.height) * 100;
  20489. switch (cue.lineAlign) {
  20490. case "middle":
  20491. linePos -= (calculatedPercentage / 2);
  20492. break;
  20493. case "end":
  20494. linePos -= calculatedPercentage;
  20495. break;
  20496. }
  20497. // Apply initial line position to the cue box.
  20498. switch (cue.vertical) {
  20499. case "":
  20500. styleBox.applyStyles({
  20501. top: styleBox.formatStyle(linePos, "%")
  20502. });
  20503. break;
  20504. case "rl":
  20505. styleBox.applyStyles({
  20506. left: styleBox.formatStyle(linePos, "%")
  20507. });
  20508. break;
  20509. case "lr":
  20510. styleBox.applyStyles({
  20511. right: styleBox.formatStyle(linePos, "%")
  20512. });
  20513. break;
  20514. }
  20515. axis = [ "+y", "-x", "+x", "-y" ];
  20516. // Get the box position again after we've applied the specified positioning
  20517. // to it.
  20518. boxPosition = new BoxPosition(styleBox);
  20519. }
  20520. var bestPosition = findBestPosition(boxPosition, axis);
  20521. styleBox.move(bestPosition.toCSSCompatValues(containerBox));
  20522. }
  20523. function WebVTT() {
  20524. // Nothing
  20525. }
  20526. // Helper to allow strings to be decoded instead of the default binary utf8 data.
  20527. WebVTT.StringDecoder = function() {
  20528. return {
  20529. decode: function(data) {
  20530. if (!data) {
  20531. return "";
  20532. }
  20533. if (typeof data !== "string") {
  20534. throw new Error("Error - expected string data.");
  20535. }
  20536. return decodeURIComponent(encodeURIComponent(data));
  20537. }
  20538. };
  20539. };
  20540. WebVTT.convertCueToDOMTree = function(window, cuetext) {
  20541. if (!window || !cuetext) {
  20542. return null;
  20543. }
  20544. return parseContent(window, cuetext);
  20545. };
  20546. var FONT_SIZE_PERCENT = 0.05;
  20547. var FONT_STYLE = "sans-serif";
  20548. var CUE_BACKGROUND_PADDING = "1.5%";
  20549. // Runs the processing model over the cues and regions passed to it.
  20550. // @param overlay A block level element (usually a div) that the computed cues
  20551. // and regions will be placed into.
  20552. WebVTT.processCues = function(window, cues, overlay) {
  20553. if (!window || !cues || !overlay) {
  20554. return null;
  20555. }
  20556. // Remove all previous children.
  20557. while (overlay.firstChild) {
  20558. overlay.removeChild(overlay.firstChild);
  20559. }
  20560. var paddedOverlay = window.document.createElement("div");
  20561. paddedOverlay.style.position = "absolute";
  20562. paddedOverlay.style.left = "0";
  20563. paddedOverlay.style.right = "0";
  20564. paddedOverlay.style.top = "0";
  20565. paddedOverlay.style.bottom = "0";
  20566. paddedOverlay.style.margin = CUE_BACKGROUND_PADDING;
  20567. overlay.appendChild(paddedOverlay);
  20568. // Determine if we need to compute the display states of the cues. This could
  20569. // be the case if a cue's state has been changed since the last computation or
  20570. // if it has not been computed yet.
  20571. function shouldCompute(cues) {
  20572. for (var i = 0; i < cues.length; i++) {
  20573. if (cues[i].hasBeenReset || !cues[i].displayState) {
  20574. return true;
  20575. }
  20576. }
  20577. return false;
  20578. }
  20579. // We don't need to recompute the cues' display states. Just reuse them.
  20580. if (!shouldCompute(cues)) {
  20581. for (var i = 0; i < cues.length; i++) {
  20582. paddedOverlay.appendChild(cues[i].displayState);
  20583. }
  20584. return;
  20585. }
  20586. var boxPositions = [],
  20587. containerBox = BoxPosition.getSimpleBoxPosition(paddedOverlay),
  20588. fontSize = Math.round(containerBox.height * FONT_SIZE_PERCENT * 100) / 100;
  20589. var styleOptions = {
  20590. font: fontSize + "px " + FONT_STYLE
  20591. };
  20592. (function() {
  20593. var styleBox, cue;
  20594. for (var i = 0; i < cues.length; i++) {
  20595. cue = cues[i];
  20596. // Compute the intial position and styles of the cue div.
  20597. styleBox = new CueStyleBox(window, cue, styleOptions);
  20598. paddedOverlay.appendChild(styleBox.div);
  20599. // Move the cue div to it's correct line position.
  20600. moveBoxToLinePosition(window, styleBox, containerBox, boxPositions);
  20601. // Remember the computed div so that we don't have to recompute it later
  20602. // if we don't have too.
  20603. cue.displayState = styleBox.div;
  20604. boxPositions.push(BoxPosition.getSimpleBoxPosition(styleBox));
  20605. }
  20606. })();
  20607. };
  20608. WebVTT.Parser = function(window, vttjs, decoder) {
  20609. if (!decoder) {
  20610. decoder = vttjs;
  20611. vttjs = {};
  20612. }
  20613. if (!vttjs) {
  20614. vttjs = {};
  20615. }
  20616. this.window = window;
  20617. this.vttjs = vttjs;
  20618. this.state = "INITIAL";
  20619. this.buffer = "";
  20620. this.decoder = decoder || new TextDecoder("utf8");
  20621. this.regionList = [];
  20622. };
  20623. WebVTT.Parser.prototype = {
  20624. // If the error is a ParsingError then report it to the consumer if
  20625. // possible. If it's not a ParsingError then throw it like normal.
  20626. reportOrThrowError: function(e) {
  20627. if (e instanceof ParsingError) {
  20628. this.onparsingerror && this.onparsingerror(e);
  20629. } else {
  20630. throw e;
  20631. }
  20632. },
  20633. parse: function (data) {
  20634. var self = this;
  20635. // If there is no data then we won't decode it, but will just try to parse
  20636. // whatever is in buffer already. This may occur in circumstances, for
  20637. // example when flush() is called.
  20638. if (data) {
  20639. // Try to decode the data that we received.
  20640. self.buffer += self.decoder.decode(data, {stream: true});
  20641. }
  20642. function collectNextLine() {
  20643. var buffer = self.buffer;
  20644. var pos = 0;
  20645. while (pos < buffer.length && buffer[pos] !== '\r' && buffer[pos] !== '\n') {
  20646. ++pos;
  20647. }
  20648. var line = buffer.substr(0, pos);
  20649. // Advance the buffer early in case we fail below.
  20650. if (buffer[pos] === '\r') {
  20651. ++pos;
  20652. }
  20653. if (buffer[pos] === '\n') {
  20654. ++pos;
  20655. }
  20656. self.buffer = buffer.substr(pos);
  20657. return line;
  20658. }
  20659. // 3.4 WebVTT region and WebVTT region settings syntax
  20660. function parseRegion(input) {
  20661. var settings = new Settings();
  20662. parseOptions(input, function (k, v) {
  20663. switch (k) {
  20664. case "id":
  20665. settings.set(k, v);
  20666. break;
  20667. case "width":
  20668. settings.percent(k, v);
  20669. break;
  20670. case "lines":
  20671. settings.integer(k, v);
  20672. break;
  20673. case "regionanchor":
  20674. case "viewportanchor":
  20675. var xy = v.split(',');
  20676. if (xy.length !== 2) {
  20677. break;
  20678. }
  20679. // We have to make sure both x and y parse, so use a temporary
  20680. // settings object here.
  20681. var anchor = new Settings();
  20682. anchor.percent("x", xy[0]);
  20683. anchor.percent("y", xy[1]);
  20684. if (!anchor.has("x") || !anchor.has("y")) {
  20685. break;
  20686. }
  20687. settings.set(k + "X", anchor.get("x"));
  20688. settings.set(k + "Y", anchor.get("y"));
  20689. break;
  20690. case "scroll":
  20691. settings.alt(k, v, ["up"]);
  20692. break;
  20693. }
  20694. }, /=/, /\s/);
  20695. // Create the region, using default values for any values that were not
  20696. // specified.
  20697. if (settings.has("id")) {
  20698. var region = new (self.vttjs.VTTRegion || self.window.VTTRegion)();
  20699. region.width = settings.get("width", 100);
  20700. region.lines = settings.get("lines", 3);
  20701. region.regionAnchorX = settings.get("regionanchorX", 0);
  20702. region.regionAnchorY = settings.get("regionanchorY", 100);
  20703. region.viewportAnchorX = settings.get("viewportanchorX", 0);
  20704. region.viewportAnchorY = settings.get("viewportanchorY", 100);
  20705. region.scroll = settings.get("scroll", "");
  20706. // Register the region.
  20707. self.onregion && self.onregion(region);
  20708. // Remember the VTTRegion for later in case we parse any VTTCues that
  20709. // reference it.
  20710. self.regionList.push({
  20711. id: settings.get("id"),
  20712. region: region
  20713. });
  20714. }
  20715. }
  20716. // 3.2 WebVTT metadata header syntax
  20717. function parseHeader(input) {
  20718. parseOptions(input, function (k, v) {
  20719. switch (k) {
  20720. case "Region":
  20721. // 3.3 WebVTT region metadata header syntax
  20722. parseRegion(v);
  20723. break;
  20724. }
  20725. }, /:/);
  20726. }
  20727. // 5.1 WebVTT file parsing.
  20728. try {
  20729. var line;
  20730. if (self.state === "INITIAL") {
  20731. // We can't start parsing until we have the first line.
  20732. if (!/\r\n|\n/.test(self.buffer)) {
  20733. return this;
  20734. }
  20735. line = collectNextLine();
  20736. var m = line.match(/^WEBVTT([ \t].*)?$/);
  20737. if (!m || !m[0]) {
  20738. throw new ParsingError(ParsingError.Errors.BadSignature);
  20739. }
  20740. self.state = "HEADER";
  20741. }
  20742. var alreadyCollectedLine = false;
  20743. while (self.buffer) {
  20744. // We can't parse a line until we have the full line.
  20745. if (!/\r\n|\n/.test(self.buffer)) {
  20746. return this;
  20747. }
  20748. if (!alreadyCollectedLine) {
  20749. line = collectNextLine();
  20750. } else {
  20751. alreadyCollectedLine = false;
  20752. }
  20753. switch (self.state) {
  20754. case "HEADER":
  20755. // 13-18 - Allow a header (metadata) under the WEBVTT line.
  20756. if (/:/.test(line)) {
  20757. parseHeader(line);
  20758. } else if (!line) {
  20759. // An empty line terminates the header and starts the body (cues).
  20760. self.state = "ID";
  20761. }
  20762. continue;
  20763. case "NOTE":
  20764. // Ignore NOTE blocks.
  20765. if (!line) {
  20766. self.state = "ID";
  20767. }
  20768. continue;
  20769. case "ID":
  20770. // Check for the start of NOTE blocks.
  20771. if (/^NOTE($|[ \t])/.test(line)) {
  20772. self.state = "NOTE";
  20773. break;
  20774. }
  20775. // 19-29 - Allow any number of line terminators, then initialize new cue values.
  20776. if (!line) {
  20777. continue;
  20778. }
  20779. self.cue = new (self.vttjs.VTTCue || self.window.VTTCue)(0, 0, "");
  20780. self.state = "CUE";
  20781. // 30-39 - Check if self line contains an optional identifier or timing data.
  20782. if (line.indexOf("-->") === -1) {
  20783. self.cue.id = line;
  20784. continue;
  20785. }
  20786. // Process line as start of a cue.
  20787. /*falls through*/
  20788. case "CUE":
  20789. // 40 - Collect cue timings and settings.
  20790. try {
  20791. parseCue(line, self.cue, self.regionList);
  20792. } catch (e) {
  20793. self.reportOrThrowError(e);
  20794. // In case of an error ignore rest of the cue.
  20795. self.cue = null;
  20796. self.state = "BADCUE";
  20797. continue;
  20798. }
  20799. self.state = "CUETEXT";
  20800. continue;
  20801. case "CUETEXT":
  20802. var hasSubstring = line.indexOf("-->") !== -1;
  20803. // 34 - If we have an empty line then report the cue.
  20804. // 35 - If we have the special substring '-->' then report the cue,
  20805. // but do not collect the line as we need to process the current
  20806. // one as a new cue.
  20807. if (!line || hasSubstring && (alreadyCollectedLine = true)) {
  20808. // We are done parsing self cue.
  20809. self.oncue && self.oncue(self.cue);
  20810. self.cue = null;
  20811. self.state = "ID";
  20812. continue;
  20813. }
  20814. if (self.cue.text) {
  20815. self.cue.text += "\n";
  20816. }
  20817. self.cue.text += line;
  20818. continue;
  20819. case "BADCUE": // BADCUE
  20820. // 54-62 - Collect and discard the remaining cue.
  20821. if (!line) {
  20822. self.state = "ID";
  20823. }
  20824. continue;
  20825. }
  20826. }
  20827. } catch (e) {
  20828. self.reportOrThrowError(e);
  20829. // If we are currently parsing a cue, report what we have.
  20830. if (self.state === "CUETEXT" && self.cue && self.oncue) {
  20831. self.oncue(self.cue);
  20832. }
  20833. self.cue = null;
  20834. // Enter BADWEBVTT state if header was not parsed correctly otherwise
  20835. // another exception occurred so enter BADCUE state.
  20836. self.state = self.state === "INITIAL" ? "BADWEBVTT" : "BADCUE";
  20837. }
  20838. return this;
  20839. },
  20840. flush: function () {
  20841. var self = this;
  20842. try {
  20843. // Finish decoding the stream.
  20844. self.buffer += self.decoder.decode();
  20845. // Synthesize the end of the current cue or region.
  20846. if (self.cue || self.state === "HEADER") {
  20847. self.buffer += "\n\n";
  20848. self.parse();
  20849. }
  20850. // If we've flushed, parsed, and we're still on the INITIAL state then
  20851. // that means we don't have enough of the stream to parse the first
  20852. // line.
  20853. if (self.state === "INITIAL") {
  20854. throw new ParsingError(ParsingError.Errors.BadSignature);
  20855. }
  20856. } catch(e) {
  20857. self.reportOrThrowError(e);
  20858. }
  20859. self.onflush && self.onflush();
  20860. return this;
  20861. }
  20862. };
  20863. global.WebVTT = WebVTT;
  20864. }(this, (this.vttjs || {})));
  20865. },{}],101:[function(_dereq_,module,exports){
  20866. /**
  20867. * Copyright 2013 vtt.js Contributors
  20868. *
  20869. * Licensed under the Apache License, Version 2.0 (the "License");
  20870. * you may not use this file except in compliance with the License.
  20871. * You may obtain a copy of the License at
  20872. *
  20873. * http://www.apache.org/licenses/LICENSE-2.0
  20874. *
  20875. * Unless required by applicable law or agreed to in writing, software
  20876. * distributed under the License is distributed on an "AS IS" BASIS,
  20877. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  20878. * See the License for the specific language governing permissions and
  20879. * limitations under the License.
  20880. */
  20881. // If we're in Node.js then require VTTCue so we can extend it, otherwise assume
  20882. // VTTCue is on the global.
  20883. if (typeof module !== "undefined" && module.exports) {
  20884. this.VTTCue = this.VTTCue || _dereq_(102).VTTCue;
  20885. }
  20886. // Extend VTTCue with methods to convert to JSON, from JSON, and construct a
  20887. // VTTCue from an options object. The primary purpose of this is for use in the
  20888. // vtt.js test suite (for testing only properties that we care about). It's also
  20889. // useful if you need to work with VTTCues in JSON format.
  20890. (function(root) {
  20891. root.VTTCue.prototype.toJSON = function() {
  20892. var cue = {},
  20893. self = this;
  20894. // Filter out getCueAsHTML as it's a function and hasBeenReset and displayState as
  20895. // they're only used when running the processing model algorithm.
  20896. Object.keys(this).forEach(function(key) {
  20897. if (key !== "getCueAsHTML" && key !== "hasBeenReset" && key !== "displayState") {
  20898. cue[key] = self[key];
  20899. }
  20900. });
  20901. return cue;
  20902. };
  20903. root.VTTCue.create = function(options) {
  20904. if (!options.hasOwnProperty("startTime") || !options.hasOwnProperty("endTime") ||
  20905. !options.hasOwnProperty("text")) {
  20906. throw new Error("You must at least have start time, end time, and text.");
  20907. }
  20908. var cue = new root.VTTCue(options.startTime, options.endTime, options.text);
  20909. for (var key in options) {
  20910. if (cue.hasOwnProperty(key)) {
  20911. cue[key] = options[key];
  20912. }
  20913. }
  20914. return cue;
  20915. };
  20916. root.VTTCue.fromJSON = function(json) {
  20917. return this.create(JSON.parse(json));
  20918. };
  20919. }(this));
  20920. },{"102":102}],102:[function(_dereq_,module,exports){
  20921. /**
  20922. * Copyright 2013 vtt.js Contributors
  20923. *
  20924. * Licensed under the Apache License, Version 2.0 (the "License");
  20925. * you may not use this file except in compliance with the License.
  20926. * You may obtain a copy of the License at
  20927. *
  20928. * http://www.apache.org/licenses/LICENSE-2.0
  20929. *
  20930. * Unless required by applicable law or agreed to in writing, software
  20931. * distributed under the License is distributed on an "AS IS" BASIS,
  20932. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  20933. * See the License for the specific language governing permissions and
  20934. * limitations under the License.
  20935. */
  20936. (function(root, vttjs) {
  20937. var autoKeyword = "auto";
  20938. var directionSetting = {
  20939. "": true,
  20940. "lr": true,
  20941. "rl": true
  20942. };
  20943. var alignSetting = {
  20944. "start": true,
  20945. "middle": true,
  20946. "end": true,
  20947. "left": true,
  20948. "right": true
  20949. };
  20950. function findDirectionSetting(value) {
  20951. if (typeof value !== "string") {
  20952. return false;
  20953. }
  20954. var dir = directionSetting[value.toLowerCase()];
  20955. return dir ? value.toLowerCase() : false;
  20956. }
  20957. function findAlignSetting(value) {
  20958. if (typeof value !== "string") {
  20959. return false;
  20960. }
  20961. var align = alignSetting[value.toLowerCase()];
  20962. return align ? value.toLowerCase() : false;
  20963. }
  20964. function extend(obj) {
  20965. var i = 1;
  20966. for (; i < arguments.length; i++) {
  20967. var cobj = arguments[i];
  20968. for (var p in cobj) {
  20969. obj[p] = cobj[p];
  20970. }
  20971. }
  20972. return obj;
  20973. }
  20974. function VTTCue(startTime, endTime, text) {
  20975. var cue = this;
  20976. var isIE8 = (/MSIE\s8\.0/).test(navigator.userAgent);
  20977. var baseObj = {};
  20978. if (isIE8) {
  20979. cue = document.createElement('custom');
  20980. } else {
  20981. baseObj.enumerable = true;
  20982. }
  20983. /**
  20984. * Shim implementation specific properties. These properties are not in
  20985. * the spec.
  20986. */
  20987. // Lets us know when the VTTCue's data has changed in such a way that we need
  20988. // to recompute its display state. This lets us compute its display state
  20989. // lazily.
  20990. cue.hasBeenReset = false;
  20991. /**
  20992. * VTTCue and TextTrackCue properties
  20993. * http://dev.w3.org/html5/webvtt/#vttcue-interface
  20994. */
  20995. var _id = "";
  20996. var _pauseOnExit = false;
  20997. var _startTime = startTime;
  20998. var _endTime = endTime;
  20999. var _text = text;
  21000. var _region = null;
  21001. var _vertical = "";
  21002. var _snapToLines = true;
  21003. var _line = "auto";
  21004. var _lineAlign = "start";
  21005. var _position = 50;
  21006. var _positionAlign = "middle";
  21007. var _size = 50;
  21008. var _align = "middle";
  21009. Object.defineProperty(cue,
  21010. "id", extend({}, baseObj, {
  21011. get: function() {
  21012. return _id;
  21013. },
  21014. set: function(value) {
  21015. _id = "" + value;
  21016. }
  21017. }));
  21018. Object.defineProperty(cue,
  21019. "pauseOnExit", extend({}, baseObj, {
  21020. get: function() {
  21021. return _pauseOnExit;
  21022. },
  21023. set: function(value) {
  21024. _pauseOnExit = !!value;
  21025. }
  21026. }));
  21027. Object.defineProperty(cue,
  21028. "startTime", extend({}, baseObj, {
  21029. get: function() {
  21030. return _startTime;
  21031. },
  21032. set: function(value) {
  21033. if (typeof value !== "number") {
  21034. throw new TypeError("Start time must be set to a number.");
  21035. }
  21036. _startTime = value;
  21037. this.hasBeenReset = true;
  21038. }
  21039. }));
  21040. Object.defineProperty(cue,
  21041. "endTime", extend({}, baseObj, {
  21042. get: function() {
  21043. return _endTime;
  21044. },
  21045. set: function(value) {
  21046. if (typeof value !== "number") {
  21047. throw new TypeError("End time must be set to a number.");
  21048. }
  21049. _endTime = value;
  21050. this.hasBeenReset = true;
  21051. }
  21052. }));
  21053. Object.defineProperty(cue,
  21054. "text", extend({}, baseObj, {
  21055. get: function() {
  21056. return _text;
  21057. },
  21058. set: function(value) {
  21059. _text = "" + value;
  21060. this.hasBeenReset = true;
  21061. }
  21062. }));
  21063. Object.defineProperty(cue,
  21064. "region", extend({}, baseObj, {
  21065. get: function() {
  21066. return _region;
  21067. },
  21068. set: function(value) {
  21069. _region = value;
  21070. this.hasBeenReset = true;
  21071. }
  21072. }));
  21073. Object.defineProperty(cue,
  21074. "vertical", extend({}, baseObj, {
  21075. get: function() {
  21076. return _vertical;
  21077. },
  21078. set: function(value) {
  21079. var setting = findDirectionSetting(value);
  21080. // Have to check for false because the setting an be an empty string.
  21081. if (setting === false) {
  21082. throw new SyntaxError("An invalid or illegal string was specified.");
  21083. }
  21084. _vertical = setting;
  21085. this.hasBeenReset = true;
  21086. }
  21087. }));
  21088. Object.defineProperty(cue,
  21089. "snapToLines", extend({}, baseObj, {
  21090. get: function() {
  21091. return _snapToLines;
  21092. },
  21093. set: function(value) {
  21094. _snapToLines = !!value;
  21095. this.hasBeenReset = true;
  21096. }
  21097. }));
  21098. Object.defineProperty(cue,
  21099. "line", extend({}, baseObj, {
  21100. get: function() {
  21101. return _line;
  21102. },
  21103. set: function(value) {
  21104. if (typeof value !== "number" && value !== autoKeyword) {
  21105. throw new SyntaxError("An invalid number or illegal string was specified.");
  21106. }
  21107. _line = value;
  21108. this.hasBeenReset = true;
  21109. }
  21110. }));
  21111. Object.defineProperty(cue,
  21112. "lineAlign", extend({}, baseObj, {
  21113. get: function() {
  21114. return _lineAlign;
  21115. },
  21116. set: function(value) {
  21117. var setting = findAlignSetting(value);
  21118. if (!setting) {
  21119. throw new SyntaxError("An invalid or illegal string was specified.");
  21120. }
  21121. _lineAlign = setting;
  21122. this.hasBeenReset = true;
  21123. }
  21124. }));
  21125. Object.defineProperty(cue,
  21126. "position", extend({}, baseObj, {
  21127. get: function() {
  21128. return _position;
  21129. },
  21130. set: function(value) {
  21131. if (value < 0 || value > 100) {
  21132. throw new Error("Position must be between 0 and 100.");
  21133. }
  21134. _position = value;
  21135. this.hasBeenReset = true;
  21136. }
  21137. }));
  21138. Object.defineProperty(cue,
  21139. "positionAlign", extend({}, baseObj, {
  21140. get: function() {
  21141. return _positionAlign;
  21142. },
  21143. set: function(value) {
  21144. var setting = findAlignSetting(value);
  21145. if (!setting) {
  21146. throw new SyntaxError("An invalid or illegal string was specified.");
  21147. }
  21148. _positionAlign = setting;
  21149. this.hasBeenReset = true;
  21150. }
  21151. }));
  21152. Object.defineProperty(cue,
  21153. "size", extend({}, baseObj, {
  21154. get: function() {
  21155. return _size;
  21156. },
  21157. set: function(value) {
  21158. if (value < 0 || value > 100) {
  21159. throw new Error("Size must be between 0 and 100.");
  21160. }
  21161. _size = value;
  21162. this.hasBeenReset = true;
  21163. }
  21164. }));
  21165. Object.defineProperty(cue,
  21166. "align", extend({}, baseObj, {
  21167. get: function() {
  21168. return _align;
  21169. },
  21170. set: function(value) {
  21171. var setting = findAlignSetting(value);
  21172. if (!setting) {
  21173. throw new SyntaxError("An invalid or illegal string was specified.");
  21174. }
  21175. _align = setting;
  21176. this.hasBeenReset = true;
  21177. }
  21178. }));
  21179. /**
  21180. * Other <track> spec defined properties
  21181. */
  21182. // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#text-track-cue-display-state
  21183. cue.displayState = undefined;
  21184. if (isIE8) {
  21185. return cue;
  21186. }
  21187. }
  21188. /**
  21189. * VTTCue methods
  21190. */
  21191. VTTCue.prototype.getCueAsHTML = function() {
  21192. // Assume WebVTT.convertCueToDOMTree is on the global.
  21193. return WebVTT.convertCueToDOMTree(window, this.text);
  21194. };
  21195. root.VTTCue = root.VTTCue || VTTCue;
  21196. vttjs.VTTCue = VTTCue;
  21197. }(this, (this.vttjs || {})));
  21198. },{}],103:[function(_dereq_,module,exports){
  21199. /**
  21200. * Copyright 2013 vtt.js Contributors
  21201. *
  21202. * Licensed under the Apache License, Version 2.0 (the "License");
  21203. * you may not use this file except in compliance with the License.
  21204. * You may obtain a copy of the License at
  21205. *
  21206. * http://www.apache.org/licenses/LICENSE-2.0
  21207. *
  21208. * Unless required by applicable law or agreed to in writing, software
  21209. * distributed under the License is distributed on an "AS IS" BASIS,
  21210. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  21211. * See the License for the specific language governing permissions and
  21212. * limitations under the License.
  21213. */
  21214. // If we're in Node.js then require VTTRegion so we can extend it, otherwise assume
  21215. // VTTRegion is on the global.
  21216. if (typeof module !== "undefined" && module.exports) {
  21217. this.VTTRegion = _dereq_(104).VTTRegion;
  21218. }
  21219. // Extend VTTRegion with methods to convert to JSON, from JSON, and construct a
  21220. // VTTRegion from an options object. The primary purpose of this is for use in the
  21221. // vtt.js test suite. It's also useful if you need to work with VTTRegions in
  21222. // JSON format.
  21223. (function(root) {
  21224. root.VTTRegion.create = function(options) {
  21225. var region = new root.VTTRegion();
  21226. for (var key in options) {
  21227. if (region.hasOwnProperty(key)) {
  21228. region[key] = options[key];
  21229. }
  21230. }
  21231. return region;
  21232. };
  21233. root.VTTRegion.fromJSON = function(json) {
  21234. return this.create(JSON.parse(json));
  21235. };
  21236. }(this));
  21237. },{"104":104}],104:[function(_dereq_,module,exports){
  21238. /**
  21239. * Copyright 2013 vtt.js Contributors
  21240. *
  21241. * Licensed under the Apache License, Version 2.0 (the "License");
  21242. * you may not use this file except in compliance with the License.
  21243. * You may obtain a copy of the License at
  21244. *
  21245. * http://www.apache.org/licenses/LICENSE-2.0
  21246. *
  21247. * Unless required by applicable law or agreed to in writing, software
  21248. * distributed under the License is distributed on an "AS IS" BASIS,
  21249. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  21250. * See the License for the specific language governing permissions and
  21251. * limitations under the License.
  21252. */
  21253. (function(root, vttjs) {
  21254. var scrollSetting = {
  21255. "": true,
  21256. "up": true
  21257. };
  21258. function findScrollSetting(value) {
  21259. if (typeof value !== "string") {
  21260. return false;
  21261. }
  21262. var scroll = scrollSetting[value.toLowerCase()];
  21263. return scroll ? value.toLowerCase() : false;
  21264. }
  21265. function isValidPercentValue(value) {
  21266. return typeof value === "number" && (value >= 0 && value <= 100);
  21267. }
  21268. // VTTRegion shim http://dev.w3.org/html5/webvtt/#vttregion-interface
  21269. function VTTRegion() {
  21270. var _width = 100;
  21271. var _lines = 3;
  21272. var _regionAnchorX = 0;
  21273. var _regionAnchorY = 100;
  21274. var _viewportAnchorX = 0;
  21275. var _viewportAnchorY = 100;
  21276. var _scroll = "";
  21277. Object.defineProperties(this, {
  21278. "width": {
  21279. enumerable: true,
  21280. get: function() {
  21281. return _width;
  21282. },
  21283. set: function(value) {
  21284. if (!isValidPercentValue(value)) {
  21285. throw new Error("Width must be between 0 and 100.");
  21286. }
  21287. _width = value;
  21288. }
  21289. },
  21290. "lines": {
  21291. enumerable: true,
  21292. get: function() {
  21293. return _lines;
  21294. },
  21295. set: function(value) {
  21296. if (typeof value !== "number") {
  21297. throw new TypeError("Lines must be set to a number.");
  21298. }
  21299. _lines = value;
  21300. }
  21301. },
  21302. "regionAnchorY": {
  21303. enumerable: true,
  21304. get: function() {
  21305. return _regionAnchorY;
  21306. },
  21307. set: function(value) {
  21308. if (!isValidPercentValue(value)) {
  21309. throw new Error("RegionAnchorX must be between 0 and 100.");
  21310. }
  21311. _regionAnchorY = value;
  21312. }
  21313. },
  21314. "regionAnchorX": {
  21315. enumerable: true,
  21316. get: function() {
  21317. return _regionAnchorX;
  21318. },
  21319. set: function(value) {
  21320. if(!isValidPercentValue(value)) {
  21321. throw new Error("RegionAnchorY must be between 0 and 100.");
  21322. }
  21323. _regionAnchorX = value;
  21324. }
  21325. },
  21326. "viewportAnchorY": {
  21327. enumerable: true,
  21328. get: function() {
  21329. return _viewportAnchorY;
  21330. },
  21331. set: function(value) {
  21332. if (!isValidPercentValue(value)) {
  21333. throw new Error("ViewportAnchorY must be between 0 and 100.");
  21334. }
  21335. _viewportAnchorY = value;
  21336. }
  21337. },
  21338. "viewportAnchorX": {
  21339. enumerable: true,
  21340. get: function() {
  21341. return _viewportAnchorX;
  21342. },
  21343. set: function(value) {
  21344. if (!isValidPercentValue(value)) {
  21345. throw new Error("ViewportAnchorX must be between 0 and 100.");
  21346. }
  21347. _viewportAnchorX = value;
  21348. }
  21349. },
  21350. "scroll": {
  21351. enumerable: true,
  21352. get: function() {
  21353. return _scroll;
  21354. },
  21355. set: function(value) {
  21356. var setting = findScrollSetting(value);
  21357. // Have to check for false as an empty string is a legal value.
  21358. if (setting === false) {
  21359. throw new SyntaxError("An invalid or illegal string was specified.");
  21360. }
  21361. _scroll = setting;
  21362. }
  21363. }
  21364. });
  21365. }
  21366. root.VTTRegion = root.VTTRegion || VTTRegion;
  21367. vttjs.VTTRegion = VTTRegion;
  21368. }(this, (this.vttjs || {})));
  21369. },{}],105:[function(_dereq_,module,exports){
  21370. "use strict";
  21371. var window = _dereq_(95)
  21372. var isFunction = _dereq_(106)
  21373. var parseHeaders = _dereq_(109)
  21374. var xtend = _dereq_(110)
  21375. module.exports = createXHR
  21376. createXHR.XMLHttpRequest = window.XMLHttpRequest || noop
  21377. createXHR.XDomainRequest = "withCredentials" in (new createXHR.XMLHttpRequest()) ? createXHR.XMLHttpRequest : window.XDomainRequest
  21378. forEachArray(["get", "put", "post", "patch", "head", "delete"], function(method) {
  21379. createXHR[method === "delete" ? "del" : method] = function(uri, options, callback) {
  21380. options = initParams(uri, options, callback)
  21381. options.method = method.toUpperCase()
  21382. return _createXHR(options)
  21383. }
  21384. })
  21385. function forEachArray(array, iterator) {
  21386. for (var i = 0; i < array.length; i++) {
  21387. iterator(array[i])
  21388. }
  21389. }
  21390. function isEmpty(obj){
  21391. for(var i in obj){
  21392. if(obj.hasOwnProperty(i)) return false
  21393. }
  21394. return true
  21395. }
  21396. function initParams(uri, options, callback) {
  21397. var params = uri
  21398. if (isFunction(options)) {
  21399. callback = options
  21400. if (typeof uri === "string") {
  21401. params = {uri:uri}
  21402. }
  21403. } else {
  21404. params = xtend(options, {uri: uri})
  21405. }
  21406. params.callback = callback
  21407. return params
  21408. }
  21409. function createXHR(uri, options, callback) {
  21410. options = initParams(uri, options, callback)
  21411. return _createXHR(options)
  21412. }
  21413. function _createXHR(options) {
  21414. if(typeof options.callback === "undefined"){
  21415. throw new Error("callback argument missing")
  21416. }
  21417. var called = false
  21418. var callback = function cbOnce(err, response, body){
  21419. if(!called){
  21420. called = true
  21421. options.callback(err, response, body)
  21422. }
  21423. }
  21424. function readystatechange() {
  21425. if (xhr.readyState === 4) {
  21426. loadFunc()
  21427. }
  21428. }
  21429. function getBody() {
  21430. // Chrome with requestType=blob throws errors arround when even testing access to responseText
  21431. var body = undefined
  21432. if (xhr.response) {
  21433. body = xhr.response
  21434. } else {
  21435. body = xhr.responseText || getXml(xhr)
  21436. }
  21437. if (isJson) {
  21438. try {
  21439. body = JSON.parse(body)
  21440. } catch (e) {}
  21441. }
  21442. return body
  21443. }
  21444. var failureResponse = {
  21445. body: undefined,
  21446. headers: {},
  21447. statusCode: 0,
  21448. method: method,
  21449. url: uri,
  21450. rawRequest: xhr
  21451. }
  21452. function errorFunc(evt) {
  21453. clearTimeout(timeoutTimer)
  21454. if(!(evt instanceof Error)){
  21455. evt = new Error("" + (evt || "Unknown XMLHttpRequest Error") )
  21456. }
  21457. evt.statusCode = 0
  21458. return callback(evt, failureResponse)
  21459. }
  21460. // will load the data & process the response in a special response object
  21461. function loadFunc() {
  21462. if (aborted) return
  21463. var status
  21464. clearTimeout(timeoutTimer)
  21465. if(options.useXDR && xhr.status===undefined) {
  21466. //IE8 CORS GET successful response doesn't have a status field, but body is fine
  21467. status = 200
  21468. } else {
  21469. status = (xhr.status === 1223 ? 204 : xhr.status)
  21470. }
  21471. var response = failureResponse
  21472. var err = null
  21473. if (status !== 0){
  21474. response = {
  21475. body: getBody(),
  21476. statusCode: status,
  21477. method: method,
  21478. headers: {},
  21479. url: uri,
  21480. rawRequest: xhr
  21481. }
  21482. if(xhr.getAllResponseHeaders){ //remember xhr can in fact be XDR for CORS in IE
  21483. response.headers = parseHeaders(xhr.getAllResponseHeaders())
  21484. }
  21485. } else {
  21486. err = new Error("Internal XMLHttpRequest Error")
  21487. }
  21488. return callback(err, response, response.body)
  21489. }
  21490. var xhr = options.xhr || null
  21491. if (!xhr) {
  21492. if (options.cors || options.useXDR) {
  21493. xhr = new createXHR.XDomainRequest()
  21494. }else{
  21495. xhr = new createXHR.XMLHttpRequest()
  21496. }
  21497. }
  21498. var key
  21499. var aborted
  21500. var uri = xhr.url = options.uri || options.url
  21501. var method = xhr.method = options.method || "GET"
  21502. var body = options.body || options.data || null
  21503. var headers = xhr.headers = options.headers || {}
  21504. var sync = !!options.sync
  21505. var isJson = false
  21506. var timeoutTimer
  21507. if ("json" in options) {
  21508. isJson = true
  21509. headers["accept"] || headers["Accept"] || (headers["Accept"] = "application/json") //Don't override existing accept header declared by user
  21510. if (method !== "GET" && method !== "HEAD") {
  21511. headers["content-type"] || headers["Content-Type"] || (headers["Content-Type"] = "application/json") //Don't override existing accept header declared by user
  21512. body = JSON.stringify(options.json)
  21513. }
  21514. }
  21515. xhr.onreadystatechange = readystatechange
  21516. xhr.onload = loadFunc
  21517. xhr.onerror = errorFunc
  21518. // IE9 must have onprogress be set to a unique function.
  21519. xhr.onprogress = function () {
  21520. // IE must die
  21521. }
  21522. xhr.ontimeout = errorFunc
  21523. xhr.open(method, uri, !sync, options.username, options.password)
  21524. //has to be after open
  21525. if(!sync) {
  21526. xhr.withCredentials = !!options.withCredentials
  21527. }
  21528. // Cannot set timeout with sync request
  21529. // not setting timeout on the xhr object, because of old webkits etc. not handling that correctly
  21530. // both npm's request and jquery 1.x use this kind of timeout, so this is being consistent
  21531. if (!sync && options.timeout > 0 ) {
  21532. timeoutTimer = setTimeout(function(){
  21533. aborted=true//IE9 may still call readystatechange
  21534. xhr.abort("timeout")
  21535. var e = new Error("XMLHttpRequest timeout")
  21536. e.code = "ETIMEDOUT"
  21537. errorFunc(e)
  21538. }, options.timeout )
  21539. }
  21540. if (xhr.setRequestHeader) {
  21541. for(key in headers){
  21542. if(headers.hasOwnProperty(key)){
  21543. xhr.setRequestHeader(key, headers[key])
  21544. }
  21545. }
  21546. } else if (options.headers && !isEmpty(options.headers)) {
  21547. throw new Error("Headers cannot be set on an XDomainRequest object")
  21548. }
  21549. if ("responseType" in options) {
  21550. xhr.responseType = options.responseType
  21551. }
  21552. if ("beforeSend" in options &&
  21553. typeof options.beforeSend === "function"
  21554. ) {
  21555. options.beforeSend(xhr)
  21556. }
  21557. xhr.send(body)
  21558. return xhr
  21559. }
  21560. function getXml(xhr) {
  21561. if (xhr.responseType === "document") {
  21562. return xhr.responseXML
  21563. }
  21564. var firefoxBugTakenEffect = xhr.status === 204 && xhr.responseXML && xhr.responseXML.documentElement.nodeName === "parsererror"
  21565. if (xhr.responseType === "" && !firefoxBugTakenEffect) {
  21566. return xhr.responseXML
  21567. }
  21568. return null
  21569. }
  21570. function noop() {}
  21571. },{"106":106,"109":109,"110":110,"95":95}],106:[function(_dereq_,module,exports){
  21572. module.exports = isFunction
  21573. var toString = Object.prototype.toString
  21574. function isFunction (fn) {
  21575. var string = toString.call(fn)
  21576. return string === '[object Function]' ||
  21577. (typeof fn === 'function' && string !== '[object RegExp]') ||
  21578. (typeof window !== 'undefined' &&
  21579. // IE8 and below
  21580. (fn === window.setTimeout ||
  21581. fn === window.alert ||
  21582. fn === window.confirm ||
  21583. fn === window.prompt))
  21584. };
  21585. },{}],107:[function(_dereq_,module,exports){
  21586. var isFunction = _dereq_(106)
  21587. module.exports = forEach
  21588. var toString = Object.prototype.toString
  21589. var hasOwnProperty = Object.prototype.hasOwnProperty
  21590. function forEach(list, iterator, context) {
  21591. if (!isFunction(iterator)) {
  21592. throw new TypeError('iterator must be a function')
  21593. }
  21594. if (arguments.length < 3) {
  21595. context = this
  21596. }
  21597. if (toString.call(list) === '[object Array]')
  21598. forEachArray(list, iterator, context)
  21599. else if (typeof list === 'string')
  21600. forEachString(list, iterator, context)
  21601. else
  21602. forEachObject(list, iterator, context)
  21603. }
  21604. function forEachArray(array, iterator, context) {
  21605. for (var i = 0, len = array.length; i < len; i++) {
  21606. if (hasOwnProperty.call(array, i)) {
  21607. iterator.call(context, array[i], i, array)
  21608. }
  21609. }
  21610. }
  21611. function forEachString(string, iterator, context) {
  21612. for (var i = 0, len = string.length; i < len; i++) {
  21613. // no such thing as a sparse string.
  21614. iterator.call(context, string.charAt(i), i, string)
  21615. }
  21616. }
  21617. function forEachObject(object, iterator, context) {
  21618. for (var k in object) {
  21619. if (hasOwnProperty.call(object, k)) {
  21620. iterator.call(context, object[k], k, object)
  21621. }
  21622. }
  21623. }
  21624. },{"106":106}],108:[function(_dereq_,module,exports){
  21625. exports = module.exports = trim;
  21626. function trim(str){
  21627. return str.replace(/^\s*|\s*$/g, '');
  21628. }
  21629. exports.left = function(str){
  21630. return str.replace(/^\s*/, '');
  21631. };
  21632. exports.right = function(str){
  21633. return str.replace(/\s*$/, '');
  21634. };
  21635. },{}],109:[function(_dereq_,module,exports){
  21636. var trim = _dereq_(108)
  21637. , forEach = _dereq_(107)
  21638. , isArray = function(arg) {
  21639. return Object.prototype.toString.call(arg) === '[object Array]';
  21640. }
  21641. module.exports = function (headers) {
  21642. if (!headers)
  21643. return {}
  21644. var result = {}
  21645. forEach(
  21646. trim(headers).split('\n')
  21647. , function (row) {
  21648. var index = row.indexOf(':')
  21649. , key = trim(row.slice(0, index)).toLowerCase()
  21650. , value = trim(row.slice(index + 1))
  21651. if (typeof(result[key]) === 'undefined') {
  21652. result[key] = value
  21653. } else if (isArray(result[key])) {
  21654. result[key].push(value)
  21655. } else {
  21656. result[key] = [ result[key], value ]
  21657. }
  21658. }
  21659. )
  21660. return result
  21661. }
  21662. },{"107":107,"108":108}],110:[function(_dereq_,module,exports){
  21663. module.exports = extend
  21664. var hasOwnProperty = Object.prototype.hasOwnProperty;
  21665. function extend() {
  21666. var target = {}
  21667. for (var i = 0; i < arguments.length; i++) {
  21668. var source = arguments[i]
  21669. for (var key in source) {
  21670. if (hasOwnProperty.call(source, key)) {
  21671. target[key] = source[key]
  21672. }
  21673. }
  21674. }
  21675. return target
  21676. }
  21677. },{}]},{},[93])(93)
  21678. });