12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368936993709371937293739374937593769377937893799380938193829383938493859386938793889389939093919392939393949395939693979398939994009401940294039404940594069407940894099410941194129413941494159416941794189419942094219422942394249425942694279428942994309431943294339434943594369437943894399440944194429443944494459446944794489449945094519452945394549455945694579458945994609461946294639464946594669467946894699470947194729473947494759476947794789479948094819482948394849485948694879488948994909491949294939494949594969497949894999500950195029503950495059506950795089509951095119512951395149515951695179518951995209521952295239524952595269527952895299530953195329533953495359536953795389539954095419542954395449545954695479548954995509551955295539554955595569557955895599560956195629563956495659566956795689569957095719572957395749575957695779578957995809581958295839584958595869587958895899590959195929593959495959596959795989599960096019602960396049605960696079608960996109611961296139614961596169617961896199620962196229623962496259626962796289629963096319632963396349635963696379638963996409641964296439644964596469647964896499650965196529653965496559656965796589659966096619662966396649665966696679668966996709671967296739674967596769677967896799680968196829683968496859686968796889689969096919692969396949695969696979698969997009701970297039704970597069707970897099710971197129713971497159716971797189719972097219722972397249725972697279728972997309731973297339734973597369737973897399740974197429743974497459746974797489749975097519752975397549755975697579758975997609761976297639764976597669767976897699770977197729773977497759776977797789779978097819782978397849785978697879788978997909791979297939794979597969797979897999800980198029803980498059806980798089809981098119812981398149815981698179818981998209821982298239824982598269827982898299830983198329833983498359836983798389839984098419842984398449845984698479848984998509851985298539854985598569857985898599860986198629863986498659866986798689869987098719872987398749875987698779878987998809881988298839884988598869887988898899890989198929893989498959896989798989899990099019902990399049905990699079908990999109911991299139914991599169917991899199920992199229923992499259926992799289929993099319932993399349935993699379938993999409941994299439944994599469947994899499950995199529953995499559956995799589959996099619962996399649965996699679968996999709971997299739974997599769977997899799980998199829983998499859986998799889989999099919992999399949995999699979998999910000100011000210003100041000510006100071000810009100101001110012100131001410015100161001710018100191002010021100221002310024100251002610027100281002910030100311003210033100341003510036100371003810039100401004110042100431004410045100461004710048100491005010051100521005310054100551005610057100581005910060100611006210063100641006510066100671006810069100701007110072100731007410075100761007710078100791008010081100821008310084100851008610087100881008910090100911009210093100941009510096100971009810099101001010110102101031010410105101061010710108101091011010111101121011310114101151011610117101181011910120101211012210123101241012510126101271012810129101301013110132101331013410135101361013710138101391014010141101421014310144101451014610147101481014910150101511015210153101541015510156101571015810159101601016110162101631016410165101661016710168101691017010171101721017310174101751017610177101781017910180101811018210183101841018510186101871018810189101901019110192101931019410195101961019710198101991020010201102021020310204102051020610207102081020910210102111021210213102141021510216102171021810219102201022110222102231022410225102261022710228102291023010231102321023310234102351023610237102381023910240102411024210243102441024510246102471024810249102501025110252102531025410255102561025710258102591026010261102621026310264102651026610267102681026910270102711027210273102741027510276102771027810279102801028110282102831028410285102861028710288102891029010291102921029310294102951029610297102981029910300103011030210303103041030510306103071030810309103101031110312103131031410315103161031710318103191032010321103221032310324103251032610327103281032910330103311033210333103341033510336103371033810339103401034110342103431034410345103461034710348103491035010351103521035310354103551035610357103581035910360103611036210363103641036510366103671036810369103701037110372103731037410375103761037710378103791038010381103821038310384103851038610387103881038910390103911039210393103941039510396103971039810399104001040110402104031040410405104061040710408104091041010411104121041310414104151041610417104181041910420104211042210423104241042510426104271042810429104301043110432104331043410435104361043710438104391044010441104421044310444104451044610447104481044910450104511045210453104541045510456104571045810459104601046110462104631046410465104661046710468104691047010471104721047310474104751047610477104781047910480104811048210483104841048510486104871048810489104901049110492104931049410495104961049710498104991050010501105021050310504105051050610507105081050910510105111051210513105141051510516105171051810519105201052110522105231052410525105261052710528105291053010531105321053310534105351053610537105381053910540105411054210543105441054510546105471054810549105501055110552105531055410555105561055710558105591056010561105621056310564105651056610567105681056910570105711057210573105741057510576105771057810579105801058110582105831058410585105861058710588105891059010591105921059310594105951059610597105981059910600106011060210603106041060510606106071060810609106101061110612106131061410615106161061710618106191062010621106221062310624106251062610627106281062910630106311063210633106341063510636106371063810639106401064110642106431064410645106461064710648106491065010651106521065310654106551065610657106581065910660106611066210663106641066510666106671066810669106701067110672106731067410675106761067710678106791068010681106821068310684106851068610687106881068910690106911069210693106941069510696106971069810699107001070110702107031070410705107061070710708107091071010711107121071310714107151071610717107181071910720107211072210723107241072510726107271072810729107301073110732107331073410735107361073710738107391074010741107421074310744107451074610747107481074910750107511075210753107541075510756107571075810759107601076110762107631076410765107661076710768107691077010771107721077310774107751077610777107781077910780107811078210783107841078510786107871078810789107901079110792107931079410795107961079710798107991080010801108021080310804108051080610807108081080910810108111081210813108141081510816108171081810819108201082110822108231082410825108261082710828108291083010831108321083310834108351083610837108381083910840108411084210843108441084510846108471084810849108501085110852108531085410855108561085710858108591086010861108621086310864108651086610867108681086910870108711087210873108741087510876108771087810879108801088110882108831088410885108861088710888108891089010891108921089310894108951089610897108981089910900109011090210903109041090510906109071090810909109101091110912109131091410915109161091710918109191092010921109221092310924109251092610927109281092910930109311093210933109341093510936109371093810939109401094110942109431094410945109461094710948109491095010951109521095310954109551095610957109581095910960109611096210963109641096510966109671096810969109701097110972109731097410975109761097710978109791098010981109821098310984109851098610987109881098910990109911099210993109941099510996109971099810999110001100111002110031100411005110061100711008110091101011011110121101311014110151101611017110181101911020110211102211023110241102511026110271102811029110301103111032110331103411035110361103711038110391104011041110421104311044110451104611047110481104911050110511105211053110541105511056110571105811059110601106111062110631106411065110661106711068110691107011071110721107311074110751107611077110781107911080110811108211083110841108511086110871108811089110901109111092110931109411095110961109711098110991110011101111021110311104111051110611107111081110911110111111111211113111141111511116111171111811119111201112111122111231112411125111261112711128111291113011131111321113311134111351113611137111381113911140111411114211143111441114511146111471114811149111501115111152111531115411155111561115711158111591116011161111621116311164111651116611167111681116911170111711117211173111741117511176111771117811179111801118111182111831118411185111861118711188111891119011191111921119311194111951119611197111981119911200112011120211203112041120511206112071120811209112101121111212112131121411215112161121711218112191122011221112221122311224112251122611227112281122911230112311123211233112341123511236112371123811239112401124111242112431124411245112461124711248112491125011251112521125311254112551125611257112581125911260112611126211263112641126511266112671126811269112701127111272112731127411275112761127711278112791128011281112821128311284112851128611287112881128911290112911129211293112941129511296112971129811299113001130111302113031130411305113061130711308113091131011311113121131311314113151131611317113181131911320113211132211323113241132511326113271132811329113301133111332113331133411335113361133711338113391134011341113421134311344113451134611347113481134911350113511135211353113541135511356113571135811359113601136111362113631136411365113661136711368113691137011371113721137311374113751137611377113781137911380113811138211383113841138511386113871138811389113901139111392113931139411395113961139711398113991140011401114021140311404114051140611407114081140911410114111141211413114141141511416114171141811419114201142111422114231142411425114261142711428114291143011431114321143311434114351143611437114381143911440114411144211443114441144511446114471144811449114501145111452114531145411455114561145711458114591146011461114621146311464114651146611467114681146911470114711147211473114741147511476114771147811479114801148111482114831148411485114861148711488114891149011491114921149311494114951149611497114981149911500115011150211503115041150511506115071150811509115101151111512115131151411515115161151711518115191152011521115221152311524115251152611527115281152911530115311153211533115341153511536115371153811539115401154111542115431154411545115461154711548115491155011551115521155311554115551155611557115581155911560115611156211563115641156511566115671156811569115701157111572115731157411575115761157711578115791158011581115821158311584115851158611587115881158911590115911159211593115941159511596115971159811599116001160111602116031160411605116061160711608116091161011611116121161311614116151161611617116181161911620116211162211623116241162511626116271162811629116301163111632116331163411635116361163711638116391164011641116421164311644116451164611647116481164911650116511165211653116541165511656116571165811659116601166111662116631166411665116661166711668116691167011671116721167311674116751167611677116781167911680116811168211683116841168511686116871168811689116901169111692116931169411695116961169711698116991170011701117021170311704117051170611707117081170911710117111171211713117141171511716117171171811719117201172111722117231172411725117261172711728117291173011731117321173311734117351173611737117381173911740117411174211743117441174511746117471174811749117501175111752117531175411755117561175711758117591176011761117621176311764117651176611767117681176911770117711177211773117741177511776117771177811779117801178111782117831178411785117861178711788117891179011791117921179311794117951179611797117981179911800118011180211803118041180511806118071180811809118101181111812118131181411815118161181711818118191182011821118221182311824118251182611827118281182911830118311183211833118341183511836118371183811839118401184111842118431184411845118461184711848118491185011851118521185311854118551185611857118581185911860118611186211863118641186511866118671186811869118701187111872118731187411875118761187711878118791188011881118821188311884118851188611887118881188911890118911189211893118941189511896118971189811899119001190111902119031190411905119061190711908119091191011911119121191311914119151191611917119181191911920119211192211923119241192511926119271192811929119301193111932119331193411935119361193711938119391194011941119421194311944119451194611947119481194911950119511195211953119541195511956119571195811959119601196111962119631196411965119661196711968119691197011971119721197311974119751197611977119781197911980119811198211983119841198511986119871198811989119901199111992119931199411995119961199711998119991200012001120021200312004120051200612007120081200912010120111201212013120141201512016120171201812019120201202112022120231202412025120261202712028120291203012031120321203312034120351203612037120381203912040120411204212043120441204512046120471204812049120501205112052120531205412055120561205712058120591206012061120621206312064120651206612067120681206912070120711207212073120741207512076120771207812079120801208112082120831208412085120861208712088120891209012091120921209312094120951209612097120981209912100121011210212103121041210512106121071210812109121101211112112121131211412115121161211712118121191212012121121221212312124121251212612127121281212912130121311213212133121341213512136121371213812139121401214112142121431214412145 |
- (function (global, factory) {
- typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
- typeof define === 'function' && define.amd ? define(factory) :
- (global = global || self, global.csstree = factory());
- }(this, function () { 'use strict';
- //
- // list
- // ┌──────┐
- // ┌──────────────┼─head │
- // │ │ tail─┼──────────────┐
- // │ └──────┘ │
- // ▼ ▼
- // item item item item
- // ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐
- // null ◀──┼─prev │◀───┼─prev │◀───┼─prev │◀───┼─prev │
- // │ next─┼───▶│ next─┼───▶│ next─┼───▶│ next─┼──▶ null
- // ├──────┤ ├──────┤ ├──────┤ ├──────┤
- // │ data │ │ data │ │ data │ │ data │
- // └──────┘ └──────┘ └──────┘ └──────┘
- //
- function createItem(data) {
- return {
- prev: null,
- next: null,
- data: data
- };
- }
- function allocateCursor(node, prev, next) {
- var cursor;
- if (cursors !== null) {
- cursor = cursors;
- cursors = cursors.cursor;
- cursor.prev = prev;
- cursor.next = next;
- cursor.cursor = node.cursor;
- } else {
- cursor = {
- prev: prev,
- next: next,
- cursor: node.cursor
- };
- }
- node.cursor = cursor;
- return cursor;
- }
- function releaseCursor(node) {
- var cursor = node.cursor;
- node.cursor = cursor.cursor;
- cursor.prev = null;
- cursor.next = null;
- cursor.cursor = cursors;
- cursors = cursor;
- }
- var cursors = null;
- var List = function() {
- this.cursor = null;
- this.head = null;
- this.tail = null;
- };
- List.createItem = createItem;
- List.prototype.createItem = createItem;
- List.prototype.updateCursors = function(prevOld, prevNew, nextOld, nextNew) {
- var cursor = this.cursor;
- while (cursor !== null) {
- if (cursor.prev === prevOld) {
- cursor.prev = prevNew;
- }
- if (cursor.next === nextOld) {
- cursor.next = nextNew;
- }
- cursor = cursor.cursor;
- }
- };
- List.prototype.getSize = function() {
- var size = 0;
- var cursor = this.head;
- while (cursor) {
- size++;
- cursor = cursor.next;
- }
- return size;
- };
- List.prototype.fromArray = function(array) {
- var cursor = null;
- this.head = null;
- for (var i = 0; i < array.length; i++) {
- var item = createItem(array[i]);
- if (cursor !== null) {
- cursor.next = item;
- } else {
- this.head = item;
- }
- item.prev = cursor;
- cursor = item;
- }
- this.tail = cursor;
- return this;
- };
- List.prototype.toArray = function() {
- var cursor = this.head;
- var result = [];
- while (cursor) {
- result.push(cursor.data);
- cursor = cursor.next;
- }
- return result;
- };
- List.prototype.toJSON = List.prototype.toArray;
- List.prototype.isEmpty = function() {
- return this.head === null;
- };
- List.prototype.first = function() {
- return this.head && this.head.data;
- };
- List.prototype.last = function() {
- return this.tail && this.tail.data;
- };
- List.prototype.each = function(fn, context) {
- var item;
- if (context === undefined) {
- context = this;
- }
- // push cursor
- var cursor = allocateCursor(this, null, this.head);
- while (cursor.next !== null) {
- item = cursor.next;
- cursor.next = item.next;
- fn.call(context, item.data, item, this);
- }
- // pop cursor
- releaseCursor(this);
- };
- List.prototype.forEach = List.prototype.each;
- List.prototype.eachRight = function(fn, context) {
- var item;
- if (context === undefined) {
- context = this;
- }
- // push cursor
- var cursor = allocateCursor(this, this.tail, null);
- while (cursor.prev !== null) {
- item = cursor.prev;
- cursor.prev = item.prev;
- fn.call(context, item.data, item, this);
- }
- // pop cursor
- releaseCursor(this);
- };
- List.prototype.forEachRight = List.prototype.eachRight;
- List.prototype.nextUntil = function(start, fn, context) {
- if (start === null) {
- return;
- }
- var item;
- if (context === undefined) {
- context = this;
- }
- // push cursor
- var cursor = allocateCursor(this, null, start);
- while (cursor.next !== null) {
- item = cursor.next;
- cursor.next = item.next;
- if (fn.call(context, item.data, item, this)) {
- break;
- }
- }
- // pop cursor
- releaseCursor(this);
- };
- List.prototype.prevUntil = function(start, fn, context) {
- if (start === null) {
- return;
- }
- var item;
- if (context === undefined) {
- context = this;
- }
- // push cursor
- var cursor = allocateCursor(this, start, null);
- while (cursor.prev !== null) {
- item = cursor.prev;
- cursor.prev = item.prev;
- if (fn.call(context, item.data, item, this)) {
- break;
- }
- }
- // pop cursor
- releaseCursor(this);
- };
- List.prototype.some = function(fn, context) {
- var cursor = this.head;
- if (context === undefined) {
- context = this;
- }
- while (cursor !== null) {
- if (fn.call(context, cursor.data, cursor, this)) {
- return true;
- }
- cursor = cursor.next;
- }
- return false;
- };
- List.prototype.map = function(fn, context) {
- var result = new List();
- var cursor = this.head;
- if (context === undefined) {
- context = this;
- }
- while (cursor !== null) {
- result.appendData(fn.call(context, cursor.data, cursor, this));
- cursor = cursor.next;
- }
- return result;
- };
- List.prototype.filter = function(fn, context) {
- var result = new List();
- var cursor = this.head;
- if (context === undefined) {
- context = this;
- }
- while (cursor !== null) {
- if (fn.call(context, cursor.data, cursor, this)) {
- result.appendData(cursor.data);
- }
- cursor = cursor.next;
- }
- return result;
- };
- List.prototype.clear = function() {
- this.head = null;
- this.tail = null;
- };
- List.prototype.copy = function() {
- var result = new List();
- var cursor = this.head;
- while (cursor !== null) {
- result.insert(createItem(cursor.data));
- cursor = cursor.next;
- }
- return result;
- };
- List.prototype.prepend = function(item) {
- // head
- // ^
- // item
- this.updateCursors(null, item, this.head, item);
- // insert to the beginning of the list
- if (this.head !== null) {
- // new item <- first item
- this.head.prev = item;
- // new item -> first item
- item.next = this.head;
- } else {
- // if list has no head, then it also has no tail
- // in this case tail points to the new item
- this.tail = item;
- }
- // head always points to new item
- this.head = item;
- return this;
- };
- List.prototype.prependData = function(data) {
- return this.prepend(createItem(data));
- };
- List.prototype.append = function(item) {
- return this.insert(item);
- };
- List.prototype.appendData = function(data) {
- return this.insert(createItem(data));
- };
- List.prototype.insert = function(item, before) {
- if (before !== undefined && before !== null) {
- // prev before
- // ^
- // item
- this.updateCursors(before.prev, item, before, item);
- if (before.prev === null) {
- // insert to the beginning of list
- if (this.head !== before) {
- throw new Error('before doesn\'t belong to list');
- }
- // since head points to before therefore list doesn't empty
- // no need to check tail
- this.head = item;
- before.prev = item;
- item.next = before;
- this.updateCursors(null, item);
- } else {
- // insert between two items
- before.prev.next = item;
- item.prev = before.prev;
- before.prev = item;
- item.next = before;
- }
- } else {
- // tail
- // ^
- // item
- this.updateCursors(this.tail, item, null, item);
- // insert to the ending of the list
- if (this.tail !== null) {
- // last item -> new item
- this.tail.next = item;
- // last item <- new item
- item.prev = this.tail;
- } else {
- // if list has no tail, then it also has no head
- // in this case head points to new item
- this.head = item;
- }
- // tail always points to new item
- this.tail = item;
- }
- return this;
- };
- List.prototype.insertData = function(data, before) {
- return this.insert(createItem(data), before);
- };
- List.prototype.remove = function(item) {
- // item
- // ^
- // prev next
- this.updateCursors(item, item.prev, item, item.next);
- if (item.prev !== null) {
- item.prev.next = item.next;
- } else {
- if (this.head !== item) {
- throw new Error('item doesn\'t belong to list');
- }
- this.head = item.next;
- }
- if (item.next !== null) {
- item.next.prev = item.prev;
- } else {
- if (this.tail !== item) {
- throw new Error('item doesn\'t belong to list');
- }
- this.tail = item.prev;
- }
- item.prev = null;
- item.next = null;
- return item;
- };
- List.prototype.push = function(data) {
- this.insert(createItem(data));
- };
- List.prototype.pop = function() {
- if (this.tail !== null) {
- return this.remove(this.tail);
- }
- };
- List.prototype.unshift = function(data) {
- this.prepend(createItem(data));
- };
- List.prototype.shift = function() {
- if (this.head !== null) {
- return this.remove(this.head);
- }
- };
- List.prototype.prependList = function(list) {
- return this.insertList(list, this.head);
- };
- List.prototype.appendList = function(list) {
- return this.insertList(list);
- };
- List.prototype.insertList = function(list, before) {
- // ignore empty lists
- if (list.head === null) {
- return this;
- }
- if (before !== undefined && before !== null) {
- this.updateCursors(before.prev, list.tail, before, list.head);
- // insert in the middle of dist list
- if (before.prev !== null) {
- // before.prev <-> list.head
- before.prev.next = list.head;
- list.head.prev = before.prev;
- } else {
- this.head = list.head;
- }
- before.prev = list.tail;
- list.tail.next = before;
- } else {
- this.updateCursors(this.tail, list.tail, null, list.head);
- // insert to end of the list
- if (this.tail !== null) {
- // if destination list has a tail, then it also has a head,
- // but head doesn't change
- // dest tail -> source head
- this.tail.next = list.head;
- // dest tail <- source head
- list.head.prev = this.tail;
- } else {
- // if list has no a tail, then it also has no a head
- // in this case points head to new item
- this.head = list.head;
- }
- // tail always start point to new item
- this.tail = list.tail;
- }
- list.head = null;
- list.tail = null;
- return this;
- };
- List.prototype.replace = function(oldItem, newItemOrList) {
- if ('head' in newItemOrList) {
- this.insertList(newItemOrList, oldItem);
- } else {
- this.insert(newItemOrList, oldItem);
- }
- this.remove(oldItem);
- };
- var List_1 = List;
- var createCustomError = function createCustomError(name, message) {
- // use Object.create(), because some VMs prevent setting line/column otherwise
- // (iOS Safari 10 even throws an exception)
- var error = Object.create(SyntaxError.prototype);
- var errorStack = new Error();
- error.name = name;
- error.message = message;
- Object.defineProperty(error, 'stack', {
- get: function() {
- return (errorStack.stack || '').replace(/^(.+\n){1,3}/, name + ': ' + message + '\n');
- }
- });
- return error;
- };
- var MAX_LINE_LENGTH = 100;
- var OFFSET_CORRECTION = 60;
- var TAB_REPLACEMENT = ' ';
- function sourceFragment(error, extraLines) {
- function processLines(start, end) {
- return lines.slice(start, end).map(function(line, idx) {
- var num = String(start + idx + 1);
- while (num.length < maxNumLength) {
- num = ' ' + num;
- }
- return num + ' |' + line;
- }).join('\n');
- }
- var lines = error.source.split(/\r\n?|\n|\f/);
- var line = error.line;
- var column = error.column;
- var startLine = Math.max(1, line - extraLines) - 1;
- var endLine = Math.min(line + extraLines, lines.length + 1);
- var maxNumLength = Math.max(4, String(endLine).length) + 1;
- var cutLeft = 0;
- // column correction according to replaced tab before column
- column += (TAB_REPLACEMENT.length - 1) * (lines[line - 1].substr(0, column - 1).match(/\t/g) || []).length;
- if (column > MAX_LINE_LENGTH) {
- cutLeft = column - OFFSET_CORRECTION + 3;
- column = OFFSET_CORRECTION - 2;
- }
- for (var i = startLine; i <= endLine; i++) {
- if (i >= 0 && i < lines.length) {
- lines[i] = lines[i].replace(/\t/g, TAB_REPLACEMENT);
- lines[i] =
- (cutLeft > 0 && lines[i].length > cutLeft ? '\u2026' : '') +
- lines[i].substr(cutLeft, MAX_LINE_LENGTH - 2) +
- (lines[i].length > cutLeft + MAX_LINE_LENGTH - 1 ? '\u2026' : '');
- }
- }
- return [
- processLines(startLine, line),
- new Array(column + maxNumLength + 2).join('-') + '^',
- processLines(line, endLine)
- ].filter(Boolean).join('\n');
- }
- var SyntaxError$1 = function(message, source, offset, line, column) {
- var error = createCustomError('SyntaxError', message);
- error.source = source;
- error.offset = offset;
- error.line = line;
- error.column = column;
- error.sourceFragment = function(extraLines) {
- return sourceFragment(error, isNaN(extraLines) ? 0 : extraLines);
- };
- Object.defineProperty(error, 'formattedMessage', {
- get: function() {
- return (
- 'Parse error: ' + error.message + '\n' +
- sourceFragment(error, 2)
- );
- }
- });
- // for backward capability
- error.parseError = {
- offset: offset,
- line: line,
- column: column
- };
- return error;
- };
- var _SyntaxError = SyntaxError$1;
- // CSS Syntax Module Level 3
- // https://www.w3.org/TR/css-syntax-3/
- var TYPE = {
- EOF: 0, // <EOF-token>
- Ident: 1, // <ident-token>
- Function: 2, // <function-token>
- AtKeyword: 3, // <at-keyword-token>
- Hash: 4, // <hash-token>
- String: 5, // <string-token>
- BadString: 6, // <bad-string-token>
- Url: 7, // <url-token>
- BadUrl: 8, // <bad-url-token>
- Delim: 9, // <delim-token>
- Number: 10, // <number-token>
- Percentage: 11, // <percentage-token>
- Dimension: 12, // <dimension-token>
- WhiteSpace: 13, // <whitespace-token>
- CDO: 14, // <CDO-token>
- CDC: 15, // <CDC-token>
- Colon: 16, // <colon-token> :
- Semicolon: 17, // <semicolon-token> ;
- Comma: 18, // <comma-token> ,
- LeftSquareBracket: 19, // <[-token>
- RightSquareBracket: 20, // <]-token>
- LeftParenthesis: 21, // <(-token>
- RightParenthesis: 22, // <)-token>
- LeftCurlyBracket: 23, // <{-token>
- RightCurlyBracket: 24, // <}-token>
- Comment: 25
- };
- var NAME = Object.keys(TYPE).reduce(function(result, key) {
- result[TYPE[key]] = key;
- return result;
- }, {});
- var _const = {
- TYPE: TYPE,
- NAME: NAME
- };
- var EOF = 0;
- // https://drafts.csswg.org/css-syntax-3/
- // § 4.2. Definitions
- // digit
- // A code point between U+0030 DIGIT ZERO (0) and U+0039 DIGIT NINE (9).
- function isDigit(code) {
- return code >= 0x0030 && code <= 0x0039;
- }
- // hex digit
- // A digit, or a code point between U+0041 LATIN CAPITAL LETTER A (A) and U+0046 LATIN CAPITAL LETTER F (F),
- // or a code point between U+0061 LATIN SMALL LETTER A (a) and U+0066 LATIN SMALL LETTER F (f).
- function isHexDigit(code) {
- return (
- isDigit(code) || // 0 .. 9
- (code >= 0x0041 && code <= 0x0046) || // A .. F
- (code >= 0x0061 && code <= 0x0066) // a .. f
- );
- }
- // uppercase letter
- // A code point between U+0041 LATIN CAPITAL LETTER A (A) and U+005A LATIN CAPITAL LETTER Z (Z).
- function isUppercaseLetter(code) {
- return code >= 0x0041 && code <= 0x005A;
- }
- // lowercase letter
- // A code point between U+0061 LATIN SMALL LETTER A (a) and U+007A LATIN SMALL LETTER Z (z).
- function isLowercaseLetter(code) {
- return code >= 0x0061 && code <= 0x007A;
- }
- // letter
- // An uppercase letter or a lowercase letter.
- function isLetter(code) {
- return isUppercaseLetter(code) || isLowercaseLetter(code);
- }
- // non-ASCII code point
- // A code point with a value equal to or greater than U+0080 <control>.
- function isNonAscii(code) {
- return code >= 0x0080;
- }
- // name-start code point
- // A letter, a non-ASCII code point, or U+005F LOW LINE (_).
- function isNameStart(code) {
- return isLetter(code) || isNonAscii(code) || code === 0x005F;
- }
- // name code point
- // A name-start code point, a digit, or U+002D HYPHEN-MINUS (-).
- function isName(code) {
- return isNameStart(code) || isDigit(code) || code === 0x002D;
- }
- // non-printable code point
- // A code point between U+0000 NULL and U+0008 BACKSPACE, or U+000B LINE TABULATION,
- // or a code point between U+000E SHIFT OUT and U+001F INFORMATION SEPARATOR ONE, or U+007F DELETE.
- function isNonPrintable(code) {
- return (
- (code >= 0x0000 && code <= 0x0008) ||
- (code === 0x000B) ||
- (code >= 0x000E && code <= 0x001F) ||
- (code === 0x007F)
- );
- }
- // newline
- // U+000A LINE FEED. Note that U+000D CARRIAGE RETURN and U+000C FORM FEED are not included in this definition,
- // as they are converted to U+000A LINE FEED during preprocessing.
- // TODO: we doesn't do a preprocessing, so check a code point for U+000D CARRIAGE RETURN and U+000C FORM FEED
- function isNewline(code) {
- return code === 0x000A || code === 0x000D || code === 0x000C;
- }
- // whitespace
- // A newline, U+0009 CHARACTER TABULATION, or U+0020 SPACE.
- function isWhiteSpace(code) {
- return isNewline(code) || code === 0x0020 || code === 0x0009;
- }
- // § 4.3.8. Check if two code points are a valid escape
- function isValidEscape(first, second) {
- // If the first code point is not U+005C REVERSE SOLIDUS (\), return false.
- if (first !== 0x005C) {
- return false;
- }
- // Otherwise, if the second code point is a newline or EOF, return false.
- if (isNewline(second) || second === EOF) {
- return false;
- }
- // Otherwise, return true.
- return true;
- }
- // § 4.3.9. Check if three code points would start an identifier
- function isIdentifierStart(first, second, third) {
- // Look at the first code point:
- // U+002D HYPHEN-MINUS
- if (first === 0x002D) {
- // If the second code point is a name-start code point or a U+002D HYPHEN-MINUS,
- // or the second and third code points are a valid escape, return true. Otherwise, return false.
- return (
- isNameStart(second) ||
- second === 0x002D ||
- isValidEscape(second, third)
- );
- }
- // name-start code point
- if (isNameStart(first)) {
- // Return true.
- return true;
- }
- // U+005C REVERSE SOLIDUS (\)
- if (first === 0x005C) {
- // If the first and second code points are a valid escape, return true. Otherwise, return false.
- return isValidEscape(first, second);
- }
- // anything else
- // Return false.
- return false;
- }
- // § 4.3.10. Check if three code points would start a number
- function isNumberStart(first, second, third) {
- // Look at the first code point:
- // U+002B PLUS SIGN (+)
- // U+002D HYPHEN-MINUS (-)
- if (first === 0x002B || first === 0x002D) {
- // If the second code point is a digit, return true.
- if (isDigit(second)) {
- return 2;
- }
- // Otherwise, if the second code point is a U+002E FULL STOP (.)
- // and the third code point is a digit, return true.
- // Otherwise, return false.
- return second === 0x002E && isDigit(third) ? 3 : 0;
- }
- // U+002E FULL STOP (.)
- if (first === 0x002E) {
- // If the second code point is a digit, return true. Otherwise, return false.
- return isDigit(second) ? 2 : 0;
- }
- // digit
- if (isDigit(first)) {
- // Return true.
- return 1;
- }
- // anything else
- // Return false.
- return 0;
- }
- //
- // Misc
- //
- // detect BOM (https://en.wikipedia.org/wiki/Byte_order_mark)
- function isBOM(code) {
- // UTF-16BE
- if (code === 0xFEFF) {
- return 1;
- }
- // UTF-16LE
- if (code === 0xFFFE) {
- return 1;
- }
- return 0;
- }
- // Fast code category
- //
- // https://drafts.csswg.org/css-syntax/#tokenizer-definitions
- // > non-ASCII code point
- // > A code point with a value equal to or greater than U+0080 <control>
- // > name-start code point
- // > A letter, a non-ASCII code point, or U+005F LOW LINE (_).
- // > name code point
- // > A name-start code point, a digit, or U+002D HYPHEN-MINUS (-)
- // That means only ASCII code points has a special meaning and we define a maps for 0..127 codes only
- var CATEGORY = new Array(0x80);
- charCodeCategory.Eof = 0x80;
- charCodeCategory.WhiteSpace = 0x82;
- charCodeCategory.Digit = 0x83;
- charCodeCategory.NameStart = 0x84;
- charCodeCategory.NonPrintable = 0x85;
- for (var i = 0; i < CATEGORY.length; i++) {
- switch (true) {
- case isWhiteSpace(i):
- CATEGORY[i] = charCodeCategory.WhiteSpace;
- break;
- case isDigit(i):
- CATEGORY[i] = charCodeCategory.Digit;
- break;
- case isNameStart(i):
- CATEGORY[i] = charCodeCategory.NameStart;
- break;
- case isNonPrintable(i):
- CATEGORY[i] = charCodeCategory.NonPrintable;
- break;
- default:
- CATEGORY[i] = i || charCodeCategory.Eof;
- }
- }
- function charCodeCategory(code) {
- return code < 0x80 ? CATEGORY[code] : charCodeCategory.NameStart;
- }
- var charCodeDefinitions = {
- isDigit: isDigit,
- isHexDigit: isHexDigit,
- isUppercaseLetter: isUppercaseLetter,
- isLowercaseLetter: isLowercaseLetter,
- isLetter: isLetter,
- isNonAscii: isNonAscii,
- isNameStart: isNameStart,
- isName: isName,
- isNonPrintable: isNonPrintable,
- isNewline: isNewline,
- isWhiteSpace: isWhiteSpace,
- isValidEscape: isValidEscape,
- isIdentifierStart: isIdentifierStart,
- isNumberStart: isNumberStart,
- isBOM: isBOM,
- charCodeCategory: charCodeCategory
- };
- var isDigit$1 = charCodeDefinitions.isDigit;
- var isHexDigit$1 = charCodeDefinitions.isHexDigit;
- var isUppercaseLetter$1 = charCodeDefinitions.isUppercaseLetter;
- var isName$1 = charCodeDefinitions.isName;
- var isWhiteSpace$1 = charCodeDefinitions.isWhiteSpace;
- var isValidEscape$1 = charCodeDefinitions.isValidEscape;
- function getCharCode(source, offset) {
- return offset < source.length ? source.charCodeAt(offset) : 0;
- }
- function getNewlineLength(source, offset, code) {
- if (code === 13 /* \r */ && getCharCode(source, offset + 1) === 10 /* \n */) {
- return 2;
- }
- return 1;
- }
- function cmpChar(testStr, offset, referenceCode) {
- var code = testStr.charCodeAt(offset);
- // code.toLowerCase() for A..Z
- if (isUppercaseLetter$1(code)) {
- code = code | 32;
- }
- return code === referenceCode;
- }
- function cmpStr(testStr, start, end, referenceStr) {
- if (end - start !== referenceStr.length) {
- return false;
- }
- if (start < 0 || end > testStr.length) {
- return false;
- }
- for (var i = start; i < end; i++) {
- var testCode = testStr.charCodeAt(i);
- var referenceCode = referenceStr.charCodeAt(i - start);
- // testCode.toLowerCase() for A..Z
- if (isUppercaseLetter$1(testCode)) {
- testCode = testCode | 32;
- }
- if (testCode !== referenceCode) {
- return false;
- }
- }
- return true;
- }
- function findWhiteSpaceStart(source, offset) {
- for (; offset >= 0; offset--) {
- if (!isWhiteSpace$1(source.charCodeAt(offset))) {
- break;
- }
- }
- return offset + 1;
- }
- function findWhiteSpaceEnd(source, offset) {
- for (; offset < source.length; offset++) {
- if (!isWhiteSpace$1(source.charCodeAt(offset))) {
- break;
- }
- }
- return offset;
- }
- function findDecimalNumberEnd(source, offset) {
- for (; offset < source.length; offset++) {
- if (!isDigit$1(source.charCodeAt(offset))) {
- break;
- }
- }
- return offset;
- }
- // § 4.3.7. Consume an escaped code point
- function consumeEscaped(source, offset) {
- // It assumes that the U+005C REVERSE SOLIDUS (\) has already been consumed and
- // that the next input code point has already been verified to be part of a valid escape.
- offset += 2;
- // hex digit
- if (isHexDigit$1(getCharCode(source, offset - 1))) {
- // Consume as many hex digits as possible, but no more than 5.
- // Note that this means 1-6 hex digits have been consumed in total.
- for (var maxOffset = Math.min(source.length, offset + 5); offset < maxOffset; offset++) {
- if (!isHexDigit$1(getCharCode(source, offset))) {
- break;
- }
- }
- // If the next input code point is whitespace, consume it as well.
- var code = getCharCode(source, offset);
- if (isWhiteSpace$1(code)) {
- offset += getNewlineLength(source, offset, code);
- }
- }
- return offset;
- }
- // §4.3.11. Consume a name
- // Note: This algorithm does not do the verification of the first few code points that are necessary
- // to ensure the returned code points would constitute an <ident-token>. If that is the intended use,
- // ensure that the stream starts with an identifier before calling this algorithm.
- function consumeName(source, offset) {
- // Let result initially be an empty string.
- // Repeatedly consume the next input code point from the stream:
- for (; offset < source.length; offset++) {
- var code = source.charCodeAt(offset);
- // name code point
- if (isName$1(code)) {
- // Append the code point to result.
- continue;
- }
- // the stream starts with a valid escape
- if (isValidEscape$1(code, getCharCode(source, offset + 1))) {
- // Consume an escaped code point. Append the returned code point to result.
- offset = consumeEscaped(source, offset) - 1;
- continue;
- }
- // anything else
- // Reconsume the current input code point. Return result.
- break;
- }
- return offset;
- }
- // §4.3.12. Consume a number
- function consumeNumber(source, offset) {
- var code = source.charCodeAt(offset);
- // 2. If the next input code point is U+002B PLUS SIGN (+) or U+002D HYPHEN-MINUS (-),
- // consume it and append it to repr.
- if (code === 0x002B || code === 0x002D) {
- code = source.charCodeAt(offset += 1);
- }
- // 3. While the next input code point is a digit, consume it and append it to repr.
- if (isDigit$1(code)) {
- offset = findDecimalNumberEnd(source, offset + 1);
- code = source.charCodeAt(offset);
- }
- // 4. If the next 2 input code points are U+002E FULL STOP (.) followed by a digit, then:
- if (code === 0x002E && isDigit$1(source.charCodeAt(offset + 1))) {
- // 4.1 Consume them.
- // 4.2 Append them to repr.
- code = source.charCodeAt(offset += 2);
- // 4.3 Set type to "number".
- // TODO
- // 4.4 While the next input code point is a digit, consume it and append it to repr.
- offset = findDecimalNumberEnd(source, offset);
- }
- // 5. If the next 2 or 3 input code points are U+0045 LATIN CAPITAL LETTER E (E)
- // or U+0065 LATIN SMALL LETTER E (e), ... , followed by a digit, then:
- if (cmpChar(source, offset, 101 /* e */)) {
- var sign = 0;
- code = source.charCodeAt(offset + 1);
- // ... optionally followed by U+002D HYPHEN-MINUS (-) or U+002B PLUS SIGN (+) ...
- if (code === 0x002D || code === 0x002B) {
- sign = 1;
- code = source.charCodeAt(offset + 2);
- }
- // ... followed by a digit
- if (isDigit$1(code)) {
- // 5.1 Consume them.
- // 5.2 Append them to repr.
- // 5.3 Set type to "number".
- // TODO
- // 5.4 While the next input code point is a digit, consume it and append it to repr.
- offset = findDecimalNumberEnd(source, offset + 1 + sign + 1);
- }
- }
- return offset;
- }
- // § 4.3.14. Consume the remnants of a bad url
- // ... its sole use is to consume enough of the input stream to reach a recovery point
- // where normal tokenizing can resume.
- function consumeBadUrlRemnants(source, offset) {
- // Repeatedly consume the next input code point from the stream:
- for (; offset < source.length; offset++) {
- var code = source.charCodeAt(offset);
- // U+0029 RIGHT PARENTHESIS ())
- // EOF
- if (code === 0x0029) {
- // Return.
- offset++;
- break;
- }
- if (isValidEscape$1(code, getCharCode(source, offset + 1))) {
- // Consume an escaped code point.
- // Note: This allows an escaped right parenthesis ("\)") to be encountered
- // without ending the <bad-url-token>. This is otherwise identical to
- // the "anything else" clause.
- offset = consumeEscaped(source, offset);
- }
- }
- return offset;
- }
- var utils = {
- consumeEscaped: consumeEscaped,
- consumeName: consumeName,
- consumeNumber: consumeNumber,
- consumeBadUrlRemnants: consumeBadUrlRemnants,
- cmpChar: cmpChar,
- cmpStr: cmpStr,
- getNewlineLength: getNewlineLength,
- findWhiteSpaceStart: findWhiteSpaceStart,
- findWhiteSpaceEnd: findWhiteSpaceEnd
- };
- var TYPE$1 = _const.TYPE;
- var NAME$1 = _const.NAME;
- var cmpStr$1 = utils.cmpStr;
- var EOF$1 = TYPE$1.EOF;
- var WHITESPACE = TYPE$1.WhiteSpace;
- var COMMENT = TYPE$1.Comment;
- var OFFSET_MASK = 0x00FFFFFF;
- var TYPE_SHIFT = 24;
- var TokenStream = function() {
- this.offsetAndType = null;
- this.balance = null;
- this.reset();
- };
- TokenStream.prototype = {
- reset: function() {
- this.eof = false;
- this.tokenIndex = -1;
- this.tokenType = 0;
- this.tokenStart = this.firstCharOffset;
- this.tokenEnd = this.firstCharOffset;
- },
- lookupType: function(offset) {
- offset += this.tokenIndex;
- if (offset < this.tokenCount) {
- return this.offsetAndType[offset] >> TYPE_SHIFT;
- }
- return EOF$1;
- },
- lookupOffset: function(offset) {
- offset += this.tokenIndex;
- if (offset < this.tokenCount) {
- return this.offsetAndType[offset - 1] & OFFSET_MASK;
- }
- return this.source.length;
- },
- lookupValue: function(offset, referenceStr) {
- offset += this.tokenIndex;
- if (offset < this.tokenCount) {
- return cmpStr$1(
- this.source,
- this.offsetAndType[offset - 1] & OFFSET_MASK,
- this.offsetAndType[offset] & OFFSET_MASK,
- referenceStr
- );
- }
- return false;
- },
- getTokenStart: function(tokenIndex) {
- if (tokenIndex === this.tokenIndex) {
- return this.tokenStart;
- }
- if (tokenIndex > 0) {
- return tokenIndex < this.tokenCount
- ? this.offsetAndType[tokenIndex - 1] & OFFSET_MASK
- : this.offsetAndType[this.tokenCount] & OFFSET_MASK;
- }
- return this.firstCharOffset;
- },
- // TODO: -> skipUntilBalanced
- getRawLength: function(startToken, mode) {
- var cursor = startToken;
- var balanceEnd;
- var offset = this.offsetAndType[Math.max(cursor - 1, 0)] & OFFSET_MASK;
- var type;
- loop:
- for (; cursor < this.tokenCount; cursor++) {
- balanceEnd = this.balance[cursor];
- // stop scanning on balance edge that points to offset before start token
- if (balanceEnd < startToken) {
- break loop;
- }
- type = this.offsetAndType[cursor] >> TYPE_SHIFT;
- // check token is stop type
- switch (mode(type, this.source, offset)) {
- case 1:
- break loop;
- case 2:
- cursor++;
- break loop;
- default:
- offset = this.offsetAndType[cursor] & OFFSET_MASK;
- // fast forward to the end of balanced block
- if (this.balance[balanceEnd] === cursor) {
- cursor = balanceEnd;
- }
- }
- }
- return cursor - this.tokenIndex;
- },
- isBalanceEdge: function(pos) {
- return this.balance[this.tokenIndex] < pos;
- },
- isDelim: function(code, offset) {
- if (offset) {
- return (
- this.lookupType(offset) === TYPE$1.Delim &&
- this.source.charCodeAt(this.lookupOffset(offset)) === code
- );
- }
- return (
- this.tokenType === TYPE$1.Delim &&
- this.source.charCodeAt(this.tokenStart) === code
- );
- },
- getTokenValue: function() {
- return this.source.substring(this.tokenStart, this.tokenEnd);
- },
- getTokenLength: function() {
- return this.tokenEnd - this.tokenStart;
- },
- substrToCursor: function(start) {
- return this.source.substring(start, this.tokenStart);
- },
- skipWS: function() {
- for (var i = this.tokenIndex, skipTokenCount = 0; i < this.tokenCount; i++, skipTokenCount++) {
- if ((this.offsetAndType[i] >> TYPE_SHIFT) !== WHITESPACE) {
- break;
- }
- }
- if (skipTokenCount > 0) {
- this.skip(skipTokenCount);
- }
- },
- skipSC: function() {
- while (this.tokenType === WHITESPACE || this.tokenType === COMMENT) {
- this.next();
- }
- },
- skip: function(tokenCount) {
- var next = this.tokenIndex + tokenCount;
- if (next < this.tokenCount) {
- this.tokenIndex = next;
- this.tokenStart = this.offsetAndType[next - 1] & OFFSET_MASK;
- next = this.offsetAndType[next];
- this.tokenType = next >> TYPE_SHIFT;
- this.tokenEnd = next & OFFSET_MASK;
- } else {
- this.tokenIndex = this.tokenCount;
- this.next();
- }
- },
- next: function() {
- var next = this.tokenIndex + 1;
- if (next < this.tokenCount) {
- this.tokenIndex = next;
- this.tokenStart = this.tokenEnd;
- next = this.offsetAndType[next];
- this.tokenType = next >> TYPE_SHIFT;
- this.tokenEnd = next & OFFSET_MASK;
- } else {
- this.tokenIndex = this.tokenCount;
- this.eof = true;
- this.tokenType = EOF$1;
- this.tokenStart = this.tokenEnd = this.source.length;
- }
- },
- dump: function() {
- var offset = this.firstCharOffset;
- return Array.prototype.slice.call(this.offsetAndType, 0, this.tokenCount).map(function(item, idx) {
- var start = offset;
- var end = item & OFFSET_MASK;
- offset = end;
- return {
- idx: idx,
- type: NAME$1[item >> TYPE_SHIFT],
- chunk: this.source.substring(start, end),
- balance: this.balance[idx]
- };
- }, this);
- }
- };
- var TokenStream_1 = TokenStream;
- function noop(value) {
- return value;
- }
- function generateMultiplier(multiplier) {
- if (multiplier.min === 0 && multiplier.max === 0) {
- return '*';
- }
- if (multiplier.min === 0 && multiplier.max === 1) {
- return '?';
- }
- if (multiplier.min === 1 && multiplier.max === 0) {
- return multiplier.comma ? '#' : '+';
- }
- if (multiplier.min === 1 && multiplier.max === 1) {
- return '';
- }
- return (
- (multiplier.comma ? '#' : '') +
- (multiplier.min === multiplier.max
- ? '{' + multiplier.min + '}'
- : '{' + multiplier.min + ',' + (multiplier.max !== 0 ? multiplier.max : '') + '}'
- )
- );
- }
- function generateTypeOpts(node) {
- switch (node.type) {
- case 'Range':
- return (
- ' [' +
- (node.min === null ? '-∞' : node.min) +
- ',' +
- (node.max === null ? '∞' : node.max) +
- ']'
- );
- default:
- throw new Error('Unknown node type `' + node.type + '`');
- }
- }
- function generateSequence(node, decorate, forceBraces, compact) {
- var combinator = node.combinator === ' ' || compact ? node.combinator : ' ' + node.combinator + ' ';
- var result = node.terms.map(function(term) {
- return generate(term, decorate, forceBraces, compact);
- }).join(combinator);
- if (node.explicit || forceBraces) {
- result = (compact || result[0] === ',' ? '[' : '[ ') + result + (compact ? ']' : ' ]');
- }
- return result;
- }
- function generate(node, decorate, forceBraces, compact) {
- var result;
- switch (node.type) {
- case 'Group':
- result =
- generateSequence(node, decorate, forceBraces, compact) +
- (node.disallowEmpty ? '!' : '');
- break;
- case 'Multiplier':
- // return since node is a composition
- return (
- generate(node.term, decorate, forceBraces, compact) +
- decorate(generateMultiplier(node), node)
- );
- case 'Type':
- result = '<' + node.name + (node.opts ? decorate(generateTypeOpts(node.opts), node.opts) : '') + '>';
- break;
- case 'Property':
- result = '<\'' + node.name + '\'>';
- break;
- case 'Keyword':
- result = node.name;
- break;
- case 'AtKeyword':
- result = '@' + node.name;
- break;
- case 'Function':
- result = node.name + '(';
- break;
- case 'String':
- case 'Token':
- result = node.value;
- break;
- case 'Comma':
- result = ',';
- break;
- default:
- throw new Error('Unknown node type `' + node.type + '`');
- }
- return decorate(result, node);
- }
- var generate_1 = function(node, options) {
- var decorate = noop;
- var forceBraces = false;
- var compact = false;
- if (typeof options === 'function') {
- decorate = options;
- } else if (options) {
- forceBraces = Boolean(options.forceBraces);
- compact = Boolean(options.compact);
- if (typeof options.decorate === 'function') {
- decorate = options.decorate;
- }
- }
- return generate(node, decorate, forceBraces, compact);
- };
- function fromMatchResult(matchResult) {
- var tokens = matchResult.tokens;
- var longestMatch = matchResult.longestMatch;
- var node = longestMatch < tokens.length ? tokens[longestMatch].node : null;
- var mismatchOffset = -1;
- var entries = 0;
- var css = '';
- for (var i = 0; i < tokens.length; i++) {
- if (i === longestMatch) {
- mismatchOffset = css.length;
- }
- if (node !== null && tokens[i].node === node) {
- if (i <= longestMatch) {
- entries++;
- } else {
- entries = 0;
- }
- }
- css += tokens[i].value;
- }
- return {
- node: node,
- css: css,
- mismatchOffset: mismatchOffset === -1 ? css.length : mismatchOffset,
- last: node === null || entries > 1
- };
- }
- function getLocation(node, point) {
- var loc = node && node.loc && node.loc[point];
- if (loc) {
- return {
- offset: loc.offset,
- line: loc.line,
- column: loc.column
- };
- }
- return null;
- }
- var SyntaxReferenceError = function(type, referenceName) {
- var error = createCustomError(
- 'SyntaxReferenceError',
- type + (referenceName ? ' `' + referenceName + '`' : '')
- );
- error.reference = referenceName;
- return error;
- };
- var MatchError = function(message, syntax, node, matchResult) {
- var error = createCustomError('SyntaxMatchError', message);
- var details = fromMatchResult(matchResult);
- var mismatchOffset = details.mismatchOffset || 0;
- var badNode = details.node || node;
- var end = getLocation(badNode, 'end');
- var start = details.last ? end : getLocation(badNode, 'start');
- var css = details.css;
- error.rawMessage = message;
- error.syntax = syntax ? generate_1(syntax) : '<generic>';
- error.css = css;
- error.mismatchOffset = mismatchOffset;
- error.loc = {
- source: (badNode && badNode.loc && badNode.loc.source) || '<unknown>',
- start: start,
- end: end
- };
- error.line = start ? start.line : undefined;
- error.column = start ? start.column : undefined;
- error.offset = start ? start.offset : undefined;
- error.message = message + '\n' +
- ' syntax: ' + error.syntax + '\n' +
- ' value: ' + (error.css || '<empty string>') + '\n' +
- ' --------' + new Array(error.mismatchOffset + 1).join('-') + '^';
- return error;
- };
- var error = {
- SyntaxReferenceError: SyntaxReferenceError,
- MatchError: MatchError
- };
- var hasOwnProperty = Object.prototype.hasOwnProperty;
- var keywords = Object.create(null);
- var properties = Object.create(null);
- var HYPHENMINUS = 45; // '-'.charCodeAt()
- function isCustomProperty(str, offset) {
- offset = offset || 0;
- return str.length - offset >= 2 &&
- str.charCodeAt(offset) === HYPHENMINUS &&
- str.charCodeAt(offset + 1) === HYPHENMINUS;
- }
- function getVendorPrefix(str, offset) {
- offset = offset || 0;
- // verdor prefix should be at least 3 chars length
- if (str.length - offset >= 3) {
- // vendor prefix starts with hyper minus following non-hyper minus
- if (str.charCodeAt(offset) === HYPHENMINUS &&
- str.charCodeAt(offset + 1) !== HYPHENMINUS) {
- // vendor prefix should contain a hyper minus at the ending
- var secondDashIndex = str.indexOf('-', offset + 2);
- if (secondDashIndex !== -1) {
- return str.substring(offset, secondDashIndex + 1);
- }
- }
- }
- return '';
- }
- function getKeywordDescriptor(keyword) {
- if (hasOwnProperty.call(keywords, keyword)) {
- return keywords[keyword];
- }
- var name = keyword.toLowerCase();
- if (hasOwnProperty.call(keywords, name)) {
- return keywords[keyword] = keywords[name];
- }
- var custom = isCustomProperty(name, 0);
- var vendor = !custom ? getVendorPrefix(name, 0) : '';
- return keywords[keyword] = Object.freeze({
- basename: name.substr(vendor.length),
- name: name,
- vendor: vendor,
- prefix: vendor,
- custom: custom
- });
- }
- function getPropertyDescriptor(property) {
- if (hasOwnProperty.call(properties, property)) {
- return properties[property];
- }
- var name = property;
- var hack = property[0];
- if (hack === '/') {
- hack = property[1] === '/' ? '//' : '/';
- } else if (hack !== '_' &&
- hack !== '*' &&
- hack !== '$' &&
- hack !== '#' &&
- hack !== '+' &&
- hack !== '&') {
- hack = '';
- }
- var custom = isCustomProperty(name, hack.length);
- // re-use result when possible (the same as for lower case)
- if (!custom) {
- name = name.toLowerCase();
- if (hasOwnProperty.call(properties, name)) {
- return properties[property] = properties[name];
- }
- }
- var vendor = !custom ? getVendorPrefix(name, hack.length) : '';
- var prefix = name.substr(0, hack.length + vendor.length);
- return properties[property] = Object.freeze({
- basename: name.substr(prefix.length),
- name: name.substr(hack.length),
- hack: hack,
- vendor: vendor,
- prefix: prefix,
- custom: custom
- });
- }
- var names = {
- keyword: getKeywordDescriptor,
- property: getPropertyDescriptor,
- isCustomProperty: isCustomProperty,
- vendorPrefix: getVendorPrefix
- };
- var MIN_SIZE = 16 * 1024;
- var SafeUint32Array = typeof Uint32Array !== 'undefined' ? Uint32Array : Array; // fallback on Array when TypedArray is not supported
- var adoptBuffer = function adoptBuffer(buffer, size) {
- if (buffer === null || buffer.length < size) {
- return new SafeUint32Array(Math.max(size + 1024, MIN_SIZE));
- }
- return buffer;
- };
- var TYPE$2 = _const.TYPE;
- var isNewline$1 = charCodeDefinitions.isNewline;
- var isName$2 = charCodeDefinitions.isName;
- var isValidEscape$2 = charCodeDefinitions.isValidEscape;
- var isNumberStart$1 = charCodeDefinitions.isNumberStart;
- var isIdentifierStart$1 = charCodeDefinitions.isIdentifierStart;
- var charCodeCategory$1 = charCodeDefinitions.charCodeCategory;
- var isBOM$1 = charCodeDefinitions.isBOM;
- var cmpStr$2 = utils.cmpStr;
- var getNewlineLength$1 = utils.getNewlineLength;
- var findWhiteSpaceEnd$1 = utils.findWhiteSpaceEnd;
- var consumeEscaped$1 = utils.consumeEscaped;
- var consumeName$1 = utils.consumeName;
- var consumeNumber$1 = utils.consumeNumber;
- var consumeBadUrlRemnants$1 = utils.consumeBadUrlRemnants;
- var OFFSET_MASK$1 = 0x00FFFFFF;
- var TYPE_SHIFT$1 = 24;
- function tokenize(source, stream) {
- function getCharCode(offset) {
- return offset < sourceLength ? source.charCodeAt(offset) : 0;
- }
- // § 4.3.3. Consume a numeric token
- function consumeNumericToken() {
- // Consume a number and let number be the result.
- offset = consumeNumber$1(source, offset);
- // If the next 3 input code points would start an identifier, then:
- if (isIdentifierStart$1(getCharCode(offset), getCharCode(offset + 1), getCharCode(offset + 2))) {
- // Create a <dimension-token> with the same value and type flag as number, and a unit set initially to the empty string.
- // Consume a name. Set the <dimension-token>’s unit to the returned value.
- // Return the <dimension-token>.
- type = TYPE$2.Dimension;
- offset = consumeName$1(source, offset);
- return;
- }
- // Otherwise, if the next input code point is U+0025 PERCENTAGE SIGN (%), consume it.
- if (getCharCode(offset) === 0x0025) {
- // Create a <percentage-token> with the same value as number, and return it.
- type = TYPE$2.Percentage;
- offset++;
- return;
- }
- // Otherwise, create a <number-token> with the same value and type flag as number, and return it.
- type = TYPE$2.Number;
- }
- // § 4.3.4. Consume an ident-like token
- function consumeIdentLikeToken() {
- const nameStartOffset = offset;
- // Consume a name, and let string be the result.
- offset = consumeName$1(source, offset);
- // If string’s value is an ASCII case-insensitive match for "url",
- // and the next input code point is U+0028 LEFT PARENTHESIS ((), consume it.
- if (cmpStr$2(source, nameStartOffset, offset, 'url') && getCharCode(offset) === 0x0028) {
- // While the next two input code points are whitespace, consume the next input code point.
- offset = findWhiteSpaceEnd$1(source, offset + 1);
- // If the next one or two input code points are U+0022 QUOTATION MARK ("), U+0027 APOSTROPHE ('),
- // or whitespace followed by U+0022 QUOTATION MARK (") or U+0027 APOSTROPHE ('),
- // then create a <function-token> with its value set to string and return it.
- if (getCharCode(offset) === 0x0022 ||
- getCharCode(offset) === 0x0027) {
- type = TYPE$2.Function;
- offset = nameStartOffset + 4;
- return;
- }
- // Otherwise, consume a url token, and return it.
- consumeUrlToken();
- return;
- }
- // Otherwise, if the next input code point is U+0028 LEFT PARENTHESIS ((), consume it.
- // Create a <function-token> with its value set to string and return it.
- if (getCharCode(offset) === 0x0028) {
- type = TYPE$2.Function;
- offset++;
- return;
- }
- // Otherwise, create an <ident-token> with its value set to string and return it.
- type = TYPE$2.Ident;
- }
- // § 4.3.5. Consume a string token
- function consumeStringToken(endingCodePoint) {
- // This algorithm may be called with an ending code point, which denotes the code point
- // that ends the string. If an ending code point is not specified,
- // the current input code point is used.
- if (!endingCodePoint) {
- endingCodePoint = getCharCode(offset++);
- }
- // Initially create a <string-token> with its value set to the empty string.
- type = TYPE$2.String;
- // Repeatedly consume the next input code point from the stream:
- for (; offset < source.length; offset++) {
- var code = source.charCodeAt(offset);
- switch (charCodeCategory$1(code)) {
- // ending code point
- case endingCodePoint:
- // Return the <string-token>.
- offset++;
- return;
- // EOF
- case charCodeCategory$1.Eof:
- // This is a parse error. Return the <string-token>.
- return;
- // newline
- case charCodeCategory$1.WhiteSpace:
- if (isNewline$1(code)) {
- // This is a parse error. Reconsume the current input code point,
- // create a <bad-string-token>, and return it.
- offset += getNewlineLength$1(source, offset, code);
- type = TYPE$2.BadString;
- return;
- }
- break;
- // U+005C REVERSE SOLIDUS (\)
- case 0x005C:
- // If the next input code point is EOF, do nothing.
- if (offset === source.length - 1) {
- break;
- }
- var nextCode = getCharCode(offset + 1);
- // Otherwise, if the next input code point is a newline, consume it.
- if (isNewline$1(nextCode)) {
- offset += getNewlineLength$1(source, offset + 1, nextCode);
- } else if (isValidEscape$2(code, nextCode)) {
- // Otherwise, (the stream starts with a valid escape) consume
- // an escaped code point and append the returned code point to
- // the <string-token>’s value.
- offset = consumeEscaped$1(source, offset) - 1;
- }
- break;
- // anything else
- // Append the current input code point to the <string-token>’s value.
- }
- }
- }
- // § 4.3.6. Consume a url token
- // Note: This algorithm assumes that the initial "url(" has already been consumed.
- // This algorithm also assumes that it’s being called to consume an "unquoted" value, like url(foo).
- // A quoted value, like url("foo"), is parsed as a <function-token>. Consume an ident-like token
- // automatically handles this distinction; this algorithm shouldn’t be called directly otherwise.
- function consumeUrlToken() {
- // Initially create a <url-token> with its value set to the empty string.
- type = TYPE$2.Url;
- // Consume as much whitespace as possible.
- offset = findWhiteSpaceEnd$1(source, offset);
- // Repeatedly consume the next input code point from the stream:
- for (; offset < source.length; offset++) {
- var code = source.charCodeAt(offset);
- switch (charCodeCategory$1(code)) {
- // U+0029 RIGHT PARENTHESIS ())
- case 0x0029:
- // Return the <url-token>.
- offset++;
- return;
- // EOF
- case charCodeCategory$1.Eof:
- // This is a parse error. Return the <url-token>.
- return;
- // whitespace
- case charCodeCategory$1.WhiteSpace:
- // Consume as much whitespace as possible.
- offset = findWhiteSpaceEnd$1(source, offset);
- // If the next input code point is U+0029 RIGHT PARENTHESIS ()) or EOF,
- // consume it and return the <url-token>
- // (if EOF was encountered, this is a parse error);
- if (getCharCode(offset) === 0x0029 || offset >= source.length) {
- if (offset < source.length) {
- offset++;
- }
- return;
- }
- // otherwise, consume the remnants of a bad url, create a <bad-url-token>,
- // and return it.
- offset = consumeBadUrlRemnants$1(source, offset);
- type = TYPE$2.BadUrl;
- return;
- // U+0022 QUOTATION MARK (")
- // U+0027 APOSTROPHE (')
- // U+0028 LEFT PARENTHESIS (()
- // non-printable code point
- case 0x0022:
- case 0x0027:
- case 0x0028:
- case charCodeCategory$1.NonPrintable:
- // This is a parse error. Consume the remnants of a bad url,
- // create a <bad-url-token>, and return it.
- offset = consumeBadUrlRemnants$1(source, offset);
- type = TYPE$2.BadUrl;
- return;
- // U+005C REVERSE SOLIDUS (\)
- case 0x005C:
- // If the stream starts with a valid escape, consume an escaped code point and
- // append the returned code point to the <url-token>’s value.
- if (isValidEscape$2(code, getCharCode(offset + 1))) {
- offset = consumeEscaped$1(source, offset) - 1;
- break;
- }
- // Otherwise, this is a parse error. Consume the remnants of a bad url,
- // create a <bad-url-token>, and return it.
- offset = consumeBadUrlRemnants$1(source, offset);
- type = TYPE$2.BadUrl;
- return;
- // anything else
- // Append the current input code point to the <url-token>’s value.
- }
- }
- }
- if (!stream) {
- stream = new TokenStream_1();
- }
- // ensure source is a string
- source = String(source || '');
- var sourceLength = source.length;
- var offsetAndType = adoptBuffer(stream.offsetAndType, sourceLength + 1); // +1 because of eof-token
- var balance = adoptBuffer(stream.balance, sourceLength + 1);
- var tokenCount = 0;
- var start = isBOM$1(getCharCode(0));
- var offset = start;
- var balanceCloseType = 0;
- var balanceStart = 0;
- var balancePrev = 0;
- // https://drafts.csswg.org/css-syntax-3/#consume-token
- // § 4.3.1. Consume a token
- while (offset < sourceLength) {
- var code = source.charCodeAt(offset);
- var type = 0;
- balance[tokenCount] = sourceLength;
- switch (charCodeCategory$1(code)) {
- // whitespace
- case charCodeCategory$1.WhiteSpace:
- // Consume as much whitespace as possible. Return a <whitespace-token>.
- type = TYPE$2.WhiteSpace;
- offset = findWhiteSpaceEnd$1(source, offset + 1);
- break;
- // U+0022 QUOTATION MARK (")
- case 0x0022:
- // Consume a string token and return it.
- consumeStringToken();
- break;
- // U+0023 NUMBER SIGN (#)
- case 0x0023:
- // If the next input code point is a name code point or the next two input code points are a valid escape, then:
- if (isName$2(getCharCode(offset + 1)) || isValidEscape$2(getCharCode(offset + 1), getCharCode(offset + 2))) {
- // Create a <hash-token>.
- type = TYPE$2.Hash;
- // If the next 3 input code points would start an identifier, set the <hash-token>’s type flag to "id".
- // if (isIdentifierStart(getCharCode(offset + 1), getCharCode(offset + 2), getCharCode(offset + 3))) {
- // // TODO: set id flag
- // }
- // Consume a name, and set the <hash-token>’s value to the returned string.
- offset = consumeName$1(source, offset + 1);
- // Return the <hash-token>.
- } else {
- // Otherwise, return a <delim-token> with its value set to the current input code point.
- type = TYPE$2.Delim;
- offset++;
- }
- break;
- // U+0027 APOSTROPHE (')
- case 0x0027:
- // Consume a string token and return it.
- consumeStringToken();
- break;
- // U+0028 LEFT PARENTHESIS (()
- case 0x0028:
- // Return a <(-token>.
- type = TYPE$2.LeftParenthesis;
- offset++;
- break;
- // U+0029 RIGHT PARENTHESIS ())
- case 0x0029:
- // Return a <)-token>.
- type = TYPE$2.RightParenthesis;
- offset++;
- break;
- // U+002B PLUS SIGN (+)
- case 0x002B:
- // If the input stream starts with a number, ...
- if (isNumberStart$1(code, getCharCode(offset + 1), getCharCode(offset + 2))) {
- // ... reconsume the current input code point, consume a numeric token, and return it.
- consumeNumericToken();
- } else {
- // Otherwise, return a <delim-token> with its value set to the current input code point.
- type = TYPE$2.Delim;
- offset++;
- }
- break;
- // U+002C COMMA (,)
- case 0x002C:
- // Return a <comma-token>.
- type = TYPE$2.Comma;
- offset++;
- break;
- // U+002D HYPHEN-MINUS (-)
- case 0x002D:
- // If the input stream starts with a number, reconsume the current input code point, consume a numeric token, and return it.
- if (isNumberStart$1(code, getCharCode(offset + 1), getCharCode(offset + 2))) {
- consumeNumericToken();
- } else {
- // Otherwise, if the next 2 input code points are U+002D HYPHEN-MINUS U+003E GREATER-THAN SIGN (->), consume them and return a <CDC-token>.
- if (getCharCode(offset + 1) === 0x002D &&
- getCharCode(offset + 2) === 0x003E) {
- type = TYPE$2.CDC;
- offset = offset + 3;
- } else {
- // Otherwise, if the input stream starts with an identifier, ...
- if (isIdentifierStart$1(code, getCharCode(offset + 1), getCharCode(offset + 2))) {
- // ... reconsume the current input code point, consume an ident-like token, and return it.
- consumeIdentLikeToken();
- } else {
- // Otherwise, return a <delim-token> with its value set to the current input code point.
- type = TYPE$2.Delim;
- offset++;
- }
- }
- }
- break;
- // U+002E FULL STOP (.)
- case 0x002E:
- // If the input stream starts with a number, ...
- if (isNumberStart$1(code, getCharCode(offset + 1), getCharCode(offset + 2))) {
- // ... reconsume the current input code point, consume a numeric token, and return it.
- consumeNumericToken();
- } else {
- // Otherwise, return a <delim-token> with its value set to the current input code point.
- type = TYPE$2.Delim;
- offset++;
- }
- break;
- // U+002F SOLIDUS (/)
- case 0x002F:
- // If the next two input code point are U+002F SOLIDUS (/) followed by a U+002A ASTERISK (*),
- if (getCharCode(offset + 1) === 0x002A) {
- // ... consume them and all following code points up to and including the first U+002A ASTERISK (*)
- // followed by a U+002F SOLIDUS (/), or up to an EOF code point.
- type = TYPE$2.Comment;
- offset = source.indexOf('*/', offset + 2) + 2;
- if (offset === 1) {
- offset = source.length;
- }
- } else {
- type = TYPE$2.Delim;
- offset++;
- }
- break;
- // U+003A COLON (:)
- case 0x003A:
- // Return a <colon-token>.
- type = TYPE$2.Colon;
- offset++;
- break;
- // U+003B SEMICOLON (;)
- case 0x003B:
- // Return a <semicolon-token>.
- type = TYPE$2.Semicolon;
- offset++;
- break;
- // U+003C LESS-THAN SIGN (<)
- case 0x003C:
- // If the next 3 input code points are U+0021 EXCLAMATION MARK U+002D HYPHEN-MINUS U+002D HYPHEN-MINUS (!--), ...
- if (getCharCode(offset + 1) === 0x0021 &&
- getCharCode(offset + 2) === 0x002D &&
- getCharCode(offset + 3) === 0x002D) {
- // ... consume them and return a <CDO-token>.
- type = TYPE$2.CDO;
- offset = offset + 4;
- } else {
- // Otherwise, return a <delim-token> with its value set to the current input code point.
- type = TYPE$2.Delim;
- offset++;
- }
- break;
- // U+0040 COMMERCIAL AT (@)
- case 0x0040:
- // If the next 3 input code points would start an identifier, ...
- if (isIdentifierStart$1(getCharCode(offset + 1), getCharCode(offset + 2), getCharCode(offset + 3))) {
- // ... consume a name, create an <at-keyword-token> with its value set to the returned value, and return it.
- type = TYPE$2.AtKeyword;
- offset = consumeName$1(source, offset + 1);
- } else {
- // Otherwise, return a <delim-token> with its value set to the current input code point.
- type = TYPE$2.Delim;
- offset++;
- }
- break;
- // U+005B LEFT SQUARE BRACKET ([)
- case 0x005B:
- // Return a <[-token>.
- type = TYPE$2.LeftSquareBracket;
- offset++;
- break;
- // U+005C REVERSE SOLIDUS (\)
- case 0x005C:
- // If the input stream starts with a valid escape, ...
- if (isValidEscape$2(code, getCharCode(offset + 1))) {
- // ... reconsume the current input code point, consume an ident-like token, and return it.
- consumeIdentLikeToken();
- } else {
- // Otherwise, this is a parse error. Return a <delim-token> with its value set to the current input code point.
- type = TYPE$2.Delim;
- offset++;
- }
- break;
- // U+005D RIGHT SQUARE BRACKET (])
- case 0x005D:
- // Return a <]-token>.
- type = TYPE$2.RightSquareBracket;
- offset++;
- break;
- // U+007B LEFT CURLY BRACKET ({)
- case 0x007B:
- // Return a <{-token>.
- type = TYPE$2.LeftCurlyBracket;
- offset++;
- break;
- // U+007D RIGHT CURLY BRACKET (})
- case 0x007D:
- // Return a <}-token>.
- type = TYPE$2.RightCurlyBracket;
- offset++;
- break;
- // digit
- case charCodeCategory$1.Digit:
- // Reconsume the current input code point, consume a numeric token, and return it.
- consumeNumericToken();
- break;
- // name-start code point
- case charCodeCategory$1.NameStart:
- // Reconsume the current input code point, consume an ident-like token, and return it.
- consumeIdentLikeToken();
- break;
- // EOF
- case charCodeCategory$1.Eof:
- // Return an <EOF-token>.
- break;
- // anything else
- default:
- // Return a <delim-token> with its value set to the current input code point.
- type = TYPE$2.Delim;
- offset++;
- }
- switch (type) {
- case balanceCloseType:
- balancePrev = balanceStart & OFFSET_MASK$1;
- balanceStart = balance[balancePrev];
- balanceCloseType = balanceStart >> TYPE_SHIFT$1;
- balance[tokenCount] = balancePrev;
- balance[balancePrev++] = tokenCount;
- for (; balancePrev < tokenCount; balancePrev++) {
- if (balance[balancePrev] === sourceLength) {
- balance[balancePrev] = tokenCount;
- }
- }
- break;
- case TYPE$2.LeftParenthesis:
- case TYPE$2.Function:
- balance[tokenCount] = balanceStart;
- balanceCloseType = TYPE$2.RightParenthesis;
- balanceStart = (balanceCloseType << TYPE_SHIFT$1) | tokenCount;
- break;
- case TYPE$2.LeftSquareBracket:
- balance[tokenCount] = balanceStart;
- balanceCloseType = TYPE$2.RightSquareBracket;
- balanceStart = (balanceCloseType << TYPE_SHIFT$1) | tokenCount;
- break;
- case TYPE$2.LeftCurlyBracket:
- balance[tokenCount] = balanceStart;
- balanceCloseType = TYPE$2.RightCurlyBracket;
- balanceStart = (balanceCloseType << TYPE_SHIFT$1) | tokenCount;
- break;
- }
- offsetAndType[tokenCount++] = (type << TYPE_SHIFT$1) | offset;
- }
- // finalize buffers
- offsetAndType[tokenCount] = (TYPE$2.EOF << TYPE_SHIFT$1) | offset; // <EOF-token>
- balance[tokenCount] = sourceLength;
- balance[sourceLength] = sourceLength; // prevents false positive balance match with any token
- while (balanceStart !== 0) {
- balancePrev = balanceStart & OFFSET_MASK$1;
- balanceStart = balance[balancePrev];
- balance[balancePrev] = sourceLength;
- }
- // update stream
- stream.source = source;
- stream.firstCharOffset = start;
- stream.offsetAndType = offsetAndType;
- stream.tokenCount = tokenCount;
- stream.balance = balance;
- stream.reset();
- stream.next();
- return stream;
- }
- // extend tokenizer with constants
- Object.keys(_const).forEach(function(key) {
- tokenize[key] = _const[key];
- });
- // extend tokenizer with static methods from utils
- Object.keys(charCodeDefinitions).forEach(function(key) {
- tokenize[key] = charCodeDefinitions[key];
- });
- Object.keys(utils).forEach(function(key) {
- tokenize[key] = utils[key];
- });
- var tokenizer = tokenize;
- var isDigit$2 = tokenizer.isDigit;
- var cmpChar$1 = tokenizer.cmpChar;
- var TYPE$3 = tokenizer.TYPE;
- var DELIM = TYPE$3.Delim;
- var WHITESPACE$1 = TYPE$3.WhiteSpace;
- var COMMENT$1 = TYPE$3.Comment;
- var IDENT = TYPE$3.Ident;
- var NUMBER = TYPE$3.Number;
- var DIMENSION = TYPE$3.Dimension;
- var PLUSSIGN = 0x002B; // U+002B PLUS SIGN (+)
- var HYPHENMINUS$1 = 0x002D; // U+002D HYPHEN-MINUS (-)
- var N = 0x006E; // U+006E LATIN SMALL LETTER N (n)
- var DISALLOW_SIGN = true;
- var ALLOW_SIGN = false;
- function isDelim(token, code) {
- return token !== null && token.type === DELIM && token.value.charCodeAt(0) === code;
- }
- function skipSC(token, offset, getNextToken) {
- while (token !== null && (token.type === WHITESPACE$1 || token.type === COMMENT$1)) {
- token = getNextToken(++offset);
- }
- return offset;
- }
- function checkInteger(token, valueOffset, disallowSign, offset) {
- if (!token) {
- return 0;
- }
- var code = token.value.charCodeAt(valueOffset);
- if (code === PLUSSIGN || code === HYPHENMINUS$1) {
- if (disallowSign) {
- // Number sign is not allowed
- return 0;
- }
- valueOffset++;
- }
- for (; valueOffset < token.value.length; valueOffset++) {
- if (!isDigit$2(token.value.charCodeAt(valueOffset))) {
- // Integer is expected
- return 0;
- }
- }
- return offset + 1;
- }
- // ... <signed-integer>
- // ... ['+' | '-'] <signless-integer>
- function consumeB(token, offset_, getNextToken) {
- var sign = false;
- var offset = skipSC(token, offset_, getNextToken);
- token = getNextToken(offset);
- if (token === null) {
- return offset_;
- }
- if (token.type !== NUMBER) {
- if (isDelim(token, PLUSSIGN) || isDelim(token, HYPHENMINUS$1)) {
- sign = true;
- offset = skipSC(getNextToken(++offset), offset, getNextToken);
- token = getNextToken(offset);
- if (token === null && token.type !== NUMBER) {
- return 0;
- }
- } else {
- return offset_;
- }
- }
- if (!sign) {
- var code = token.value.charCodeAt(0);
- if (code !== PLUSSIGN && code !== HYPHENMINUS$1) {
- // Number sign is expected
- return 0;
- }
- }
- return checkInteger(token, sign ? 0 : 1, sign, offset);
- }
- // An+B microsyntax https://www.w3.org/TR/css-syntax-3/#anb
- var genericAnPlusB = function anPlusB(token, getNextToken) {
- /* eslint-disable brace-style*/
- var offset = 0;
- if (!token) {
- return 0;
- }
- // <integer>
- if (token.type === NUMBER) {
- return checkInteger(token, 0, ALLOW_SIGN, offset); // b
- }
- // -n
- // -n <signed-integer>
- // -n ['+' | '-'] <signless-integer>
- // -n- <signless-integer>
- // <dashndashdigit-ident>
- else if (token.type === IDENT && token.value.charCodeAt(0) === HYPHENMINUS$1) {
- // expect 1st char is N
- if (!cmpChar$1(token.value, 1, N)) {
- return 0;
- }
- switch (token.value.length) {
- // -n
- // -n <signed-integer>
- // -n ['+' | '-'] <signless-integer>
- case 2:
- return consumeB(getNextToken(++offset), offset, getNextToken);
- // -n- <signless-integer>
- case 3:
- if (token.value.charCodeAt(2) !== HYPHENMINUS$1) {
- return 0;
- }
- offset = skipSC(getNextToken(++offset), offset, getNextToken);
- token = getNextToken(offset);
- return checkInteger(token, 0, DISALLOW_SIGN, offset);
- // <dashndashdigit-ident>
- default:
- if (token.value.charCodeAt(2) !== HYPHENMINUS$1) {
- return 0;
- }
- return checkInteger(token, 3, DISALLOW_SIGN, offset);
- }
- }
- // '+'? n
- // '+'? n <signed-integer>
- // '+'? n ['+' | '-'] <signless-integer>
- // '+'? n- <signless-integer>
- // '+'? <ndashdigit-ident>
- else if (token.type === IDENT || (isDelim(token, PLUSSIGN) && getNextToken(offset + 1).type === IDENT)) {
- // just ignore a plus
- if (token.type !== IDENT) {
- token = getNextToken(++offset);
- }
- if (token === null || !cmpChar$1(token.value, 0, N)) {
- return 0;
- }
- switch (token.value.length) {
- // '+'? n
- // '+'? n <signed-integer>
- // '+'? n ['+' | '-'] <signless-integer>
- case 1:
- return consumeB(getNextToken(++offset), offset, getNextToken);
- // '+'? n- <signless-integer>
- case 2:
- if (token.value.charCodeAt(1) !== HYPHENMINUS$1) {
- return 0;
- }
- offset = skipSC(getNextToken(++offset), offset, getNextToken);
- token = getNextToken(offset);
- return checkInteger(token, 0, DISALLOW_SIGN, offset);
- // '+'? <ndashdigit-ident>
- default:
- if (token.value.charCodeAt(1) !== HYPHENMINUS$1) {
- return 0;
- }
- return checkInteger(token, 2, DISALLOW_SIGN, offset);
- }
- }
- // <ndashdigit-dimension>
- // <ndash-dimension> <signless-integer>
- // <n-dimension>
- // <n-dimension> <signed-integer>
- // <n-dimension> ['+' | '-'] <signless-integer>
- else if (token.type === DIMENSION) {
- var code = token.value.charCodeAt(0);
- var sign = code === PLUSSIGN || code === HYPHENMINUS$1 ? 1 : 0;
- for (var i = sign; i < token.value.length; i++) {
- if (!isDigit$2(token.value.charCodeAt(i))) {
- break;
- }
- }
- if (i === sign) {
- // Integer is expected
- return 0;
- }
- if (!cmpChar$1(token.value, i, N)) {
- return 0;
- }
- // <n-dimension>
- // <n-dimension> <signed-integer>
- // <n-dimension> ['+' | '-'] <signless-integer>
- if (i + 1 === token.value.length) {
- return consumeB(getNextToken(++offset), offset, getNextToken);
- } else {
- if (token.value.charCodeAt(i + 1) !== HYPHENMINUS$1) {
- return 0;
- }
- // <ndash-dimension> <signless-integer>
- if (i + 2 === token.value.length) {
- offset = skipSC(getNextToken(++offset), offset, getNextToken);
- token = getNextToken(offset);
- return checkInteger(token, 0, DISALLOW_SIGN, offset);
- }
- // <ndashdigit-dimension>
- else {
- return checkInteger(token, i + 2, DISALLOW_SIGN, offset);
- }
- }
- }
- return 0;
- };
- var isHexDigit$2 = tokenizer.isHexDigit;
- var cmpChar$2 = tokenizer.cmpChar;
- var TYPE$4 = tokenizer.TYPE;
- var IDENT$1 = TYPE$4.Ident;
- var DELIM$1 = TYPE$4.Delim;
- var NUMBER$1 = TYPE$4.Number;
- var DIMENSION$1 = TYPE$4.Dimension;
- var PLUSSIGN$1 = 0x002B; // U+002B PLUS SIGN (+)
- var HYPHENMINUS$2 = 0x002D; // U+002D HYPHEN-MINUS (-)
- var QUESTIONMARK = 0x003F; // U+003F QUESTION MARK (?)
- var U = 0x0075; // U+0075 LATIN SMALL LETTER U (u)
- function isDelim$1(token, code) {
- return token !== null && token.type === DELIM$1 && token.value.charCodeAt(0) === code;
- }
- function startsWith(token, code) {
- return token.value.charCodeAt(0) === code;
- }
- function hexSequence(token, offset, allowDash) {
- for (var pos = offset, hexlen = 0; pos < token.value.length; pos++) {
- var code = token.value.charCodeAt(pos);
- if (code === HYPHENMINUS$2 && allowDash && hexlen !== 0) {
- if (hexSequence(token, offset + hexlen + 1, false) > 0) {
- return 6; // dissallow following question marks
- }
- return 0; // dash at the ending of a hex sequence is not allowed
- }
- if (!isHexDigit$2(code)) {
- return 0; // not a hex digit
- }
- if (++hexlen > 6) {
- return 0; // too many hex digits
- } }
- return hexlen;
- }
- function withQuestionMarkSequence(consumed, length, getNextToken) {
- if (!consumed) {
- return 0; // nothing consumed
- }
- while (isDelim$1(getNextToken(length), QUESTIONMARK)) {
- if (++consumed > 6) {
- return 0; // too many question marks
- }
- length++;
- }
- return length;
- }
- // https://drafts.csswg.org/css-syntax/#urange
- // Informally, the <urange> production has three forms:
- // U+0001
- // Defines a range consisting of a single code point, in this case the code point "1".
- // U+0001-00ff
- // Defines a range of codepoints between the first and the second value, in this case
- // the range between "1" and "ff" (255 in decimal) inclusive.
- // U+00??
- // Defines a range of codepoints where the "?" characters range over all hex digits,
- // in this case defining the same as the value U+0000-00ff.
- // In each form, a maximum of 6 digits is allowed for each hexadecimal number (if you treat "?" as a hexadecimal digit).
- //
- // <urange> =
- // u '+' <ident-token> '?'* |
- // u <dimension-token> '?'* |
- // u <number-token> '?'* |
- // u <number-token> <dimension-token> |
- // u <number-token> <number-token> |
- // u '+' '?'+
- var genericUrange = function urange(token, getNextToken) {
- var length = 0;
- // should start with `u` or `U`
- if (token === null || token.type !== IDENT$1 || !cmpChar$2(token.value, 0, U)) {
- return 0;
- }
- token = getNextToken(++length);
- if (token === null) {
- return 0;
- }
- // u '+' <ident-token> '?'*
- // u '+' '?'+
- if (isDelim$1(token, PLUSSIGN$1)) {
- token = getNextToken(++length);
- if (token === null) {
- return 0;
- }
- if (token.type === IDENT$1) {
- // u '+' <ident-token> '?'*
- return withQuestionMarkSequence(hexSequence(token, 0, true), ++length, getNextToken);
- }
- if (isDelim$1(token, QUESTIONMARK)) {
- // u '+' '?'+
- return withQuestionMarkSequence(1, ++length, getNextToken);
- }
- // Hex digit or question mark is expected
- return 0;
- }
- // u <number-token> '?'*
- // u <number-token> <dimension-token>
- // u <number-token> <number-token>
- if (token.type === NUMBER$1) {
- if (!startsWith(token, PLUSSIGN$1)) {
- return 0;
- }
- var consumedHexLength = hexSequence(token, 1, true);
- if (consumedHexLength === 0) {
- return 0;
- }
- token = getNextToken(++length);
- if (token === null) {
- // u <number-token> <eof>
- return length;
- }
- if (token.type === DIMENSION$1 || token.type === NUMBER$1) {
- // u <number-token> <dimension-token>
- // u <number-token> <number-token>
- if (!startsWith(token, HYPHENMINUS$2) || !hexSequence(token, 1, false)) {
- return 0;
- }
- return length + 1;
- }
- // u <number-token> '?'*
- return withQuestionMarkSequence(consumedHexLength, length, getNextToken);
- }
- // u <dimension-token> '?'*
- if (token.type === DIMENSION$1) {
- if (!startsWith(token, PLUSSIGN$1)) {
- return 0;
- }
- return withQuestionMarkSequence(hexSequence(token, 1, true), ++length, getNextToken);
- }
- return 0;
- };
- var isIdentifierStart$2 = tokenizer.isIdentifierStart;
- var isHexDigit$3 = tokenizer.isHexDigit;
- var isDigit$3 = tokenizer.isDigit;
- var cmpStr$3 = tokenizer.cmpStr;
- var consumeNumber$2 = tokenizer.consumeNumber;
- var TYPE$5 = tokenizer.TYPE;
- var cssWideKeywords = ['unset', 'initial', 'inherit'];
- var calcFunctionNames = ['calc(', '-moz-calc(', '-webkit-calc('];
- // https://www.w3.org/TR/css-values-3/#lengths
- var LENGTH = {
- // absolute length units
- 'px': true,
- 'mm': true,
- 'cm': true,
- 'in': true,
- 'pt': true,
- 'pc': true,
- 'q': true,
- // relative length units
- 'em': true,
- 'ex': true,
- 'ch': true,
- 'rem': true,
- // viewport-percentage lengths
- 'vh': true,
- 'vw': true,
- 'vmin': true,
- 'vmax': true,
- 'vm': true
- };
- var ANGLE = {
- 'deg': true,
- 'grad': true,
- 'rad': true,
- 'turn': true
- };
- var TIME = {
- 's': true,
- 'ms': true
- };
- var FREQUENCY = {
- 'hz': true,
- 'khz': true
- };
- // https://www.w3.org/TR/css-values-3/#resolution (https://drafts.csswg.org/css-values/#resolution)
- var RESOLUTION = {
- 'dpi': true,
- 'dpcm': true,
- 'dppx': true,
- 'x': true // https://github.com/w3c/csswg-drafts/issues/461
- };
- // https://drafts.csswg.org/css-grid/#fr-unit
- var FLEX = {
- 'fr': true
- };
- // https://www.w3.org/TR/css3-speech/#mixing-props-voice-volume
- var DECIBEL = {
- 'db': true
- };
- // https://www.w3.org/TR/css3-speech/#voice-props-voice-pitch
- var SEMITONES = {
- 'st': true
- };
- // safe char code getter
- function charCode(str, index) {
- return index < str.length ? str.charCodeAt(index) : 0;
- }
- function eqStr(actual, expected) {
- return cmpStr$3(actual, 0, actual.length, expected);
- }
- function eqStrAny(actual, expected) {
- for (var i = 0; i < expected.length; i++) {
- if (eqStr(actual, expected[i])) {
- return true;
- }
- }
- return false;
- }
- // IE postfix hack, i.e. 123\0 or 123px\9
- function isPostfixIeHack(str, offset) {
- if (offset !== str.length - 2) {
- return false;
- }
- return (
- str.charCodeAt(offset) === 0x005C && // U+005C REVERSE SOLIDUS (\)
- isDigit$3(str.charCodeAt(offset + 1))
- );
- }
- function outOfRange(opts, value, numEnd) {
- if (opts && opts.type === 'Range') {
- var num = Number(
- numEnd !== undefined && numEnd !== value.length
- ? value.substr(0, numEnd)
- : value
- );
- if (isNaN(num)) {
- return true;
- }
- if (opts.min !== null && num < opts.min) {
- return true;
- }
- if (opts.max !== null && num > opts.max) {
- return true;
- }
- }
- return false;
- }
- function consumeFunction(token, getNextToken) {
- var startIdx = token.index;
- var length = 0;
- // balanced token consuming
- do {
- length++;
- if (token.balance <= startIdx) {
- break;
- }
- } while (token = getNextToken(length));
- return length;
- }
- // TODO: implement
- // can be used wherever <length>, <frequency>, <angle>, <time>, <percentage>, <number>, or <integer> values are allowed
- // https://drafts.csswg.org/css-values/#calc-notation
- function calc(next) {
- return function(token, getNextToken, opts) {
- if (token === null) {
- return 0;
- }
- if (token.type === TYPE$5.Function && eqStrAny(token.value, calcFunctionNames)) {
- return consumeFunction(token, getNextToken);
- }
- return next(token, getNextToken, opts);
- };
- }
- function tokenType(expectedTokenType) {
- return function(token) {
- if (token === null || token.type !== expectedTokenType) {
- return 0;
- }
- return 1;
- };
- }
- function func(name) {
- name = name + '(';
- return function(token, getNextToken) {
- if (token !== null && eqStr(token.value, name)) {
- return consumeFunction(token, getNextToken);
- }
- return 0;
- };
- }
- // =========================
- // Complex types
- //
- // https://drafts.csswg.org/css-values-4/#custom-idents
- // 4.2. Author-defined Identifiers: the <custom-ident> type
- // Some properties accept arbitrary author-defined identifiers as a component value.
- // This generic data type is denoted by <custom-ident>, and represents any valid CSS identifier
- // that would not be misinterpreted as a pre-defined keyword in that property’s value definition.
- //
- // See also: https://developer.mozilla.org/en-US/docs/Web/CSS/custom-ident
- function customIdent(token) {
- if (token === null || token.type !== TYPE$5.Ident) {
- return 0;
- }
- var name = token.value.toLowerCase();
- // The CSS-wide keywords are not valid <custom-ident>s
- if (eqStrAny(name, cssWideKeywords)) {
- return 0;
- }
- // The default keyword is reserved and is also not a valid <custom-ident>
- if (eqStr(name, 'default')) {
- return 0;
- }
- // TODO: ignore property specific keywords (as described https://developer.mozilla.org/en-US/docs/Web/CSS/custom-ident)
- // Specifications using <custom-ident> must specify clearly what other keywords
- // are excluded from <custom-ident>, if any—for example by saying that any pre-defined keywords
- // in that property’s value definition are excluded. Excluded keywords are excluded
- // in all ASCII case permutations.
- return 1;
- }
- // https://drafts.csswg.org/css-variables/#typedef-custom-property-name
- // A custom property is any property whose name starts with two dashes (U+002D HYPHEN-MINUS), like --foo.
- // The <custom-property-name> production corresponds to this: it’s defined as any valid identifier
- // that starts with two dashes, except -- itself, which is reserved for future use by CSS.
- // NOTE: Current implementation treat `--` as a valid name since most (all?) major browsers treat it as valid.
- function customPropertyName(token) {
- // ... defined as any valid identifier
- if (token === null || token.type !== TYPE$5.Ident) {
- return 0;
- }
- // ... that starts with two dashes (U+002D HYPHEN-MINUS)
- if (charCode(token.value, 0) !== 0x002D || charCode(token.value, 1) !== 0x002D) {
- return 0;
- }
- return 1;
- }
- // https://drafts.csswg.org/css-color-4/#hex-notation
- // The syntax of a <hex-color> is a <hash-token> token whose value consists of 3, 4, 6, or 8 hexadecimal digits.
- // In other words, a hex color is written as a hash character, "#", followed by some number of digits 0-9 or
- // letters a-f (the case of the letters doesn’t matter - #00ff00 is identical to #00FF00).
- function hexColor(token) {
- if (token === null || token.type !== TYPE$5.Hash) {
- return 0;
- }
- var length = token.value.length;
- // valid values (length): #rgb (4), #rgba (5), #rrggbb (7), #rrggbbaa (9)
- if (length !== 4 && length !== 5 && length !== 7 && length !== 9) {
- return 0;
- }
- for (var i = 1; i < length; i++) {
- if (!isHexDigit$3(token.value.charCodeAt(i))) {
- return 0;
- }
- }
- return 1;
- }
- function idSelector(token) {
- if (token === null || token.type !== TYPE$5.Hash) {
- return 0;
- }
- if (!isIdentifierStart$2(charCode(token.value, 1), charCode(token.value, 2), charCode(token.value, 3))) {
- return 0;
- }
- return 1;
- }
- // https://drafts.csswg.org/css-syntax/#any-value
- // It represents the entirety of what a valid declaration can have as its value.
- function declarationValue(token, getNextToken) {
- if (!token) {
- return 0;
- }
- var length = 0;
- var level = 0;
- var startIdx = token.index;
- // The <declaration-value> production matches any sequence of one or more tokens,
- // so long as the sequence ...
- scan:
- do {
- switch (token.type) {
- // ... does not contain <bad-string-token>, <bad-url-token>,
- case TYPE$5.BadString:
- case TYPE$5.BadUrl:
- break scan;
- // ... unmatched <)-token>, <]-token>, or <}-token>,
- case TYPE$5.RightCurlyBracket:
- case TYPE$5.RightParenthesis:
- case TYPE$5.RightSquareBracket:
- if (token.balance > token.index || token.balance < startIdx) {
- break scan;
- }
- level--;
- break;
- // ... or top-level <semicolon-token> tokens
- case TYPE$5.Semicolon:
- if (level === 0) {
- break scan;
- }
- break;
- // ... or <delim-token> tokens with a value of "!"
- case TYPE$5.Delim:
- if (token.value === '!' && level === 0) {
- break scan;
- }
- break;
- case TYPE$5.Function:
- case TYPE$5.LeftParenthesis:
- case TYPE$5.LeftSquareBracket:
- case TYPE$5.LeftCurlyBracket:
- level++;
- break;
- }
- length++;
- // until balance closing
- if (token.balance <= startIdx) {
- break;
- }
- } while (token = getNextToken(length));
- return length;
- }
- // https://drafts.csswg.org/css-syntax/#any-value
- // The <any-value> production is identical to <declaration-value>, but also
- // allows top-level <semicolon-token> tokens and <delim-token> tokens
- // with a value of "!". It represents the entirety of what valid CSS can be in any context.
- function anyValue(token, getNextToken) {
- if (!token) {
- return 0;
- }
- var startIdx = token.index;
- var length = 0;
- // The <any-value> production matches any sequence of one or more tokens,
- // so long as the sequence ...
- scan:
- do {
- switch (token.type) {
- // ... does not contain <bad-string-token>, <bad-url-token>,
- case TYPE$5.BadString:
- case TYPE$5.BadUrl:
- break scan;
- // ... unmatched <)-token>, <]-token>, or <}-token>,
- case TYPE$5.RightCurlyBracket:
- case TYPE$5.RightParenthesis:
- case TYPE$5.RightSquareBracket:
- if (token.balance > token.index || token.balance < startIdx) {
- break scan;
- }
- break;
- }
- length++;
- // until balance closing
- if (token.balance <= startIdx) {
- break;
- }
- } while (token = getNextToken(length));
- return length;
- }
- // =========================
- // Dimensions
- //
- function dimension(type) {
- return function(token, getNextToken, opts) {
- if (token === null || token.type !== TYPE$5.Dimension) {
- return 0;
- }
- var numberEnd = consumeNumber$2(token.value, 0);
- // check unit
- if (type !== null) {
- // check for IE postfix hack, i.e. 123px\0 or 123px\9
- var reverseSolidusOffset = token.value.indexOf('\\', numberEnd);
- var unit = reverseSolidusOffset === -1 || !isPostfixIeHack(token.value, reverseSolidusOffset)
- ? token.value.substr(numberEnd)
- : token.value.substring(numberEnd, reverseSolidusOffset);
- if (type.hasOwnProperty(unit.toLowerCase()) === false) {
- return 0;
- }
- }
- // check range if specified
- if (outOfRange(opts, token.value, numberEnd)) {
- return 0;
- }
- return 1;
- };
- }
- // =========================
- // Percentage
- //
- // §5.5. Percentages: the <percentage> type
- // https://drafts.csswg.org/css-values-4/#percentages
- function percentage(token, getNextToken, opts) {
- // ... corresponds to the <percentage-token> production
- if (token === null || token.type !== TYPE$5.Percentage) {
- return 0;
- }
- // check range if specified
- if (outOfRange(opts, token.value, token.value.length - 1)) {
- return 0;
- }
- return 1;
- }
- // =========================
- // Numeric
- //
- // https://drafts.csswg.org/css-values-4/#numbers
- // The value <zero> represents a literal number with the value 0. Expressions that merely
- // evaluate to a <number> with the value 0 (for example, calc(0)) do not match <zero>;
- // only literal <number-token>s do.
- function zero(next) {
- if (typeof next !== 'function') {
- next = function() {
- return 0;
- };
- }
- return function(token, getNextToken, opts) {
- if (token !== null && token.type === TYPE$5.Number) {
- if (Number(token.value) === 0) {
- return 1;
- }
- }
- return next(token, getNextToken, opts);
- };
- }
- // § 5.3. Real Numbers: the <number> type
- // https://drafts.csswg.org/css-values-4/#numbers
- // Number values are denoted by <number>, and represent real numbers, possibly with a fractional component.
- // ... It corresponds to the <number-token> production
- function number(token, getNextToken, opts) {
- if (token === null) {
- return 0;
- }
- var numberEnd = consumeNumber$2(token.value, 0);
- var isNumber = numberEnd === token.value.length;
- if (!isNumber && !isPostfixIeHack(token.value, numberEnd)) {
- return 0;
- }
- // check range if specified
- if (outOfRange(opts, token.value, numberEnd)) {
- return 0;
- }
- return 1;
- }
- // §5.2. Integers: the <integer> type
- // https://drafts.csswg.org/css-values-4/#integers
- function integer(token, getNextToken, opts) {
- // ... corresponds to a subset of the <number-token> production
- if (token === null || token.type !== TYPE$5.Number) {
- return 0;
- }
- // The first digit of an integer may be immediately preceded by `-` or `+` to indicate the integer’s sign.
- var i = token.value.charCodeAt(0) === 0x002B || // U+002B PLUS SIGN (+)
- token.value.charCodeAt(0) === 0x002D ? 1 : 0; // U+002D HYPHEN-MINUS (-)
- // When written literally, an integer is one or more decimal digits 0 through 9 ...
- for (; i < token.value.length; i++) {
- if (!isDigit$3(token.value.charCodeAt(i))) {
- return 0;
- }
- }
- // check range if specified
- if (outOfRange(opts, token.value, i)) {
- return 0;
- }
- return 1;
- }
- var generic = {
- // token types
- 'ident-token': tokenType(TYPE$5.Ident),
- 'function-token': tokenType(TYPE$5.Function),
- 'at-keyword-token': tokenType(TYPE$5.AtKeyword),
- 'hash-token': tokenType(TYPE$5.Hash),
- 'string-token': tokenType(TYPE$5.String),
- 'bad-string-token': tokenType(TYPE$5.BadString),
- 'url-token': tokenType(TYPE$5.Url),
- 'bad-url-token': tokenType(TYPE$5.BadUrl),
- 'delim-token': tokenType(TYPE$5.Delim),
- 'number-token': tokenType(TYPE$5.Number),
- 'percentage-token': tokenType(TYPE$5.Percentage),
- 'dimension-token': tokenType(TYPE$5.Dimension),
- 'whitespace-token': tokenType(TYPE$5.WhiteSpace),
- 'CDO-token': tokenType(TYPE$5.CDO),
- 'CDC-token': tokenType(TYPE$5.CDC),
- 'colon-token': tokenType(TYPE$5.Colon),
- 'semicolon-token': tokenType(TYPE$5.Semicolon),
- 'comma-token': tokenType(TYPE$5.Comma),
- '[-token': tokenType(TYPE$5.LeftSquareBracket),
- ']-token': tokenType(TYPE$5.RightSquareBracket),
- '(-token': tokenType(TYPE$5.LeftParenthesis),
- ')-token': tokenType(TYPE$5.RightParenthesis),
- '{-token': tokenType(TYPE$5.LeftCurlyBracket),
- '}-token': tokenType(TYPE$5.RightCurlyBracket),
- // token type aliases
- 'string': tokenType(TYPE$5.String),
- 'ident': tokenType(TYPE$5.Ident),
- // complex types
- 'custom-ident': customIdent,
- 'custom-property-name': customPropertyName,
- 'hex-color': hexColor,
- 'id-selector': idSelector, // element( <id-selector> )
- 'an-plus-b': genericAnPlusB,
- 'urange': genericUrange,
- 'declaration-value': declarationValue,
- 'any-value': anyValue,
- // dimensions
- 'dimension': calc(dimension(null)),
- 'angle': calc(dimension(ANGLE)),
- 'decibel': calc(dimension(DECIBEL)),
- 'frequency': calc(dimension(FREQUENCY)),
- 'flex': calc(dimension(FLEX)),
- 'length': calc(zero(dimension(LENGTH))),
- 'resolution': calc(dimension(RESOLUTION)),
- 'semitones': calc(dimension(SEMITONES)),
- 'time': calc(dimension(TIME)),
- // percentage
- 'percentage': calc(percentage),
- // numeric
- 'zero': zero(),
- 'number': calc(number),
- 'integer': calc(integer),
- // old IE stuff
- '-ms-legacy-expression': func('expression')
- };
- var _SyntaxError$1 = function SyntaxError(message, input, offset) {
- var error = createCustomError('SyntaxError', message);
- error.input = input;
- error.offset = offset;
- error.rawMessage = message;
- error.message = error.rawMessage + '\n' +
- ' ' + error.input + '\n' +
- '--' + new Array((error.offset || error.input.length) + 1).join('-') + '^';
- return error;
- };
- var TAB = 9;
- var N$1 = 10;
- var F = 12;
- var R = 13;
- var SPACE = 32;
- var Tokenizer = function(str) {
- this.str = str;
- this.pos = 0;
- };
- Tokenizer.prototype = {
- charCodeAt: function(pos) {
- return pos < this.str.length ? this.str.charCodeAt(pos) : 0;
- },
- charCode: function() {
- return this.charCodeAt(this.pos);
- },
- nextCharCode: function() {
- return this.charCodeAt(this.pos + 1);
- },
- nextNonWsCode: function(pos) {
- return this.charCodeAt(this.findWsEnd(pos));
- },
- findWsEnd: function(pos) {
- for (; pos < this.str.length; pos++) {
- var code = this.str.charCodeAt(pos);
- if (code !== R && code !== N$1 && code !== F && code !== SPACE && code !== TAB) {
- break;
- }
- }
- return pos;
- },
- substringToPos: function(end) {
- return this.str.substring(this.pos, this.pos = end);
- },
- eat: function(code) {
- if (this.charCode() !== code) {
- this.error('Expect `' + String.fromCharCode(code) + '`');
- }
- this.pos++;
- },
- peek: function() {
- return this.pos < this.str.length ? this.str.charAt(this.pos++) : '';
- },
- error: function(message) {
- throw new _SyntaxError$1(message, this.str, this.pos);
- }
- };
- var tokenizer$1 = Tokenizer;
- var TAB$1 = 9;
- var N$2 = 10;
- var F$1 = 12;
- var R$1 = 13;
- var SPACE$1 = 32;
- var EXCLAMATIONMARK = 33; // !
- var NUMBERSIGN = 35; // #
- var AMPERSAND = 38; // &
- var APOSTROPHE = 39; // '
- var LEFTPARENTHESIS = 40; // (
- var RIGHTPARENTHESIS = 41; // )
- var ASTERISK = 42; // *
- var PLUSSIGN$2 = 43; // +
- var COMMA = 44; // ,
- var HYPERMINUS = 45; // -
- var LESSTHANSIGN = 60; // <
- var GREATERTHANSIGN = 62; // >
- var QUESTIONMARK$1 = 63; // ?
- var COMMERCIALAT = 64; // @
- var LEFTSQUAREBRACKET = 91; // [
- var RIGHTSQUAREBRACKET = 93; // ]
- var LEFTCURLYBRACKET = 123; // {
- var VERTICALLINE = 124; // |
- var RIGHTCURLYBRACKET = 125; // }
- var INFINITY = 8734; // ∞
- var NAME_CHAR = createCharMap(function(ch) {
- return /[a-zA-Z0-9\-]/.test(ch);
- });
- var COMBINATOR_PRECEDENCE = {
- ' ': 1,
- '&&': 2,
- '||': 3,
- '|': 4
- };
- function createCharMap(fn) {
- var array = typeof Uint32Array === 'function' ? new Uint32Array(128) : new Array(128);
- for (var i = 0; i < 128; i++) {
- array[i] = fn(String.fromCharCode(i)) ? 1 : 0;
- }
- return array;
- }
- function scanSpaces(tokenizer) {
- return tokenizer.substringToPos(
- tokenizer.findWsEnd(tokenizer.pos)
- );
- }
- function scanWord(tokenizer) {
- var end = tokenizer.pos;
- for (; end < tokenizer.str.length; end++) {
- var code = tokenizer.str.charCodeAt(end);
- if (code >= 128 || NAME_CHAR[code] === 0) {
- break;
- }
- }
- if (tokenizer.pos === end) {
- tokenizer.error('Expect a keyword');
- }
- return tokenizer.substringToPos(end);
- }
- function scanNumber(tokenizer) {
- var end = tokenizer.pos;
- for (; end < tokenizer.str.length; end++) {
- var code = tokenizer.str.charCodeAt(end);
- if (code < 48 || code > 57) {
- break;
- }
- }
- if (tokenizer.pos === end) {
- tokenizer.error('Expect a number');
- }
- return tokenizer.substringToPos(end);
- }
- function scanString(tokenizer) {
- var end = tokenizer.str.indexOf('\'', tokenizer.pos + 1);
- if (end === -1) {
- tokenizer.pos = tokenizer.str.length;
- tokenizer.error('Expect an apostrophe');
- }
- return tokenizer.substringToPos(end + 1);
- }
- function readMultiplierRange(tokenizer) {
- var min = null;
- var max = null;
- tokenizer.eat(LEFTCURLYBRACKET);
- min = scanNumber(tokenizer);
- if (tokenizer.charCode() === COMMA) {
- tokenizer.pos++;
- if (tokenizer.charCode() !== RIGHTCURLYBRACKET) {
- max = scanNumber(tokenizer);
- }
- } else {
- max = min;
- }
- tokenizer.eat(RIGHTCURLYBRACKET);
- return {
- min: Number(min),
- max: max ? Number(max) : 0
- };
- }
- function readMultiplier(tokenizer) {
- var range = null;
- var comma = false;
- switch (tokenizer.charCode()) {
- case ASTERISK:
- tokenizer.pos++;
- range = {
- min: 0,
- max: 0
- };
- break;
- case PLUSSIGN$2:
- tokenizer.pos++;
- range = {
- min: 1,
- max: 0
- };
- break;
- case QUESTIONMARK$1:
- tokenizer.pos++;
- range = {
- min: 0,
- max: 1
- };
- break;
- case NUMBERSIGN:
- tokenizer.pos++;
- comma = true;
- if (tokenizer.charCode() === LEFTCURLYBRACKET) {
- range = readMultiplierRange(tokenizer);
- } else {
- range = {
- min: 1,
- max: 0
- };
- }
- break;
- case LEFTCURLYBRACKET:
- range = readMultiplierRange(tokenizer);
- break;
- default:
- return null;
- }
- return {
- type: 'Multiplier',
- comma: comma,
- min: range.min,
- max: range.max,
- term: null
- };
- }
- function maybeMultiplied(tokenizer, node) {
- var multiplier = readMultiplier(tokenizer);
- if (multiplier !== null) {
- multiplier.term = node;
- return multiplier;
- }
- return node;
- }
- function maybeToken(tokenizer) {
- var ch = tokenizer.peek();
- if (ch === '') {
- return null;
- }
- return {
- type: 'Token',
- value: ch
- };
- }
- function readProperty(tokenizer) {
- var name;
- tokenizer.eat(LESSTHANSIGN);
- tokenizer.eat(APOSTROPHE);
- name = scanWord(tokenizer);
- tokenizer.eat(APOSTROPHE);
- tokenizer.eat(GREATERTHANSIGN);
- return maybeMultiplied(tokenizer, {
- type: 'Property',
- name: name
- });
- }
- // https://drafts.csswg.org/css-values-3/#numeric-ranges
- // 4.1. Range Restrictions and Range Definition Notation
- //
- // Range restrictions can be annotated in the numeric type notation using CSS bracketed
- // range notation—[min,max]—within the angle brackets, after the identifying keyword,
- // indicating a closed range between (and including) min and max.
- // For example, <integer [0, 10]> indicates an integer between 0 and 10, inclusive.
- function readTypeRange(tokenizer) {
- // use null for Infinity to make AST format JSON serializable/deserializable
- var min = null; // -Infinity
- var max = null; // Infinity
- var sign = 1;
- tokenizer.eat(LEFTSQUAREBRACKET);
- if (tokenizer.charCode() === HYPERMINUS) {
- tokenizer.peek();
- sign = -1;
- }
- if (sign == -1 && tokenizer.charCode() === INFINITY) {
- tokenizer.peek();
- } else {
- min = sign * Number(scanNumber(tokenizer));
- }
- scanSpaces(tokenizer);
- tokenizer.eat(COMMA);
- scanSpaces(tokenizer);
- if (tokenizer.charCode() === INFINITY) {
- tokenizer.peek();
- } else {
- sign = 1;
- if (tokenizer.charCode() === HYPERMINUS) {
- tokenizer.peek();
- sign = -1;
- }
- max = sign * Number(scanNumber(tokenizer));
- }
- tokenizer.eat(RIGHTSQUAREBRACKET);
- // If no range is indicated, either by using the bracketed range notation
- // or in the property description, then [−∞,∞] is assumed.
- if (min === null && max === null) {
- return null;
- }
- return {
- type: 'Range',
- min: min,
- max: max
- };
- }
- function readType(tokenizer) {
- var name;
- var opts = null;
- tokenizer.eat(LESSTHANSIGN);
- name = scanWord(tokenizer);
- if (tokenizer.charCode() === LEFTPARENTHESIS &&
- tokenizer.nextCharCode() === RIGHTPARENTHESIS) {
- tokenizer.pos += 2;
- name += '()';
- }
- if (tokenizer.charCodeAt(tokenizer.findWsEnd(tokenizer.pos)) === LEFTSQUAREBRACKET) {
- scanSpaces(tokenizer);
- opts = readTypeRange(tokenizer);
- }
- tokenizer.eat(GREATERTHANSIGN);
- return maybeMultiplied(tokenizer, {
- type: 'Type',
- name: name,
- opts: opts
- });
- }
- function readKeywordOrFunction(tokenizer) {
- var name;
- name = scanWord(tokenizer);
- if (tokenizer.charCode() === LEFTPARENTHESIS) {
- tokenizer.pos++;
- return {
- type: 'Function',
- name: name
- };
- }
- return maybeMultiplied(tokenizer, {
- type: 'Keyword',
- name: name
- });
- }
- function regroupTerms(terms, combinators) {
- function createGroup(terms, combinator) {
- return {
- type: 'Group',
- terms: terms,
- combinator: combinator,
- disallowEmpty: false,
- explicit: false
- };
- }
- combinators = Object.keys(combinators).sort(function(a, b) {
- return COMBINATOR_PRECEDENCE[a] - COMBINATOR_PRECEDENCE[b];
- });
- while (combinators.length > 0) {
- var combinator = combinators.shift();
- for (var i = 0, subgroupStart = 0; i < terms.length; i++) {
- var term = terms[i];
- if (term.type === 'Combinator') {
- if (term.value === combinator) {
- if (subgroupStart === -1) {
- subgroupStart = i - 1;
- }
- terms.splice(i, 1);
- i--;
- } else {
- if (subgroupStart !== -1 && i - subgroupStart > 1) {
- terms.splice(
- subgroupStart,
- i - subgroupStart,
- createGroup(terms.slice(subgroupStart, i), combinator)
- );
- i = subgroupStart + 1;
- }
- subgroupStart = -1;
- }
- }
- }
- if (subgroupStart !== -1 && combinators.length) {
- terms.splice(
- subgroupStart,
- i - subgroupStart,
- createGroup(terms.slice(subgroupStart, i), combinator)
- );
- }
- }
- return combinator;
- }
- function readImplicitGroup(tokenizer) {
- var terms = [];
- var combinators = {};
- var token;
- var prevToken = null;
- var prevTokenPos = tokenizer.pos;
- while (token = peek(tokenizer)) {
- if (token.type !== 'Spaces') {
- if (token.type === 'Combinator') {
- // check for combinator in group beginning and double combinator sequence
- if (prevToken === null || prevToken.type === 'Combinator') {
- tokenizer.pos = prevTokenPos;
- tokenizer.error('Unexpected combinator');
- }
- combinators[token.value] = true;
- } else if (prevToken !== null && prevToken.type !== 'Combinator') {
- combinators[' '] = true; // a b
- terms.push({
- type: 'Combinator',
- value: ' '
- });
- }
- terms.push(token);
- prevToken = token;
- prevTokenPos = tokenizer.pos;
- }
- }
- // check for combinator in group ending
- if (prevToken !== null && prevToken.type === 'Combinator') {
- tokenizer.pos -= prevTokenPos;
- tokenizer.error('Unexpected combinator');
- }
- return {
- type: 'Group',
- terms: terms,
- combinator: regroupTerms(terms, combinators) || ' ',
- disallowEmpty: false,
- explicit: false
- };
- }
- function readGroup(tokenizer) {
- var result;
- tokenizer.eat(LEFTSQUAREBRACKET);
- result = readImplicitGroup(tokenizer);
- tokenizer.eat(RIGHTSQUAREBRACKET);
- result.explicit = true;
- if (tokenizer.charCode() === EXCLAMATIONMARK) {
- tokenizer.pos++;
- result.disallowEmpty = true;
- }
- return result;
- }
- function peek(tokenizer) {
- var code = tokenizer.charCode();
- if (code < 128 && NAME_CHAR[code] === 1) {
- return readKeywordOrFunction(tokenizer);
- }
- switch (code) {
- case RIGHTSQUAREBRACKET:
- // don't eat, stop scan a group
- break;
- case LEFTSQUAREBRACKET:
- return maybeMultiplied(tokenizer, readGroup(tokenizer));
- case LESSTHANSIGN:
- return tokenizer.nextCharCode() === APOSTROPHE
- ? readProperty(tokenizer)
- : readType(tokenizer);
- case VERTICALLINE:
- return {
- type: 'Combinator',
- value: tokenizer.substringToPos(
- tokenizer.nextCharCode() === VERTICALLINE
- ? tokenizer.pos + 2
- : tokenizer.pos + 1
- )
- };
- case AMPERSAND:
- tokenizer.pos++;
- tokenizer.eat(AMPERSAND);
- return {
- type: 'Combinator',
- value: '&&'
- };
- case COMMA:
- tokenizer.pos++;
- return {
- type: 'Comma'
- };
- case APOSTROPHE:
- return maybeMultiplied(tokenizer, {
- type: 'String',
- value: scanString(tokenizer)
- });
- case SPACE$1:
- case TAB$1:
- case N$2:
- case R$1:
- case F$1:
- return {
- type: 'Spaces',
- value: scanSpaces(tokenizer)
- };
- case COMMERCIALAT:
- code = tokenizer.nextCharCode();
- if (code < 128 && NAME_CHAR[code] === 1) {
- tokenizer.pos++;
- return {
- type: 'AtKeyword',
- name: scanWord(tokenizer)
- };
- }
- return maybeToken(tokenizer);
- case ASTERISK:
- case PLUSSIGN$2:
- case QUESTIONMARK$1:
- case NUMBERSIGN:
- case EXCLAMATIONMARK:
- // prohibited tokens (used as a multiplier start)
- break;
- case LEFTCURLYBRACKET:
- // LEFTCURLYBRACKET is allowed since mdn/data uses it w/o quoting
- // check next char isn't a number, because it's likely a disjoined multiplier
- code = tokenizer.nextCharCode();
- if (code < 48 || code > 57) {
- return maybeToken(tokenizer);
- }
- break;
- default:
- return maybeToken(tokenizer);
- }
- }
- function parse(source) {
- var tokenizer = new tokenizer$1(source);
- var result = readImplicitGroup(tokenizer);
- if (tokenizer.pos !== source.length) {
- tokenizer.error('Unexpected input');
- }
- // reduce redundant groups with single group term
- if (result.terms.length === 1 && result.terms[0].type === 'Group') {
- result = result.terms[0];
- }
- return result;
- }
- // warm up parse to elimitate code branches that never execute
- // fix soft deoptimizations (insufficient type feedback)
- parse('[a&&<b>#|<\'c\'>*||e() f{2} /,(% g#{1,2} h{2,})]!');
- var parse_1 = parse;
- var noop$1 = function() {};
- function ensureFunction(value) {
- return typeof value === 'function' ? value : noop$1;
- }
- var walk = function(node, options, context) {
- function walk(node) {
- enter.call(context, node);
- switch (node.type) {
- case 'Group':
- node.terms.forEach(walk);
- break;
- case 'Multiplier':
- walk(node.term);
- break;
- case 'Type':
- case 'Property':
- case 'Keyword':
- case 'AtKeyword':
- case 'Function':
- case 'String':
- case 'Token':
- case 'Comma':
- break;
- default:
- throw new Error('Unknown type: ' + node.type);
- }
- leave.call(context, node);
- }
- var enter = noop$1;
- var leave = noop$1;
- if (typeof options === 'function') {
- enter = options;
- } else if (options) {
- enter = ensureFunction(options.enter);
- leave = ensureFunction(options.leave);
- }
- if (enter === noop$1 && leave === noop$1) {
- throw new Error('Neither `enter` nor `leave` walker handler is set or both aren\'t a function');
- }
- walk(node);
- };
- var tokenStream = new TokenStream_1();
- var astToTokens = {
- decorator: function(handlers) {
- var curNode = null;
- var prev = { len: 0, node: null };
- var nodes = [prev];
- var buffer = '';
- return {
- children: handlers.children,
- node: function(node) {
- var tmp = curNode;
- curNode = node;
- handlers.node.call(this, node);
- curNode = tmp;
- },
- chunk: function(chunk) {
- buffer += chunk;
- if (prev.node !== curNode) {
- nodes.push({
- len: chunk.length,
- node: curNode
- });
- } else {
- prev.len += chunk.length;
- }
- },
- result: function() {
- return prepareTokens(buffer, nodes);
- }
- };
- }
- };
- function prepareTokens(str, nodes) {
- var tokens = [];
- var nodesOffset = 0;
- var nodesIndex = 0;
- var currentNode = nodes ? nodes[nodesIndex].node : null;
- tokenizer(str, tokenStream);
- while (!tokenStream.eof) {
- if (nodes) {
- while (nodesIndex < nodes.length && nodesOffset + nodes[nodesIndex].len <= tokenStream.tokenStart) {
- nodesOffset += nodes[nodesIndex++].len;
- currentNode = nodes[nodesIndex].node;
- }
- }
- tokens.push({
- type: tokenStream.tokenType,
- value: tokenStream.getTokenValue(),
- index: tokenStream.tokenIndex, // TODO: remove it, temporary solution
- balance: tokenStream.balance[tokenStream.tokenIndex], // TODO: remove it, temporary solution
- node: currentNode
- });
- tokenStream.next();
- // console.log({ ...tokens[tokens.length - 1], node: undefined });
- }
- return tokens;
- }
- var prepareTokens_1 = function(value, syntax) {
- if (typeof value === 'string') {
- return prepareTokens(value, null);
- }
- return syntax.generate(value, astToTokens);
- };
- var MATCH = { type: 'Match' };
- var MISMATCH = { type: 'Mismatch' };
- var DISALLOW_EMPTY = { type: 'DisallowEmpty' };
- var LEFTPARENTHESIS$1 = 40; // (
- var RIGHTPARENTHESIS$1 = 41; // )
- function createCondition(match, thenBranch, elseBranch) {
- // reduce node count
- if (thenBranch === MATCH && elseBranch === MISMATCH) {
- return match;
- }
- if (match === MATCH && thenBranch === MATCH && elseBranch === MATCH) {
- return match;
- }
- if (match.type === 'If' && match.else === MISMATCH && thenBranch === MATCH) {
- thenBranch = match.then;
- match = match.match;
- }
- return {
- type: 'If',
- match: match,
- then: thenBranch,
- else: elseBranch
- };
- }
- function isFunctionType(name) {
- return (
- name.length > 2 &&
- name.charCodeAt(name.length - 2) === LEFTPARENTHESIS$1 &&
- name.charCodeAt(name.length - 1) === RIGHTPARENTHESIS$1
- );
- }
- function isEnumCapatible(term) {
- return (
- term.type === 'Keyword' ||
- term.type === 'AtKeyword' ||
- term.type === 'Function' ||
- term.type === 'Type' && isFunctionType(term.name)
- );
- }
- function buildGroupMatchGraph(combinator, terms, atLeastOneTermMatched) {
- switch (combinator) {
- case ' ':
- // Juxtaposing components means that all of them must occur, in the given order.
- //
- // a b c
- // =
- // match a
- // then match b
- // then match c
- // then MATCH
- // else MISMATCH
- // else MISMATCH
- // else MISMATCH
- var result = MATCH;
- for (var i = terms.length - 1; i >= 0; i--) {
- var term = terms[i];
- result = createCondition(
- term,
- result,
- MISMATCH
- );
- }
- return result;
- case '|':
- // A bar (|) separates two or more alternatives: exactly one of them must occur.
- //
- // a | b | c
- // =
- // match a
- // then MATCH
- // else match b
- // then MATCH
- // else match c
- // then MATCH
- // else MISMATCH
- var result = MISMATCH;
- var map = null;
- for (var i = terms.length - 1; i >= 0; i--) {
- var term = terms[i];
- // reduce sequence of keywords into a Enum
- if (isEnumCapatible(term)) {
- if (map === null && i > 0 && isEnumCapatible(terms[i - 1])) {
- map = Object.create(null);
- result = createCondition(
- {
- type: 'Enum',
- map: map
- },
- MATCH,
- result
- );
- }
- if (map !== null) {
- var key = (isFunctionType(term.name) ? term.name.slice(0, -1) : term.name).toLowerCase();
- if (key in map === false) {
- map[key] = term;
- continue;
- }
- }
- }
- map = null;
- // create a new conditonal node
- result = createCondition(
- term,
- MATCH,
- result
- );
- }
- return result;
- case '&&':
- // A double ampersand (&&) separates two or more components,
- // all of which must occur, in any order.
- // Use MatchOnce for groups with a large number of terms,
- // since &&-groups produces at least N!-node trees
- if (terms.length > 5) {
- return {
- type: 'MatchOnce',
- terms: terms,
- all: true
- };
- }
- // Use a combination tree for groups with small number of terms
- //
- // a && b && c
- // =
- // match a
- // then [b && c]
- // else match b
- // then [a && c]
- // else match c
- // then [a && b]
- // else MISMATCH
- //
- // a && b
- // =
- // match a
- // then match b
- // then MATCH
- // else MISMATCH
- // else match b
- // then match a
- // then MATCH
- // else MISMATCH
- // else MISMATCH
- var result = MISMATCH;
- for (var i = terms.length - 1; i >= 0; i--) {
- var term = terms[i];
- var thenClause;
- if (terms.length > 1) {
- thenClause = buildGroupMatchGraph(
- combinator,
- terms.filter(function(newGroupTerm) {
- return newGroupTerm !== term;
- }),
- false
- );
- } else {
- thenClause = MATCH;
- }
- result = createCondition(
- term,
- thenClause,
- result
- );
- }
- return result;
- case '||':
- // A double bar (||) separates two or more options:
- // one or more of them must occur, in any order.
- // Use MatchOnce for groups with a large number of terms,
- // since ||-groups produces at least N!-node trees
- if (terms.length > 5) {
- return {
- type: 'MatchOnce',
- terms: terms,
- all: false
- };
- }
- // Use a combination tree for groups with small number of terms
- //
- // a || b || c
- // =
- // match a
- // then [b || c]
- // else match b
- // then [a || c]
- // else match c
- // then [a || b]
- // else MISMATCH
- //
- // a || b
- // =
- // match a
- // then match b
- // then MATCH
- // else MATCH
- // else match b
- // then match a
- // then MATCH
- // else MATCH
- // else MISMATCH
- var result = atLeastOneTermMatched ? MATCH : MISMATCH;
- for (var i = terms.length - 1; i >= 0; i--) {
- var term = terms[i];
- var thenClause;
- if (terms.length > 1) {
- thenClause = buildGroupMatchGraph(
- combinator,
- terms.filter(function(newGroupTerm) {
- return newGroupTerm !== term;
- }),
- true
- );
- } else {
- thenClause = MATCH;
- }
- result = createCondition(
- term,
- thenClause,
- result
- );
- }
- return result;
- }
- }
- function buildMultiplierMatchGraph(node) {
- var result = MATCH;
- var matchTerm = buildMatchGraph(node.term);
- if (node.max === 0) {
- // disable repeating of empty match to prevent infinite loop
- matchTerm = createCondition(
- matchTerm,
- DISALLOW_EMPTY,
- MISMATCH
- );
- // an occurrence count is not limited, make a cycle;
- // to collect more terms on each following matching mismatch
- result = createCondition(
- matchTerm,
- null, // will be a loop
- MISMATCH
- );
- result.then = createCondition(
- MATCH,
- MATCH,
- result // make a loop
- );
- if (node.comma) {
- result.then.else = createCondition(
- { type: 'Comma', syntax: node },
- result,
- MISMATCH
- );
- }
- } else {
- // create a match node chain for [min .. max] interval with optional matches
- for (var i = node.min || 1; i <= node.max; i++) {
- if (node.comma && result !== MATCH) {
- result = createCondition(
- { type: 'Comma', syntax: node },
- result,
- MISMATCH
- );
- }
- result = createCondition(
- matchTerm,
- createCondition(
- MATCH,
- MATCH,
- result
- ),
- MISMATCH
- );
- }
- }
- if (node.min === 0) {
- // allow zero match
- result = createCondition(
- MATCH,
- MATCH,
- result
- );
- } else {
- // create a match node chain to collect [0 ... min - 1] required matches
- for (var i = 0; i < node.min - 1; i++) {
- if (node.comma && result !== MATCH) {
- result = createCondition(
- { type: 'Comma', syntax: node },
- result,
- MISMATCH
- );
- }
- result = createCondition(
- matchTerm,
- result,
- MISMATCH
- );
- }
- }
- return result;
- }
- function buildMatchGraph(node) {
- if (typeof node === 'function') {
- return {
- type: 'Generic',
- fn: node
- };
- }
- switch (node.type) {
- case 'Group':
- var result = buildGroupMatchGraph(
- node.combinator,
- node.terms.map(buildMatchGraph),
- false
- );
- if (node.disallowEmpty) {
- result = createCondition(
- result,
- DISALLOW_EMPTY,
- MISMATCH
- );
- }
- return result;
- case 'Multiplier':
- return buildMultiplierMatchGraph(node);
- case 'Type':
- case 'Property':
- return {
- type: node.type,
- name: node.name,
- syntax: node
- };
- case 'Keyword':
- return {
- type: node.type,
- name: node.name.toLowerCase(),
- syntax: node
- };
- case 'AtKeyword':
- return {
- type: node.type,
- name: '@' + node.name.toLowerCase(),
- syntax: node
- };
- case 'Function':
- return {
- type: node.type,
- name: node.name.toLowerCase() + '(',
- syntax: node
- };
- case 'String':
- // convert a one char length String to a Token
- if (node.value.length === 3) {
- return {
- type: 'Token',
- value: node.value.charAt(1),
- syntax: node
- };
- }
- // otherwise use it as is
- return {
- type: node.type,
- value: node.value.substr(1, node.value.length - 2).replace(/\\'/g, '\''),
- syntax: node
- };
- case 'Token':
- return {
- type: node.type,
- value: node.value,
- syntax: node
- };
- case 'Comma':
- return {
- type: node.type,
- syntax: node
- };
- default:
- throw new Error('Unknown node type:', node.type);
- }
- }
- var matchGraph = {
- MATCH: MATCH,
- MISMATCH: MISMATCH,
- DISALLOW_EMPTY: DISALLOW_EMPTY,
- buildMatchGraph: function(syntaxTree, ref) {
- if (typeof syntaxTree === 'string') {
- syntaxTree = parse_1(syntaxTree);
- }
- return {
- type: 'MatchGraph',
- match: buildMatchGraph(syntaxTree),
- syntax: ref || null,
- source: syntaxTree
- };
- }
- };
- var hasOwnProperty$1 = Object.prototype.hasOwnProperty;
- var MATCH$1 = matchGraph.MATCH;
- var MISMATCH$1 = matchGraph.MISMATCH;
- var DISALLOW_EMPTY$1 = matchGraph.DISALLOW_EMPTY;
- var TYPE$6 = _const.TYPE;
- var STUB = 0;
- var TOKEN = 1;
- var OPEN_SYNTAX = 2;
- var CLOSE_SYNTAX = 3;
- var EXIT_REASON_MATCH = 'Match';
- var EXIT_REASON_MISMATCH = 'Mismatch';
- var EXIT_REASON_ITERATION_LIMIT = 'Maximum iteration number exceeded (please fill an issue on https://github.com/csstree/csstree/issues)';
- var ITERATION_LIMIT = 15000;
- var totalIterationCount = 0;
- function reverseList(list) {
- var prev = null;
- var next = null;
- var item = list;
- while (item !== null) {
- next = item.prev;
- item.prev = prev;
- prev = item;
- item = next;
- }
- return prev;
- }
- function areStringsEqualCaseInsensitive(testStr, referenceStr) {
- if (testStr.length !== referenceStr.length) {
- return false;
- }
- for (var i = 0; i < testStr.length; i++) {
- var testCode = testStr.charCodeAt(i);
- var referenceCode = referenceStr.charCodeAt(i);
- // testCode.toLowerCase() for U+0041 LATIN CAPITAL LETTER A (A) .. U+005A LATIN CAPITAL LETTER Z (Z).
- if (testCode >= 0x0041 && testCode <= 0x005A) {
- testCode = testCode | 32;
- }
- if (testCode !== referenceCode) {
- return false;
- }
- }
- return true;
- }
- function isCommaContextStart(token) {
- if (token === null) {
- return true;
- }
- return (
- token.type === TYPE$6.Comma ||
- token.type === TYPE$6.Function ||
- token.type === TYPE$6.LeftParenthesis ||
- token.type === TYPE$6.LeftSquareBracket ||
- token.type === TYPE$6.LeftCurlyBracket ||
- token.type === TYPE$6.Delim
- );
- }
- function isCommaContextEnd(token) {
- if (token === null) {
- return true;
- }
- return (
- token.type === TYPE$6.RightParenthesis ||
- token.type === TYPE$6.RightSquareBracket ||
- token.type === TYPE$6.RightCurlyBracket ||
- token.type === TYPE$6.Delim
- );
- }
- function internalMatch(tokens, state, syntaxes) {
- function moveToNextToken() {
- do {
- tokenIndex++;
- token = tokenIndex < tokens.length ? tokens[tokenIndex] : null;
- } while (token !== null && (token.type === TYPE$6.WhiteSpace || token.type === TYPE$6.Comment));
- }
- function getNextToken(offset) {
- var nextIndex = tokenIndex + offset;
- return nextIndex < tokens.length ? tokens[nextIndex] : null;
- }
- function stateSnapshotFromSyntax(nextState, prev) {
- return {
- nextState: nextState,
- matchStack: matchStack,
- syntaxStack: syntaxStack,
- thenStack: thenStack,
- tokenIndex: tokenIndex,
- prev: prev
- };
- }
- function pushThenStack(nextState) {
- thenStack = {
- nextState: nextState,
- matchStack: matchStack,
- syntaxStack: syntaxStack,
- prev: thenStack
- };
- }
- function pushElseStack(nextState) {
- elseStack = stateSnapshotFromSyntax(nextState, elseStack);
- }
- function addTokenToMatch() {
- matchStack = {
- type: TOKEN,
- syntax: state.syntax,
- token: token,
- prev: matchStack
- };
- moveToNextToken();
- syntaxStash = null;
- if (tokenIndex > longestMatch) {
- longestMatch = tokenIndex;
- }
- }
- function openSyntax() {
- syntaxStack = {
- syntax: state.syntax,
- opts: state.syntax.opts || (syntaxStack !== null && syntaxStack.opts) || null,
- prev: syntaxStack
- };
- matchStack = {
- type: OPEN_SYNTAX,
- syntax: state.syntax,
- token: matchStack.token,
- prev: matchStack
- };
- }
- function closeSyntax() {
- if (matchStack.type === OPEN_SYNTAX) {
- matchStack = matchStack.prev;
- } else {
- matchStack = {
- type: CLOSE_SYNTAX,
- syntax: syntaxStack.syntax,
- token: matchStack.token,
- prev: matchStack
- };
- }
- syntaxStack = syntaxStack.prev;
- }
- var syntaxStack = null;
- var thenStack = null;
- var elseStack = null;
- // null – stashing allowed, nothing stashed
- // false – stashing disabled, nothing stashed
- // anithing else – fail stashable syntaxes, some syntax stashed
- var syntaxStash = null;
- var iterationCount = 0; // count iterations and prevent infinite loop
- var exitReason = null;
- var token = null;
- var tokenIndex = -1;
- var longestMatch = 0;
- var matchStack = {
- type: STUB,
- syntax: null,
- token: null,
- prev: null
- };
- moveToNextToken();
- while (exitReason === null && ++iterationCount < ITERATION_LIMIT) {
- // function mapList(list, fn) {
- // var result = [];
- // while (list) {
- // result.unshift(fn(list));
- // list = list.prev;
- // }
- // return result;
- // }
- // console.log('--\n',
- // '#' + iterationCount,
- // require('util').inspect({
- // match: mapList(matchStack, x => x.type === TOKEN ? x.token && x.token.value : x.syntax ? ({ [OPEN_SYNTAX]: '<', [CLOSE_SYNTAX]: '</' }[x.type] || x.type) + '!' + x.syntax.name : null),
- // token: token && token.value,
- // tokenIndex,
- // syntax: syntax.type + (syntax.id ? ' #' + syntax.id : '')
- // }, { depth: null })
- // );
- switch (state.type) {
- case 'Match':
- if (thenStack === null) {
- // turn to MISMATCH when some tokens left unmatched
- if (token !== null) {
- // doesn't mismatch if just one token left and it's an IE hack
- if (tokenIndex !== tokens.length - 1 || (token.value !== '\\0' && token.value !== '\\9')) {
- state = MISMATCH$1;
- break;
- }
- }
- // break the main loop, return a result - MATCH
- exitReason = EXIT_REASON_MATCH;
- break;
- }
- // go to next syntax (`then` branch)
- state = thenStack.nextState;
- // check match is not empty
- if (state === DISALLOW_EMPTY$1) {
- if (thenStack.matchStack === matchStack) {
- state = MISMATCH$1;
- break;
- } else {
- state = MATCH$1;
- }
- }
- // close syntax if needed
- while (thenStack.syntaxStack !== syntaxStack) {
- closeSyntax();
- }
- // pop stack
- thenStack = thenStack.prev;
- break;
- case 'Mismatch':
- // when some syntax is stashed
- if (syntaxStash !== null && syntaxStash !== false) {
- // there is no else branches or a branch reduce match stack
- if (elseStack === null || tokenIndex > elseStack.tokenIndex) {
- // restore state from the stash
- elseStack = syntaxStash;
- syntaxStash = false; // disable stashing
- }
- } else if (elseStack === null) {
- // no else branches -> break the main loop
- // return a result - MISMATCH
- exitReason = EXIT_REASON_MISMATCH;
- break;
- }
- // go to next syntax (`else` branch)
- state = elseStack.nextState;
- // restore all the rest stack states
- thenStack = elseStack.thenStack;
- syntaxStack = elseStack.syntaxStack;
- matchStack = elseStack.matchStack;
- tokenIndex = elseStack.tokenIndex;
- token = tokenIndex < tokens.length ? tokens[tokenIndex] : null;
- // pop stack
- elseStack = elseStack.prev;
- break;
- case 'MatchGraph':
- state = state.match;
- break;
- case 'If':
- // IMPORTANT: else stack push must go first,
- // since it stores the state of thenStack before changes
- if (state.else !== MISMATCH$1) {
- pushElseStack(state.else);
- }
- if (state.then !== MATCH$1) {
- pushThenStack(state.then);
- }
- state = state.match;
- break;
- case 'MatchOnce':
- state = {
- type: 'MatchOnceBuffer',
- syntax: state,
- index: 0,
- mask: 0
- };
- break;
- case 'MatchOnceBuffer':
- var terms = state.syntax.terms;
- if (state.index === terms.length) {
- // no matches at all or it's required all terms to be matched
- if (state.mask === 0 || state.syntax.all) {
- state = MISMATCH$1;
- break;
- }
- // a partial match is ok
- state = MATCH$1;
- break;
- }
- // all terms are matched
- if (state.mask === (1 << terms.length) - 1) {
- state = MATCH$1;
- break;
- }
- for (; state.index < terms.length; state.index++) {
- var matchFlag = 1 << state.index;
- if ((state.mask & matchFlag) === 0) {
- // IMPORTANT: else stack push must go first,
- // since it stores the state of thenStack before changes
- pushElseStack(state);
- pushThenStack({
- type: 'AddMatchOnce',
- syntax: state.syntax,
- mask: state.mask | matchFlag
- });
- // match
- state = terms[state.index++];
- break;
- }
- }
- break;
- case 'AddMatchOnce':
- state = {
- type: 'MatchOnceBuffer',
- syntax: state.syntax,
- index: 0,
- mask: state.mask
- };
- break;
- case 'Enum':
- if (token !== null) {
- var name = token.value.toLowerCase();
- // drop \0 and \9 hack from keyword name
- if (name.indexOf('\\') !== -1) {
- name = name.replace(/\\[09].*$/, '');
- }
- if (hasOwnProperty$1.call(state.map, name)) {
- state = state.map[name];
- break;
- }
- }
- state = MISMATCH$1;
- break;
- case 'Generic':
- var opts = syntaxStack !== null ? syntaxStack.opts : null;
- var lastTokenIndex = tokenIndex + Math.floor(state.fn(token, getNextToken, opts));
- if (!isNaN(lastTokenIndex) && lastTokenIndex > tokenIndex) {
- while (tokenIndex < lastTokenIndex) {
- addTokenToMatch();
- }
- state = MATCH$1;
- } else {
- state = MISMATCH$1;
- }
- break;
- case 'Type':
- case 'Property':
- var syntaxDict = state.type === 'Type' ? 'types' : 'properties';
- var dictSyntax = hasOwnProperty$1.call(syntaxes, syntaxDict) ? syntaxes[syntaxDict][state.name] : null;
- if (!dictSyntax || !dictSyntax.match) {
- throw new Error(
- 'Bad syntax reference: ' +
- (state.type === 'Type'
- ? '<' + state.name + '>'
- : '<\'' + state.name + '\'>')
- );
- }
- // stash a syntax for types with low priority
- if (syntaxStash !== false && token !== null && state.type === 'Type') {
- var lowPriorityMatching =
- // https://drafts.csswg.org/css-values-4/#custom-idents
- // When parsing positionally-ambiguous keywords in a property value, a <custom-ident> production
- // can only claim the keyword if no other unfulfilled production can claim it.
- (state.name === 'custom-ident' && token.type === TYPE$6.Ident) ||
- // https://drafts.csswg.org/css-values-4/#lengths
- // ... if a `0` could be parsed as either a <number> or a <length> in a property (such as line-height),
- // it must parse as a <number>
- (state.name === 'length' && token.value === '0');
- if (lowPriorityMatching) {
- if (syntaxStash === null) {
- syntaxStash = stateSnapshotFromSyntax(state, elseStack);
- }
- state = MISMATCH$1;
- break;
- }
- }
- openSyntax();
- state = dictSyntax.match;
- break;
- case 'Keyword':
- var name = state.name;
- if (token !== null) {
- var keywordName = token.value;
- // drop \0 and \9 hack from keyword name
- if (keywordName.indexOf('\\') !== -1) {
- keywordName = keywordName.replace(/\\[09].*$/, '');
- }
- if (areStringsEqualCaseInsensitive(keywordName, name)) {
- addTokenToMatch();
- state = MATCH$1;
- break;
- }
- }
- state = MISMATCH$1;
- break;
- case 'AtKeyword':
- case 'Function':
- if (token !== null && areStringsEqualCaseInsensitive(token.value, state.name)) {
- addTokenToMatch();
- state = MATCH$1;
- break;
- }
- state = MISMATCH$1;
- break;
- case 'Token':
- if (token !== null && token.value === state.value) {
- addTokenToMatch();
- state = MATCH$1;
- break;
- }
- state = MISMATCH$1;
- break;
- case 'Comma':
- if (token !== null && token.type === TYPE$6.Comma) {
- if (isCommaContextStart(matchStack.token)) {
- state = MISMATCH$1;
- } else {
- addTokenToMatch();
- state = isCommaContextEnd(token) ? MISMATCH$1 : MATCH$1;
- }
- } else {
- state = isCommaContextStart(matchStack.token) || isCommaContextEnd(token) ? MATCH$1 : MISMATCH$1;
- }
- break;
- case 'String':
- var string = '';
- for (var lastTokenIndex = tokenIndex; lastTokenIndex < tokens.length && string.length < state.value.length; lastTokenIndex++) {
- string += tokens[lastTokenIndex].value;
- }
- if (areStringsEqualCaseInsensitive(string, state.value)) {
- while (tokenIndex < lastTokenIndex) {
- addTokenToMatch();
- }
- state = MATCH$1;
- } else {
- state = MISMATCH$1;
- }
- break;
- default:
- throw new Error('Unknown node type: ' + state.type);
- }
- }
- totalIterationCount += iterationCount;
- switch (exitReason) {
- case null:
- console.warn('[csstree-match] BREAK after ' + ITERATION_LIMIT + ' iterations');
- exitReason = EXIT_REASON_ITERATION_LIMIT;
- matchStack = null;
- break;
- case EXIT_REASON_MATCH:
- while (syntaxStack !== null) {
- closeSyntax();
- }
- break;
- default:
- matchStack = null;
- }
- return {
- tokens: tokens,
- reason: exitReason,
- iterations: iterationCount,
- match: matchStack,
- longestMatch: longestMatch
- };
- }
- function matchAsList(tokens, matchGraph, syntaxes) {
- var matchResult = internalMatch(tokens, matchGraph, syntaxes || {});
- if (matchResult.match !== null) {
- var item = reverseList(matchResult.match).prev;
- matchResult.match = [];
- while (item !== null) {
- switch (item.type) {
- case STUB:
- break;
- case OPEN_SYNTAX:
- case CLOSE_SYNTAX:
- matchResult.match.push({
- type: item.type,
- syntax: item.syntax
- });
- break;
- default:
- matchResult.match.push({
- token: item.token.value,
- node: item.token.node
- });
- break;
- }
- item = item.prev;
- }
- }
- return matchResult;
- }
- function matchAsTree(tokens, matchGraph, syntaxes) {
- var matchResult = internalMatch(tokens, matchGraph, syntaxes || {});
- if (matchResult.match === null) {
- return matchResult;
- }
- var item = matchResult.match;
- var host = matchResult.match = {
- syntax: matchGraph.syntax || null,
- match: []
- };
- var hostStack = [host];
- // revert a list and start with 2nd item since 1st is a stub item
- item = reverseList(item).prev;
- // build a tree
- while (item !== null) {
- switch (item.type) {
- case OPEN_SYNTAX:
- host.match.push(host = {
- syntax: item.syntax,
- match: []
- });
- hostStack.push(host);
- break;
- case CLOSE_SYNTAX:
- hostStack.pop();
- host = hostStack[hostStack.length - 1];
- break;
- default:
- host.match.push({
- syntax: item.syntax || null,
- token: item.token.value,
- node: item.token.node
- });
- }
- item = item.prev;
- }
- return matchResult;
- }
- var match = {
- matchAsList: matchAsList,
- matchAsTree: matchAsTree,
- getTotalIterationCount: function() {
- return totalIterationCount;
- }
- };
- function getTrace(node) {
- function shouldPutToTrace(syntax) {
- if (syntax === null) {
- return false;
- }
- return (
- syntax.type === 'Type' ||
- syntax.type === 'Property' ||
- syntax.type === 'Keyword'
- );
- }
- function hasMatch(matchNode) {
- if (Array.isArray(matchNode.match)) {
- // use for-loop for better perfomance
- for (var i = 0; i < matchNode.match.length; i++) {
- if (hasMatch(matchNode.match[i])) {
- if (shouldPutToTrace(matchNode.syntax)) {
- result.unshift(matchNode.syntax);
- }
- return true;
- }
- }
- } else if (matchNode.node === node) {
- result = shouldPutToTrace(matchNode.syntax)
- ? [matchNode.syntax]
- : [];
- return true;
- }
- return false;
- }
- var result = null;
- if (this.matched !== null) {
- hasMatch(this.matched);
- }
- return result;
- }
- function testNode(match, node, fn) {
- var trace = getTrace.call(match, node);
- if (trace === null) {
- return false;
- }
- return trace.some(fn);
- }
- function isType(node, type) {
- return testNode(this, node, function(matchNode) {
- return matchNode.type === 'Type' && matchNode.name === type;
- });
- }
- function isProperty(node, property) {
- return testNode(this, node, function(matchNode) {
- return matchNode.type === 'Property' && matchNode.name === property;
- });
- }
- function isKeyword(node) {
- return testNode(this, node, function(matchNode) {
- return matchNode.type === 'Keyword';
- });
- }
- var trace = {
- getTrace: getTrace,
- isType: isType,
- isProperty: isProperty,
- isKeyword: isKeyword
- };
- function getFirstMatchNode(matchNode) {
- if ('node' in matchNode) {
- return matchNode.node;
- }
- return getFirstMatchNode(matchNode.match[0]);
- }
- function getLastMatchNode(matchNode) {
- if ('node' in matchNode) {
- return matchNode.node;
- }
- return getLastMatchNode(matchNode.match[matchNode.match.length - 1]);
- }
- function matchFragments(lexer, ast, match, type, name) {
- function findFragments(matchNode) {
- if (matchNode.syntax !== null &&
- matchNode.syntax.type === type &&
- matchNode.syntax.name === name) {
- var start = getFirstMatchNode(matchNode);
- var end = getLastMatchNode(matchNode);
- lexer.syntax.walk(ast, function(node, item, list) {
- if (node === start) {
- var nodes = new List_1();
- do {
- nodes.appendData(item.data);
- if (item.data === end) {
- break;
- }
- item = item.next;
- } while (item !== null);
- fragments.push({
- parent: list,
- nodes: nodes
- });
- }
- });
- }
- if (Array.isArray(matchNode.match)) {
- matchNode.match.forEach(findFragments);
- }
- }
- var fragments = [];
- if (match.matched !== null) {
- findFragments(match.matched);
- }
- return fragments;
- }
- var search = {
- matchFragments: matchFragments
- };
- var hasOwnProperty$2 = Object.prototype.hasOwnProperty;
- function isValidNumber(value) {
- // Number.isInteger(value) && value >= 0
- return (
- typeof value === 'number' &&
- isFinite(value) &&
- Math.floor(value) === value &&
- value >= 0
- );
- }
- function isValidLocation(loc) {
- return (
- Boolean(loc) &&
- isValidNumber(loc.offset) &&
- isValidNumber(loc.line) &&
- isValidNumber(loc.column)
- );
- }
- function createNodeStructureChecker(type, fields) {
- return function checkNode(node, warn) {
- if (!node || node.constructor !== Object) {
- return warn(node, 'Type of node should be an Object');
- }
- for (var key in node) {
- var valid = true;
- if (hasOwnProperty$2.call(node, key) === false) {
- continue;
- }
- if (key === 'type') {
- if (node.type !== type) {
- warn(node, 'Wrong node type `' + node.type + '`, expected `' + type + '`');
- }
- } else if (key === 'loc') {
- if (node.loc === null) {
- continue;
- } else if (node.loc && node.loc.constructor === Object) {
- if (typeof node.loc.source !== 'string') {
- key += '.source';
- } else if (!isValidLocation(node.loc.start)) {
- key += '.start';
- } else if (!isValidLocation(node.loc.end)) {
- key += '.end';
- } else {
- continue;
- }
- }
- valid = false;
- } else if (fields.hasOwnProperty(key)) {
- for (var i = 0, valid = false; !valid && i < fields[key].length; i++) {
- var fieldType = fields[key][i];
- switch (fieldType) {
- case String:
- valid = typeof node[key] === 'string';
- break;
- case Boolean:
- valid = typeof node[key] === 'boolean';
- break;
- case null:
- valid = node[key] === null;
- break;
- default:
- if (typeof fieldType === 'string') {
- valid = node[key] && node[key].type === fieldType;
- } else if (Array.isArray(fieldType)) {
- valid = node[key] instanceof List_1;
- }
- }
- }
- } else {
- warn(node, 'Unknown field `' + key + '` for ' + type + ' node type');
- }
- if (!valid) {
- warn(node, 'Bad value for `' + type + '.' + key + '`');
- }
- }
- for (var key in fields) {
- if (hasOwnProperty$2.call(fields, key) &&
- hasOwnProperty$2.call(node, key) === false) {
- warn(node, 'Field `' + type + '.' + key + '` is missed');
- }
- }
- };
- }
- function processStructure(name, nodeType) {
- var structure = nodeType.structure;
- var fields = {
- type: String,
- loc: true
- };
- var docs = {
- type: '"' + name + '"'
- };
- for (var key in structure) {
- if (hasOwnProperty$2.call(structure, key) === false) {
- continue;
- }
- var docsTypes = [];
- var fieldTypes = fields[key] = Array.isArray(structure[key])
- ? structure[key].slice()
- : [structure[key]];
- for (var i = 0; i < fieldTypes.length; i++) {
- var fieldType = fieldTypes[i];
- if (fieldType === String || fieldType === Boolean) {
- docsTypes.push(fieldType.name);
- } else if (fieldType === null) {
- docsTypes.push('null');
- } else if (typeof fieldType === 'string') {
- docsTypes.push('<' + fieldType + '>');
- } else if (Array.isArray(fieldType)) {
- docsTypes.push('List'); // TODO: use type enum
- } else {
- throw new Error('Wrong value `' + fieldType + '` in `' + name + '.' + key + '` structure definition');
- }
- }
- docs[key] = docsTypes.join(' | ');
- }
- return {
- docs: docs,
- check: createNodeStructureChecker(name, fields)
- };
- }
- var structure = {
- getStructureFromConfig: function(config) {
- var structure = {};
- if (config.node) {
- for (var name in config.node) {
- if (hasOwnProperty$2.call(config.node, name)) {
- var nodeType = config.node[name];
- if (nodeType.structure) {
- structure[name] = processStructure(name, nodeType);
- } else {
- throw new Error('Missed `structure` field in `' + name + '` node type definition');
- }
- }
- }
- }
- return structure;
- }
- };
- var SyntaxReferenceError$1 = error.SyntaxReferenceError;
- var MatchError$1 = error.MatchError;
- var buildMatchGraph$1 = matchGraph.buildMatchGraph;
- var matchAsTree$1 = match.matchAsTree;
- var getStructureFromConfig = structure.getStructureFromConfig;
- var cssWideKeywords$1 = buildMatchGraph$1('inherit | initial | unset');
- var cssWideKeywordsWithExpression = buildMatchGraph$1('inherit | initial | unset | <-ms-legacy-expression>');
- function dumpMapSyntax(map, compact, syntaxAsAst) {
- var result = {};
- for (var name in map) {
- if (map[name].syntax) {
- result[name] = syntaxAsAst
- ? map[name].syntax
- : generate_1(map[name].syntax, { compact: compact });
- }
- }
- return result;
- }
- function valueHasVar(tokens) {
- for (var i = 0; i < tokens.length; i++) {
- if (tokens[i].value.toLowerCase() === 'var(') {
- return true;
- }
- }
- return false;
- }
- function buildMatchResult(match, error, iterations) {
- return {
- matched: match,
- iterations: iterations,
- error: error,
- getTrace: trace.getTrace,
- isType: trace.isType,
- isProperty: trace.isProperty,
- isKeyword: trace.isKeyword
- };
- }
- function matchSyntax(lexer, syntax, value, useCommon) {
- var tokens = prepareTokens_1(value, lexer.syntax);
- var result;
- if (valueHasVar(tokens)) {
- return buildMatchResult(null, new Error('Matching for a tree with var() is not supported'));
- }
- if (useCommon) {
- result = matchAsTree$1(tokens, lexer.valueCommonSyntax, lexer);
- }
- if (!useCommon || !result.match) {
- result = matchAsTree$1(tokens, syntax.match, lexer);
- if (!result.match) {
- return buildMatchResult(
- null,
- new MatchError$1(result.reason, syntax.syntax, value, result),
- result.iterations
- );
- }
- }
- return buildMatchResult(result.match, null, result.iterations);
- }
- var Lexer = function(config, syntax, structure) {
- this.valueCommonSyntax = cssWideKeywords$1;
- this.syntax = syntax;
- this.generic = false;
- this.properties = {};
- this.types = {};
- this.structure = structure || getStructureFromConfig(config);
- if (config) {
- if (config.types) {
- for (var name in config.types) {
- this.addType_(name, config.types[name]);
- }
- }
- if (config.generic) {
- this.generic = true;
- for (var name in generic) {
- this.addType_(name, generic[name]);
- }
- }
- if (config.properties) {
- for (var name in config.properties) {
- this.addProperty_(name, config.properties[name]);
- }
- }
- }
- };
- Lexer.prototype = {
- structure: {},
- checkStructure: function(ast) {
- function collectWarning(node, message) {
- warns.push({
- node: node,
- message: message
- });
- }
- var structure = this.structure;
- var warns = [];
- this.syntax.walk(ast, function(node) {
- if (structure.hasOwnProperty(node.type)) {
- structure[node.type].check(node, collectWarning);
- } else {
- collectWarning(node, 'Unknown node type `' + node.type + '`');
- }
- });
- return warns.length ? warns : false;
- },
- createDescriptor: function(syntax, type, name) {
- var ref = {
- type: type,
- name: name
- };
- var descriptor = {
- type: type,
- name: name,
- syntax: null,
- match: null
- };
- if (typeof syntax === 'function') {
- descriptor.match = buildMatchGraph$1(syntax, ref);
- } else {
- if (typeof syntax === 'string') {
- // lazy parsing on first access
- Object.defineProperty(descriptor, 'syntax', {
- get: function() {
- Object.defineProperty(descriptor, 'syntax', {
- value: parse_1(syntax)
- });
- return descriptor.syntax;
- }
- });
- } else {
- descriptor.syntax = syntax;
- }
- // lazy graph build on first access
- Object.defineProperty(descriptor, 'match', {
- get: function() {
- Object.defineProperty(descriptor, 'match', {
- value: buildMatchGraph$1(descriptor.syntax, ref)
- });
- return descriptor.match;
- }
- });
- }
- return descriptor;
- },
- addProperty_: function(name, syntax) {
- this.properties[name] = this.createDescriptor(syntax, 'Property', name);
- },
- addType_: function(name, syntax) {
- this.types[name] = this.createDescriptor(syntax, 'Type', name);
- if (syntax === generic['-ms-legacy-expression']) {
- this.valueCommonSyntax = cssWideKeywordsWithExpression;
- }
- },
- matchDeclaration: function(node) {
- if (node.type !== 'Declaration') {
- return buildMatchResult(null, new Error('Not a Declaration node'));
- }
- return this.matchProperty(node.property, node.value);
- },
- matchProperty: function(propertyName, value) {
- var property = names.property(propertyName);
- // don't match syntax for a custom property
- if (property.custom) {
- return buildMatchResult(null, new Error('Lexer matching doesn\'t applicable for custom properties'));
- }
- var propertySyntax = property.vendor
- ? this.getProperty(property.name) || this.getProperty(property.basename)
- : this.getProperty(property.name);
- if (!propertySyntax) {
- return buildMatchResult(null, new SyntaxReferenceError$1('Unknown property', propertyName));
- }
- return matchSyntax(this, propertySyntax, value, true);
- },
- matchType: function(typeName, value) {
- var typeSyntax = this.getType(typeName);
- if (!typeSyntax) {
- return buildMatchResult(null, new SyntaxReferenceError$1('Unknown type', typeName));
- }
- return matchSyntax(this, typeSyntax, value, false);
- },
- match: function(syntax, value) {
- if (typeof syntax !== 'string' && (!syntax || !syntax.type)) {
- return buildMatchResult(null, new SyntaxReferenceError$1('Bad syntax'));
- }
- if (typeof syntax === 'string' || !syntax.match) {
- syntax = this.createDescriptor(syntax, 'Type', 'anonymous');
- }
- return matchSyntax(this, syntax, value, false);
- },
- findValueFragments: function(propertyName, value, type, name) {
- return search.matchFragments(this, value, this.matchProperty(propertyName, value), type, name);
- },
- findDeclarationValueFragments: function(declaration, type, name) {
- return search.matchFragments(this, declaration.value, this.matchDeclaration(declaration), type, name);
- },
- findAllFragments: function(ast, type, name) {
- var result = [];
- this.syntax.walk(ast, {
- visit: 'Declaration',
- enter: function(declaration) {
- result.push.apply(result, this.findDeclarationValueFragments(declaration, type, name));
- }.bind(this)
- });
- return result;
- },
- getProperty: function(name) {
- return this.properties.hasOwnProperty(name) ? this.properties[name] : null;
- },
- getType: function(name) {
- return this.types.hasOwnProperty(name) ? this.types[name] : null;
- },
- validate: function() {
- function validate(syntax, name, broken, descriptor) {
- if (broken.hasOwnProperty(name)) {
- return broken[name];
- }
- broken[name] = false;
- if (descriptor.syntax !== null) {
- walk(descriptor.syntax, function(node) {
- if (node.type !== 'Type' && node.type !== 'Property') {
- return;
- }
- var map = node.type === 'Type' ? syntax.types : syntax.properties;
- var brokenMap = node.type === 'Type' ? brokenTypes : brokenProperties;
- if (!map.hasOwnProperty(node.name) || validate(syntax, node.name, brokenMap, map[node.name])) {
- broken[name] = true;
- }
- }, this);
- }
- }
- var brokenTypes = {};
- var brokenProperties = {};
- for (var key in this.types) {
- validate(this, key, brokenTypes, this.types[key]);
- }
- for (var key in this.properties) {
- validate(this, key, brokenProperties, this.properties[key]);
- }
- brokenTypes = Object.keys(brokenTypes).filter(function(name) {
- return brokenTypes[name];
- });
- brokenProperties = Object.keys(brokenProperties).filter(function(name) {
- return brokenProperties[name];
- });
- if (brokenTypes.length || brokenProperties.length) {
- return {
- types: brokenTypes,
- properties: brokenProperties
- };
- }
- return null;
- },
- dump: function(syntaxAsAst, pretty) {
- return {
- generic: this.generic,
- types: dumpMapSyntax(this.types, !pretty, syntaxAsAst),
- properties: dumpMapSyntax(this.properties, !pretty, syntaxAsAst)
- };
- },
- toString: function() {
- return JSON.stringify(this.dump());
- }
- };
- var Lexer_1 = Lexer;
- var definitionSyntax = {
- SyntaxError: _SyntaxError$1,
- parse: parse_1,
- generate: generate_1,
- walk: walk
- };
- var isBOM$2 = tokenizer.isBOM;
- var N$3 = 10;
- var F$2 = 12;
- var R$2 = 13;
- function computeLinesAndColumns(host, source) {
- var sourceLength = source.length;
- var lines = adoptBuffer(host.lines, sourceLength); // +1
- var line = host.startLine;
- var columns = adoptBuffer(host.columns, sourceLength);
- var column = host.startColumn;
- var startOffset = source.length > 0 ? isBOM$2(source.charCodeAt(0)) : 0;
- for (var i = startOffset; i < sourceLength; i++) { // -1
- var code = source.charCodeAt(i);
- lines[i] = line;
- columns[i] = column++;
- if (code === N$3 || code === R$2 || code === F$2) {
- if (code === R$2 && i + 1 < sourceLength && source.charCodeAt(i + 1) === N$3) {
- i++;
- lines[i] = line;
- columns[i] = column;
- }
- line++;
- column = 1;
- }
- }
- lines[i] = line;
- columns[i] = column;
- host.lines = lines;
- host.columns = columns;
- }
- var OffsetToLocation = function() {
- this.lines = null;
- this.columns = null;
- this.linesAndColumnsComputed = false;
- };
- OffsetToLocation.prototype = {
- setSource: function(source, startOffset, startLine, startColumn) {
- this.source = source;
- this.startOffset = typeof startOffset === 'undefined' ? 0 : startOffset;
- this.startLine = typeof startLine === 'undefined' ? 1 : startLine;
- this.startColumn = typeof startColumn === 'undefined' ? 1 : startColumn;
- this.linesAndColumnsComputed = false;
- },
- ensureLinesAndColumnsComputed: function() {
- if (!this.linesAndColumnsComputed) {
- computeLinesAndColumns(this, this.source);
- this.linesAndColumnsComputed = true;
- }
- },
- getLocation: function(offset, filename) {
- this.ensureLinesAndColumnsComputed();
- return {
- source: filename,
- offset: this.startOffset + offset,
- line: this.lines[offset],
- column: this.columns[offset]
- };
- },
- getLocationRange: function(start, end, filename) {
- this.ensureLinesAndColumnsComputed();
- return {
- source: filename,
- start: {
- offset: this.startOffset + start,
- line: this.lines[start],
- column: this.columns[start]
- },
- end: {
- offset: this.startOffset + end,
- line: this.lines[end],
- column: this.columns[end]
- }
- };
- }
- };
- var OffsetToLocation_1 = OffsetToLocation;
- var TYPE$7 = tokenizer.TYPE;
- var WHITESPACE$2 = TYPE$7.WhiteSpace;
- var COMMENT$2 = TYPE$7.Comment;
- var sequence = function readSequence(recognizer) {
- var children = this.createList();
- var child = null;
- var context = {
- recognizer: recognizer,
- space: null,
- ignoreWS: false,
- ignoreWSAfter: false
- };
- this.scanner.skipSC();
- while (!this.scanner.eof) {
- switch (this.scanner.tokenType) {
- case COMMENT$2:
- this.scanner.next();
- continue;
- case WHITESPACE$2:
- if (context.ignoreWS) {
- this.scanner.next();
- } else {
- context.space = this.WhiteSpace();
- }
- continue;
- }
- child = recognizer.getNode.call(this, context);
- if (child === undefined) {
- break;
- }
- if (context.space !== null) {
- children.push(context.space);
- context.space = null;
- }
- children.push(child);
- if (context.ignoreWSAfter) {
- context.ignoreWSAfter = false;
- context.ignoreWS = true;
- } else {
- context.ignoreWS = false;
- }
- }
- return children;
- };
- var findWhiteSpaceStart$1 = utils.findWhiteSpaceStart;
- var noop$2 = function() {};
- var TYPE$8 = _const.TYPE;
- var NAME$2 = _const.NAME;
- var WHITESPACE$3 = TYPE$8.WhiteSpace;
- var IDENT$2 = TYPE$8.Ident;
- var FUNCTION = TYPE$8.Function;
- var URL = TYPE$8.Url;
- var HASH = TYPE$8.Hash;
- var PERCENTAGE = TYPE$8.Percentage;
- var NUMBER$2 = TYPE$8.Number;
- var NUMBERSIGN$1 = 0x0023; // U+0023 NUMBER SIGN (#)
- var NULL = 0;
- function createParseContext(name) {
- return function() {
- return this[name]();
- };
- }
- function processConfig(config) {
- var parserConfig = {
- context: {},
- scope: {},
- atrule: {},
- pseudo: {}
- };
- if (config.parseContext) {
- for (var name in config.parseContext) {
- switch (typeof config.parseContext[name]) {
- case 'function':
- parserConfig.context[name] = config.parseContext[name];
- break;
- case 'string':
- parserConfig.context[name] = createParseContext(config.parseContext[name]);
- break;
- }
- }
- }
- if (config.scope) {
- for (var name in config.scope) {
- parserConfig.scope[name] = config.scope[name];
- }
- }
- if (config.atrule) {
- for (var name in config.atrule) {
- var atrule = config.atrule[name];
- if (atrule.parse) {
- parserConfig.atrule[name] = atrule.parse;
- }
- }
- }
- if (config.pseudo) {
- for (var name in config.pseudo) {
- var pseudo = config.pseudo[name];
- if (pseudo.parse) {
- parserConfig.pseudo[name] = pseudo.parse;
- }
- }
- }
- if (config.node) {
- for (var name in config.node) {
- parserConfig[name] = config.node[name].parse;
- }
- }
- return parserConfig;
- }
- var create = function createParser(config) {
- var parser = {
- scanner: new TokenStream_1(),
- locationMap: new OffsetToLocation_1(),
- filename: '<unknown>',
- needPositions: false,
- onParseError: noop$2,
- onParseErrorThrow: false,
- parseAtrulePrelude: true,
- parseRulePrelude: true,
- parseValue: true,
- parseCustomProperty: false,
- readSequence: sequence,
- createList: function() {
- return new List_1();
- },
- createSingleNodeList: function(node) {
- return new List_1().appendData(node);
- },
- getFirstListNode: function(list) {
- return list && list.first();
- },
- getLastListNode: function(list) {
- return list.last();
- },
- parseWithFallback: function(consumer, fallback) {
- var startToken = this.scanner.tokenIndex;
- try {
- return consumer.call(this);
- } catch (e) {
- if (this.onParseErrorThrow) {
- throw e;
- }
- var fallbackNode = fallback.call(this, startToken);
- this.onParseErrorThrow = true;
- this.onParseError(e, fallbackNode);
- this.onParseErrorThrow = false;
- return fallbackNode;
- }
- },
- lookupNonWSType: function(offset) {
- do {
- var type = this.scanner.lookupType(offset++);
- if (type !== WHITESPACE$3) {
- return type;
- }
- } while (type !== NULL);
- return NULL;
- },
- eat: function(tokenType) {
- if (this.scanner.tokenType !== tokenType) {
- var offset = this.scanner.tokenStart;
- var message = NAME$2[tokenType] + ' is expected';
- // tweak message and offset
- switch (tokenType) {
- case IDENT$2:
- // when identifier is expected but there is a function or url
- if (this.scanner.tokenType === FUNCTION || this.scanner.tokenType === URL) {
- offset = this.scanner.tokenEnd - 1;
- message = 'Identifier is expected but function found';
- } else {
- message = 'Identifier is expected';
- }
- break;
- case HASH:
- if (this.scanner.isDelim(NUMBERSIGN$1)) {
- this.scanner.next();
- offset++;
- message = 'Name is expected';
- }
- break;
- case PERCENTAGE:
- if (this.scanner.tokenType === NUMBER$2) {
- offset = this.scanner.tokenEnd;
- message = 'Percent sign is expected';
- }
- break;
- default:
- // when test type is part of another token show error for current position + 1
- // e.g. eat(HYPHENMINUS) will fail on "-foo", but pointing on "-" is odd
- if (this.scanner.source.charCodeAt(this.scanner.tokenStart) === tokenType) {
- offset = offset + 1;
- }
- }
- this.error(message, offset);
- }
- this.scanner.next();
- },
- consume: function(tokenType) {
- var value = this.scanner.getTokenValue();
- this.eat(tokenType);
- return value;
- },
- consumeFunctionName: function() {
- var name = this.scanner.source.substring(this.scanner.tokenStart, this.scanner.tokenEnd - 1);
- this.eat(FUNCTION);
- return name;
- },
- getLocation: function(start, end) {
- if (this.needPositions) {
- return this.locationMap.getLocationRange(
- start,
- end,
- this.filename
- );
- }
- return null;
- },
- getLocationFromList: function(list) {
- if (this.needPositions) {
- var head = this.getFirstListNode(list);
- var tail = this.getLastListNode(list);
- return this.locationMap.getLocationRange(
- head !== null ? head.loc.start.offset - this.locationMap.startOffset : this.scanner.tokenStart,
- tail !== null ? tail.loc.end.offset - this.locationMap.startOffset : this.scanner.tokenStart,
- this.filename
- );
- }
- return null;
- },
- error: function(message, offset) {
- var location = typeof offset !== 'undefined' && offset < this.scanner.source.length
- ? this.locationMap.getLocation(offset)
- : this.scanner.eof
- ? this.locationMap.getLocation(findWhiteSpaceStart$1(this.scanner.source, this.scanner.source.length - 1))
- : this.locationMap.getLocation(this.scanner.tokenStart);
- throw new _SyntaxError(
- message || 'Unexpected input',
- this.scanner.source,
- location.offset,
- location.line,
- location.column
- );
- }
- };
- config = processConfig(config || {});
- for (var key in config) {
- parser[key] = config[key];
- }
- return function(source, options) {
- options = options || {};
- var context = options.context || 'default';
- var ast;
- tokenizer(source, parser.scanner);
- parser.locationMap.setSource(
- source,
- options.offset,
- options.line,
- options.column
- );
- parser.filename = options.filename || '<unknown>';
- parser.needPositions = Boolean(options.positions);
- parser.onParseError = typeof options.onParseError === 'function' ? options.onParseError : noop$2;
- parser.onParseErrorThrow = false;
- parser.parseAtrulePrelude = 'parseAtrulePrelude' in options ? Boolean(options.parseAtrulePrelude) : true;
- parser.parseRulePrelude = 'parseRulePrelude' in options ? Boolean(options.parseRulePrelude) : true;
- parser.parseValue = 'parseValue' in options ? Boolean(options.parseValue) : true;
- parser.parseCustomProperty = 'parseCustomProperty' in options ? Boolean(options.parseCustomProperty) : false;
- if (!parser.context.hasOwnProperty(context)) {
- throw new Error('Unknown context `' + context + '`');
- }
- ast = parser.context[context].call(parser, options);
- if (!parser.scanner.eof) {
- parser.error();
- }
- return ast;
- };
- };
- /* -*- Mode: js; js-indent-level: 2; -*- */
- /*
- * Copyright 2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE or:
- * http://opensource.org/licenses/BSD-3-Clause
- */
- var intToCharMap = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'.split('');
- /**
- * Encode an integer in the range of 0 to 63 to a single base 64 digit.
- */
- var encode = function (number) {
- if (0 <= number && number < intToCharMap.length) {
- return intToCharMap[number];
- }
- throw new TypeError("Must be between 0 and 63: " + number);
- };
- /**
- * Decode a single base 64 character code digit to an integer. Returns -1 on
- * failure.
- */
- var decode = function (charCode) {
- var bigA = 65; // 'A'
- var bigZ = 90; // 'Z'
- var littleA = 97; // 'a'
- var littleZ = 122; // 'z'
- var zero = 48; // '0'
- var nine = 57; // '9'
- var plus = 43; // '+'
- var slash = 47; // '/'
- var littleOffset = 26;
- var numberOffset = 52;
- // 0 - 25: ABCDEFGHIJKLMNOPQRSTUVWXYZ
- if (bigA <= charCode && charCode <= bigZ) {
- return (charCode - bigA);
- }
- // 26 - 51: abcdefghijklmnopqrstuvwxyz
- if (littleA <= charCode && charCode <= littleZ) {
- return (charCode - littleA + littleOffset);
- }
- // 52 - 61: 0123456789
- if (zero <= charCode && charCode <= nine) {
- return (charCode - zero + numberOffset);
- }
- // 62: +
- if (charCode == plus) {
- return 62;
- }
- // 63: /
- if (charCode == slash) {
- return 63;
- }
- // Invalid base64 digit.
- return -1;
- };
- var base64 = {
- encode: encode,
- decode: decode
- };
- /* -*- Mode: js; js-indent-level: 2; -*- */
- /*
- * Copyright 2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE or:
- * http://opensource.org/licenses/BSD-3-Clause
- *
- * Based on the Base 64 VLQ implementation in Closure Compiler:
- * https://code.google.com/p/closure-compiler/source/browse/trunk/src/com/google/debugging/sourcemap/Base64VLQ.java
- *
- * Copyright 2011 The Closure Compiler Authors. All rights reserved.
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
- // A single base 64 digit can contain 6 bits of data. For the base 64 variable
- // length quantities we use in the source map spec, the first bit is the sign,
- // the next four bits are the actual value, and the 6th bit is the
- // continuation bit. The continuation bit tells us whether there are more
- // digits in this value following this digit.
- //
- // Continuation
- // | Sign
- // | |
- // V V
- // 101011
- var VLQ_BASE_SHIFT = 5;
- // binary: 100000
- var VLQ_BASE = 1 << VLQ_BASE_SHIFT;
- // binary: 011111
- var VLQ_BASE_MASK = VLQ_BASE - 1;
- // binary: 100000
- var VLQ_CONTINUATION_BIT = VLQ_BASE;
- /**
- * Converts from a two-complement value to a value where the sign bit is
- * placed in the least significant bit. For example, as decimals:
- * 1 becomes 2 (10 binary), -1 becomes 3 (11 binary)
- * 2 becomes 4 (100 binary), -2 becomes 5 (101 binary)
- */
- function toVLQSigned(aValue) {
- return aValue < 0
- ? ((-aValue) << 1) + 1
- : (aValue << 1) + 0;
- }
- /**
- * Converts to a two-complement value from a value where the sign bit is
- * placed in the least significant bit. For example, as decimals:
- * 2 (10 binary) becomes 1, 3 (11 binary) becomes -1
- * 4 (100 binary) becomes 2, 5 (101 binary) becomes -2
- */
- function fromVLQSigned(aValue) {
- var isNegative = (aValue & 1) === 1;
- var shifted = aValue >> 1;
- return isNegative
- ? -shifted
- : shifted;
- }
- /**
- * Returns the base 64 VLQ encoded value.
- */
- var encode$1 = function base64VLQ_encode(aValue) {
- var encoded = "";
- var digit;
- var vlq = toVLQSigned(aValue);
- do {
- digit = vlq & VLQ_BASE_MASK;
- vlq >>>= VLQ_BASE_SHIFT;
- if (vlq > 0) {
- // There are still more digits in this value, so we must make sure the
- // continuation bit is marked.
- digit |= VLQ_CONTINUATION_BIT;
- }
- encoded += base64.encode(digit);
- } while (vlq > 0);
- return encoded;
- };
- /**
- * Decodes the next base 64 VLQ value from the given string and returns the
- * value and the rest of the string via the out parameter.
- */
- var decode$1 = function base64VLQ_decode(aStr, aIndex, aOutParam) {
- var strLen = aStr.length;
- var result = 0;
- var shift = 0;
- var continuation, digit;
- do {
- if (aIndex >= strLen) {
- throw new Error("Expected more digits in base 64 VLQ value.");
- }
- digit = base64.decode(aStr.charCodeAt(aIndex++));
- if (digit === -1) {
- throw new Error("Invalid base64 digit: " + aStr.charAt(aIndex - 1));
- }
- continuation = !!(digit & VLQ_CONTINUATION_BIT);
- digit &= VLQ_BASE_MASK;
- result = result + (digit << shift);
- shift += VLQ_BASE_SHIFT;
- } while (continuation);
- aOutParam.value = fromVLQSigned(result);
- aOutParam.rest = aIndex;
- };
- var base64Vlq = {
- encode: encode$1,
- decode: decode$1
- };
- function createCommonjsModule(fn, module) {
- return module = { exports: {} }, fn(module, module.exports), module.exports;
- }
- function getCjsExportFromNamespace (n) {
- return n && n['default'] || n;
- }
- var util = createCommonjsModule(function (module, exports) {
- /* -*- Mode: js; js-indent-level: 2; -*- */
- /*
- * Copyright 2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE or:
- * http://opensource.org/licenses/BSD-3-Clause
- */
- /**
- * This is a helper function for getting values from parameter/options
- * objects.
- *
- * @param args The object we are extracting values from
- * @param name The name of the property we are getting.
- * @param defaultValue An optional value to return if the property is missing
- * from the object. If this is not specified and the property is missing, an
- * error will be thrown.
- */
- function getArg(aArgs, aName, aDefaultValue) {
- if (aName in aArgs) {
- return aArgs[aName];
- } else if (arguments.length === 3) {
- return aDefaultValue;
- } else {
- throw new Error('"' + aName + '" is a required argument.');
- }
- }
- exports.getArg = getArg;
- var urlRegexp = /^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.-]*)(?::(\d+))?(.*)$/;
- var dataUrlRegexp = /^data:.+\,.+$/;
- function urlParse(aUrl) {
- var match = aUrl.match(urlRegexp);
- if (!match) {
- return null;
- }
- return {
- scheme: match[1],
- auth: match[2],
- host: match[3],
- port: match[4],
- path: match[5]
- };
- }
- exports.urlParse = urlParse;
- function urlGenerate(aParsedUrl) {
- var url = '';
- if (aParsedUrl.scheme) {
- url += aParsedUrl.scheme + ':';
- }
- url += '//';
- if (aParsedUrl.auth) {
- url += aParsedUrl.auth + '@';
- }
- if (aParsedUrl.host) {
- url += aParsedUrl.host;
- }
- if (aParsedUrl.port) {
- url += ":" + aParsedUrl.port;
- }
- if (aParsedUrl.path) {
- url += aParsedUrl.path;
- }
- return url;
- }
- exports.urlGenerate = urlGenerate;
- /**
- * Normalizes a path, or the path portion of a URL:
- *
- * - Replaces consecutive slashes with one slash.
- * - Removes unnecessary '.' parts.
- * - Removes unnecessary '<dir>/..' parts.
- *
- * Based on code in the Node.js 'path' core module.
- *
- * @param aPath The path or url to normalize.
- */
- function normalize(aPath) {
- var path = aPath;
- var url = urlParse(aPath);
- if (url) {
- if (!url.path) {
- return aPath;
- }
- path = url.path;
- }
- var isAbsolute = exports.isAbsolute(path);
- var parts = path.split(/\/+/);
- for (var part, up = 0, i = parts.length - 1; i >= 0; i--) {
- part = parts[i];
- if (part === '.') {
- parts.splice(i, 1);
- } else if (part === '..') {
- up++;
- } else if (up > 0) {
- if (part === '') {
- // The first part is blank if the path is absolute. Trying to go
- // above the root is a no-op. Therefore we can remove all '..' parts
- // directly after the root.
- parts.splice(i + 1, up);
- up = 0;
- } else {
- parts.splice(i, 2);
- up--;
- }
- }
- }
- path = parts.join('/');
- if (path === '') {
- path = isAbsolute ? '/' : '.';
- }
- if (url) {
- url.path = path;
- return urlGenerate(url);
- }
- return path;
- }
- exports.normalize = normalize;
- /**
- * Joins two paths/URLs.
- *
- * @param aRoot The root path or URL.
- * @param aPath The path or URL to be joined with the root.
- *
- * - If aPath is a URL or a data URI, aPath is returned, unless aPath is a
- * scheme-relative URL: Then the scheme of aRoot, if any, is prepended
- * first.
- * - Otherwise aPath is a path. If aRoot is a URL, then its path portion
- * is updated with the result and aRoot is returned. Otherwise the result
- * is returned.
- * - If aPath is absolute, the result is aPath.
- * - Otherwise the two paths are joined with a slash.
- * - Joining for example 'http://' and 'www.example.com' is also supported.
- */
- function join(aRoot, aPath) {
- if (aRoot === "") {
- aRoot = ".";
- }
- if (aPath === "") {
- aPath = ".";
- }
- var aPathUrl = urlParse(aPath);
- var aRootUrl = urlParse(aRoot);
- if (aRootUrl) {
- aRoot = aRootUrl.path || '/';
- }
- // `join(foo, '//www.example.org')`
- if (aPathUrl && !aPathUrl.scheme) {
- if (aRootUrl) {
- aPathUrl.scheme = aRootUrl.scheme;
- }
- return urlGenerate(aPathUrl);
- }
- if (aPathUrl || aPath.match(dataUrlRegexp)) {
- return aPath;
- }
- // `join('http://', 'www.example.com')`
- if (aRootUrl && !aRootUrl.host && !aRootUrl.path) {
- aRootUrl.host = aPath;
- return urlGenerate(aRootUrl);
- }
- var joined = aPath.charAt(0) === '/'
- ? aPath
- : normalize(aRoot.replace(/\/+$/, '') + '/' + aPath);
- if (aRootUrl) {
- aRootUrl.path = joined;
- return urlGenerate(aRootUrl);
- }
- return joined;
- }
- exports.join = join;
- exports.isAbsolute = function (aPath) {
- return aPath.charAt(0) === '/' || urlRegexp.test(aPath);
- };
- /**
- * Make a path relative to a URL or another path.
- *
- * @param aRoot The root path or URL.
- * @param aPath The path or URL to be made relative to aRoot.
- */
- function relative(aRoot, aPath) {
- if (aRoot === "") {
- aRoot = ".";
- }
- aRoot = aRoot.replace(/\/$/, '');
- // It is possible for the path to be above the root. In this case, simply
- // checking whether the root is a prefix of the path won't work. Instead, we
- // need to remove components from the root one by one, until either we find
- // a prefix that fits, or we run out of components to remove.
- var level = 0;
- while (aPath.indexOf(aRoot + '/') !== 0) {
- var index = aRoot.lastIndexOf("/");
- if (index < 0) {
- return aPath;
- }
- // If the only part of the root that is left is the scheme (i.e. http://,
- // file:///, etc.), one or more slashes (/), or simply nothing at all, we
- // have exhausted all components, so the path is not relative to the root.
- aRoot = aRoot.slice(0, index);
- if (aRoot.match(/^([^\/]+:\/)?\/*$/)) {
- return aPath;
- }
- ++level;
- }
- // Make sure we add a "../" for each component we removed from the root.
- return Array(level + 1).join("../") + aPath.substr(aRoot.length + 1);
- }
- exports.relative = relative;
- var supportsNullProto = (function () {
- var obj = Object.create(null);
- return !('__proto__' in obj);
- }());
- function identity (s) {
- return s;
- }
- /**
- * Because behavior goes wacky when you set `__proto__` on objects, we
- * have to prefix all the strings in our set with an arbitrary character.
- *
- * See https://github.com/mozilla/source-map/pull/31 and
- * https://github.com/mozilla/source-map/issues/30
- *
- * @param String aStr
- */
- function toSetString(aStr) {
- if (isProtoString(aStr)) {
- return '$' + aStr;
- }
- return aStr;
- }
- exports.toSetString = supportsNullProto ? identity : toSetString;
- function fromSetString(aStr) {
- if (isProtoString(aStr)) {
- return aStr.slice(1);
- }
- return aStr;
- }
- exports.fromSetString = supportsNullProto ? identity : fromSetString;
- function isProtoString(s) {
- if (!s) {
- return false;
- }
- var length = s.length;
- if (length < 9 /* "__proto__".length */) {
- return false;
- }
- if (s.charCodeAt(length - 1) !== 95 /* '_' */ ||
- s.charCodeAt(length - 2) !== 95 /* '_' */ ||
- s.charCodeAt(length - 3) !== 111 /* 'o' */ ||
- s.charCodeAt(length - 4) !== 116 /* 't' */ ||
- s.charCodeAt(length - 5) !== 111 /* 'o' */ ||
- s.charCodeAt(length - 6) !== 114 /* 'r' */ ||
- s.charCodeAt(length - 7) !== 112 /* 'p' */ ||
- s.charCodeAt(length - 8) !== 95 /* '_' */ ||
- s.charCodeAt(length - 9) !== 95 /* '_' */) {
- return false;
- }
- for (var i = length - 10; i >= 0; i--) {
- if (s.charCodeAt(i) !== 36 /* '$' */) {
- return false;
- }
- }
- return true;
- }
- /**
- * Comparator between two mappings where the original positions are compared.
- *
- * Optionally pass in `true` as `onlyCompareGenerated` to consider two
- * mappings with the same original source/line/column, but different generated
- * line and column the same. Useful when searching for a mapping with a
- * stubbed out mapping.
- */
- function compareByOriginalPositions(mappingA, mappingB, onlyCompareOriginal) {
- var cmp = strcmp(mappingA.source, mappingB.source);
- if (cmp !== 0) {
- return cmp;
- }
- cmp = mappingA.originalLine - mappingB.originalLine;
- if (cmp !== 0) {
- return cmp;
- }
- cmp = mappingA.originalColumn - mappingB.originalColumn;
- if (cmp !== 0 || onlyCompareOriginal) {
- return cmp;
- }
- cmp = mappingA.generatedColumn - mappingB.generatedColumn;
- if (cmp !== 0) {
- return cmp;
- }
- cmp = mappingA.generatedLine - mappingB.generatedLine;
- if (cmp !== 0) {
- return cmp;
- }
- return strcmp(mappingA.name, mappingB.name);
- }
- exports.compareByOriginalPositions = compareByOriginalPositions;
- /**
- * Comparator between two mappings with deflated source and name indices where
- * the generated positions are compared.
- *
- * Optionally pass in `true` as `onlyCompareGenerated` to consider two
- * mappings with the same generated line and column, but different
- * source/name/original line and column the same. Useful when searching for a
- * mapping with a stubbed out mapping.
- */
- function compareByGeneratedPositionsDeflated(mappingA, mappingB, onlyCompareGenerated) {
- var cmp = mappingA.generatedLine - mappingB.generatedLine;
- if (cmp !== 0) {
- return cmp;
- }
- cmp = mappingA.generatedColumn - mappingB.generatedColumn;
- if (cmp !== 0 || onlyCompareGenerated) {
- return cmp;
- }
- cmp = strcmp(mappingA.source, mappingB.source);
- if (cmp !== 0) {
- return cmp;
- }
- cmp = mappingA.originalLine - mappingB.originalLine;
- if (cmp !== 0) {
- return cmp;
- }
- cmp = mappingA.originalColumn - mappingB.originalColumn;
- if (cmp !== 0) {
- return cmp;
- }
- return strcmp(mappingA.name, mappingB.name);
- }
- exports.compareByGeneratedPositionsDeflated = compareByGeneratedPositionsDeflated;
- function strcmp(aStr1, aStr2) {
- if (aStr1 === aStr2) {
- return 0;
- }
- if (aStr1 === null) {
- return 1; // aStr2 !== null
- }
- if (aStr2 === null) {
- return -1; // aStr1 !== null
- }
- if (aStr1 > aStr2) {
- return 1;
- }
- return -1;
- }
- /**
- * Comparator between two mappings with inflated source and name strings where
- * the generated positions are compared.
- */
- function compareByGeneratedPositionsInflated(mappingA, mappingB) {
- var cmp = mappingA.generatedLine - mappingB.generatedLine;
- if (cmp !== 0) {
- return cmp;
- }
- cmp = mappingA.generatedColumn - mappingB.generatedColumn;
- if (cmp !== 0) {
- return cmp;
- }
- cmp = strcmp(mappingA.source, mappingB.source);
- if (cmp !== 0) {
- return cmp;
- }
- cmp = mappingA.originalLine - mappingB.originalLine;
- if (cmp !== 0) {
- return cmp;
- }
- cmp = mappingA.originalColumn - mappingB.originalColumn;
- if (cmp !== 0) {
- return cmp;
- }
- return strcmp(mappingA.name, mappingB.name);
- }
- exports.compareByGeneratedPositionsInflated = compareByGeneratedPositionsInflated;
- /**
- * Strip any JSON XSSI avoidance prefix from the string (as documented
- * in the source maps specification), and then parse the string as
- * JSON.
- */
- function parseSourceMapInput(str) {
- return JSON.parse(str.replace(/^\)]}'[^\n]*\n/, ''));
- }
- exports.parseSourceMapInput = parseSourceMapInput;
- /**
- * Compute the URL of a source given the the source root, the source's
- * URL, and the source map's URL.
- */
- function computeSourceURL(sourceRoot, sourceURL, sourceMapURL) {
- sourceURL = sourceURL || '';
- if (sourceRoot) {
- // This follows what Chrome does.
- if (sourceRoot[sourceRoot.length - 1] !== '/' && sourceURL[0] !== '/') {
- sourceRoot += '/';
- }
- // The spec says:
- // Line 4: An optional source root, useful for relocating source
- // files on a server or removing repeated values in the
- // “sources” entry. This value is prepended to the individual
- // entries in the “source” field.
- sourceURL = sourceRoot + sourceURL;
- }
- // Historically, SourceMapConsumer did not take the sourceMapURL as
- // a parameter. This mode is still somewhat supported, which is why
- // this code block is conditional. However, it's preferable to pass
- // the source map URL to SourceMapConsumer, so that this function
- // can implement the source URL resolution algorithm as outlined in
- // the spec. This block is basically the equivalent of:
- // new URL(sourceURL, sourceMapURL).toString()
- // ... except it avoids using URL, which wasn't available in the
- // older releases of node still supported by this library.
- //
- // The spec says:
- // If the sources are not absolute URLs after prepending of the
- // “sourceRoot”, the sources are resolved relative to the
- // SourceMap (like resolving script src in a html document).
- if (sourceMapURL) {
- var parsed = urlParse(sourceMapURL);
- if (!parsed) {
- throw new Error("sourceMapURL could not be parsed");
- }
- if (parsed.path) {
- // Strip the last path component, but keep the "/".
- var index = parsed.path.lastIndexOf('/');
- if (index >= 0) {
- parsed.path = parsed.path.substring(0, index + 1);
- }
- }
- sourceURL = join(urlGenerate(parsed), sourceURL);
- }
- return normalize(sourceURL);
- }
- exports.computeSourceURL = computeSourceURL;
- });
- var util_1 = util.getArg;
- var util_2 = util.urlParse;
- var util_3 = util.urlGenerate;
- var util_4 = util.normalize;
- var util_5 = util.join;
- var util_6 = util.isAbsolute;
- var util_7 = util.relative;
- var util_8 = util.toSetString;
- var util_9 = util.fromSetString;
- var util_10 = util.compareByOriginalPositions;
- var util_11 = util.compareByGeneratedPositionsDeflated;
- var util_12 = util.compareByGeneratedPositionsInflated;
- var util_13 = util.parseSourceMapInput;
- var util_14 = util.computeSourceURL;
- /* -*- Mode: js; js-indent-level: 2; -*- */
- /*
- * Copyright 2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE or:
- * http://opensource.org/licenses/BSD-3-Clause
- */
- var has = Object.prototype.hasOwnProperty;
- var hasNativeMap = typeof Map !== "undefined";
- /**
- * A data structure which is a combination of an array and a set. Adding a new
- * member is O(1), testing for membership is O(1), and finding the index of an
- * element is O(1). Removing elements from the set is not supported. Only
- * strings are supported for membership.
- */
- function ArraySet() {
- this._array = [];
- this._set = hasNativeMap ? new Map() : Object.create(null);
- }
- /**
- * Static method for creating ArraySet instances from an existing array.
- */
- ArraySet.fromArray = function ArraySet_fromArray(aArray, aAllowDuplicates) {
- var set = new ArraySet();
- for (var i = 0, len = aArray.length; i < len; i++) {
- set.add(aArray[i], aAllowDuplicates);
- }
- return set;
- };
- /**
- * Return how many unique items are in this ArraySet. If duplicates have been
- * added, than those do not count towards the size.
- *
- * @returns Number
- */
- ArraySet.prototype.size = function ArraySet_size() {
- return hasNativeMap ? this._set.size : Object.getOwnPropertyNames(this._set).length;
- };
- /**
- * Add the given string to this set.
- *
- * @param String aStr
- */
- ArraySet.prototype.add = function ArraySet_add(aStr, aAllowDuplicates) {
- var sStr = hasNativeMap ? aStr : util.toSetString(aStr);
- var isDuplicate = hasNativeMap ? this.has(aStr) : has.call(this._set, sStr);
- var idx = this._array.length;
- if (!isDuplicate || aAllowDuplicates) {
- this._array.push(aStr);
- }
- if (!isDuplicate) {
- if (hasNativeMap) {
- this._set.set(aStr, idx);
- } else {
- this._set[sStr] = idx;
- }
- }
- };
- /**
- * Is the given string a member of this set?
- *
- * @param String aStr
- */
- ArraySet.prototype.has = function ArraySet_has(aStr) {
- if (hasNativeMap) {
- return this._set.has(aStr);
- } else {
- var sStr = util.toSetString(aStr);
- return has.call(this._set, sStr);
- }
- };
- /**
- * What is the index of the given string in the array?
- *
- * @param String aStr
- */
- ArraySet.prototype.indexOf = function ArraySet_indexOf(aStr) {
- if (hasNativeMap) {
- var idx = this._set.get(aStr);
- if (idx >= 0) {
- return idx;
- }
- } else {
- var sStr = util.toSetString(aStr);
- if (has.call(this._set, sStr)) {
- return this._set[sStr];
- }
- }
- throw new Error('"' + aStr + '" is not in the set.');
- };
- /**
- * What is the element at the given index?
- *
- * @param Number aIdx
- */
- ArraySet.prototype.at = function ArraySet_at(aIdx) {
- if (aIdx >= 0 && aIdx < this._array.length) {
- return this._array[aIdx];
- }
- throw new Error('No element indexed by ' + aIdx);
- };
- /**
- * Returns the array representation of this set (which has the proper indices
- * indicated by indexOf). Note that this is a copy of the internal array used
- * for storing the members so that no one can mess with internal state.
- */
- ArraySet.prototype.toArray = function ArraySet_toArray() {
- return this._array.slice();
- };
- var ArraySet_1 = ArraySet;
- var arraySet = {
- ArraySet: ArraySet_1
- };
- /* -*- Mode: js; js-indent-level: 2; -*- */
- /*
- * Copyright 2014 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE or:
- * http://opensource.org/licenses/BSD-3-Clause
- */
- /**
- * Determine whether mappingB is after mappingA with respect to generated
- * position.
- */
- function generatedPositionAfter(mappingA, mappingB) {
- // Optimized for most common case
- var lineA = mappingA.generatedLine;
- var lineB = mappingB.generatedLine;
- var columnA = mappingA.generatedColumn;
- var columnB = mappingB.generatedColumn;
- return lineB > lineA || lineB == lineA && columnB >= columnA ||
- util.compareByGeneratedPositionsInflated(mappingA, mappingB) <= 0;
- }
- /**
- * A data structure to provide a sorted view of accumulated mappings in a
- * performance conscious manner. It trades a neglibable overhead in general
- * case for a large speedup in case of mappings being added in order.
- */
- function MappingList() {
- this._array = [];
- this._sorted = true;
- // Serves as infimum
- this._last = {generatedLine: -1, generatedColumn: 0};
- }
- /**
- * Iterate through internal items. This method takes the same arguments that
- * `Array.prototype.forEach` takes.
- *
- * NOTE: The order of the mappings is NOT guaranteed.
- */
- MappingList.prototype.unsortedForEach =
- function MappingList_forEach(aCallback, aThisArg) {
- this._array.forEach(aCallback, aThisArg);
- };
- /**
- * Add the given source mapping.
- *
- * @param Object aMapping
- */
- MappingList.prototype.add = function MappingList_add(aMapping) {
- if (generatedPositionAfter(this._last, aMapping)) {
- this._last = aMapping;
- this._array.push(aMapping);
- } else {
- this._sorted = false;
- this._array.push(aMapping);
- }
- };
- /**
- * Returns the flat, sorted array of mappings. The mappings are sorted by
- * generated position.
- *
- * WARNING: This method returns internal data without copying, for
- * performance. The return value must NOT be mutated, and should be treated as
- * an immutable borrow. If you want to take ownership, you must make your own
- * copy.
- */
- MappingList.prototype.toArray = function MappingList_toArray() {
- if (!this._sorted) {
- this._array.sort(util.compareByGeneratedPositionsInflated);
- this._sorted = true;
- }
- return this._array;
- };
- var MappingList_1 = MappingList;
- var mappingList = {
- MappingList: MappingList_1
- };
- /* -*- Mode: js; js-indent-level: 2; -*- */
- /*
- * Copyright 2011 Mozilla Foundation and contributors
- * Licensed under the New BSD license. See LICENSE or:
- * http://opensource.org/licenses/BSD-3-Clause
- */
- var ArraySet$1 = arraySet.ArraySet;
- var MappingList$1 = mappingList.MappingList;
- /**
- * An instance of the SourceMapGenerator represents a source map which is
- * being built incrementally. You may pass an object with the following
- * properties:
- *
- * - file: The filename of the generated source.
- * - sourceRoot: A root for all relative URLs in this source map.
- */
- function SourceMapGenerator(aArgs) {
- if (!aArgs) {
- aArgs = {};
- }
- this._file = util.getArg(aArgs, 'file', null);
- this._sourceRoot = util.getArg(aArgs, 'sourceRoot', null);
- this._skipValidation = util.getArg(aArgs, 'skipValidation', false);
- this._sources = new ArraySet$1();
- this._names = new ArraySet$1();
- this._mappings = new MappingList$1();
- this._sourcesContents = null;
- }
- SourceMapGenerator.prototype._version = 3;
- /**
- * Creates a new SourceMapGenerator based on a SourceMapConsumer
- *
- * @param aSourceMapConsumer The SourceMap.
- */
- SourceMapGenerator.fromSourceMap =
- function SourceMapGenerator_fromSourceMap(aSourceMapConsumer) {
- var sourceRoot = aSourceMapConsumer.sourceRoot;
- var generator = new SourceMapGenerator({
- file: aSourceMapConsumer.file,
- sourceRoot: sourceRoot
- });
- aSourceMapConsumer.eachMapping(function (mapping) {
- var newMapping = {
- generated: {
- line: mapping.generatedLine,
- column: mapping.generatedColumn
- }
- };
- if (mapping.source != null) {
- newMapping.source = mapping.source;
- if (sourceRoot != null) {
- newMapping.source = util.relative(sourceRoot, newMapping.source);
- }
- newMapping.original = {
- line: mapping.originalLine,
- column: mapping.originalColumn
- };
- if (mapping.name != null) {
- newMapping.name = mapping.name;
- }
- }
- generator.addMapping(newMapping);
- });
- aSourceMapConsumer.sources.forEach(function (sourceFile) {
- var sourceRelative = sourceFile;
- if (sourceRoot !== null) {
- sourceRelative = util.relative(sourceRoot, sourceFile);
- }
- if (!generator._sources.has(sourceRelative)) {
- generator._sources.add(sourceRelative);
- }
- var content = aSourceMapConsumer.sourceContentFor(sourceFile);
- if (content != null) {
- generator.setSourceContent(sourceFile, content);
- }
- });
- return generator;
- };
- /**
- * Add a single mapping from original source line and column to the generated
- * source's line and column for this source map being created. The mapping
- * object should have the following properties:
- *
- * - generated: An object with the generated line and column positions.
- * - original: An object with the original line and column positions.
- * - source: The original source file (relative to the sourceRoot).
- * - name: An optional original token name for this mapping.
- */
- SourceMapGenerator.prototype.addMapping =
- function SourceMapGenerator_addMapping(aArgs) {
- var generated = util.getArg(aArgs, 'generated');
- var original = util.getArg(aArgs, 'original', null);
- var source = util.getArg(aArgs, 'source', null);
- var name = util.getArg(aArgs, 'name', null);
- if (!this._skipValidation) {
- this._validateMapping(generated, original, source, name);
- }
- if (source != null) {
- source = String(source);
- if (!this._sources.has(source)) {
- this._sources.add(source);
- }
- }
- if (name != null) {
- name = String(name);
- if (!this._names.has(name)) {
- this._names.add(name);
- }
- }
- this._mappings.add({
- generatedLine: generated.line,
- generatedColumn: generated.column,
- originalLine: original != null && original.line,
- originalColumn: original != null && original.column,
- source: source,
- name: name
- });
- };
- /**
- * Set the source content for a source file.
- */
- SourceMapGenerator.prototype.setSourceContent =
- function SourceMapGenerator_setSourceContent(aSourceFile, aSourceContent) {
- var source = aSourceFile;
- if (this._sourceRoot != null) {
- source = util.relative(this._sourceRoot, source);
- }
- if (aSourceContent != null) {
- // Add the source content to the _sourcesContents map.
- // Create a new _sourcesContents map if the property is null.
- if (!this._sourcesContents) {
- this._sourcesContents = Object.create(null);
- }
- this._sourcesContents[util.toSetString(source)] = aSourceContent;
- } else if (this._sourcesContents) {
- // Remove the source file from the _sourcesContents map.
- // If the _sourcesContents map is empty, set the property to null.
- delete this._sourcesContents[util.toSetString(source)];
- if (Object.keys(this._sourcesContents).length === 0) {
- this._sourcesContents = null;
- }
- }
- };
- /**
- * Applies the mappings of a sub-source-map for a specific source file to the
- * source map being generated. Each mapping to the supplied source file is
- * rewritten using the supplied source map. Note: The resolution for the
- * resulting mappings is the minimium of this map and the supplied map.
- *
- * @param aSourceMapConsumer The source map to be applied.
- * @param aSourceFile Optional. The filename of the source file.
- * If omitted, SourceMapConsumer's file property will be used.
- * @param aSourceMapPath Optional. The dirname of the path to the source map
- * to be applied. If relative, it is relative to the SourceMapConsumer.
- * This parameter is needed when the two source maps aren't in the same
- * directory, and the source map to be applied contains relative source
- * paths. If so, those relative source paths need to be rewritten
- * relative to the SourceMapGenerator.
- */
- SourceMapGenerator.prototype.applySourceMap =
- function SourceMapGenerator_applySourceMap(aSourceMapConsumer, aSourceFile, aSourceMapPath) {
- var sourceFile = aSourceFile;
- // If aSourceFile is omitted, we will use the file property of the SourceMap
- if (aSourceFile == null) {
- if (aSourceMapConsumer.file == null) {
- throw new Error(
- 'SourceMapGenerator.prototype.applySourceMap requires either an explicit source file, ' +
- 'or the source map\'s "file" property. Both were omitted.'
- );
- }
- sourceFile = aSourceMapConsumer.file;
- }
- var sourceRoot = this._sourceRoot;
- // Make "sourceFile" relative if an absolute Url is passed.
- if (sourceRoot != null) {
- sourceFile = util.relative(sourceRoot, sourceFile);
- }
- // Applying the SourceMap can add and remove items from the sources and
- // the names array.
- var newSources = new ArraySet$1();
- var newNames = new ArraySet$1();
- // Find mappings for the "sourceFile"
- this._mappings.unsortedForEach(function (mapping) {
- if (mapping.source === sourceFile && mapping.originalLine != null) {
- // Check if it can be mapped by the source map, then update the mapping.
- var original = aSourceMapConsumer.originalPositionFor({
- line: mapping.originalLine,
- column: mapping.originalColumn
- });
- if (original.source != null) {
- // Copy mapping
- mapping.source = original.source;
- if (aSourceMapPath != null) {
- mapping.source = util.join(aSourceMapPath, mapping.source);
- }
- if (sourceRoot != null) {
- mapping.source = util.relative(sourceRoot, mapping.source);
- }
- mapping.originalLine = original.line;
- mapping.originalColumn = original.column;
- if (original.name != null) {
- mapping.name = original.name;
- }
- }
- }
- var source = mapping.source;
- if (source != null && !newSources.has(source)) {
- newSources.add(source);
- }
- var name = mapping.name;
- if (name != null && !newNames.has(name)) {
- newNames.add(name);
- }
- }, this);
- this._sources = newSources;
- this._names = newNames;
- // Copy sourcesContents of applied map.
- aSourceMapConsumer.sources.forEach(function (sourceFile) {
- var content = aSourceMapConsumer.sourceContentFor(sourceFile);
- if (content != null) {
- if (aSourceMapPath != null) {
- sourceFile = util.join(aSourceMapPath, sourceFile);
- }
- if (sourceRoot != null) {
- sourceFile = util.relative(sourceRoot, sourceFile);
- }
- this.setSourceContent(sourceFile, content);
- }
- }, this);
- };
- /**
- * A mapping can have one of the three levels of data:
- *
- * 1. Just the generated position.
- * 2. The Generated position, original position, and original source.
- * 3. Generated and original position, original source, as well as a name
- * token.
- *
- * To maintain consistency, we validate that any new mapping being added falls
- * in to one of these categories.
- */
- SourceMapGenerator.prototype._validateMapping =
- function SourceMapGenerator_validateMapping(aGenerated, aOriginal, aSource,
- aName) {
- // When aOriginal is truthy but has empty values for .line and .column,
- // it is most likely a programmer error. In this case we throw a very
- // specific error message to try to guide them the right way.
- // For example: https://github.com/Polymer/polymer-bundler/pull/519
- if (aOriginal && typeof aOriginal.line !== 'number' && typeof aOriginal.column !== 'number') {
- throw new Error(
- 'original.line and original.column are not numbers -- you probably meant to omit ' +
- 'the original mapping entirely and only map the generated position. If so, pass ' +
- 'null for the original mapping instead of an object with empty or null values.'
- );
- }
- if (aGenerated && 'line' in aGenerated && 'column' in aGenerated
- && aGenerated.line > 0 && aGenerated.column >= 0
- && !aOriginal && !aSource && !aName) {
- // Case 1.
- return;
- }
- else if (aGenerated && 'line' in aGenerated && 'column' in aGenerated
- && aOriginal && 'line' in aOriginal && 'column' in aOriginal
- && aGenerated.line > 0 && aGenerated.column >= 0
- && aOriginal.line > 0 && aOriginal.column >= 0
- && aSource) {
- // Cases 2 and 3.
- return;
- }
- else {
- throw new Error('Invalid mapping: ' + JSON.stringify({
- generated: aGenerated,
- source: aSource,
- original: aOriginal,
- name: aName
- }));
- }
- };
- /**
- * Serialize the accumulated mappings in to the stream of base 64 VLQs
- * specified by the source map format.
- */
- SourceMapGenerator.prototype._serializeMappings =
- function SourceMapGenerator_serializeMappings() {
- var previousGeneratedColumn = 0;
- var previousGeneratedLine = 1;
- var previousOriginalColumn = 0;
- var previousOriginalLine = 0;
- var previousName = 0;
- var previousSource = 0;
- var result = '';
- var next;
- var mapping;
- var nameIdx;
- var sourceIdx;
- var mappings = this._mappings.toArray();
- for (var i = 0, len = mappings.length; i < len; i++) {
- mapping = mappings[i];
- next = '';
- if (mapping.generatedLine !== previousGeneratedLine) {
- previousGeneratedColumn = 0;
- while (mapping.generatedLine !== previousGeneratedLine) {
- next += ';';
- previousGeneratedLine++;
- }
- }
- else {
- if (i > 0) {
- if (!util.compareByGeneratedPositionsInflated(mapping, mappings[i - 1])) {
- continue;
- }
- next += ',';
- }
- }
- next += base64Vlq.encode(mapping.generatedColumn
- - previousGeneratedColumn);
- previousGeneratedColumn = mapping.generatedColumn;
- if (mapping.source != null) {
- sourceIdx = this._sources.indexOf(mapping.source);
- next += base64Vlq.encode(sourceIdx - previousSource);
- previousSource = sourceIdx;
- // lines are stored 0-based in SourceMap spec version 3
- next += base64Vlq.encode(mapping.originalLine - 1
- - previousOriginalLine);
- previousOriginalLine = mapping.originalLine - 1;
- next += base64Vlq.encode(mapping.originalColumn
- - previousOriginalColumn);
- previousOriginalColumn = mapping.originalColumn;
- if (mapping.name != null) {
- nameIdx = this._names.indexOf(mapping.name);
- next += base64Vlq.encode(nameIdx - previousName);
- previousName = nameIdx;
- }
- }
- result += next;
- }
- return result;
- };
- SourceMapGenerator.prototype._generateSourcesContent =
- function SourceMapGenerator_generateSourcesContent(aSources, aSourceRoot) {
- return aSources.map(function (source) {
- if (!this._sourcesContents) {
- return null;
- }
- if (aSourceRoot != null) {
- source = util.relative(aSourceRoot, source);
- }
- var key = util.toSetString(source);
- return Object.prototype.hasOwnProperty.call(this._sourcesContents, key)
- ? this._sourcesContents[key]
- : null;
- }, this);
- };
- /**
- * Externalize the source map.
- */
- SourceMapGenerator.prototype.toJSON =
- function SourceMapGenerator_toJSON() {
- var map = {
- version: this._version,
- sources: this._sources.toArray(),
- names: this._names.toArray(),
- mappings: this._serializeMappings()
- };
- if (this._file != null) {
- map.file = this._file;
- }
- if (this._sourceRoot != null) {
- map.sourceRoot = this._sourceRoot;
- }
- if (this._sourcesContents) {
- map.sourcesContent = this._generateSourcesContent(map.sources, map.sourceRoot);
- }
- return map;
- };
- /**
- * Render the source map being generated to a string.
- */
- SourceMapGenerator.prototype.toString =
- function SourceMapGenerator_toString() {
- return JSON.stringify(this.toJSON());
- };
- var SourceMapGenerator_1 = SourceMapGenerator;
- var sourceMapGenerator = {
- SourceMapGenerator: SourceMapGenerator_1
- };
- var SourceMapGenerator$1 = sourceMapGenerator.SourceMapGenerator;
- var trackNodes = {
- Atrule: true,
- Selector: true,
- Declaration: true
- };
- var sourceMap = function generateSourceMap(handlers) {
- var map = new SourceMapGenerator$1();
- var line = 1;
- var column = 0;
- var generated = {
- line: 1,
- column: 0
- };
- var original = {
- line: 0, // should be zero to add first mapping
- column: 0
- };
- var sourceMappingActive = false;
- var activatedGenerated = {
- line: 1,
- column: 0
- };
- var activatedMapping = {
- generated: activatedGenerated
- };
- var handlersNode = handlers.node;
- handlers.node = function(node) {
- if (node.loc && node.loc.start && trackNodes.hasOwnProperty(node.type)) {
- var nodeLine = node.loc.start.line;
- var nodeColumn = node.loc.start.column - 1;
- if (original.line !== nodeLine ||
- original.column !== nodeColumn) {
- original.line = nodeLine;
- original.column = nodeColumn;
- generated.line = line;
- generated.column = column;
- if (sourceMappingActive) {
- sourceMappingActive = false;
- if (generated.line !== activatedGenerated.line ||
- generated.column !== activatedGenerated.column) {
- map.addMapping(activatedMapping);
- }
- }
- sourceMappingActive = true;
- map.addMapping({
- source: node.loc.source,
- original: original,
- generated: generated
- });
- }
- }
- handlersNode.call(this, node);
- if (sourceMappingActive && trackNodes.hasOwnProperty(node.type)) {
- activatedGenerated.line = line;
- activatedGenerated.column = column;
- }
- };
- var handlersChunk = handlers.chunk;
- handlers.chunk = function(chunk) {
- for (var i = 0; i < chunk.length; i++) {
- if (chunk.charCodeAt(i) === 10) { // \n
- line++;
- column = 0;
- } else {
- column++;
- }
- }
- handlersChunk(chunk);
- };
- var handlersResult = handlers.result;
- handlers.result = function() {
- if (sourceMappingActive) {
- map.addMapping(activatedMapping);
- }
- return {
- css: handlersResult(),
- map: map
- };
- };
- return handlers;
- };
- var hasOwnProperty$3 = Object.prototype.hasOwnProperty;
- function processChildren(node, delimeter) {
- var list = node.children;
- var prev = null;
- if (typeof delimeter !== 'function') {
- list.forEach(this.node, this);
- } else {
- list.forEach(function(node) {
- if (prev !== null) {
- delimeter.call(this, prev);
- }
- this.node(node);
- prev = node;
- }, this);
- }
- }
- var create$1 = function createGenerator(config) {
- function processNode(node) {
- if (hasOwnProperty$3.call(types, node.type)) {
- types[node.type].call(this, node);
- } else {
- throw new Error('Unknown node type: ' + node.type);
- }
- }
- var types = {};
- if (config.node) {
- for (var name in config.node) {
- types[name] = config.node[name].generate;
- }
- }
- return function(node, options) {
- var buffer = '';
- var handlers = {
- children: processChildren,
- node: processNode,
- chunk: function(chunk) {
- buffer += chunk;
- },
- result: function() {
- return buffer;
- }
- };
- if (options) {
- if (typeof options.decorator === 'function') {
- handlers = options.decorator(handlers);
- }
- if (options.sourceMap) {
- handlers = sourceMap(handlers);
- }
- }
- handlers.node(node);
- return handlers.result();
- };
- };
- var create$2 = function createConvertors(walk) {
- return {
- fromPlainObject: function(ast) {
- walk(ast, {
- enter: function(node) {
- if (node.children && node.children instanceof List_1 === false) {
- node.children = new List_1().fromArray(node.children);
- }
- }
- });
- return ast;
- },
- toPlainObject: function(ast) {
- walk(ast, {
- leave: function(node) {
- if (node.children && node.children instanceof List_1) {
- node.children = node.children.toArray();
- }
- }
- });
- return ast;
- }
- };
- };
- var hasOwnProperty$4 = Object.prototype.hasOwnProperty;
- var noop$3 = function() {};
- function ensureFunction$1(value) {
- return typeof value === 'function' ? value : noop$3;
- }
- function invokeForType(fn, type) {
- return function(node, item, list) {
- if (node.type === type) {
- fn.call(this, node, item, list);
- }
- };
- }
- function getWalkersFromStructure(name, nodeType) {
- var structure = nodeType.structure;
- var walkers = [];
- for (var key in structure) {
- if (hasOwnProperty$4.call(structure, key) === false) {
- continue;
- }
- var fieldTypes = structure[key];
- var walker = {
- name: key,
- type: false,
- nullable: false
- };
- if (!Array.isArray(structure[key])) {
- fieldTypes = [structure[key]];
- }
- for (var i = 0; i < fieldTypes.length; i++) {
- var fieldType = fieldTypes[i];
- if (fieldType === null) {
- walker.nullable = true;
- } else if (typeof fieldType === 'string') {
- walker.type = 'node';
- } else if (Array.isArray(fieldType)) {
- walker.type = 'list';
- }
- }
- if (walker.type) {
- walkers.push(walker);
- }
- }
- if (walkers.length) {
- return {
- context: nodeType.walkContext,
- fields: walkers
- };
- }
- return null;
- }
- function getTypesFromConfig(config) {
- var types = {};
- for (var name in config.node) {
- if (hasOwnProperty$4.call(config.node, name)) {
- var nodeType = config.node[name];
- if (!nodeType.structure) {
- throw new Error('Missed `structure` field in `' + name + '` node type definition');
- }
- types[name] = getWalkersFromStructure(name, nodeType);
- }
- }
- return types;
- }
- function createTypeIterator(config, reverse) {
- var fields = config.fields.slice();
- var contextName = config.context;
- var useContext = typeof contextName === 'string';
- if (reverse) {
- fields.reverse();
- }
- return function(node, context, walk) {
- var prevContextValue;
- if (useContext) {
- prevContextValue = context[contextName];
- context[contextName] = node;
- }
- for (var i = 0; i < fields.length; i++) {
- var field = fields[i];
- var ref = node[field.name];
- if (!field.nullable || ref) {
- if (field.type === 'list') {
- if (reverse) {
- ref.forEachRight(walk);
- } else {
- ref.forEach(walk);
- }
- } else {
- walk(ref);
- }
- }
- }
- if (useContext) {
- context[contextName] = prevContextValue;
- }
- };
- }
- function createFastTraveralMap(iterators) {
- return {
- Atrule: {
- StyleSheet: iterators.StyleSheet,
- Atrule: iterators.Atrule,
- Rule: iterators.Rule,
- Block: iterators.Block
- },
- Rule: {
- StyleSheet: iterators.StyleSheet,
- Atrule: iterators.Atrule,
- Rule: iterators.Rule,
- Block: iterators.Block
- },
- Declaration: {
- StyleSheet: iterators.StyleSheet,
- Atrule: iterators.Atrule,
- Rule: iterators.Rule,
- Block: iterators.Block
- }
- };
- }
- var create$3 = function createWalker(config) {
- var types = getTypesFromConfig(config);
- var iteratorsNatural = {};
- var iteratorsReverse = {};
- for (var name in types) {
- if (hasOwnProperty$4.call(types, name) && types[name] !== null) {
- iteratorsNatural[name] = createTypeIterator(types[name], false);
- iteratorsReverse[name] = createTypeIterator(types[name], true);
- }
- }
- var fastTraversalIteratorsNatural = createFastTraveralMap(iteratorsNatural);
- var fastTraversalIteratorsReverse = createFastTraveralMap(iteratorsReverse);
- var walk = function(root, options) {
- function walkNode(node, item, list) {
- enter.call(context, node, item, list);
- if (iterators.hasOwnProperty(node.type)) {
- iterators[node.type](node, context, walkNode);
- }
- leave.call(context, node, item, list);
- }
- var enter = noop$3;
- var leave = noop$3;
- var iterators = iteratorsNatural;
- var context = {
- root: root,
- stylesheet: null,
- atrule: null,
- atrulePrelude: null,
- rule: null,
- selector: null,
- block: null,
- declaration: null,
- function: null
- };
- if (typeof options === 'function') {
- enter = options;
- } else if (options) {
- enter = ensureFunction$1(options.enter);
- leave = ensureFunction$1(options.leave);
- if (options.reverse) {
- iterators = iteratorsReverse;
- }
- if (options.visit) {
- if (fastTraversalIteratorsNatural.hasOwnProperty(options.visit)) {
- iterators = options.reverse
- ? fastTraversalIteratorsReverse[options.visit]
- : fastTraversalIteratorsNatural[options.visit];
- } else if (!types.hasOwnProperty(options.visit)) {
- throw new Error('Bad value `' + options.visit + '` for `visit` option (should be: ' + Object.keys(types).join(', ') + ')');
- }
- enter = invokeForType(enter, options.visit);
- leave = invokeForType(leave, options.visit);
- }
- }
- if (enter === noop$3 && leave === noop$3) {
- throw new Error('Neither `enter` nor `leave` walker handler is set or both aren\'t a function');
- }
- // swap handlers in reverse mode to invert visit order
- if (options.reverse) {
- var tmp = enter;
- enter = leave;
- leave = tmp;
- }
- walkNode(root);
- };
- walk.find = function(ast, fn) {
- var found = null;
- walk(ast, function(node, item, list) {
- if (found === null && fn.call(this, node, item, list)) {
- found = node;
- }
- });
- return found;
- };
- walk.findLast = function(ast, fn) {
- var found = null;
- walk(ast, {
- reverse: true,
- enter: function(node, item, list) {
- if (found === null && fn.call(this, node, item, list)) {
- found = node;
- }
- }
- });
- return found;
- };
- walk.findAll = function(ast, fn) {
- var found = [];
- walk(ast, function(node, item, list) {
- if (fn.call(this, node, item, list)) {
- found.push(node);
- }
- });
- return found;
- };
- return walk;
- };
- var clone = function clone(node) {
- var result = {};
- for (var key in node) {
- var value = node[key];
- if (value) {
- if (Array.isArray(value) || value instanceof List_1) {
- value = value.map(clone);
- } else if (value.constructor === Object) {
- value = clone(value);
- }
- }
- result[key] = value;
- }
- return result;
- };
- var hasOwnProperty$5 = Object.prototype.hasOwnProperty;
- var shape = {
- generic: true,
- types: {},
- properties: {},
- parseContext: {},
- scope: {},
- atrule: ['parse'],
- pseudo: ['parse'],
- node: ['name', 'structure', 'parse', 'generate', 'walkContext']
- };
- function isObject(value) {
- return value && value.constructor === Object;
- }
- function copy(value) {
- if (isObject(value)) {
- var res = {};
- for (var key in value) {
- if (hasOwnProperty$5.call(value, key)) {
- res[key] = value[key];
- }
- }
- return res;
- } else {
- return value;
- }
- }
- function extend(dest, src) {
- for (var key in src) {
- if (hasOwnProperty$5.call(src, key)) {
- if (isObject(dest[key])) {
- extend(dest[key], copy(src[key]));
- } else {
- dest[key] = copy(src[key]);
- }
- }
- }
- }
- function mix(dest, src, shape) {
- for (var key in shape) {
- if (hasOwnProperty$5.call(shape, key) === false) {
- continue;
- }
- if (shape[key] === true) {
- if (key in src) {
- if (hasOwnProperty$5.call(src, key)) {
- dest[key] = copy(src[key]);
- }
- }
- } else if (shape[key]) {
- if (isObject(shape[key])) {
- var res = {};
- extend(res, dest[key]);
- extend(res, src[key]);
- dest[key] = res;
- } else if (Array.isArray(shape[key])) {
- var res = {};
- var innerShape = shape[key].reduce(function(s, k) {
- s[k] = true;
- return s;
- }, {});
- for (var name in dest[key]) {
- if (hasOwnProperty$5.call(dest[key], name)) {
- res[name] = {};
- if (dest[key] && dest[key][name]) {
- mix(res[name], dest[key][name], innerShape);
- }
- }
- }
- for (var name in src[key]) {
- if (hasOwnProperty$5.call(src[key], name)) {
- if (!res[name]) {
- res[name] = {};
- }
- if (src[key] && src[key][name]) {
- mix(res[name], src[key][name], innerShape);
- }
- }
- }
- dest[key] = res;
- }
- }
- }
- return dest;
- }
- var mix_1 = function(dest, src) {
- return mix(dest, src, shape);
- };
- function assign(dest, src) {
- for (var key in src) {
- dest[key] = src[key];
- }
- return dest;
- }
- function createSyntax(config) {
- var parse = create(config);
- var walk = create$3(config);
- var generate = create$1(config);
- var convert = create$2(walk);
- var syntax = {
- List: List_1,
- SyntaxError: _SyntaxError,
- TokenStream: TokenStream_1,
- Lexer: Lexer_1,
- vendorPrefix: names.vendorPrefix,
- keyword: names.keyword,
- property: names.property,
- isCustomProperty: names.isCustomProperty,
- definitionSyntax: definitionSyntax,
- lexer: null,
- createLexer: function(config) {
- return new Lexer_1(config, syntax, syntax.lexer.structure);
- },
- tokenize: tokenizer,
- parse: parse,
- walk: walk,
- generate: generate,
- find: walk.find,
- findLast: walk.findLast,
- findAll: walk.findAll,
- clone: clone,
- fromPlainObject: convert.fromPlainObject,
- toPlainObject: convert.toPlainObject,
- createSyntax: function(config) {
- return createSyntax(mix_1({}, config));
- },
- fork: function(extension) {
- var base = mix_1({}, config); // copy of config
- return createSyntax(
- typeof extension === 'function'
- ? extension(base, assign)
- : mix_1(base, extension)
- );
- }
- };
- syntax.lexer = new Lexer_1({
- generic: true,
- types: config.types,
- properties: config.properties,
- node: config.node
- }, syntax);
- return syntax;
- }
- var create_1 = function(config) {
- return createSyntax(mix_1({}, config));
- };
- var create$4 = {
- create: create_1
- };
- var generic$1 = true;
- var types = {
- "absolute-size": "xx-small|x-small|small|medium|large|x-large|xx-large",
- "alpha-value": "<number>|<percentage>",
- "angle-percentage": "<angle>|<percentage>",
- "angular-color-hint": "<angle-percentage>",
- "angular-color-stop": "<color>&&<color-stop-angle>?",
- "angular-color-stop-list": "[<angular-color-stop> [, <angular-color-hint>]?]# , <angular-color-stop>",
- "animateable-feature": "scroll-position|contents|<custom-ident>",
- attachment: "scroll|fixed|local",
- "attr()": "attr( <attr-name> <type-or-unit>? [, <attr-fallback>]? )",
- "attr-matcher": "['~'|'|'|'^'|'$'|'*']? '='",
- "attr-modifier": "i|s",
- "attribute-selector": "'[' <wq-name> ']'|'[' <wq-name> <attr-matcher> [<string-token>|<ident-token>] <attr-modifier>? ']'",
- "auto-repeat": "repeat( [auto-fill|auto-fit] , [<line-names>? <fixed-size>]+ <line-names>? )",
- "auto-track-list": "[<line-names>? [<fixed-size>|<fixed-repeat>]]* <line-names>? <auto-repeat> [<line-names>? [<fixed-size>|<fixed-repeat>]]* <line-names>?",
- "baseline-position": "[first|last]? baseline",
- "basic-shape": "<inset()>|<circle()>|<ellipse()>|<polygon()>",
- "bg-image": "none|<image>",
- "bg-layer": "<bg-image>||<bg-position> [/ <bg-size>]?||<repeat-style>||<attachment>||<box>||<box>",
- "bg-position": "[[left|center|right|top|bottom|<length-percentage>]|[left|center|right|<length-percentage>] [top|center|bottom|<length-percentage>]|[center|[left|right] <length-percentage>?]&&[center|[top|bottom] <length-percentage>?]]",
- "bg-size": "[<length-percentage>|auto]{1,2}|cover|contain",
- "blur()": "blur( <length> )",
- "blend-mode": "normal|multiply|screen|overlay|darken|lighten|color-dodge|color-burn|hard-light|soft-light|difference|exclusion|hue|saturation|color|luminosity",
- box: "border-box|padding-box|content-box",
- "brightness()": "brightness( <number-percentage> )",
- "calc()": "calc( <calc-sum> )",
- "calc-sum": "<calc-product> [['+'|'-'] <calc-product>]*",
- "calc-product": "<calc-value> ['*' <calc-value>|'/' <number>]*",
- "calc-value": "<number>|<dimension>|<percentage>|( <calc-sum> )",
- "cf-final-image": "<image>|<color>",
- "cf-mixing-image": "<percentage>?&&<image>",
- "circle()": "circle( [<shape-radius>]? [at <position>]? )",
- "clamp()": "clamp( <calc-sum>#{3} )",
- "class-selector": "'.' <ident-token>",
- "clip-source": "<url>",
- color: "<rgb()>|<rgba()>|<hsl()>|<hsla()>|<hex-color>|<named-color>|currentcolor|<deprecated-system-color>",
- "color-stop": "<color-stop-length>|<color-stop-angle>",
- "color-stop-angle": "<angle-percentage>{1,2}",
- "color-stop-length": "<length-percentage>{1,2}",
- "color-stop-list": "[<linear-color-stop> [, <linear-color-hint>]?]# , <linear-color-stop>",
- combinator: "'>'|'+'|'~'|['||']",
- "common-lig-values": "[common-ligatures|no-common-ligatures]",
- compat: "searchfield|textarea|push-button|button-bevel|slider-horizontal|checkbox|radio|square-button|menulist|menulist-button|listbox|meter|progress-bar",
- "composite-style": "clear|copy|source-over|source-in|source-out|source-atop|destination-over|destination-in|destination-out|destination-atop|xor",
- "compositing-operator": "add|subtract|intersect|exclude",
- "compound-selector": "[<type-selector>? <subclass-selector>* [<pseudo-element-selector> <pseudo-class-selector>*]*]!",
- "compound-selector-list": "<compound-selector>#",
- "complex-selector": "<compound-selector> [<combinator>? <compound-selector>]*",
- "complex-selector-list": "<complex-selector>#",
- "conic-gradient()": "conic-gradient( [from <angle>]? [at <position>]? , <angular-color-stop-list> )",
- "contextual-alt-values": "[contextual|no-contextual]",
- "content-distribution": "space-between|space-around|space-evenly|stretch",
- "content-list": "[<string>|contents|<url>|<quote>|<attr()>|counter( <ident> , <'list-style-type'>? )]+",
- "content-position": "center|start|end|flex-start|flex-end",
- "content-replacement": "<image>",
- "contrast()": "contrast( [<number-percentage>] )",
- "counter()": "counter( <custom-ident> , [<counter-style>|none]? )",
- "counter-style": "<counter-style-name>|symbols( )",
- "counter-style-name": "<custom-ident>",
- "counters()": "counters( <custom-ident> , <string> , [<counter-style>|none]? )",
- "cross-fade()": "cross-fade( <cf-mixing-image> , <cf-final-image>? )",
- "cubic-bezier-timing-function": "ease|ease-in|ease-out|ease-in-out|cubic-bezier( <number> , <number> , <number> , <number> )",
- "deprecated-system-color": "ActiveBorder|ActiveCaption|AppWorkspace|Background|ButtonFace|ButtonHighlight|ButtonShadow|ButtonText|CaptionText|GrayText|Highlight|HighlightText|InactiveBorder|InactiveCaption|InactiveCaptionText|InfoBackground|InfoText|Menu|MenuText|Scrollbar|ThreeDDarkShadow|ThreeDFace|ThreeDHighlight|ThreeDLightShadow|ThreeDShadow|Window|WindowFrame|WindowText",
- "discretionary-lig-values": "[discretionary-ligatures|no-discretionary-ligatures]",
- "display-box": "contents|none",
- "display-inside": "flow|flow-root|table|flex|grid|ruby",
- "display-internal": "table-row-group|table-header-group|table-footer-group|table-row|table-cell|table-column-group|table-column|table-caption|ruby-base|ruby-text|ruby-base-container|ruby-text-container",
- "display-legacy": "inline-block|inline-list-item|inline-table|inline-flex|inline-grid",
- "display-listitem": "<display-outside>?&&[flow|flow-root]?&&list-item",
- "display-outside": "block|inline|run-in",
- "drop-shadow()": "drop-shadow( <length>{2,3} <color>? )",
- "east-asian-variant-values": "[jis78|jis83|jis90|jis04|simplified|traditional]",
- "east-asian-width-values": "[full-width|proportional-width]",
- "element()": "element( <id-selector> )",
- "ellipse()": "ellipse( [<shape-radius>{2}]? [at <position>]? )",
- "ending-shape": "circle|ellipse",
- "env()": "env( <custom-ident> , <declaration-value>? )",
- "explicit-track-list": "[<line-names>? <track-size>]+ <line-names>?",
- "family-name": "<string>|<custom-ident>+",
- "feature-tag-value": "<string> [<integer>|on|off]?",
- "feature-type": "@stylistic|@historical-forms|@styleset|@character-variant|@swash|@ornaments|@annotation",
- "feature-value-block": "<feature-type> '{' <feature-value-declaration-list> '}'",
- "feature-value-block-list": "<feature-value-block>+",
- "feature-value-declaration": "<custom-ident> : <integer>+ ;",
- "feature-value-declaration-list": "<feature-value-declaration>",
- "feature-value-name": "<custom-ident>",
- "fill-rule": "nonzero|evenodd",
- "filter-function": "<blur()>|<brightness()>|<contrast()>|<drop-shadow()>|<grayscale()>|<hue-rotate()>|<invert()>|<opacity()>|<saturate()>|<sepia()>",
- "filter-function-list": "[<filter-function>|<url>]+",
- "final-bg-layer": "<'background-color'>||<bg-image>||<bg-position> [/ <bg-size>]?||<repeat-style>||<attachment>||<box>||<box>",
- "fit-content()": "fit-content( [<length>|<percentage>] )",
- "fixed-breadth": "<length-percentage>",
- "fixed-repeat": "repeat( [<positive-integer>] , [<line-names>? <fixed-size>]+ <line-names>? )",
- "fixed-size": "<fixed-breadth>|minmax( <fixed-breadth> , <track-breadth> )|minmax( <inflexible-breadth> , <fixed-breadth> )",
- "font-stretch-absolute": "normal|ultra-condensed|extra-condensed|condensed|semi-condensed|semi-expanded|expanded|extra-expanded|ultra-expanded|<percentage>",
- "font-variant-css21": "[normal|small-caps]",
- "font-weight-absolute": "normal|bold|<number>",
- "frequency-percentage": "<frequency>|<percentage>",
- "general-enclosed": "[<function-token> <any-value> )]|( <ident> <any-value> )",
- "generic-family": "serif|sans-serif|cursive|fantasy|monospace|-apple-system",
- "generic-name": "serif|sans-serif|cursive|fantasy|monospace",
- "geometry-box": "<shape-box>|fill-box|stroke-box|view-box",
- gradient: "<linear-gradient()>|<repeating-linear-gradient()>|<radial-gradient()>|<repeating-radial-gradient()>|<conic-gradient()>|<-legacy-gradient>",
- "grayscale()": "grayscale( <number-percentage> )",
- "grid-line": "auto|<custom-ident>|[<integer>&&<custom-ident>?]|[span&&[<integer>||<custom-ident>]]",
- "historical-lig-values": "[historical-ligatures|no-historical-ligatures]",
- "hsl()": "hsl( <hue> <percentage> <percentage> [/ <alpha-value>]? )|hsl( <hue> , <percentage> , <percentage> , <alpha-value>? )",
- "hsla()": "hsla( <hue> <percentage> <percentage> [/ <alpha-value>]? )|hsla( <hue> , <percentage> , <percentage> , <alpha-value>? )",
- hue: "<number>|<angle>",
- "hue-rotate()": "hue-rotate( <angle> )",
- image: "<url>|<image()>|<image-set()>|<element()>|<cross-fade()>|<gradient>",
- "image()": "image( <image-tags>? [<image-src>? , <color>?]! )",
- "image-set()": "image-set( <image-set-option># )",
- "image-set-option": "[<image>|<string>] <resolution>",
- "image-src": "<url>|<string>",
- "image-tags": "ltr|rtl",
- "inflexible-breadth": "<length>|<percentage>|min-content|max-content|auto",
- "inset()": "inset( <length-percentage>{1,4} [round <'border-radius'>]? )",
- "invert()": "invert( <number-percentage> )",
- "keyframes-name": "<custom-ident>|<string>",
- "keyframe-block": "<keyframe-selector># { <declaration-list> }",
- "keyframe-block-list": "<keyframe-block>+",
- "keyframe-selector": "from|to|<percentage>",
- "leader()": "leader( <leader-type> )",
- "leader-type": "dotted|solid|space|<string>",
- "length-percentage": "<length>|<percentage>",
- "line-names": "'[' <custom-ident>* ']'",
- "line-name-list": "[<line-names>|<name-repeat>]+",
- "line-style": "none|hidden|dotted|dashed|solid|double|groove|ridge|inset|outset",
- "line-width": "<length>|thin|medium|thick",
- "linear-color-hint": "<length-percentage>",
- "linear-color-stop": "<color> <color-stop-length>?",
- "linear-gradient()": "linear-gradient( [<angle>|to <side-or-corner>]? , <color-stop-list> )",
- "mask-layer": "<mask-reference>||<position> [/ <bg-size>]?||<repeat-style>||<geometry-box>||[<geometry-box>|no-clip]||<compositing-operator>||<masking-mode>",
- "mask-position": "[<length-percentage>|left|center|right] [<length-percentage>|top|center|bottom]?",
- "mask-reference": "none|<image>|<mask-source>",
- "mask-source": "<url>",
- "masking-mode": "alpha|luminance|match-source",
- "matrix()": "matrix( <number>#{6} )",
- "matrix3d()": "matrix3d( <number>#{16} )",
- "max()": "max( <calc-sum># )",
- "media-and": "<media-in-parens> [and <media-in-parens>]+",
- "media-condition": "<media-not>|<media-and>|<media-or>|<media-in-parens>",
- "media-condition-without-or": "<media-not>|<media-and>|<media-in-parens>",
- "media-feature": "( [<mf-plain>|<mf-boolean>|<mf-range>] )",
- "media-in-parens": "( <media-condition> )|<media-feature>|<general-enclosed>",
- "media-not": "not <media-in-parens>",
- "media-or": "<media-in-parens> [or <media-in-parens>]+",
- "media-query": "<media-condition>|[not|only]? <media-type> [and <media-condition-without-or>]?",
- "media-query-list": "<media-query>#",
- "media-type": "<ident>",
- "mf-boolean": "<mf-name>",
- "mf-name": "<ident>",
- "mf-plain": "<mf-name> : <mf-value>",
- "mf-range": "<mf-name> ['<'|'>']? '='? <mf-value>|<mf-value> ['<'|'>']? '='? <mf-name>|<mf-value> '<' '='? <mf-name> '<' '='? <mf-value>|<mf-value> '>' '='? <mf-name> '>' '='? <mf-value>",
- "mf-value": "<number>|<dimension>|<ident>|<ratio>",
- "min()": "min( <calc-sum># )",
- "minmax()": "minmax( [<length>|<percentage>|<flex>|min-content|max-content|auto] , [<length>|<percentage>|<flex>|min-content|max-content|auto] )",
- "named-color": "transparent|aliceblue|antiquewhite|aqua|aquamarine|azure|beige|bisque|black|blanchedalmond|blue|blueviolet|brown|burlywood|cadetblue|chartreuse|chocolate|coral|cornflowerblue|cornsilk|crimson|cyan|darkblue|darkcyan|darkgoldenrod|darkgray|darkgreen|darkgrey|darkkhaki|darkmagenta|darkolivegreen|darkorange|darkorchid|darkred|darksalmon|darkseagreen|darkslateblue|darkslategray|darkslategrey|darkturquoise|darkviolet|deeppink|deepskyblue|dimgray|dimgrey|dodgerblue|firebrick|floralwhite|forestgreen|fuchsia|gainsboro|ghostwhite|gold|goldenrod|gray|green|greenyellow|grey|honeydew|hotpink|indianred|indigo|ivory|khaki|lavender|lavenderblush|lawngreen|lemonchiffon|lightblue|lightcoral|lightcyan|lightgoldenrodyellow|lightgray|lightgreen|lightgrey|lightpink|lightsalmon|lightseagreen|lightskyblue|lightslategray|lightslategrey|lightsteelblue|lightyellow|lime|limegreen|linen|magenta|maroon|mediumaquamarine|mediumblue|mediumorchid|mediumpurple|mediumseagreen|mediumslateblue|mediumspringgreen|mediumturquoise|mediumvioletred|midnightblue|mintcream|mistyrose|moccasin|navajowhite|navy|oldlace|olive|olivedrab|orange|orangered|orchid|palegoldenrod|palegreen|paleturquoise|palevioletred|papayawhip|peachpuff|peru|pink|plum|powderblue|purple|rebeccapurple|red|rosybrown|royalblue|saddlebrown|salmon|sandybrown|seagreen|seashell|sienna|silver|skyblue|slateblue|slategray|slategrey|snow|springgreen|steelblue|tan|teal|thistle|tomato|turquoise|violet|wheat|white|whitesmoke|yellow|yellowgreen|<-non-standard-color>",
- "namespace-prefix": "<ident>",
- "ns-prefix": "[<ident-token>|'*']? '|'",
- "number-percentage": "<number>|<percentage>",
- "numeric-figure-values": "[lining-nums|oldstyle-nums]",
- "numeric-fraction-values": "[diagonal-fractions|stacked-fractions]",
- "numeric-spacing-values": "[proportional-nums|tabular-nums]",
- nth: "<an-plus-b>|even|odd",
- "opacity()": "opacity( [<number-percentage>] )",
- "overflow-position": "unsafe|safe",
- "outline-radius": "<length>|<percentage>",
- "page-body": "<declaration>? [; <page-body>]?|<page-margin-box> <page-body>",
- "page-margin-box": "<page-margin-box-type> '{' <declaration-list> '}'",
- "page-margin-box-type": "@top-left-corner|@top-left|@top-center|@top-right|@top-right-corner|@bottom-left-corner|@bottom-left|@bottom-center|@bottom-right|@bottom-right-corner|@left-top|@left-middle|@left-bottom|@right-top|@right-middle|@right-bottom",
- "page-selector-list": "[<page-selector>#]?",
- "page-selector": "<pseudo-page>+|<ident> <pseudo-page>*",
- "perspective()": "perspective( <length> )",
- "polygon()": "polygon( <fill-rule>? , [<length-percentage> <length-percentage>]# )",
- position: "[[left|center|right]||[top|center|bottom]|[left|center|right|<length-percentage>] [top|center|bottom|<length-percentage>]?|[[left|right] <length-percentage>]&&[[top|bottom] <length-percentage>]]",
- "pseudo-class-selector": "':' <ident-token>|':' <function-token> <any-value> ')'",
- "pseudo-element-selector": "':' <pseudo-class-selector>",
- "pseudo-page": ": [left|right|first|blank]",
- quote: "open-quote|close-quote|no-open-quote|no-close-quote",
- "radial-gradient()": "radial-gradient( [<ending-shape>||<size>]? [at <position>]? , <color-stop-list> )",
- "relative-selector": "<combinator>? <complex-selector>",
- "relative-selector-list": "<relative-selector>#",
- "relative-size": "larger|smaller",
- "repeat-style": "repeat-x|repeat-y|[repeat|space|round|no-repeat]{1,2}",
- "repeating-linear-gradient()": "repeating-linear-gradient( [<angle>|to <side-or-corner>]? , <color-stop-list> )",
- "repeating-radial-gradient()": "repeating-radial-gradient( [<ending-shape>||<size>]? [at <position>]? , <color-stop-list> )",
- "rgb()": "rgb( <percentage>{3} [/ <alpha-value>]? )|rgb( <number>{3} [/ <alpha-value>]? )|rgb( <percentage>#{3} , <alpha-value>? )|rgb( <number>#{3} , <alpha-value>? )",
- "rgba()": "rgba( <percentage>{3} [/ <alpha-value>]? )|rgba( <number>{3} [/ <alpha-value>]? )|rgba( <percentage>#{3} , <alpha-value>? )|rgba( <number>#{3} , <alpha-value>? )",
- "rotate()": "rotate( [<angle>|<zero>] )",
- "rotate3d()": "rotate3d( <number> , <number> , <number> , [<angle>|<zero>] )",
- "rotateX()": "rotateX( [<angle>|<zero>] )",
- "rotateY()": "rotateY( [<angle>|<zero>] )",
- "rotateZ()": "rotateZ( [<angle>|<zero>] )",
- "saturate()": "saturate( <number-percentage> )",
- "scale()": "scale( <number> , <number>? )",
- "scale3d()": "scale3d( <number> , <number> , <number> )",
- "scaleX()": "scaleX( <number> )",
- "scaleY()": "scaleY( <number> )",
- "scaleZ()": "scaleZ( <number> )",
- "self-position": "center|start|end|self-start|self-end|flex-start|flex-end",
- "shape-radius": "<length-percentage>|closest-side|farthest-side",
- "skew()": "skew( [<angle>|<zero>] , [<angle>|<zero>]? )",
- "skewX()": "skewX( [<angle>|<zero>] )",
- "skewY()": "skewY( [<angle>|<zero>] )",
- "sepia()": "sepia( <number-percentage> )",
- shadow: "inset?&&<length>{2,4}&&<color>?",
- "shadow-t": "[<length>{2,3}&&<color>?]",
- shape: "rect( <top> , <right> , <bottom> , <left> )|rect( <top> <right> <bottom> <left> )",
- "shape-box": "<box>|margin-box",
- "side-or-corner": "[left|right]||[top|bottom]",
- "single-animation": "<time>||<timing-function>||<time>||<single-animation-iteration-count>||<single-animation-direction>||<single-animation-fill-mode>||<single-animation-play-state>||[none|<keyframes-name>]",
- "single-animation-direction": "normal|reverse|alternate|alternate-reverse",
- "single-animation-fill-mode": "none|forwards|backwards|both",
- "single-animation-iteration-count": "infinite|<number>",
- "single-animation-play-state": "running|paused",
- "single-transition": "[none|<single-transition-property>]||<time>||<timing-function>||<time>",
- "single-transition-property": "all|<custom-ident>",
- size: "closest-side|farthest-side|closest-corner|farthest-corner|<length>|<length-percentage>{2}",
- "step-position": "jump-start|jump-end|jump-none|jump-both|start|end",
- "step-timing-function": "step-start|step-end|steps( <integer> [, <step-position>]? )",
- "subclass-selector": "<id-selector>|<class-selector>|<attribute-selector>|<pseudo-class-selector>",
- "supports-condition": "not <supports-in-parens>|<supports-in-parens> [and <supports-in-parens>]*|<supports-in-parens> [or <supports-in-parens>]*",
- "supports-in-parens": "( <supports-condition> )|<supports-feature>|<general-enclosed>",
- "supports-feature": "<supports-decl>|<supports-selector-fn>",
- "supports-decl": "( <declaration> )",
- "supports-selector-fn": "selector( <complex-selector> )",
- symbol: "<string>|<image>|<custom-ident>",
- target: "<target-counter()>|<target-counters()>|<target-text()>",
- "target-counter()": "target-counter( [<string>|<url>] , <custom-ident> , <counter-style>? )",
- "target-counters()": "target-counters( [<string>|<url>] , <custom-ident> , <string> , <counter-style>? )",
- "target-text()": "target-text( [<string>|<url>] , [content|before|after|first-letter]? )",
- "time-percentage": "<time>|<percentage>",
- "timing-function": "linear|<cubic-bezier-timing-function>|<step-timing-function>",
- "track-breadth": "<length-percentage>|<flex>|min-content|max-content|auto",
- "track-list": "[<line-names>? [<track-size>|<track-repeat>]]+ <line-names>?",
- "track-repeat": "repeat( [<positive-integer>] , [<line-names>? <track-size>]+ <line-names>? )",
- "track-size": "<track-breadth>|minmax( <inflexible-breadth> , <track-breadth> )|fit-content( [<length>|<percentage>] )",
- "transform-function": "<matrix()>|<translate()>|<translateX()>|<translateY()>|<scale()>|<scaleX()>|<scaleY()>|<rotate()>|<skew()>|<skewX()>|<skewY()>|<matrix3d()>|<translate3d()>|<translateZ()>|<scale3d()>|<scaleZ()>|<rotate3d()>|<rotateX()>|<rotateY()>|<rotateZ()>|<perspective()>",
- "transform-list": "<transform-function>+",
- "translate()": "translate( <length-percentage> , <length-percentage>? )",
- "translate3d()": "translate3d( <length-percentage> , <length-percentage> , <length> )",
- "translateX()": "translateX( <length-percentage> )",
- "translateY()": "translateY( <length-percentage> )",
- "translateZ()": "translateZ( <length> )",
- "type-or-unit": "string|color|url|integer|number|length|angle|time|frequency|cap|ch|em|ex|ic|lh|rlh|rem|vb|vi|vw|vh|vmin|vmax|mm|Q|cm|in|pt|pc|px|deg|grad|rad|turn|ms|s|Hz|kHz|%",
- "type-selector": "<wq-name>|<ns-prefix>? '*'",
- "var()": "var( <custom-property-name> , <declaration-value>? )",
- "viewport-length": "auto|<length-percentage>",
- "wq-name": "<ns-prefix>? <ident-token>",
- "-legacy-gradient": "<-webkit-gradient()>|<-legacy-linear-gradient>|<-legacy-repeating-linear-gradient>|<-legacy-radial-gradient>|<-legacy-repeating-radial-gradient>",
- "-legacy-linear-gradient": "-moz-linear-gradient( <-legacy-linear-gradient-arguments> )|-webkit-linear-gradient( <-legacy-linear-gradient-arguments> )|-o-linear-gradient( <-legacy-linear-gradient-arguments> )",
- "-legacy-repeating-linear-gradient": "-moz-repeating-linear-gradient( <-legacy-linear-gradient-arguments> )|-webkit-repeating-linear-gradient( <-legacy-linear-gradient-arguments> )|-o-repeating-linear-gradient( <-legacy-linear-gradient-arguments> )",
- "-legacy-linear-gradient-arguments": "[<angle>|<side-or-corner>]? , <color-stop-list>",
- "-legacy-radial-gradient": "-moz-radial-gradient( <-legacy-radial-gradient-arguments> )|-webkit-radial-gradient( <-legacy-radial-gradient-arguments> )|-o-radial-gradient( <-legacy-radial-gradient-arguments> )",
- "-legacy-repeating-radial-gradient": "-moz-repeating-radial-gradient( <-legacy-radial-gradient-arguments> )|-webkit-repeating-radial-gradient( <-legacy-radial-gradient-arguments> )|-o-repeating-radial-gradient( <-legacy-radial-gradient-arguments> )",
- "-legacy-radial-gradient-arguments": "[<position> ,]? [[[<-legacy-radial-gradient-shape>||<-legacy-radial-gradient-size>]|[<length>|<percentage>]{2}] ,]? <color-stop-list>",
- "-legacy-radial-gradient-size": "closest-side|closest-corner|farthest-side|farthest-corner|contain|cover",
- "-legacy-radial-gradient-shape": "circle|ellipse",
- "-non-standard-font": "-apple-system-body|-apple-system-headline|-apple-system-subheadline|-apple-system-caption1|-apple-system-caption2|-apple-system-footnote|-apple-system-short-body|-apple-system-short-headline|-apple-system-short-subheadline|-apple-system-short-caption1|-apple-system-short-footnote|-apple-system-tall-body",
- "-non-standard-color": "-moz-ButtonDefault|-moz-ButtonHoverFace|-moz-ButtonHoverText|-moz-CellHighlight|-moz-CellHighlightText|-moz-Combobox|-moz-ComboboxText|-moz-Dialog|-moz-DialogText|-moz-dragtargetzone|-moz-EvenTreeRow|-moz-Field|-moz-FieldText|-moz-html-CellHighlight|-moz-html-CellHighlightText|-moz-mac-accentdarkestshadow|-moz-mac-accentdarkshadow|-moz-mac-accentface|-moz-mac-accentlightesthighlight|-moz-mac-accentlightshadow|-moz-mac-accentregularhighlight|-moz-mac-accentregularshadow|-moz-mac-chrome-active|-moz-mac-chrome-inactive|-moz-mac-focusring|-moz-mac-menuselect|-moz-mac-menushadow|-moz-mac-menutextselect|-moz-MenuHover|-moz-MenuHoverText|-moz-MenuBarText|-moz-MenuBarHoverText|-moz-nativehyperlinktext|-moz-OddTreeRow|-moz-win-communicationstext|-moz-win-mediatext|-moz-activehyperlinktext|-moz-default-background-color|-moz-default-color|-moz-hyperlinktext|-moz-visitedhyperlinktext|-webkit-activelink|-webkit-focus-ring-color|-webkit-link|-webkit-text",
- "-non-standard-image-rendering": "optimize-contrast|-moz-crisp-edges|-o-crisp-edges|-webkit-optimize-contrast",
- "-non-standard-overflow": "-moz-scrollbars-none|-moz-scrollbars-horizontal|-moz-scrollbars-vertical|-moz-hidden-unscrollable",
- "-non-standard-width": "min-intrinsic|intrinsic|-moz-min-content|-moz-max-content|-webkit-min-content|-webkit-max-content",
- "-webkit-gradient()": "-webkit-gradient( <-webkit-gradient-type> , <-webkit-gradient-point> [, <-webkit-gradient-point>|, <-webkit-gradient-radius> , <-webkit-gradient-point>] [, <-webkit-gradient-radius>]? [, <-webkit-gradient-color-stop>]* )",
- "-webkit-gradient-color-stop": "from( <color> )|color-stop( [<number-zero-one>|<percentage>] , <color> )|to( <color> )",
- "-webkit-gradient-point": "[left|center|right|<length-percentage>] [top|center|bottom|<length-percentage>]",
- "-webkit-gradient-radius": "<length>|<percentage>",
- "-webkit-gradient-type": "linear|radial",
- "-webkit-mask-box-repeat": "repeat|stretch|round",
- "-webkit-mask-clip-style": "border|border-box|padding|padding-box|content|content-box|text",
- "-ms-filter-function-list": "<-ms-filter-function>+",
- "-ms-filter-function": "<-ms-filter-function-progid>|<-ms-filter-function-legacy>",
- "-ms-filter-function-progid": "'progid:' [<ident-token> '.']* [<ident-token>|<function-token> <any-value>? )]",
- "-ms-filter-function-legacy": "<ident-token>|<function-token> <any-value>? )",
- "-ms-filter": "<string>",
- age: "child|young|old",
- "attr-name": "<wq-name>",
- "attr-fallback": "<any-value>",
- "border-radius": "<length-percentage>{1,2}",
- bottom: "<length>|auto",
- "generic-voice": "[<age>? <gender> <integer>?]",
- gender: "male|female|neutral",
- left: "<length>|auto",
- "mask-image": "<mask-reference>#",
- "name-repeat": "repeat( [<positive-integer>|auto-fill] , <line-names>+ )",
- paint: "none|<color>|<url> [none|<color>]?|context-fill|context-stroke",
- "path()": "path( <string> )",
- ratio: "<integer> / <integer>",
- right: "<length>|auto",
- "svg-length": "<percentage>|<length>|<number>",
- "svg-writing-mode": "lr-tb|rl-tb|tb-rl|lr|rl|tb",
- top: "<length>|auto",
- x: "<number>",
- y: "<number>",
- declaration: "<ident-token> : <declaration-value>? ['!' important]?",
- "declaration-list": "[<declaration>? ';']* <declaration>?",
- url: "url( <string> <url-modifier>* )|<url-token>",
- "url-modifier": "<ident>|<function-token> <any-value> )",
- "number-zero-one": "<number [0,1]>",
- "number-one-or-greater": "<number [1,∞]>",
- "positive-integer": "<integer [0,∞]>"
- };
- var properties$1 = {
- "--*": "<declaration-value>",
- "-ms-accelerator": "false|true",
- "-ms-block-progression": "tb|rl|bt|lr",
- "-ms-content-zoom-chaining": "none|chained",
- "-ms-content-zooming": "none|zoom",
- "-ms-content-zoom-limit": "<'-ms-content-zoom-limit-min'> <'-ms-content-zoom-limit-max'>",
- "-ms-content-zoom-limit-max": "<percentage>",
- "-ms-content-zoom-limit-min": "<percentage>",
- "-ms-content-zoom-snap": "<'-ms-content-zoom-snap-type'>||<'-ms-content-zoom-snap-points'>",
- "-ms-content-zoom-snap-points": "snapInterval( <percentage> , <percentage> )|snapList( <percentage># )",
- "-ms-content-zoom-snap-type": "none|proximity|mandatory",
- "-ms-filter": "<string>",
- "-ms-flow-from": "[none|<custom-ident>]#",
- "-ms-flow-into": "[none|<custom-ident>]#",
- "-ms-high-contrast-adjust": "auto|none",
- "-ms-hyphenate-limit-chars": "auto|<integer>{1,3}",
- "-ms-hyphenate-limit-lines": "no-limit|<integer>",
- "-ms-hyphenate-limit-zone": "<percentage>|<length>",
- "-ms-ime-align": "auto|after",
- "-ms-overflow-style": "auto|none|scrollbar|-ms-autohiding-scrollbar",
- "-ms-scrollbar-3dlight-color": "<color>",
- "-ms-scrollbar-arrow-color": "<color>",
- "-ms-scrollbar-base-color": "<color>",
- "-ms-scrollbar-darkshadow-color": "<color>",
- "-ms-scrollbar-face-color": "<color>",
- "-ms-scrollbar-highlight-color": "<color>",
- "-ms-scrollbar-shadow-color": "<color>",
- "-ms-scrollbar-track-color": "<color>",
- "-ms-scroll-chaining": "chained|none",
- "-ms-scroll-limit": "<'-ms-scroll-limit-x-min'> <'-ms-scroll-limit-y-min'> <'-ms-scroll-limit-x-max'> <'-ms-scroll-limit-y-max'>",
- "-ms-scroll-limit-x-max": "auto|<length>",
- "-ms-scroll-limit-x-min": "<length>",
- "-ms-scroll-limit-y-max": "auto|<length>",
- "-ms-scroll-limit-y-min": "<length>",
- "-ms-scroll-rails": "none|railed",
- "-ms-scroll-snap-points-x": "snapInterval( <length-percentage> , <length-percentage> )|snapList( <length-percentage># )",
- "-ms-scroll-snap-points-y": "snapInterval( <length-percentage> , <length-percentage> )|snapList( <length-percentage># )",
- "-ms-scroll-snap-type": "none|proximity|mandatory",
- "-ms-scroll-snap-x": "<'-ms-scroll-snap-type'> <'-ms-scroll-snap-points-x'>",
- "-ms-scroll-snap-y": "<'-ms-scroll-snap-type'> <'-ms-scroll-snap-points-y'>",
- "-ms-scroll-translation": "none|vertical-to-horizontal",
- "-ms-text-autospace": "none|ideograph-alpha|ideograph-numeric|ideograph-parenthesis|ideograph-space",
- "-ms-touch-select": "grippers|none",
- "-ms-user-select": "none|element|text",
- "-ms-wrap-flow": "auto|both|start|end|maximum|clear",
- "-ms-wrap-margin": "<length>",
- "-ms-wrap-through": "wrap|none",
- "-moz-appearance": "none|button|button-arrow-down|button-arrow-next|button-arrow-previous|button-arrow-up|button-bevel|button-focus|caret|checkbox|checkbox-container|checkbox-label|checkmenuitem|dualbutton|groupbox|listbox|listitem|menuarrow|menubar|menucheckbox|menuimage|menuitem|menuitemtext|menulist|menulist-button|menulist-text|menulist-textfield|menupopup|menuradio|menuseparator|meterbar|meterchunk|progressbar|progressbar-vertical|progresschunk|progresschunk-vertical|radio|radio-container|radio-label|radiomenuitem|range|range-thumb|resizer|resizerpanel|scale-horizontal|scalethumbend|scalethumb-horizontal|scalethumbstart|scalethumbtick|scalethumb-vertical|scale-vertical|scrollbarbutton-down|scrollbarbutton-left|scrollbarbutton-right|scrollbarbutton-up|scrollbarthumb-horizontal|scrollbarthumb-vertical|scrollbartrack-horizontal|scrollbartrack-vertical|searchfield|separator|sheet|spinner|spinner-downbutton|spinner-textfield|spinner-upbutton|splitter|statusbar|statusbarpanel|tab|tabpanel|tabpanels|tab-scroll-arrow-back|tab-scroll-arrow-forward|textfield|textfield-multiline|toolbar|toolbarbutton|toolbarbutton-dropdown|toolbargripper|toolbox|tooltip|treeheader|treeheadercell|treeheadersortarrow|treeitem|treeline|treetwisty|treetwistyopen|treeview|-moz-mac-unified-toolbar|-moz-win-borderless-glass|-moz-win-browsertabbar-toolbox|-moz-win-communicationstext|-moz-win-communications-toolbox|-moz-win-exclude-glass|-moz-win-glass|-moz-win-mediatext|-moz-win-media-toolbox|-moz-window-button-box|-moz-window-button-box-maximized|-moz-window-button-close|-moz-window-button-maximize|-moz-window-button-minimize|-moz-window-button-restore|-moz-window-frame-bottom|-moz-window-frame-left|-moz-window-frame-right|-moz-window-titlebar|-moz-window-titlebar-maximized",
- "-moz-binding": "<url>|none",
- "-moz-border-bottom-colors": "<color>+|none",
- "-moz-border-left-colors": "<color>+|none",
- "-moz-border-right-colors": "<color>+|none",
- "-moz-border-top-colors": "<color>+|none",
- "-moz-context-properties": "none|[fill|fill-opacity|stroke|stroke-opacity]#",
- "-moz-float-edge": "border-box|content-box|margin-box|padding-box",
- "-moz-force-broken-image-icon": "<integer>",
- "-moz-image-region": "<shape>|auto",
- "-moz-orient": "inline|block|horizontal|vertical",
- "-moz-outline-radius": "<outline-radius>{1,4} [/ <outline-radius>{1,4}]?",
- "-moz-outline-radius-bottomleft": "<outline-radius>",
- "-moz-outline-radius-bottomright": "<outline-radius>",
- "-moz-outline-radius-topleft": "<outline-radius>",
- "-moz-outline-radius-topright": "<outline-radius>",
- "-moz-stack-sizing": "ignore|stretch-to-fit",
- "-moz-text-blink": "none|blink",
- "-moz-user-focus": "ignore|normal|select-after|select-before|select-menu|select-same|select-all|none",
- "-moz-user-input": "auto|none|enabled|disabled",
- "-moz-user-modify": "read-only|read-write|write-only",
- "-moz-window-dragging": "drag|no-drag",
- "-moz-window-shadow": "default|menu|tooltip|sheet|none",
- "-webkit-appearance": "none|button|button-bevel|caps-lock-indicator|caret|checkbox|default-button|listbox|listitem|media-fullscreen-button|media-mute-button|media-play-button|media-seek-back-button|media-seek-forward-button|media-slider|media-sliderthumb|menulist|menulist-button|menulist-text|menulist-textfield|push-button|radio|scrollbarbutton-down|scrollbarbutton-left|scrollbarbutton-right|scrollbarbutton-up|scrollbargripper-horizontal|scrollbargripper-vertical|scrollbarthumb-horizontal|scrollbarthumb-vertical|scrollbartrack-horizontal|scrollbartrack-vertical|searchfield|searchfield-cancel-button|searchfield-decoration|searchfield-results-button|searchfield-results-decoration|slider-horizontal|slider-vertical|sliderthumb-horizontal|sliderthumb-vertical|square-button|textarea|textfield",
- "-webkit-border-before": "<'border-width'>||<'border-style'>||<'color'>",
- "-webkit-border-before-color": "<'color'>",
- "-webkit-border-before-style": "<'border-style'>",
- "-webkit-border-before-width": "<'border-width'>",
- "-webkit-box-reflect": "[above|below|right|left]? <length>? <image>?",
- "-webkit-line-clamp": "none|<integer>",
- "-webkit-mask": "[<mask-reference>||<position> [/ <bg-size>]?||<repeat-style>||[<box>|border|padding|content|text]||[<box>|border|padding|content]]#",
- "-webkit-mask-attachment": "<attachment>#",
- "-webkit-mask-clip": "[<box>|border|padding|content|text]#",
- "-webkit-mask-composite": "<composite-style>#",
- "-webkit-mask-image": "<mask-reference>#",
- "-webkit-mask-origin": "[<box>|border|padding|content]#",
- "-webkit-mask-position": "<position>#",
- "-webkit-mask-position-x": "[<length-percentage>|left|center|right]#",
- "-webkit-mask-position-y": "[<length-percentage>|top|center|bottom]#",
- "-webkit-mask-repeat": "<repeat-style>#",
- "-webkit-mask-repeat-x": "repeat|no-repeat|space|round",
- "-webkit-mask-repeat-y": "repeat|no-repeat|space|round",
- "-webkit-mask-size": "<bg-size>#",
- "-webkit-overflow-scrolling": "auto|touch",
- "-webkit-tap-highlight-color": "<color>",
- "-webkit-text-fill-color": "<color>",
- "-webkit-text-stroke": "<length>||<color>",
- "-webkit-text-stroke-color": "<color>",
- "-webkit-text-stroke-width": "<length>",
- "-webkit-touch-callout": "default|none",
- "-webkit-user-modify": "read-only|read-write|read-write-plaintext-only",
- "align-content": "normal|<baseline-position>|<content-distribution>|<overflow-position>? <content-position>",
- "align-items": "normal|stretch|<baseline-position>|[<overflow-position>? <self-position>]",
- "align-self": "auto|normal|stretch|<baseline-position>|<overflow-position>? <self-position>",
- all: "initial|inherit|unset|revert",
- animation: "<single-animation>#",
- "animation-delay": "<time>#",
- "animation-direction": "<single-animation-direction>#",
- "animation-duration": "<time>#",
- "animation-fill-mode": "<single-animation-fill-mode>#",
- "animation-iteration-count": "<single-animation-iteration-count>#",
- "animation-name": "[none|<keyframes-name>]#",
- "animation-play-state": "<single-animation-play-state>#",
- "animation-timing-function": "<timing-function>#",
- appearance: "none|auto|button|textfield|<compat>",
- azimuth: "<angle>|[[left-side|far-left|left|center-left|center|center-right|right|far-right|right-side]||behind]|leftwards|rightwards",
- "backdrop-filter": "none|<filter-function-list>",
- "backface-visibility": "visible|hidden",
- background: "[<bg-layer> ,]* <final-bg-layer>",
- "background-attachment": "<attachment>#",
- "background-blend-mode": "<blend-mode>#",
- "background-clip": "<box>#",
- "background-color": "<color>",
- "background-image": "<bg-image>#",
- "background-origin": "<box>#",
- "background-position": "<bg-position>#",
- "background-position-x": "[center|[left|right|x-start|x-end]? <length-percentage>?]#",
- "background-position-y": "[center|[top|bottom|y-start|y-end]? <length-percentage>?]#",
- "background-repeat": "<repeat-style>#",
- "background-size": "<bg-size>#",
- "block-overflow": "clip|ellipsis|<string>",
- "block-size": "<'width'>",
- border: "<line-width>||<line-style>||<color>",
- "border-block": "<'border-top-width'>||<'border-top-style'>||<'color'>",
- "border-block-color": "<'border-top-color'>{1,2}",
- "border-block-style": "<'border-top-style'>",
- "border-block-width": "<'border-top-width'>",
- "border-block-end": "<'border-top-width'>||<'border-top-style'>||<'color'>",
- "border-block-end-color": "<'border-top-color'>",
- "border-block-end-style": "<'border-top-style'>",
- "border-block-end-width": "<'border-top-width'>",
- "border-block-start": "<'border-top-width'>||<'border-top-style'>||<'color'>",
- "border-block-start-color": "<'border-top-color'>",
- "border-block-start-style": "<'border-top-style'>",
- "border-block-start-width": "<'border-top-width'>",
- "border-bottom": "<line-width>||<line-style>||<color>",
- "border-bottom-color": "<'border-top-color'>",
- "border-bottom-left-radius": "<length-percentage>{1,2}",
- "border-bottom-right-radius": "<length-percentage>{1,2}",
- "border-bottom-style": "<line-style>",
- "border-bottom-width": "<line-width>",
- "border-collapse": "collapse|separate",
- "border-color": "<color>{1,4}",
- "border-end-end-radius": "<length-percentage>{1,2}",
- "border-end-start-radius": "<length-percentage>{1,2}",
- "border-image": "<'border-image-source'>||<'border-image-slice'> [/ <'border-image-width'>|/ <'border-image-width'>? / <'border-image-outset'>]?||<'border-image-repeat'>",
- "border-image-outset": "[<length>|<number>]{1,4}",
- "border-image-repeat": "[stretch|repeat|round|space]{1,2}",
- "border-image-slice": "<number-percentage>{1,4}&&fill?",
- "border-image-source": "none|<image>",
- "border-image-width": "[<length-percentage>|<number>|auto]{1,4}",
- "border-inline": "<'border-top-width'>||<'border-top-style'>||<'color'>",
- "border-inline-end": "<'border-top-width'>||<'border-top-style'>||<'color'>",
- "border-inline-color": "<'border-top-color'>{1,2}",
- "border-inline-style": "<'border-top-style'>",
- "border-inline-width": "<'border-top-width'>",
- "border-inline-end-color": "<'border-top-color'>",
- "border-inline-end-style": "<'border-top-style'>",
- "border-inline-end-width": "<'border-top-width'>",
- "border-inline-start": "<'border-top-width'>||<'border-top-style'>||<'color'>",
- "border-inline-start-color": "<'border-top-color'>",
- "border-inline-start-style": "<'border-top-style'>",
- "border-inline-start-width": "<'border-top-width'>",
- "border-left": "<line-width>||<line-style>||<color>",
- "border-left-color": "<color>",
- "border-left-style": "<line-style>",
- "border-left-width": "<line-width>",
- "border-radius": "<length-percentage>{1,4} [/ <length-percentage>{1,4}]?",
- "border-right": "<line-width>||<line-style>||<color>",
- "border-right-color": "<color>",
- "border-right-style": "<line-style>",
- "border-right-width": "<line-width>",
- "border-spacing": "<length> <length>?",
- "border-start-end-radius": "<length-percentage>{1,2}",
- "border-start-start-radius": "<length-percentage>{1,2}",
- "border-style": "<line-style>{1,4}",
- "border-top": "<line-width>||<line-style>||<color>",
- "border-top-color": "<color>",
- "border-top-left-radius": "<length-percentage>{1,2}",
- "border-top-right-radius": "<length-percentage>{1,2}",
- "border-top-style": "<line-style>",
- "border-top-width": "<line-width>",
- "border-width": "<line-width>{1,4}",
- bottom: "<length>|<percentage>|auto",
- "box-align": "start|center|end|baseline|stretch",
- "box-decoration-break": "slice|clone",
- "box-direction": "normal|reverse|inherit",
- "box-flex": "<number>",
- "box-flex-group": "<integer>",
- "box-lines": "single|multiple",
- "box-ordinal-group": "<integer>",
- "box-orient": "horizontal|vertical|inline-axis|block-axis|inherit",
- "box-pack": "start|center|end|justify",
- "box-shadow": "none|<shadow>#",
- "box-sizing": "content-box|border-box",
- "break-after": "auto|avoid|always|all|avoid-page|page|left|right|recto|verso|avoid-column|column|avoid-region|region",
- "break-before": "auto|avoid|always|all|avoid-page|page|left|right|recto|verso|avoid-column|column|avoid-region|region",
- "break-inside": "auto|avoid|avoid-page|avoid-column|avoid-region",
- "caption-side": "top|bottom|block-start|block-end|inline-start|inline-end",
- "caret-color": "auto|<color>",
- clear: "none|left|right|both|inline-start|inline-end",
- clip: "<shape>|auto",
- "clip-path": "<clip-source>|[<basic-shape>||<geometry-box>]|none",
- color: "<color>",
- "color-adjust": "economy|exact",
- "column-count": "<integer>|auto",
- "column-fill": "auto|balance|balance-all",
- "column-gap": "normal|<length-percentage>",
- "column-rule": "<'column-rule-width'>||<'column-rule-style'>||<'column-rule-color'>",
- "column-rule-color": "<color>",
- "column-rule-style": "<'border-style'>",
- "column-rule-width": "<'border-width'>",
- "column-span": "none|all",
- "column-width": "<length>|auto",
- columns: "<'column-width'>||<'column-count'>",
- contain: "none|strict|content|[size||layout||style||paint]",
- content: "normal|none|[<content-replacement>|<content-list>] [/ <string>]?",
- "counter-increment": "[<custom-ident> <integer>?]+|none",
- "counter-reset": "[<custom-ident> <integer>?]+|none",
- "counter-set": "[<custom-ident> <integer>?]+|none",
- cursor: "[[<url> [<x> <y>]? ,]* [auto|default|none|context-menu|help|pointer|progress|wait|cell|crosshair|text|vertical-text|alias|copy|move|no-drop|not-allowed|e-resize|n-resize|ne-resize|nw-resize|s-resize|se-resize|sw-resize|w-resize|ew-resize|ns-resize|nesw-resize|nwse-resize|col-resize|row-resize|all-scroll|zoom-in|zoom-out|grab|grabbing|hand|-webkit-grab|-webkit-grabbing|-webkit-zoom-in|-webkit-zoom-out|-moz-grab|-moz-grabbing|-moz-zoom-in|-moz-zoom-out]]",
- direction: "ltr|rtl",
- display: "none|inline|block|list-item|inline-list-item|inline-block|inline-table|table|table-cell|table-column|table-column-group|table-footer-group|table-header-group|table-row|table-row-group|flex|inline-flex|grid|inline-grid|run-in|ruby|ruby-base|ruby-text|ruby-base-container|ruby-text-container|contents|-ms-flexbox|-ms-inline-flexbox|-ms-grid|-ms-inline-grid|-webkit-flex|-webkit-inline-flex|-webkit-box|-webkit-inline-box|-moz-inline-stack|-moz-box|-moz-inline-box",
- "empty-cells": "show|hide",
- filter: "none|<filter-function-list>|<-ms-filter-function-list>",
- flex: "none|[<'flex-grow'> <'flex-shrink'>?||<'flex-basis'>]",
- "flex-basis": "content|<'width'>",
- "flex-direction": "row|row-reverse|column|column-reverse",
- "flex-flow": "<'flex-direction'>||<'flex-wrap'>",
- "flex-grow": "<number>",
- "flex-shrink": "<number>",
- "flex-wrap": "nowrap|wrap|wrap-reverse",
- float: "left|right|none|inline-start|inline-end",
- font: "[[<'font-style'>||<font-variant-css21>||<'font-weight'>||<'font-stretch'>]? <'font-size'> [/ <'line-height'>]? <'font-family'>]|caption|icon|menu|message-box|small-caption|status-bar",
- "font-family": "[<family-name>|<generic-family>]#",
- "font-feature-settings": "normal|<feature-tag-value>#",
- "font-kerning": "auto|normal|none",
- "font-language-override": "normal|<string>",
- "font-optical-sizing": "auto|none",
- "font-variation-settings": "normal|[<string> <number>]#",
- "font-size": "<absolute-size>|<relative-size>|<length-percentage>",
- "font-size-adjust": "none|<number>",
- "font-stretch": "<font-stretch-absolute>",
- "font-style": "normal|italic|oblique <angle>?",
- "font-synthesis": "none|[weight||style]",
- "font-variant": "normal|none|[<common-lig-values>||<discretionary-lig-values>||<historical-lig-values>||<contextual-alt-values>||stylistic( <feature-value-name> )||historical-forms||styleset( <feature-value-name># )||character-variant( <feature-value-name># )||swash( <feature-value-name> )||ornaments( <feature-value-name> )||annotation( <feature-value-name> )||[small-caps|all-small-caps|petite-caps|all-petite-caps|unicase|titling-caps]||<numeric-figure-values>||<numeric-spacing-values>||<numeric-fraction-values>||ordinal||slashed-zero||<east-asian-variant-values>||<east-asian-width-values>||ruby]",
- "font-variant-alternates": "normal|[stylistic( <feature-value-name> )||historical-forms||styleset( <feature-value-name># )||character-variant( <feature-value-name># )||swash( <feature-value-name> )||ornaments( <feature-value-name> )||annotation( <feature-value-name> )]",
- "font-variant-caps": "normal|small-caps|all-small-caps|petite-caps|all-petite-caps|unicase|titling-caps",
- "font-variant-east-asian": "normal|[<east-asian-variant-values>||<east-asian-width-values>||ruby]",
- "font-variant-ligatures": "normal|none|[<common-lig-values>||<discretionary-lig-values>||<historical-lig-values>||<contextual-alt-values>]",
- "font-variant-numeric": "normal|[<numeric-figure-values>||<numeric-spacing-values>||<numeric-fraction-values>||ordinal||slashed-zero]",
- "font-variant-position": "normal|sub|super",
- "font-weight": "<font-weight-absolute>|bolder|lighter",
- gap: "<'row-gap'> <'column-gap'>?",
- grid: "<'grid-template'>|<'grid-template-rows'> / [auto-flow&&dense?] <'grid-auto-columns'>?|[auto-flow&&dense?] <'grid-auto-rows'>? / <'grid-template-columns'>",
- "grid-area": "<grid-line> [/ <grid-line>]{0,3}",
- "grid-auto-columns": "<track-size>+",
- "grid-auto-flow": "[row|column]||dense",
- "grid-auto-rows": "<track-size>+",
- "grid-column": "<grid-line> [/ <grid-line>]?",
- "grid-column-end": "<grid-line>",
- "grid-column-gap": "<length-percentage>",
- "grid-column-start": "<grid-line>",
- "grid-gap": "<'grid-row-gap'> <'grid-column-gap'>?",
- "grid-row": "<grid-line> [/ <grid-line>]?",
- "grid-row-end": "<grid-line>",
- "grid-row-gap": "<length-percentage>",
- "grid-row-start": "<grid-line>",
- "grid-template": "none|[<'grid-template-rows'> / <'grid-template-columns'>]|[<line-names>? <string> <track-size>? <line-names>?]+ [/ <explicit-track-list>]?",
- "grid-template-areas": "none|<string>+",
- "grid-template-columns": "none|<track-list>|<auto-track-list>",
- "grid-template-rows": "none|<track-list>|<auto-track-list>",
- "hanging-punctuation": "none|[first||[force-end|allow-end]||last]",
- height: "[<length>|<percentage>]&&[border-box|content-box]?|available|min-content|max-content|fit-content|auto",
- hyphens: "none|manual|auto",
- "image-orientation": "from-image|<angle>|[<angle>? flip]",
- "image-rendering": "auto|crisp-edges|pixelated|optimizeSpeed|optimizeQuality|<-non-standard-image-rendering>",
- "image-resolution": "[from-image||<resolution>]&&snap?",
- "ime-mode": "auto|normal|active|inactive|disabled",
- "initial-letter": "normal|[<number> <integer>?]",
- "initial-letter-align": "[auto|alphabetic|hanging|ideographic]",
- "inline-size": "<'width'>",
- inset: "<'top'>{1,4}",
- "inset-block": "<'top'>{1,2}",
- "inset-block-end": "<'top'>",
- "inset-block-start": "<'top'>",
- "inset-inline": "<'top'>{1,2}",
- "inset-inline-end": "<'top'>",
- "inset-inline-start": "<'top'>",
- isolation: "auto|isolate",
- "justify-content": "normal|<content-distribution>|<overflow-position>? [<content-position>|left|right]",
- "justify-items": "normal|stretch|<baseline-position>|<overflow-position>? [<self-position>|left|right]|legacy|legacy&&[left|right|center]",
- "justify-self": "auto|normal|stretch|<baseline-position>|<overflow-position>? [<self-position>|left|right]",
- left: "<length>|<percentage>|auto",
- "letter-spacing": "normal|<length-percentage>",
- "line-break": "auto|loose|normal|strict",
- "line-clamp": "none|<integer>",
- "line-height": "normal|<number>|<length>|<percentage>",
- "line-height-step": "<length>",
- "list-style": "<'list-style-type'>||<'list-style-position'>||<'list-style-image'>",
- "list-style-image": "<url>|none",
- "list-style-position": "inside|outside",
- "list-style-type": "<counter-style>|<string>|none",
- margin: "[<length>|<percentage>|auto]{1,4}",
- "margin-block": "<'margin-left'>{1,2}",
- "margin-block-end": "<'margin-left'>",
- "margin-block-start": "<'margin-left'>",
- "margin-bottom": "<length>|<percentage>|auto",
- "margin-inline": "<'margin-left'>{1,2}",
- "margin-inline-end": "<'margin-left'>",
- "margin-inline-start": "<'margin-left'>",
- "margin-left": "<length>|<percentage>|auto",
- "margin-right": "<length>|<percentage>|auto",
- "margin-top": "<length>|<percentage>|auto",
- mask: "<mask-layer>#",
- "mask-border": "<'mask-border-source'>||<'mask-border-slice'> [/ <'mask-border-width'>? [/ <'mask-border-outset'>]?]?||<'mask-border-repeat'>||<'mask-border-mode'>",
- "mask-border-mode": "luminance|alpha",
- "mask-border-outset": "[<length>|<number>]{1,4}",
- "mask-border-repeat": "[stretch|repeat|round|space]{1,2}",
- "mask-border-slice": "<number-percentage>{1,4} fill?",
- "mask-border-source": "none|<image>",
- "mask-border-width": "[<length-percentage>|<number>|auto]{1,4}",
- "mask-clip": "[<geometry-box>|no-clip]#",
- "mask-composite": "<compositing-operator>#",
- "mask-image": "<mask-reference>#",
- "mask-mode": "<masking-mode>#",
- "mask-origin": "<geometry-box>#",
- "mask-position": "<position>#",
- "mask-repeat": "<repeat-style>#",
- "mask-size": "<bg-size>#",
- "mask-type": "luminance|alpha",
- "max-block-size": "<'max-width'>",
- "max-height": "<length>|<percentage>|none|max-content|min-content|fit-content|fill-available",
- "max-inline-size": "<'max-width'>",
- "max-lines": "none|<integer>",
- "max-width": "<length>|<percentage>|none|max-content|min-content|fit-content|fill-available|<-non-standard-width>",
- "min-block-size": "<'min-width'>",
- "min-height": "<length>|<percentage>|auto|max-content|min-content|fit-content|fill-available",
- "min-inline-size": "<'min-width'>",
- "min-width": "<length>|<percentage>|auto|max-content|min-content|fit-content|fill-available|<-non-standard-width>",
- "mix-blend-mode": "<blend-mode>",
- "object-fit": "fill|contain|cover|none|scale-down",
- "object-position": "<position>",
- offset: "[<'offset-position'>? [<'offset-path'> [<'offset-distance'>||<'offset-rotate'>]?]?]! [/ <'offset-anchor'>]?",
- "offset-anchor": "auto|<position>",
- "offset-distance": "<length-percentage>",
- "offset-path": "none|ray( [<angle>&&<size>?&&contain?] )|<path()>|<url>|[<basic-shape>||<geometry-box>]",
- "offset-position": "auto|<position>",
- "offset-rotate": "[auto|reverse]||<angle>",
- opacity: "<number-zero-one>",
- order: "<integer>",
- orphans: "<integer>",
- outline: "[<'outline-color'>||<'outline-style'>||<'outline-width'>]",
- "outline-color": "<color>|invert",
- "outline-offset": "<length>",
- "outline-style": "auto|<'border-style'>",
- "outline-width": "<line-width>",
- overflow: "[visible|hidden|clip|scroll|auto]{1,2}|<-non-standard-overflow>",
- "overflow-anchor": "auto|none",
- "overflow-block": "visible|hidden|clip|scroll|auto",
- "overflow-clip-box": "padding-box|content-box",
- "overflow-inline": "visible|hidden|clip|scroll|auto",
- "overflow-wrap": "normal|break-word|anywhere",
- "overflow-x": "visible|hidden|clip|scroll|auto",
- "overflow-y": "visible|hidden|clip|scroll|auto",
- "overscroll-behavior": "[contain|none|auto]{1,2}",
- "overscroll-behavior-x": "contain|none|auto",
- "overscroll-behavior-y": "contain|none|auto",
- padding: "[<length>|<percentage>]{1,4}",
- "padding-block": "<'padding-left'>{1,2}",
- "padding-block-end": "<'padding-left'>",
- "padding-block-start": "<'padding-left'>",
- "padding-bottom": "<length>|<percentage>",
- "padding-inline": "<'padding-left'>{1,2}",
- "padding-inline-end": "<'padding-left'>",
- "padding-inline-start": "<'padding-left'>",
- "padding-left": "<length>|<percentage>",
- "padding-right": "<length>|<percentage>",
- "padding-top": "<length>|<percentage>",
- "page-break-after": "auto|always|avoid|left|right|recto|verso",
- "page-break-before": "auto|always|avoid|left|right|recto|verso",
- "page-break-inside": "auto|avoid",
- "paint-order": "normal|[fill||stroke||markers]",
- perspective: "none|<length>",
- "perspective-origin": "<position>",
- "place-content": "<'align-content'> <'justify-content'>?",
- "place-items": "<'align-items'> <'justify-items'>?",
- "place-self": "<'align-self'> <'justify-self'>?",
- "pointer-events": "auto|none|visiblePainted|visibleFill|visibleStroke|visible|painted|fill|stroke|all|inherit",
- position: "static|relative|absolute|sticky|fixed|-webkit-sticky",
- quotes: "none|[<string> <string>]+",
- resize: "none|both|horizontal|vertical|block|inline",
- right: "<length>|<percentage>|auto",
- rotate: "none|<angle>|[x|y|z|<number>{3}]&&<angle>",
- "row-gap": "normal|<length-percentage>",
- "ruby-align": "start|center|space-between|space-around",
- "ruby-merge": "separate|collapse|auto",
- "ruby-position": "over|under|inter-character",
- scale: "none|<number>{1,3}",
- "scrollbar-color": "auto|dark|light|<color>{2}",
- "scrollbar-width": "auto|thin|none",
- "scroll-behavior": "auto|smooth",
- "scroll-margin": "<length>{1,4}",
- "scroll-margin-block": "<length>{1,2}",
- "scroll-margin-block-start": "<length>",
- "scroll-margin-block-end": "<length>",
- "scroll-margin-bottom": "<length>",
- "scroll-margin-inline": "<length>{1,2}",
- "scroll-margin-inline-start": "<length>",
- "scroll-margin-inline-end": "<length>",
- "scroll-margin-left": "<length>",
- "scroll-margin-right": "<length>",
- "scroll-margin-top": "<length>",
- "scroll-padding": "[auto|<length-percentage>]{1,4}",
- "scroll-padding-block": "[auto|<length-percentage>]{1,2}",
- "scroll-padding-block-start": "auto|<length-percentage>",
- "scroll-padding-block-end": "auto|<length-percentage>",
- "scroll-padding-bottom": "auto|<length-percentage>",
- "scroll-padding-inline": "[auto|<length-percentage>]{1,2}",
- "scroll-padding-inline-start": "auto|<length-percentage>",
- "scroll-padding-inline-end": "auto|<length-percentage>",
- "scroll-padding-left": "auto|<length-percentage>",
- "scroll-padding-right": "auto|<length-percentage>",
- "scroll-padding-top": "auto|<length-percentage>",
- "scroll-snap-align": "[none|start|end|center]{1,2}",
- "scroll-snap-coordinate": "none|<position>#",
- "scroll-snap-destination": "<position>",
- "scroll-snap-points-x": "none|repeat( <length-percentage> )",
- "scroll-snap-points-y": "none|repeat( <length-percentage> )",
- "scroll-snap-stop": "normal|always",
- "scroll-snap-type": "none|[x|y|block|inline|both] [mandatory|proximity]?",
- "scroll-snap-type-x": "none|mandatory|proximity",
- "scroll-snap-type-y": "none|mandatory|proximity",
- "shape-image-threshold": "<number>",
- "shape-margin": "<length-percentage>",
- "shape-outside": "none|<shape-box>||<basic-shape>|<image>",
- "tab-size": "<integer>|<length>",
- "table-layout": "auto|fixed",
- "text-align": "start|end|left|right|center|justify|match-parent",
- "text-align-last": "auto|start|end|left|right|center|justify",
- "text-combine-upright": "none|all|[digits <integer>?]",
- "text-decoration": "<'text-decoration-line'>||<'text-decoration-style'>||<'text-decoration-color'>",
- "text-decoration-color": "<color>",
- "text-decoration-line": "none|[underline||overline||line-through||blink]",
- "text-decoration-skip": "none|[objects||[spaces|[leading-spaces||trailing-spaces]]||edges||box-decoration]",
- "text-decoration-skip-ink": "auto|none",
- "text-decoration-style": "solid|double|dotted|dashed|wavy",
- "text-emphasis": "<'text-emphasis-style'>||<'text-emphasis-color'>",
- "text-emphasis-color": "<color>",
- "text-emphasis-position": "[over|under]&&[right|left]",
- "text-emphasis-style": "none|[[filled|open]||[dot|circle|double-circle|triangle|sesame]]|<string>",
- "text-indent": "<length-percentage>&&hanging?&&each-line?",
- "text-justify": "auto|inter-character|inter-word|none",
- "text-orientation": "mixed|upright|sideways",
- "text-overflow": "[clip|ellipsis|<string>]{1,2}",
- "text-rendering": "auto|optimizeSpeed|optimizeLegibility|geometricPrecision",
- "text-shadow": "none|<shadow-t>#",
- "text-size-adjust": "none|auto|<percentage>",
- "text-transform": "none|capitalize|uppercase|lowercase|full-width|full-size-kana",
- "text-underline-position": "auto|[under||[left|right]]",
- top: "<length>|<percentage>|auto",
- "touch-action": "auto|none|[[pan-x|pan-left|pan-right]||[pan-y|pan-up|pan-down]||pinch-zoom]|manipulation",
- transform: "none|<transform-list>",
- "transform-box": "border-box|fill-box|view-box",
- "transform-origin": "[<length-percentage>|left|center|right|top|bottom]|[[<length-percentage>|left|center|right]&&[<length-percentage>|top|center|bottom]] <length>?",
- "transform-style": "flat|preserve-3d",
- transition: "<single-transition>#",
- "transition-delay": "<time>#",
- "transition-duration": "<time>#",
- "transition-property": "none|<single-transition-property>#",
- "transition-timing-function": "<timing-function>#",
- translate: "none|<length-percentage> [<length-percentage> <length>?]?",
- "unicode-bidi": "normal|embed|isolate|bidi-override|isolate-override|plaintext|-moz-isolate|-moz-isolate-override|-moz-plaintext|-webkit-isolate",
- "user-select": "auto|text|none|contain|all",
- "vertical-align": "baseline|sub|super|text-top|text-bottom|middle|top|bottom|<percentage>|<length>",
- visibility: "visible|hidden|collapse",
- "white-space": "normal|pre|nowrap|pre-wrap|pre-line",
- widows: "<integer>",
- width: "[<length>|<percentage>]&&[border-box|content-box]?|available|min-content|max-content|fit-content|auto",
- "will-change": "auto|<animateable-feature>#",
- "word-break": "normal|break-all|keep-all|break-word",
- "word-spacing": "normal|<length-percentage>",
- "word-wrap": "normal|break-word",
- "writing-mode": "horizontal-tb|vertical-rl|vertical-lr|sideways-rl|sideways-lr|<svg-writing-mode>",
- "z-index": "auto|<integer>",
- zoom: "normal|reset|<number>|<percentage>",
- "-moz-background-clip": "padding|border",
- "-moz-border-radius-bottomleft": "<'border-bottom-left-radius'>",
- "-moz-border-radius-bottomright": "<'border-bottom-right-radius'>",
- "-moz-border-radius-topleft": "<'border-top-left-radius'>",
- "-moz-border-radius-topright": "<'border-bottom-right-radius'>",
- "-moz-osx-font-smoothing": "auto|grayscale",
- "-moz-user-select": "none|text|all|-moz-none",
- "-ms-flex-align": "start|end|center|baseline|stretch",
- "-ms-flex-item-align": "auto|start|end|center|baseline|stretch",
- "-ms-flex-line-pack": "start|end|center|justify|distribute|stretch",
- "-ms-flex-negative": "<'flex-shrink'>",
- "-ms-flex-pack": "start|end|center|justify|distribute",
- "-ms-flex-order": "<integer>",
- "-ms-flex-positive": "<'flex-grow'>",
- "-ms-flex-preferred-size": "<'flex-basis'>",
- "-ms-interpolation-mode": "nearest-neighbor|bicubic",
- "-ms-grid-column-align": "start|end|center|stretch",
- "-ms-grid-row-align": "start|end|center|stretch",
- "-webkit-background-clip": "[<box>|border|padding|content|text]#",
- "-webkit-column-break-after": "always|auto|avoid",
- "-webkit-column-break-before": "always|auto|avoid",
- "-webkit-column-break-inside": "always|auto|avoid",
- "-webkit-font-smoothing": "auto|none|antialiased|subpixel-antialiased",
- "-webkit-mask-box-image": "[<url>|<gradient>|none] [<length-percentage>{4} <-webkit-mask-box-repeat>{2}]?",
- "-webkit-print-color-adjust": "economy|exact",
- "-webkit-text-security": "none|circle|disc|square",
- "-webkit-user-drag": "none|element|auto",
- "-webkit-user-select": "auto|none|text|all",
- "alignment-baseline": "auto|baseline|before-edge|text-before-edge|middle|central|after-edge|text-after-edge|ideographic|alphabetic|hanging|mathematical",
- "baseline-shift": "baseline|sub|super|<svg-length>",
- behavior: "<url>+",
- "clip-rule": "nonzero|evenodd",
- cue: "<'cue-before'> <'cue-after'>?",
- "cue-after": "<url> <decibel>?|none",
- "cue-before": "<url> <decibel>?|none",
- "dominant-baseline": "auto|use-script|no-change|reset-size|ideographic|alphabetic|hanging|mathematical|central|middle|text-after-edge|text-before-edge",
- fill: "<paint>",
- "fill-opacity": "<number-zero-one>",
- "fill-rule": "nonzero|evenodd",
- "glyph-orientation-horizontal": "<angle>",
- "glyph-orientation-vertical": "<angle>",
- kerning: "auto|<svg-length>",
- marker: "none|<url>",
- "marker-end": "none|<url>",
- "marker-mid": "none|<url>",
- "marker-start": "none|<url>",
- pause: "<'pause-before'> <'pause-after'>?",
- "pause-after": "<time>|none|x-weak|weak|medium|strong|x-strong",
- "pause-before": "<time>|none|x-weak|weak|medium|strong|x-strong",
- rest: "<'rest-before'> <'rest-after'>?",
- "rest-after": "<time>|none|x-weak|weak|medium|strong|x-strong",
- "rest-before": "<time>|none|x-weak|weak|medium|strong|x-strong",
- "shape-rendering": "auto|optimizeSpeed|crispEdges|geometricPrecision",
- src: "[<url> [format( <string># )]?|local( <family-name> )]#",
- speak: "auto|none|normal",
- "speak-as": "normal|spell-out||digits||[literal-punctuation|no-punctuation]",
- stroke: "<paint>",
- "stroke-dasharray": "none|[<svg-length>+]#",
- "stroke-dashoffset": "<svg-length>",
- "stroke-linecap": "butt|round|square",
- "stroke-linejoin": "miter|round|bevel",
- "stroke-miterlimit": "<number-one-or-greater>",
- "stroke-opacity": "<number-zero-one>",
- "stroke-width": "<svg-length>",
- "text-anchor": "start|middle|end",
- "unicode-range": "<urange>#",
- "voice-balance": "<number>|left|center|right|leftwards|rightwards",
- "voice-duration": "auto|<time>",
- "voice-family": "[[<family-name>|<generic-voice>] ,]* [<family-name>|<generic-voice>]|preserve",
- "voice-pitch": "<frequency>&&absolute|[[x-low|low|medium|high|x-high]||[<frequency>|<semitones>|<percentage>]]",
- "voice-range": "<frequency>&&absolute|[[x-low|low|medium|high|x-high]||[<frequency>|<semitones>|<percentage>]]",
- "voice-rate": "[normal|x-slow|slow|medium|fast|x-fast]||<percentage>",
- "voice-stress": "normal|strong|moderate|none|reduced",
- "voice-volume": "silent|[[x-soft|soft|medium|loud|x-loud]||<decibel>]"
- };
- var defaultSyntax = {
- generic: generic$1,
- types: types,
- properties: properties$1
- };
- var defaultSyntax$1 = /*#__PURE__*/Object.freeze({
- __proto__: null,
- generic: generic$1,
- types: types,
- properties: properties$1,
- 'default': defaultSyntax
- });
- var cmpChar$3 = tokenizer.cmpChar;
- var isDigit$4 = tokenizer.isDigit;
- var TYPE$9 = tokenizer.TYPE;
- var WHITESPACE$4 = TYPE$9.WhiteSpace;
- var COMMENT$3 = TYPE$9.Comment;
- var IDENT$3 = TYPE$9.Ident;
- var NUMBER$3 = TYPE$9.Number;
- var DIMENSION$2 = TYPE$9.Dimension;
- var PLUSSIGN$3 = 0x002B; // U+002B PLUS SIGN (+)
- var HYPHENMINUS$3 = 0x002D; // U+002D HYPHEN-MINUS (-)
- var N$4 = 0x006E; // U+006E LATIN SMALL LETTER N (n)
- var DISALLOW_SIGN$1 = true;
- var ALLOW_SIGN$1 = false;
- function checkInteger$1(offset, disallowSign) {
- var pos = this.scanner.tokenStart + offset;
- var code = this.scanner.source.charCodeAt(pos);
- if (code === PLUSSIGN$3 || code === HYPHENMINUS$3) {
- if (disallowSign) {
- this.error('Number sign is not allowed');
- }
- pos++;
- }
- for (; pos < this.scanner.tokenEnd; pos++) {
- if (!isDigit$4(this.scanner.source.charCodeAt(pos))) {
- this.error('Integer is expected', pos);
- }
- }
- }
- function checkTokenIsInteger(disallowSign) {
- return checkInteger$1.call(this, 0, disallowSign);
- }
- function expectCharCode(offset, code) {
- if (!cmpChar$3(this.scanner.source, this.scanner.tokenStart + offset, code)) {
- var msg = '';
- switch (code) {
- case N$4:
- msg = 'N is expected';
- break;
- case HYPHENMINUS$3:
- msg = 'HyphenMinus is expected';
- break;
- }
- this.error(msg, this.scanner.tokenStart + offset);
- }
- }
- // ... <signed-integer>
- // ... ['+' | '-'] <signless-integer>
- function consumeB$1() {
- var offset = 0;
- var sign = 0;
- var type = this.scanner.tokenType;
- while (type === WHITESPACE$4 || type === COMMENT$3) {
- type = this.scanner.lookupType(++offset);
- }
- if (type !== NUMBER$3) {
- if (this.scanner.isDelim(PLUSSIGN$3, offset) ||
- this.scanner.isDelim(HYPHENMINUS$3, offset)) {
- sign = this.scanner.isDelim(PLUSSIGN$3, offset) ? PLUSSIGN$3 : HYPHENMINUS$3;
- do {
- type = this.scanner.lookupType(++offset);
- } while (type === WHITESPACE$4 || type === COMMENT$3);
- if (type !== NUMBER$3) {
- this.scanner.skip(offset);
- checkTokenIsInteger.call(this, DISALLOW_SIGN$1);
- }
- } else {
- return null;
- }
- }
- if (offset > 0) {
- this.scanner.skip(offset);
- }
- if (sign === 0) {
- type = this.scanner.source.charCodeAt(this.scanner.tokenStart);
- if (type !== PLUSSIGN$3 && type !== HYPHENMINUS$3) {
- this.error('Number sign is expected');
- }
- }
- checkTokenIsInteger.call(this, sign !== 0);
- return sign === HYPHENMINUS$3 ? '-' + this.consume(NUMBER$3) : this.consume(NUMBER$3);
- }
- // An+B microsyntax https://www.w3.org/TR/css-syntax-3/#anb
- var AnPlusB = {
- name: 'AnPlusB',
- structure: {
- a: [String, null],
- b: [String, null]
- },
- parse: function() {
- /* eslint-disable brace-style*/
- var start = this.scanner.tokenStart;
- var a = null;
- var b = null;
- // <integer>
- if (this.scanner.tokenType === NUMBER$3) {
- checkTokenIsInteger.call(this, ALLOW_SIGN$1);
- b = this.consume(NUMBER$3);
- }
- // -n
- // -n <signed-integer>
- // -n ['+' | '-'] <signless-integer>
- // -n- <signless-integer>
- // <dashndashdigit-ident>
- else if (this.scanner.tokenType === IDENT$3 && cmpChar$3(this.scanner.source, this.scanner.tokenStart, HYPHENMINUS$3)) {
- a = '-1';
- expectCharCode.call(this, 1, N$4);
- switch (this.scanner.getTokenLength()) {
- // -n
- // -n <signed-integer>
- // -n ['+' | '-'] <signless-integer>
- case 2:
- this.scanner.next();
- b = consumeB$1.call(this);
- break;
- // -n- <signless-integer>
- case 3:
- expectCharCode.call(this, 2, HYPHENMINUS$3);
- this.scanner.next();
- this.scanner.skipSC();
- checkTokenIsInteger.call(this, DISALLOW_SIGN$1);
- b = '-' + this.consume(NUMBER$3);
- break;
- // <dashndashdigit-ident>
- default:
- expectCharCode.call(this, 2, HYPHENMINUS$3);
- checkInteger$1.call(this, 3, DISALLOW_SIGN$1);
- this.scanner.next();
- b = this.scanner.substrToCursor(start + 2);
- }
- }
- // '+'? n
- // '+'? n <signed-integer>
- // '+'? n ['+' | '-'] <signless-integer>
- // '+'? n- <signless-integer>
- // '+'? <ndashdigit-ident>
- else if (this.scanner.tokenType === IDENT$3 || (this.scanner.isDelim(PLUSSIGN$3) && this.scanner.lookupType(1) === IDENT$3)) {
- var sign = 0;
- a = '1';
- // just ignore a plus
- if (this.scanner.isDelim(PLUSSIGN$3)) {
- sign = 1;
- this.scanner.next();
- }
- expectCharCode.call(this, 0, N$4);
- switch (this.scanner.getTokenLength()) {
- // '+'? n
- // '+'? n <signed-integer>
- // '+'? n ['+' | '-'] <signless-integer>
- case 1:
- this.scanner.next();
- b = consumeB$1.call(this);
- break;
- // '+'? n- <signless-integer>
- case 2:
- expectCharCode.call(this, 1, HYPHENMINUS$3);
- this.scanner.next();
- this.scanner.skipSC();
- checkTokenIsInteger.call(this, DISALLOW_SIGN$1);
- b = '-' + this.consume(NUMBER$3);
- break;
- // '+'? <ndashdigit-ident>
- default:
- expectCharCode.call(this, 1, HYPHENMINUS$3);
- checkInteger$1.call(this, 2, DISALLOW_SIGN$1);
- this.scanner.next();
- b = this.scanner.substrToCursor(start + sign + 1);
- }
- }
- // <ndashdigit-dimension>
- // <ndash-dimension> <signless-integer>
- // <n-dimension>
- // <n-dimension> <signed-integer>
- // <n-dimension> ['+' | '-'] <signless-integer>
- else if (this.scanner.tokenType === DIMENSION$2) {
- var code = this.scanner.source.charCodeAt(this.scanner.tokenStart);
- var sign = code === PLUSSIGN$3 || code === HYPHENMINUS$3;
- for (var i = this.scanner.tokenStart + sign; i < this.scanner.tokenEnd; i++) {
- if (!isDigit$4(this.scanner.source.charCodeAt(i))) {
- break;
- }
- }
- if (i === this.scanner.tokenStart + sign) {
- this.error('Integer is expected', this.scanner.tokenStart + sign);
- }
- expectCharCode.call(this, i - this.scanner.tokenStart, N$4);
- a = this.scanner.source.substring(start, i);
- // <n-dimension>
- // <n-dimension> <signed-integer>
- // <n-dimension> ['+' | '-'] <signless-integer>
- if (i + 1 === this.scanner.tokenEnd) {
- this.scanner.next();
- b = consumeB$1.call(this);
- } else {
- expectCharCode.call(this, i - this.scanner.tokenStart + 1, HYPHENMINUS$3);
- // <ndash-dimension> <signless-integer>
- if (i + 2 === this.scanner.tokenEnd) {
- this.scanner.next();
- this.scanner.skipSC();
- checkTokenIsInteger.call(this, DISALLOW_SIGN$1);
- b = '-' + this.consume(NUMBER$3);
- }
- // <ndashdigit-dimension>
- else {
- checkInteger$1.call(this, i - this.scanner.tokenStart + 2, DISALLOW_SIGN$1);
- this.scanner.next();
- b = this.scanner.substrToCursor(i + 1);
- }
- }
- } else {
- this.error();
- }
- if (a !== null && a.charCodeAt(0) === PLUSSIGN$3) {
- a = a.substr(1);
- }
- if (b !== null && b.charCodeAt(0) === PLUSSIGN$3) {
- b = b.substr(1);
- }
- return {
- type: 'AnPlusB',
- loc: this.getLocation(start, this.scanner.tokenStart),
- a: a,
- b: b
- };
- },
- generate: function(node) {
- var a = node.a !== null && node.a !== undefined;
- var b = node.b !== null && node.b !== undefined;
- if (a) {
- this.chunk(
- node.a === '+1' ? '+n' : // eslint-disable-line operator-linebreak, indent
- node.a === '1' ? 'n' : // eslint-disable-line operator-linebreak, indent
- node.a === '-1' ? '-n' : // eslint-disable-line operator-linebreak, indent
- node.a + 'n' // eslint-disable-line operator-linebreak, indent
- );
- if (b) {
- b = String(node.b);
- if (b.charAt(0) === '-' || b.charAt(0) === '+') {
- this.chunk(b.charAt(0));
- this.chunk(b.substr(1));
- } else {
- this.chunk('+');
- this.chunk(b);
- }
- }
- } else {
- this.chunk(String(node.b));
- }
- }
- };
- var TYPE$a = tokenizer.TYPE;
- var WhiteSpace = TYPE$a.WhiteSpace;
- var Semicolon = TYPE$a.Semicolon;
- var LeftCurlyBracket = TYPE$a.LeftCurlyBracket;
- var Delim = TYPE$a.Delim;
- var EXCLAMATIONMARK$1 = 0x0021; // U+0021 EXCLAMATION MARK (!)
- function getOffsetExcludeWS() {
- if (this.scanner.tokenIndex > 0) {
- if (this.scanner.lookupType(-1) === WhiteSpace) {
- return this.scanner.tokenIndex > 1
- ? this.scanner.getTokenStart(this.scanner.tokenIndex - 1)
- : this.scanner.firstCharOffset;
- }
- }
- return this.scanner.tokenStart;
- }
- // 0, 0, false
- function balanceEnd() {
- return 0;
- }
- // LEFTCURLYBRACKET, 0, false
- function leftCurlyBracket(tokenType) {
- return tokenType === LeftCurlyBracket ? 1 : 0;
- }
- // LEFTCURLYBRACKET, SEMICOLON, false
- function leftCurlyBracketOrSemicolon(tokenType) {
- return tokenType === LeftCurlyBracket || tokenType === Semicolon ? 1 : 0;
- }
- // EXCLAMATIONMARK, SEMICOLON, false
- function exclamationMarkOrSemicolon(tokenType, source, offset) {
- if (tokenType === Delim && source.charCodeAt(offset) === EXCLAMATIONMARK$1) {
- return 1;
- }
- return tokenType === Semicolon ? 1 : 0;
- }
- // 0, SEMICOLON, true
- function semicolonIncluded(tokenType) {
- return tokenType === Semicolon ? 2 : 0;
- }
- var Raw = {
- name: 'Raw',
- structure: {
- value: String
- },
- parse: function(startToken, mode, excludeWhiteSpace) {
- var startOffset = this.scanner.getTokenStart(startToken);
- var endOffset;
- this.scanner.skip(
- this.scanner.getRawLength(startToken, mode || balanceEnd)
- );
- if (excludeWhiteSpace && this.scanner.tokenStart > startOffset) {
- endOffset = getOffsetExcludeWS.call(this);
- } else {
- endOffset = this.scanner.tokenStart;
- }
- return {
- type: 'Raw',
- loc: this.getLocation(startOffset, endOffset),
- value: this.scanner.source.substring(startOffset, endOffset)
- };
- },
- generate: function(node) {
- this.chunk(node.value);
- },
- mode: {
- default: balanceEnd,
- leftCurlyBracket: leftCurlyBracket,
- leftCurlyBracketOrSemicolon: leftCurlyBracketOrSemicolon,
- exclamationMarkOrSemicolon: exclamationMarkOrSemicolon,
- semicolonIncluded: semicolonIncluded
- }
- };
- var TYPE$b = tokenizer.TYPE;
- var rawMode = Raw.mode;
- var ATKEYWORD = TYPE$b.AtKeyword;
- var SEMICOLON = TYPE$b.Semicolon;
- var LEFTCURLYBRACKET$1 = TYPE$b.LeftCurlyBracket;
- var RIGHTCURLYBRACKET$1 = TYPE$b.RightCurlyBracket;
- function consumeRaw(startToken) {
- return this.Raw(startToken, rawMode.leftCurlyBracketOrSemicolon, true);
- }
- function isDeclarationBlockAtrule() {
- for (var offset = 1, type; type = this.scanner.lookupType(offset); offset++) {
- if (type === RIGHTCURLYBRACKET$1) {
- return true;
- }
- if (type === LEFTCURLYBRACKET$1 ||
- type === ATKEYWORD) {
- return false;
- }
- }
- return false;
- }
- var Atrule = {
- name: 'Atrule',
- structure: {
- name: String,
- prelude: ['AtrulePrelude', 'Raw', null],
- block: ['Block', null]
- },
- parse: function() {
- var start = this.scanner.tokenStart;
- var name;
- var nameLowerCase;
- var prelude = null;
- var block = null;
- this.eat(ATKEYWORD);
- name = this.scanner.substrToCursor(start + 1);
- nameLowerCase = name.toLowerCase();
- this.scanner.skipSC();
- // parse prelude
- if (this.scanner.eof === false &&
- this.scanner.tokenType !== LEFTCURLYBRACKET$1 &&
- this.scanner.tokenType !== SEMICOLON) {
- if (this.parseAtrulePrelude) {
- prelude = this.parseWithFallback(this.AtrulePrelude.bind(this, name), consumeRaw);
- // turn empty AtrulePrelude into null
- if (prelude.type === 'AtrulePrelude' && prelude.children.head === null) {
- prelude = null;
- }
- } else {
- prelude = consumeRaw.call(this, this.scanner.tokenIndex);
- }
- this.scanner.skipSC();
- }
- switch (this.scanner.tokenType) {
- case SEMICOLON:
- this.scanner.next();
- break;
- case LEFTCURLYBRACKET$1:
- if (this.atrule.hasOwnProperty(nameLowerCase) &&
- typeof this.atrule[nameLowerCase].block === 'function') {
- block = this.atrule[nameLowerCase].block.call(this);
- } else {
- // TODO: should consume block content as Raw?
- block = this.Block(isDeclarationBlockAtrule.call(this));
- }
- break;
- }
- return {
- type: 'Atrule',
- loc: this.getLocation(start, this.scanner.tokenStart),
- name: name,
- prelude: prelude,
- block: block
- };
- },
- generate: function(node) {
- this.chunk('@');
- this.chunk(node.name);
- if (node.prelude !== null) {
- this.chunk(' ');
- this.node(node.prelude);
- }
- if (node.block) {
- this.node(node.block);
- } else {
- this.chunk(';');
- }
- },
- walkContext: 'atrule'
- };
- var TYPE$c = tokenizer.TYPE;
- var SEMICOLON$1 = TYPE$c.Semicolon;
- var LEFTCURLYBRACKET$2 = TYPE$c.LeftCurlyBracket;
- var AtrulePrelude = {
- name: 'AtrulePrelude',
- structure: {
- children: [[]]
- },
- parse: function(name) {
- var children = null;
- if (name !== null) {
- name = name.toLowerCase();
- }
- this.scanner.skipSC();
- if (this.atrule.hasOwnProperty(name) &&
- typeof this.atrule[name].prelude === 'function') {
- // custom consumer
- children = this.atrule[name].prelude.call(this);
- } else {
- // default consumer
- children = this.readSequence(this.scope.AtrulePrelude);
- }
- this.scanner.skipSC();
- if (this.scanner.eof !== true &&
- this.scanner.tokenType !== LEFTCURLYBRACKET$2 &&
- this.scanner.tokenType !== SEMICOLON$1) {
- this.error('Semicolon or block is expected');
- }
- if (children === null) {
- children = this.createList();
- }
- return {
- type: 'AtrulePrelude',
- loc: this.getLocationFromList(children),
- children: children
- };
- },
- generate: function(node) {
- this.children(node);
- },
- walkContext: 'atrulePrelude'
- };
- var TYPE$d = tokenizer.TYPE;
- var IDENT$4 = TYPE$d.Ident;
- var STRING = TYPE$d.String;
- var COLON = TYPE$d.Colon;
- var LEFTSQUAREBRACKET$1 = TYPE$d.LeftSquareBracket;
- var RIGHTSQUAREBRACKET$1 = TYPE$d.RightSquareBracket;
- var DOLLARSIGN = 0x0024; // U+0024 DOLLAR SIGN ($)
- var ASTERISK$1 = 0x002A; // U+002A ASTERISK (*)
- var EQUALSSIGN = 0x003D; // U+003D EQUALS SIGN (=)
- var CIRCUMFLEXACCENT = 0x005E; // U+005E (^)
- var VERTICALLINE$1 = 0x007C; // U+007C VERTICAL LINE (|)
- var TILDE = 0x007E; // U+007E TILDE (~)
- function getAttributeName() {
- if (this.scanner.eof) {
- this.error('Unexpected end of input');
- }
- var start = this.scanner.tokenStart;
- var expectIdent = false;
- var checkColon = true;
- if (this.scanner.isDelim(ASTERISK$1)) {
- expectIdent = true;
- checkColon = false;
- this.scanner.next();
- } else if (!this.scanner.isDelim(VERTICALLINE$1)) {
- this.eat(IDENT$4);
- }
- if (this.scanner.isDelim(VERTICALLINE$1)) {
- if (this.scanner.source.charCodeAt(this.scanner.tokenStart + 1) !== EQUALSSIGN) {
- this.scanner.next();
- this.eat(IDENT$4);
- } else if (expectIdent) {
- this.error('Identifier is expected', this.scanner.tokenEnd);
- }
- } else if (expectIdent) {
- this.error('Vertical line is expected');
- }
- if (checkColon && this.scanner.tokenType === COLON) {
- this.scanner.next();
- this.eat(IDENT$4);
- }
- return {
- type: 'Identifier',
- loc: this.getLocation(start, this.scanner.tokenStart),
- name: this.scanner.substrToCursor(start)
- };
- }
- function getOperator() {
- var start = this.scanner.tokenStart;
- var code = this.scanner.source.charCodeAt(start);
- if (code !== EQUALSSIGN && // =
- code !== TILDE && // ~=
- code !== CIRCUMFLEXACCENT && // ^=
- code !== DOLLARSIGN && // $=
- code !== ASTERISK$1 && // *=
- code !== VERTICALLINE$1 // |=
- ) {
- this.error('Attribute selector (=, ~=, ^=, $=, *=, |=) is expected');
- }
- this.scanner.next();
- if (code !== EQUALSSIGN) {
- if (!this.scanner.isDelim(EQUALSSIGN)) {
- this.error('Equal sign is expected');
- }
- this.scanner.next();
- }
- return this.scanner.substrToCursor(start);
- }
- // '[' <wq-name> ']'
- // '[' <wq-name> <attr-matcher> [ <string-token> | <ident-token> ] <attr-modifier>? ']'
- var AttributeSelector = {
- name: 'AttributeSelector',
- structure: {
- name: 'Identifier',
- matcher: [String, null],
- value: ['String', 'Identifier', null],
- flags: [String, null]
- },
- parse: function() {
- var start = this.scanner.tokenStart;
- var name;
- var matcher = null;
- var value = null;
- var flags = null;
- this.eat(LEFTSQUAREBRACKET$1);
- this.scanner.skipSC();
- name = getAttributeName.call(this);
- this.scanner.skipSC();
- if (this.scanner.tokenType !== RIGHTSQUAREBRACKET$1) {
- // avoid case `[name i]`
- if (this.scanner.tokenType !== IDENT$4) {
- matcher = getOperator.call(this);
- this.scanner.skipSC();
- value = this.scanner.tokenType === STRING
- ? this.String()
- : this.Identifier();
- this.scanner.skipSC();
- }
- // attribute flags
- if (this.scanner.tokenType === IDENT$4) {
- flags = this.scanner.getTokenValue();
- this.scanner.next();
- this.scanner.skipSC();
- }
- }
- this.eat(RIGHTSQUAREBRACKET$1);
- return {
- type: 'AttributeSelector',
- loc: this.getLocation(start, this.scanner.tokenStart),
- name: name,
- matcher: matcher,
- value: value,
- flags: flags
- };
- },
- generate: function(node) {
- var flagsPrefix = ' ';
- this.chunk('[');
- this.node(node.name);
- if (node.matcher !== null) {
- this.chunk(node.matcher);
- if (node.value !== null) {
- this.node(node.value);
- // space between string and flags is not required
- if (node.value.type === 'String') {
- flagsPrefix = '';
- }
- }
- }
- if (node.flags !== null) {
- this.chunk(flagsPrefix);
- this.chunk(node.flags);
- }
- this.chunk(']');
- }
- };
- var TYPE$e = tokenizer.TYPE;
- var rawMode$1 = Raw.mode;
- var WHITESPACE$5 = TYPE$e.WhiteSpace;
- var COMMENT$4 = TYPE$e.Comment;
- var SEMICOLON$2 = TYPE$e.Semicolon;
- var ATKEYWORD$1 = TYPE$e.AtKeyword;
- var LEFTCURLYBRACKET$3 = TYPE$e.LeftCurlyBracket;
- var RIGHTCURLYBRACKET$2 = TYPE$e.RightCurlyBracket;
- function consumeRaw$1(startToken) {
- return this.Raw(startToken, null, true);
- }
- function consumeRule() {
- return this.parseWithFallback(this.Rule, consumeRaw$1);
- }
- function consumeRawDeclaration(startToken) {
- return this.Raw(startToken, rawMode$1.semicolonIncluded, true);
- }
- function consumeDeclaration() {
- if (this.scanner.tokenType === SEMICOLON$2) {
- return consumeRawDeclaration.call(this, this.scanner.tokenIndex);
- }
- var node = this.parseWithFallback(this.Declaration, consumeRawDeclaration);
- if (this.scanner.tokenType === SEMICOLON$2) {
- this.scanner.next();
- }
- return node;
- }
- var Block = {
- name: 'Block',
- structure: {
- children: [[
- 'Atrule',
- 'Rule',
- 'Declaration'
- ]]
- },
- parse: function(isDeclaration) {
- var consumer = isDeclaration ? consumeDeclaration : consumeRule;
- var start = this.scanner.tokenStart;
- var children = this.createList();
- this.eat(LEFTCURLYBRACKET$3);
- scan:
- while (!this.scanner.eof) {
- switch (this.scanner.tokenType) {
- case RIGHTCURLYBRACKET$2:
- break scan;
- case WHITESPACE$5:
- case COMMENT$4:
- this.scanner.next();
- break;
- case ATKEYWORD$1:
- children.push(this.parseWithFallback(this.Atrule, consumeRaw$1));
- break;
- default:
- children.push(consumer.call(this));
- }
- }
- if (!this.scanner.eof) {
- this.eat(RIGHTCURLYBRACKET$2);
- }
- return {
- type: 'Block',
- loc: this.getLocation(start, this.scanner.tokenStart),
- children: children
- };
- },
- generate: function(node) {
- this.chunk('{');
- this.children(node, function(prev) {
- if (prev.type === 'Declaration') {
- this.chunk(';');
- }
- });
- this.chunk('}');
- },
- walkContext: 'block'
- };
- var TYPE$f = tokenizer.TYPE;
- var LEFTSQUAREBRACKET$2 = TYPE$f.LeftSquareBracket;
- var RIGHTSQUAREBRACKET$2 = TYPE$f.RightSquareBracket;
- var Brackets = {
- name: 'Brackets',
- structure: {
- children: [[]]
- },
- parse: function(readSequence, recognizer) {
- var start = this.scanner.tokenStart;
- var children = null;
- this.eat(LEFTSQUAREBRACKET$2);
- children = readSequence.call(this, recognizer);
- if (!this.scanner.eof) {
- this.eat(RIGHTSQUAREBRACKET$2);
- }
- return {
- type: 'Brackets',
- loc: this.getLocation(start, this.scanner.tokenStart),
- children: children
- };
- },
- generate: function(node) {
- this.chunk('[');
- this.children(node);
- this.chunk(']');
- }
- };
- var CDC = tokenizer.TYPE.CDC;
- var CDC_1 = {
- name: 'CDC',
- structure: [],
- parse: function() {
- var start = this.scanner.tokenStart;
- this.eat(CDC); // -->
- return {
- type: 'CDC',
- loc: this.getLocation(start, this.scanner.tokenStart)
- };
- },
- generate: function() {
- this.chunk('-->');
- }
- };
- var CDO = tokenizer.TYPE.CDO;
- var CDO_1 = {
- name: 'CDO',
- structure: [],
- parse: function() {
- var start = this.scanner.tokenStart;
- this.eat(CDO); // <!--
- return {
- type: 'CDO',
- loc: this.getLocation(start, this.scanner.tokenStart)
- };
- },
- generate: function() {
- this.chunk('<!--');
- }
- };
- var TYPE$g = tokenizer.TYPE;
- var IDENT$5 = TYPE$g.Ident;
- var FULLSTOP = 0x002E; // U+002E FULL STOP (.)
- // '.' ident
- var ClassSelector = {
- name: 'ClassSelector',
- structure: {
- name: String
- },
- parse: function() {
- if (!this.scanner.isDelim(FULLSTOP)) {
- this.error('Full stop is expected');
- }
- this.scanner.next();
- return {
- type: 'ClassSelector',
- loc: this.getLocation(this.scanner.tokenStart - 1, this.scanner.tokenEnd),
- name: this.consume(IDENT$5)
- };
- },
- generate: function(node) {
- this.chunk('.');
- this.chunk(node.name);
- }
- };
- var TYPE$h = tokenizer.TYPE;
- var IDENT$6 = TYPE$h.Ident;
- var PLUSSIGN$4 = 0x002B; // U+002B PLUS SIGN (+)
- var SOLIDUS = 0x002F; // U+002F SOLIDUS (/)
- var GREATERTHANSIGN$1 = 0x003E; // U+003E GREATER-THAN SIGN (>)
- var TILDE$1 = 0x007E; // U+007E TILDE (~)
- // + | > | ~ | /deep/
- var Combinator = {
- name: 'Combinator',
- structure: {
- name: String
- },
- parse: function() {
- var start = this.scanner.tokenStart;
- var code = this.scanner.source.charCodeAt(this.scanner.tokenStart);
- switch (code) {
- case GREATERTHANSIGN$1:
- case PLUSSIGN$4:
- case TILDE$1:
- this.scanner.next();
- break;
- case SOLIDUS:
- this.scanner.next();
- if (this.scanner.tokenType !== IDENT$6 || this.scanner.lookupValue(0, 'deep') === false) {
- this.error('Identifier `deep` is expected');
- }
- this.scanner.next();
- if (!this.scanner.isDelim(SOLIDUS)) {
- this.error('Solidus is expected');
- }
- this.scanner.next();
- break;
- default:
- this.error('Combinator is expected');
- }
- return {
- type: 'Combinator',
- loc: this.getLocation(start, this.scanner.tokenStart),
- name: this.scanner.substrToCursor(start)
- };
- },
- generate: function(node) {
- this.chunk(node.name);
- }
- };
- var TYPE$i = tokenizer.TYPE;
- var COMMENT$5 = TYPE$i.Comment;
- var ASTERISK$2 = 0x002A; // U+002A ASTERISK (*)
- var SOLIDUS$1 = 0x002F; // U+002F SOLIDUS (/)
- // '/*' .* '*/'
- var Comment = {
- name: 'Comment',
- structure: {
- value: String
- },
- parse: function() {
- var start = this.scanner.tokenStart;
- var end = this.scanner.tokenEnd;
- this.eat(COMMENT$5);
- if ((end - start + 2) >= 2 &&
- this.scanner.source.charCodeAt(end - 2) === ASTERISK$2 &&
- this.scanner.source.charCodeAt(end - 1) === SOLIDUS$1) {
- end -= 2;
- }
- return {
- type: 'Comment',
- loc: this.getLocation(start, this.scanner.tokenStart),
- value: this.scanner.source.substring(start + 2, end)
- };
- },
- generate: function(node) {
- this.chunk('/*');
- this.chunk(node.value);
- this.chunk('*/');
- }
- };
- var isCustomProperty$1 = names.isCustomProperty;
- var TYPE$j = tokenizer.TYPE;
- var rawMode$2 = Raw.mode;
- var IDENT$7 = TYPE$j.Ident;
- var HASH$1 = TYPE$j.Hash;
- var COLON$1 = TYPE$j.Colon;
- var SEMICOLON$3 = TYPE$j.Semicolon;
- var DELIM$2 = TYPE$j.Delim;
- var EXCLAMATIONMARK$2 = 0x0021; // U+0021 EXCLAMATION MARK (!)
- var NUMBERSIGN$2 = 0x0023; // U+0023 NUMBER SIGN (#)
- var DOLLARSIGN$1 = 0x0024; // U+0024 DOLLAR SIGN ($)
- var AMPERSAND$1 = 0x0026; // U+0026 ANPERSAND (&)
- var ASTERISK$3 = 0x002A; // U+002A ASTERISK (*)
- var PLUSSIGN$5 = 0x002B; // U+002B PLUS SIGN (+)
- var SOLIDUS$2 = 0x002F; // U+002F SOLIDUS (/)
- function consumeValueRaw(startToken) {
- return this.Raw(startToken, rawMode$2.exclamationMarkOrSemicolon, true);
- }
- function consumeCustomPropertyRaw(startToken) {
- return this.Raw(startToken, rawMode$2.exclamationMarkOrSemicolon, false);
- }
- function consumeValue() {
- var startValueToken = this.scanner.tokenIndex;
- var value = this.Value();
- if (value.type !== 'Raw' &&
- this.scanner.eof === false &&
- this.scanner.tokenType !== SEMICOLON$3 &&
- this.scanner.isDelim(EXCLAMATIONMARK$2) === false &&
- this.scanner.isBalanceEdge(startValueToken) === false) {
- this.error();
- }
- return value;
- }
- var Declaration = {
- name: 'Declaration',
- structure: {
- important: [Boolean, String],
- property: String,
- value: ['Value', 'Raw']
- },
- parse: function() {
- var start = this.scanner.tokenStart;
- var startToken = this.scanner.tokenIndex;
- var property = readProperty$1.call(this);
- var customProperty = isCustomProperty$1(property);
- var parseValue = customProperty ? this.parseCustomProperty : this.parseValue;
- var consumeRaw = customProperty ? consumeCustomPropertyRaw : consumeValueRaw;
- var important = false;
- var value;
- this.scanner.skipSC();
- this.eat(COLON$1);
- if (!customProperty) {
- this.scanner.skipSC();
- }
- if (parseValue) {
- value = this.parseWithFallback(consumeValue, consumeRaw);
- } else {
- value = consumeRaw.call(this, this.scanner.tokenIndex);
- }
- if (this.scanner.isDelim(EXCLAMATIONMARK$2)) {
- important = getImportant.call(this);
- this.scanner.skipSC();
- }
- // Do not include semicolon to range per spec
- // https://drafts.csswg.org/css-syntax/#declaration-diagram
- if (this.scanner.eof === false &&
- this.scanner.tokenType !== SEMICOLON$3 &&
- this.scanner.isBalanceEdge(startToken) === false) {
- this.error();
- }
- return {
- type: 'Declaration',
- loc: this.getLocation(start, this.scanner.tokenStart),
- important: important,
- property: property,
- value: value
- };
- },
- generate: function(node) {
- this.chunk(node.property);
- this.chunk(':');
- this.node(node.value);
- if (node.important) {
- this.chunk(node.important === true ? '!important' : '!' + node.important);
- }
- },
- walkContext: 'declaration'
- };
- function readProperty$1() {
- var start = this.scanner.tokenStart;
- // hacks
- if (this.scanner.tokenType === DELIM$2) {
- switch (this.scanner.source.charCodeAt(this.scanner.tokenStart)) {
- case ASTERISK$3:
- case DOLLARSIGN$1:
- case PLUSSIGN$5:
- case NUMBERSIGN$2:
- case AMPERSAND$1:
- this.scanner.next();
- break;
- // TODO: not sure we should support this hack
- case SOLIDUS$2:
- this.scanner.next();
- if (this.scanner.isDelim(SOLIDUS$2)) {
- this.scanner.next();
- }
- break;
- }
- }
- if (this.scanner.tokenType === HASH$1) {
- this.eat(HASH$1);
- } else {
- this.eat(IDENT$7);
- }
- return this.scanner.substrToCursor(start);
- }
- // ! ws* important
- function getImportant() {
- this.eat(DELIM$2);
- this.scanner.skipSC();
- var important = this.consume(IDENT$7);
- // store original value in case it differ from `important`
- // for better original source restoring and hacks like `!ie` support
- return important === 'important' ? true : important;
- }
- var TYPE$k = tokenizer.TYPE;
- var rawMode$3 = Raw.mode;
- var WHITESPACE$6 = TYPE$k.WhiteSpace;
- var COMMENT$6 = TYPE$k.Comment;
- var SEMICOLON$4 = TYPE$k.Semicolon;
- function consumeRaw$2(startToken) {
- return this.Raw(startToken, rawMode$3.semicolonIncluded, true);
- }
- var DeclarationList = {
- name: 'DeclarationList',
- structure: {
- children: [[
- 'Declaration'
- ]]
- },
- parse: function() {
- var children = this.createList();
- scan:
- while (!this.scanner.eof) {
- switch (this.scanner.tokenType) {
- case WHITESPACE$6:
- case COMMENT$6:
- case SEMICOLON$4:
- this.scanner.next();
- break;
- default:
- children.push(this.parseWithFallback(this.Declaration, consumeRaw$2));
- }
- }
- return {
- type: 'DeclarationList',
- loc: this.getLocationFromList(children),
- children: children
- };
- },
- generate: function(node) {
- this.children(node, function(prev) {
- if (prev.type === 'Declaration') {
- this.chunk(';');
- }
- });
- }
- };
- var consumeNumber$3 = utils.consumeNumber;
- var TYPE$l = tokenizer.TYPE;
- var DIMENSION$3 = TYPE$l.Dimension;
- var Dimension = {
- name: 'Dimension',
- structure: {
- value: String,
- unit: String
- },
- parse: function() {
- var start = this.scanner.tokenStart;
- var numberEnd = consumeNumber$3(this.scanner.source, start);
- this.eat(DIMENSION$3);
- return {
- type: 'Dimension',
- loc: this.getLocation(start, this.scanner.tokenStart),
- value: this.scanner.source.substring(start, numberEnd),
- unit: this.scanner.source.substring(numberEnd, this.scanner.tokenStart)
- };
- },
- generate: function(node) {
- this.chunk(node.value);
- this.chunk(node.unit);
- }
- };
- var TYPE$m = tokenizer.TYPE;
- var RIGHTPARENTHESIS$2 = TYPE$m.RightParenthesis;
- // <function-token> <sequence> )
- var _Function = {
- name: 'Function',
- structure: {
- name: String,
- children: [[]]
- },
- parse: function(readSequence, recognizer) {
- var start = this.scanner.tokenStart;
- var name = this.consumeFunctionName();
- var nameLowerCase = name.toLowerCase();
- var children;
- children = recognizer.hasOwnProperty(nameLowerCase)
- ? recognizer[nameLowerCase].call(this, recognizer)
- : readSequence.call(this, recognizer);
- if (!this.scanner.eof) {
- this.eat(RIGHTPARENTHESIS$2);
- }
- return {
- type: 'Function',
- loc: this.getLocation(start, this.scanner.tokenStart),
- name: name,
- children: children
- };
- },
- generate: function(node) {
- this.chunk(node.name);
- this.chunk('(');
- this.children(node);
- this.chunk(')');
- },
- walkContext: 'function'
- };
- var TYPE$n = tokenizer.TYPE;
- var HASH$2 = TYPE$n.Hash;
- // '#' ident
- var HexColor = {
- name: 'HexColor',
- structure: {
- value: String
- },
- parse: function() {
- var start = this.scanner.tokenStart;
- this.eat(HASH$2);
- return {
- type: 'HexColor',
- loc: this.getLocation(start, this.scanner.tokenStart),
- value: this.scanner.substrToCursor(start + 1)
- };
- },
- generate: function(node) {
- this.chunk('#');
- this.chunk(node.value);
- }
- };
- var TYPE$o = tokenizer.TYPE;
- var IDENT$8 = TYPE$o.Ident;
- var Identifier = {
- name: 'Identifier',
- structure: {
- name: String
- },
- parse: function() {
- return {
- type: 'Identifier',
- loc: this.getLocation(this.scanner.tokenStart, this.scanner.tokenEnd),
- name: this.consume(IDENT$8)
- };
- },
- generate: function(node) {
- this.chunk(node.name);
- }
- };
- var TYPE$p = tokenizer.TYPE;
- var HASH$3 = TYPE$p.Hash;
- // <hash-token>
- var IdSelector = {
- name: 'IdSelector',
- structure: {
- name: String
- },
- parse: function() {
- var start = this.scanner.tokenStart;
- // TODO: check value is an ident
- this.eat(HASH$3);
- return {
- type: 'IdSelector',
- loc: this.getLocation(start, this.scanner.tokenStart),
- name: this.scanner.substrToCursor(start + 1)
- };
- },
- generate: function(node) {
- this.chunk('#');
- this.chunk(node.name);
- }
- };
- var TYPE$q = tokenizer.TYPE;
- var IDENT$9 = TYPE$q.Ident;
- var NUMBER$4 = TYPE$q.Number;
- var DIMENSION$4 = TYPE$q.Dimension;
- var LEFTPARENTHESIS$2 = TYPE$q.LeftParenthesis;
- var RIGHTPARENTHESIS$3 = TYPE$q.RightParenthesis;
- var COLON$2 = TYPE$q.Colon;
- var DELIM$3 = TYPE$q.Delim;
- var MediaFeature = {
- name: 'MediaFeature',
- structure: {
- name: String,
- value: ['Identifier', 'Number', 'Dimension', 'Ratio', null]
- },
- parse: function() {
- var start = this.scanner.tokenStart;
- var name;
- var value = null;
- this.eat(LEFTPARENTHESIS$2);
- this.scanner.skipSC();
- name = this.consume(IDENT$9);
- this.scanner.skipSC();
- if (this.scanner.tokenType !== RIGHTPARENTHESIS$3) {
- this.eat(COLON$2);
- this.scanner.skipSC();
- switch (this.scanner.tokenType) {
- case NUMBER$4:
- if (this.lookupNonWSType(1) === DELIM$3) {
- value = this.Ratio();
- } else {
- value = this.Number();
- }
- break;
- case DIMENSION$4:
- value = this.Dimension();
- break;
- case IDENT$9:
- value = this.Identifier();
- break;
- default:
- this.error('Number, dimension, ratio or identifier is expected');
- }
- this.scanner.skipSC();
- }
- this.eat(RIGHTPARENTHESIS$3);
- return {
- type: 'MediaFeature',
- loc: this.getLocation(start, this.scanner.tokenStart),
- name: name,
- value: value
- };
- },
- generate: function(node) {
- this.chunk('(');
- this.chunk(node.name);
- if (node.value !== null) {
- this.chunk(':');
- this.node(node.value);
- }
- this.chunk(')');
- }
- };
- var TYPE$r = tokenizer.TYPE;
- var WHITESPACE$7 = TYPE$r.WhiteSpace;
- var COMMENT$7 = TYPE$r.Comment;
- var IDENT$a = TYPE$r.Ident;
- var LEFTPARENTHESIS$3 = TYPE$r.LeftParenthesis;
- var MediaQuery = {
- name: 'MediaQuery',
- structure: {
- children: [[
- 'Identifier',
- 'MediaFeature',
- 'WhiteSpace'
- ]]
- },
- parse: function() {
- this.scanner.skipSC();
- var children = this.createList();
- var child = null;
- var space = null;
- scan:
- while (!this.scanner.eof) {
- switch (this.scanner.tokenType) {
- case COMMENT$7:
- this.scanner.next();
- continue;
- case WHITESPACE$7:
- space = this.WhiteSpace();
- continue;
- case IDENT$a:
- child = this.Identifier();
- break;
- case LEFTPARENTHESIS$3:
- child = this.MediaFeature();
- break;
- default:
- break scan;
- }
- if (space !== null) {
- children.push(space);
- space = null;
- }
- children.push(child);
- }
- if (child === null) {
- this.error('Identifier or parenthesis is expected');
- }
- return {
- type: 'MediaQuery',
- loc: this.getLocationFromList(children),
- children: children
- };
- },
- generate: function(node) {
- this.children(node);
- }
- };
- var COMMA$1 = tokenizer.TYPE.Comma;
- var MediaQueryList = {
- name: 'MediaQueryList',
- structure: {
- children: [[
- 'MediaQuery'
- ]]
- },
- parse: function(relative) {
- var children = this.createList();
- this.scanner.skipSC();
- while (!this.scanner.eof) {
- children.push(this.MediaQuery(relative));
- if (this.scanner.tokenType !== COMMA$1) {
- break;
- }
- this.scanner.next();
- }
- return {
- type: 'MediaQueryList',
- loc: this.getLocationFromList(children),
- children: children
- };
- },
- generate: function(node) {
- this.children(node, function() {
- this.chunk(',');
- });
- }
- };
- var Nth = {
- name: 'Nth',
- structure: {
- nth: ['AnPlusB', 'Identifier'],
- selector: ['SelectorList', null]
- },
- parse: function(allowOfClause) {
- this.scanner.skipSC();
- var start = this.scanner.tokenStart;
- var end = start;
- var selector = null;
- var query;
- if (this.scanner.lookupValue(0, 'odd') || this.scanner.lookupValue(0, 'even')) {
- query = this.Identifier();
- } else {
- query = this.AnPlusB();
- }
- this.scanner.skipSC();
- if (allowOfClause && this.scanner.lookupValue(0, 'of')) {
- this.scanner.next();
- selector = this.SelectorList();
- if (this.needPositions) {
- end = this.getLastListNode(selector.children).loc.end.offset;
- }
- } else {
- if (this.needPositions) {
- end = query.loc.end.offset;
- }
- }
- return {
- type: 'Nth',
- loc: this.getLocation(start, end),
- nth: query,
- selector: selector
- };
- },
- generate: function(node) {
- this.node(node.nth);
- if (node.selector !== null) {
- this.chunk(' of ');
- this.node(node.selector);
- }
- }
- };
- var NUMBER$5 = tokenizer.TYPE.Number;
- var _Number = {
- name: 'Number',
- structure: {
- value: String
- },
- parse: function() {
- return {
- type: 'Number',
- loc: this.getLocation(this.scanner.tokenStart, this.scanner.tokenEnd),
- value: this.consume(NUMBER$5)
- };
- },
- generate: function(node) {
- this.chunk(node.value);
- }
- };
- // '/' | '*' | ',' | ':' | '+' | '-'
- var Operator = {
- name: 'Operator',
- structure: {
- value: String
- },
- parse: function() {
- var start = this.scanner.tokenStart;
- this.scanner.next();
- return {
- type: 'Operator',
- loc: this.getLocation(start, this.scanner.tokenStart),
- value: this.scanner.substrToCursor(start)
- };
- },
- generate: function(node) {
- this.chunk(node.value);
- }
- };
- var TYPE$s = tokenizer.TYPE;
- var LEFTPARENTHESIS$4 = TYPE$s.LeftParenthesis;
- var RIGHTPARENTHESIS$4 = TYPE$s.RightParenthesis;
- var Parentheses = {
- name: 'Parentheses',
- structure: {
- children: [[]]
- },
- parse: function(readSequence, recognizer) {
- var start = this.scanner.tokenStart;
- var children = null;
- this.eat(LEFTPARENTHESIS$4);
- children = readSequence.call(this, recognizer);
- if (!this.scanner.eof) {
- this.eat(RIGHTPARENTHESIS$4);
- }
- return {
- type: 'Parentheses',
- loc: this.getLocation(start, this.scanner.tokenStart),
- children: children
- };
- },
- generate: function(node) {
- this.chunk('(');
- this.children(node);
- this.chunk(')');
- }
- };
- var consumeNumber$4 = utils.consumeNumber;
- var TYPE$t = tokenizer.TYPE;
- var PERCENTAGE$1 = TYPE$t.Percentage;
- var Percentage = {
- name: 'Percentage',
- structure: {
- value: String
- },
- parse: function() {
- var start = this.scanner.tokenStart;
- var numberEnd = consumeNumber$4(this.scanner.source, start);
- this.eat(PERCENTAGE$1);
- return {
- type: 'Percentage',
- loc: this.getLocation(start, this.scanner.tokenStart),
- value: this.scanner.source.substring(start, numberEnd)
- };
- },
- generate: function(node) {
- this.chunk(node.value);
- this.chunk('%');
- }
- };
- var TYPE$u = tokenizer.TYPE;
- var IDENT$b = TYPE$u.Ident;
- var FUNCTION$1 = TYPE$u.Function;
- var COLON$3 = TYPE$u.Colon;
- var RIGHTPARENTHESIS$5 = TYPE$u.RightParenthesis;
- // : [ <ident> | <function-token> <any-value>? ) ]
- var PseudoClassSelector = {
- name: 'PseudoClassSelector',
- structure: {
- name: String,
- children: [['Raw'], null]
- },
- parse: function() {
- var start = this.scanner.tokenStart;
- var children = null;
- var name;
- var nameLowerCase;
- this.eat(COLON$3);
- if (this.scanner.tokenType === FUNCTION$1) {
- name = this.consumeFunctionName();
- nameLowerCase = name.toLowerCase();
- if (this.pseudo.hasOwnProperty(nameLowerCase)) {
- this.scanner.skipSC();
- children = this.pseudo[nameLowerCase].call(this);
- this.scanner.skipSC();
- } else {
- children = this.createList();
- children.push(
- this.Raw(this.scanner.tokenIndex, null, false)
- );
- }
- this.eat(RIGHTPARENTHESIS$5);
- } else {
- name = this.consume(IDENT$b);
- }
- return {
- type: 'PseudoClassSelector',
- loc: this.getLocation(start, this.scanner.tokenStart),
- name: name,
- children: children
- };
- },
- generate: function(node) {
- this.chunk(':');
- this.chunk(node.name);
- if (node.children !== null) {
- this.chunk('(');
- this.children(node);
- this.chunk(')');
- }
- },
- walkContext: 'function'
- };
- var TYPE$v = tokenizer.TYPE;
- var IDENT$c = TYPE$v.Ident;
- var FUNCTION$2 = TYPE$v.Function;
- var COLON$4 = TYPE$v.Colon;
- var RIGHTPARENTHESIS$6 = TYPE$v.RightParenthesis;
- // :: [ <ident> | <function-token> <any-value>? ) ]
- var PseudoElementSelector = {
- name: 'PseudoElementSelector',
- structure: {
- name: String,
- children: [['Raw'], null]
- },
- parse: function() {
- var start = this.scanner.tokenStart;
- var children = null;
- var name;
- var nameLowerCase;
- this.eat(COLON$4);
- this.eat(COLON$4);
- if (this.scanner.tokenType === FUNCTION$2) {
- name = this.consumeFunctionName();
- nameLowerCase = name.toLowerCase();
- if (this.pseudo.hasOwnProperty(nameLowerCase)) {
- this.scanner.skipSC();
- children = this.pseudo[nameLowerCase].call(this);
- this.scanner.skipSC();
- } else {
- children = this.createList();
- children.push(
- this.Raw(this.scanner.tokenIndex, null, false)
- );
- }
- this.eat(RIGHTPARENTHESIS$6);
- } else {
- name = this.consume(IDENT$c);
- }
- return {
- type: 'PseudoElementSelector',
- loc: this.getLocation(start, this.scanner.tokenStart),
- name: name,
- children: children
- };
- },
- generate: function(node) {
- this.chunk('::');
- this.chunk(node.name);
- if (node.children !== null) {
- this.chunk('(');
- this.children(node);
- this.chunk(')');
- }
- },
- walkContext: 'function'
- };
- var isDigit$5 = tokenizer.isDigit;
- var TYPE$w = tokenizer.TYPE;
- var NUMBER$6 = TYPE$w.Number;
- var DELIM$4 = TYPE$w.Delim;
- var SOLIDUS$3 = 0x002F; // U+002F SOLIDUS (/)
- var FULLSTOP$1 = 0x002E; // U+002E FULL STOP (.)
- // Terms of <ratio> should be a positive numbers (not zero or negative)
- // (see https://drafts.csswg.org/mediaqueries-3/#values)
- // However, -o-min-device-pixel-ratio takes fractional values as a ratio's term
- // and this is using by various sites. Therefore we relax checking on parse
- // to test a term is unsigned number without an exponent part.
- // Additional checking may be applied on lexer validation.
- function consumeNumber$5() {
- this.scanner.skipWS();
- var value = this.consume(NUMBER$6);
- for (var i = 0; i < value.length; i++) {
- var code = value.charCodeAt(i);
- if (!isDigit$5(code) && code !== FULLSTOP$1) {
- this.error('Unsigned number is expected', this.scanner.tokenStart - value.length + i);
- }
- }
- if (Number(value) === 0) {
- this.error('Zero number is not allowed', this.scanner.tokenStart - value.length);
- }
- return value;
- }
- // <positive-integer> S* '/' S* <positive-integer>
- var Ratio = {
- name: 'Ratio',
- structure: {
- left: String,
- right: String
- },
- parse: function() {
- var start = this.scanner.tokenStart;
- var left = consumeNumber$5.call(this);
- var right;
- this.scanner.skipWS();
- if (!this.scanner.isDelim(SOLIDUS$3)) {
- this.error('Solidus is expected');
- }
- this.eat(DELIM$4);
- right = consumeNumber$5.call(this);
- return {
- type: 'Ratio',
- loc: this.getLocation(start, this.scanner.tokenStart),
- left: left,
- right: right
- };
- },
- generate: function(node) {
- this.chunk(node.left);
- this.chunk('/');
- this.chunk(node.right);
- }
- };
- var TYPE$x = tokenizer.TYPE;
- var rawMode$4 = Raw.mode;
- var LEFTCURLYBRACKET$4 = TYPE$x.LeftCurlyBracket;
- function consumeRaw$3(startToken) {
- return this.Raw(startToken, rawMode$4.leftCurlyBracket, true);
- }
- function consumePrelude() {
- var prelude = this.SelectorList();
- if (prelude.type !== 'Raw' &&
- this.scanner.eof === false &&
- this.scanner.tokenType !== LEFTCURLYBRACKET$4) {
- this.error();
- }
- return prelude;
- }
- var Rule = {
- name: 'Rule',
- structure: {
- prelude: ['SelectorList', 'Raw'],
- block: ['Block']
- },
- parse: function() {
- var startToken = this.scanner.tokenIndex;
- var startOffset = this.scanner.tokenStart;
- var prelude;
- var block;
- if (this.parseRulePrelude) {
- prelude = this.parseWithFallback(consumePrelude, consumeRaw$3);
- } else {
- prelude = consumeRaw$3.call(this, startToken);
- }
- block = this.Block(true);
- return {
- type: 'Rule',
- loc: this.getLocation(startOffset, this.scanner.tokenStart),
- prelude: prelude,
- block: block
- };
- },
- generate: function(node) {
- this.node(node.prelude);
- this.node(node.block);
- },
- walkContext: 'rule'
- };
- var Selector = {
- name: 'Selector',
- structure: {
- children: [[
- 'TypeSelector',
- 'IdSelector',
- 'ClassSelector',
- 'AttributeSelector',
- 'PseudoClassSelector',
- 'PseudoElementSelector',
- 'Combinator',
- 'WhiteSpace'
- ]]
- },
- parse: function() {
- var children = this.readSequence(this.scope.Selector);
- // nothing were consumed
- if (this.getFirstListNode(children) === null) {
- this.error('Selector is expected');
- }
- return {
- type: 'Selector',
- loc: this.getLocationFromList(children),
- children: children
- };
- },
- generate: function(node) {
- this.children(node);
- }
- };
- var TYPE$y = tokenizer.TYPE;
- var COMMA$2 = TYPE$y.Comma;
- var SelectorList = {
- name: 'SelectorList',
- structure: {
- children: [[
- 'Selector',
- 'Raw'
- ]]
- },
- parse: function() {
- var children = this.createList();
- while (!this.scanner.eof) {
- children.push(this.Selector());
- if (this.scanner.tokenType === COMMA$2) {
- this.scanner.next();
- continue;
- }
- break;
- }
- return {
- type: 'SelectorList',
- loc: this.getLocationFromList(children),
- children: children
- };
- },
- generate: function(node) {
- this.children(node, function() {
- this.chunk(',');
- });
- },
- walkContext: 'selector'
- };
- var STRING$1 = tokenizer.TYPE.String;
- var _String = {
- name: 'String',
- structure: {
- value: String
- },
- parse: function() {
- return {
- type: 'String',
- loc: this.getLocation(this.scanner.tokenStart, this.scanner.tokenEnd),
- value: this.consume(STRING$1)
- };
- },
- generate: function(node) {
- this.chunk(node.value);
- }
- };
- var TYPE$z = tokenizer.TYPE;
- var WHITESPACE$8 = TYPE$z.WhiteSpace;
- var COMMENT$8 = TYPE$z.Comment;
- var ATKEYWORD$2 = TYPE$z.AtKeyword;
- var CDO$1 = TYPE$z.CDO;
- var CDC$1 = TYPE$z.CDC;
- var EXCLAMATIONMARK$3 = 0x0021; // U+0021 EXCLAMATION MARK (!)
- function consumeRaw$4(startToken) {
- return this.Raw(startToken, null, false);
- }
- var StyleSheet = {
- name: 'StyleSheet',
- structure: {
- children: [[
- 'Comment',
- 'CDO',
- 'CDC',
- 'Atrule',
- 'Rule',
- 'Raw'
- ]]
- },
- parse: function() {
- var start = this.scanner.tokenStart;
- var children = this.createList();
- var child;
- scan:
- while (!this.scanner.eof) {
- switch (this.scanner.tokenType) {
- case WHITESPACE$8:
- this.scanner.next();
- continue;
- case COMMENT$8:
- // ignore comments except exclamation comments (i.e. /*! .. */) on top level
- if (this.scanner.source.charCodeAt(this.scanner.tokenStart + 2) !== EXCLAMATIONMARK$3) {
- this.scanner.next();
- continue;
- }
- child = this.Comment();
- break;
- case CDO$1: // <!--
- child = this.CDO();
- break;
- case CDC$1: // -->
- child = this.CDC();
- break;
- // CSS Syntax Module Level 3
- // §2.2 Error handling
- // At the "top level" of a stylesheet, an <at-keyword-token> starts an at-rule.
- case ATKEYWORD$2:
- child = this.parseWithFallback(this.Atrule, consumeRaw$4);
- break;
- // Anything else starts a qualified rule ...
- default:
- child = this.parseWithFallback(this.Rule, consumeRaw$4);
- }
- children.push(child);
- }
- return {
- type: 'StyleSheet',
- loc: this.getLocation(start, this.scanner.tokenStart),
- children: children
- };
- },
- generate: function(node) {
- this.children(node);
- },
- walkContext: 'stylesheet'
- };
- var TYPE$A = tokenizer.TYPE;
- var IDENT$d = TYPE$A.Ident;
- var ASTERISK$4 = 0x002A; // U+002A ASTERISK (*)
- var VERTICALLINE$2 = 0x007C; // U+007C VERTICAL LINE (|)
- function eatIdentifierOrAsterisk() {
- if (this.scanner.tokenType !== IDENT$d &&
- this.scanner.isDelim(ASTERISK$4) === false) {
- this.error('Identifier or asterisk is expected');
- }
- this.scanner.next();
- }
- // ident
- // ident|ident
- // ident|*
- // *
- // *|ident
- // *|*
- // |ident
- // |*
- var TypeSelector = {
- name: 'TypeSelector',
- structure: {
- name: String
- },
- parse: function() {
- var start = this.scanner.tokenStart;
- if (this.scanner.isDelim(VERTICALLINE$2)) {
- this.scanner.next();
- eatIdentifierOrAsterisk.call(this);
- } else {
- eatIdentifierOrAsterisk.call(this);
- if (this.scanner.isDelim(VERTICALLINE$2)) {
- this.scanner.next();
- eatIdentifierOrAsterisk.call(this);
- }
- }
- return {
- type: 'TypeSelector',
- loc: this.getLocation(start, this.scanner.tokenStart),
- name: this.scanner.substrToCursor(start)
- };
- },
- generate: function(node) {
- this.chunk(node.name);
- }
- };
- var isHexDigit$4 = tokenizer.isHexDigit;
- var cmpChar$4 = tokenizer.cmpChar;
- var TYPE$B = tokenizer.TYPE;
- var NAME$3 = tokenizer.NAME;
- var IDENT$e = TYPE$B.Ident;
- var NUMBER$7 = TYPE$B.Number;
- var DIMENSION$5 = TYPE$B.Dimension;
- var PLUSSIGN$6 = 0x002B; // U+002B PLUS SIGN (+)
- var HYPHENMINUS$4 = 0x002D; // U+002D HYPHEN-MINUS (-)
- var QUESTIONMARK$2 = 0x003F; // U+003F QUESTION MARK (?)
- var U$1 = 0x0075; // U+0075 LATIN SMALL LETTER U (u)
- function eatHexSequence(offset, allowDash) {
- for (var pos = this.scanner.tokenStart + offset, len = 0; pos < this.scanner.tokenEnd; pos++) {
- var code = this.scanner.source.charCodeAt(pos);
- if (code === HYPHENMINUS$4 && allowDash && len !== 0) {
- if (eatHexSequence.call(this, offset + len + 1, false) === 0) {
- this.error();
- }
- return -1;
- }
- if (!isHexDigit$4(code)) {
- this.error(
- allowDash && len !== 0
- ? 'HyphenMinus' + (len < 6 ? ' or hex digit' : '') + ' is expected'
- : (len < 6 ? 'Hex digit is expected' : 'Unexpected input'),
- pos
- );
- }
- if (++len > 6) {
- this.error('Too many hex digits', pos);
- } }
- this.scanner.next();
- return len;
- }
- function eatQuestionMarkSequence(max) {
- var count = 0;
- while (this.scanner.isDelim(QUESTIONMARK$2)) {
- if (++count > max) {
- this.error('Too many question marks');
- }
- this.scanner.next();
- }
- }
- function startsWith$1(code) {
- if (this.scanner.source.charCodeAt(this.scanner.tokenStart) !== code) {
- this.error(NAME$3[code] + ' is expected');
- }
- }
- // https://drafts.csswg.org/css-syntax/#urange
- // Informally, the <urange> production has three forms:
- // U+0001
- // Defines a range consisting of a single code point, in this case the code point "1".
- // U+0001-00ff
- // Defines a range of codepoints between the first and the second value, in this case
- // the range between "1" and "ff" (255 in decimal) inclusive.
- // U+00??
- // Defines a range of codepoints where the "?" characters range over all hex digits,
- // in this case defining the same as the value U+0000-00ff.
- // In each form, a maximum of 6 digits is allowed for each hexadecimal number (if you treat "?" as a hexadecimal digit).
- //
- // <urange> =
- // u '+' <ident-token> '?'* |
- // u <dimension-token> '?'* |
- // u <number-token> '?'* |
- // u <number-token> <dimension-token> |
- // u <number-token> <number-token> |
- // u '+' '?'+
- function scanUnicodeRange() {
- var hexLength = 0;
- // u '+' <ident-token> '?'*
- // u '+' '?'+
- if (this.scanner.isDelim(PLUSSIGN$6)) {
- this.scanner.next();
- if (this.scanner.tokenType === IDENT$e) {
- hexLength = eatHexSequence.call(this, 0, true);
- if (hexLength > 0) {
- eatQuestionMarkSequence.call(this, 6 - hexLength);
- }
- return;
- }
- if (this.scanner.isDelim(QUESTIONMARK$2)) {
- this.scanner.next();
- eatQuestionMarkSequence.call(this, 5);
- return;
- }
- this.error('Hex digit or question mark is expected');
- return;
- }
- // u <number-token> '?'*
- // u <number-token> <dimension-token>
- // u <number-token> <number-token>
- if (this.scanner.tokenType === NUMBER$7) {
- startsWith$1.call(this, PLUSSIGN$6);
- hexLength = eatHexSequence.call(this, 1, true);
- if (this.scanner.isDelim(QUESTIONMARK$2)) {
- eatQuestionMarkSequence.call(this, 6 - hexLength);
- return;
- }
- if (this.scanner.tokenType === DIMENSION$5 ||
- this.scanner.tokenType === NUMBER$7) {
- startsWith$1.call(this, HYPHENMINUS$4);
- eatHexSequence.call(this, 1, false);
- return;
- }
- return;
- }
- // u <dimension-token> '?'*
- if (this.scanner.tokenType === DIMENSION$5) {
- startsWith$1.call(this, PLUSSIGN$6);
- hexLength = eatHexSequence.call(this, 1, true);
- if (hexLength > 0) {
- eatQuestionMarkSequence.call(this, 6 - hexLength);
- }
- return;
- }
- this.error();
- }
- var UnicodeRange = {
- name: 'UnicodeRange',
- structure: {
- value: String
- },
- parse: function() {
- var start = this.scanner.tokenStart;
- // U or u
- if (!cmpChar$4(this.scanner.source, start, U$1)) {
- this.error('U is expected');
- }
- if (!cmpChar$4(this.scanner.source, start + 1, PLUSSIGN$6)) {
- this.error('Plus sign is expected');
- }
- this.scanner.next();
- scanUnicodeRange.call(this);
- return {
- type: 'UnicodeRange',
- loc: this.getLocation(start, this.scanner.tokenStart),
- value: this.scanner.substrToCursor(start)
- };
- },
- generate: function(node) {
- this.chunk(node.value);
- }
- };
- var isWhiteSpace$2 = tokenizer.isWhiteSpace;
- var cmpStr$4 = tokenizer.cmpStr;
- var TYPE$C = tokenizer.TYPE;
- var FUNCTION$3 = TYPE$C.Function;
- var URL$1 = TYPE$C.Url;
- var RIGHTPARENTHESIS$7 = TYPE$C.RightParenthesis;
- // <url-token> | <function-token> <string> )
- var Url = {
- name: 'Url',
- structure: {
- value: ['String', 'Raw']
- },
- parse: function() {
- var start = this.scanner.tokenStart;
- var value;
- switch (this.scanner.tokenType) {
- case URL$1:
- var rawStart = start + 4;
- var rawEnd = this.scanner.tokenEnd - 1;
- while (rawStart < rawEnd && isWhiteSpace$2(this.scanner.source.charCodeAt(rawStart))) {
- rawStart++;
- }
- while (rawStart < rawEnd && isWhiteSpace$2(this.scanner.source.charCodeAt(rawEnd - 1))) {
- rawEnd--;
- }
- value = {
- type: 'Raw',
- loc: this.getLocation(rawStart, rawEnd),
- value: this.scanner.source.substring(rawStart, rawEnd)
- };
- this.eat(URL$1);
- break;
- case FUNCTION$3:
- if (!cmpStr$4(this.scanner.source, this.scanner.tokenStart, this.scanner.tokenEnd, 'url(')) {
- this.error('Function name must be `url`');
- }
- this.eat(FUNCTION$3);
- this.scanner.skipSC();
- value = this.String();
- this.scanner.skipSC();
- this.eat(RIGHTPARENTHESIS$7);
- break;
- default:
- this.error('Url or Function is expected');
- }
- return {
- type: 'Url',
- loc: this.getLocation(start, this.scanner.tokenStart),
- value: value
- };
- },
- generate: function(node) {
- this.chunk('url');
- this.chunk('(');
- this.node(node.value);
- this.chunk(')');
- }
- };
- var Value = {
- name: 'Value',
- structure: {
- children: [[]]
- },
- parse: function() {
- var start = this.scanner.tokenStart;
- var children = this.readSequence(this.scope.Value);
- return {
- type: 'Value',
- loc: this.getLocation(start, this.scanner.tokenStart),
- children: children
- };
- },
- generate: function(node) {
- this.children(node);
- }
- };
- var WHITESPACE$9 = tokenizer.TYPE.WhiteSpace;
- var SPACE$2 = Object.freeze({
- type: 'WhiteSpace',
- loc: null,
- value: ' '
- });
- var WhiteSpace$1 = {
- name: 'WhiteSpace',
- structure: {
- value: String
- },
- parse: function() {
- this.eat(WHITESPACE$9);
- return SPACE$2;
- // return {
- // type: 'WhiteSpace',
- // loc: this.getLocation(this.scanner.tokenStart, this.scanner.tokenEnd),
- // value: this.consume(WHITESPACE)
- // };
- },
- generate: function(node) {
- this.chunk(node.value);
- }
- };
- var node = {
- AnPlusB: AnPlusB,
- Atrule: Atrule,
- AtrulePrelude: AtrulePrelude,
- AttributeSelector: AttributeSelector,
- Block: Block,
- Brackets: Brackets,
- CDC: CDC_1,
- CDO: CDO_1,
- ClassSelector: ClassSelector,
- Combinator: Combinator,
- Comment: Comment,
- Declaration: Declaration,
- DeclarationList: DeclarationList,
- Dimension: Dimension,
- Function: _Function,
- HexColor: HexColor,
- Identifier: Identifier,
- IdSelector: IdSelector,
- MediaFeature: MediaFeature,
- MediaQuery: MediaQuery,
- MediaQueryList: MediaQueryList,
- Nth: Nth,
- Number: _Number,
- Operator: Operator,
- Parentheses: Parentheses,
- Percentage: Percentage,
- PseudoClassSelector: PseudoClassSelector,
- PseudoElementSelector: PseudoElementSelector,
- Ratio: Ratio,
- Raw: Raw,
- Rule: Rule,
- Selector: Selector,
- SelectorList: SelectorList,
- String: _String,
- StyleSheet: StyleSheet,
- TypeSelector: TypeSelector,
- UnicodeRange: UnicodeRange,
- Url: Url,
- Value: Value,
- WhiteSpace: WhiteSpace$1
- };
- var data = getCjsExportFromNamespace(defaultSyntax$1);
- var lexer = {
- generic: true,
- types: data.types,
- properties: data.properties,
- node: node
- };
- var cmpChar$5 = tokenizer.cmpChar;
- var cmpStr$5 = tokenizer.cmpStr;
- var TYPE$D = tokenizer.TYPE;
- var IDENT$f = TYPE$D.Ident;
- var STRING$2 = TYPE$D.String;
- var NUMBER$8 = TYPE$D.Number;
- var FUNCTION$4 = TYPE$D.Function;
- var URL$2 = TYPE$D.Url;
- var HASH$4 = TYPE$D.Hash;
- var DIMENSION$6 = TYPE$D.Dimension;
- var PERCENTAGE$2 = TYPE$D.Percentage;
- var LEFTPARENTHESIS$5 = TYPE$D.LeftParenthesis;
- var LEFTSQUAREBRACKET$3 = TYPE$D.LeftSquareBracket;
- var COMMA$3 = TYPE$D.Comma;
- var DELIM$5 = TYPE$D.Delim;
- var NUMBERSIGN$3 = 0x0023; // U+0023 NUMBER SIGN (#)
- var ASTERISK$5 = 0x002A; // U+002A ASTERISK (*)
- var PLUSSIGN$7 = 0x002B; // U+002B PLUS SIGN (+)
- var HYPHENMINUS$5 = 0x002D; // U+002D HYPHEN-MINUS (-)
- var SOLIDUS$4 = 0x002F; // U+002F SOLIDUS (/)
- var U$2 = 0x0075; // U+0075 LATIN SMALL LETTER U (u)
- var _default = function defaultRecognizer(context) {
- switch (this.scanner.tokenType) {
- case HASH$4:
- return this.HexColor();
- case COMMA$3:
- context.space = null;
- context.ignoreWSAfter = true;
- return this.Operator();
- case LEFTPARENTHESIS$5:
- return this.Parentheses(this.readSequence, context.recognizer);
- case LEFTSQUAREBRACKET$3:
- return this.Brackets(this.readSequence, context.recognizer);
- case STRING$2:
- return this.String();
- case DIMENSION$6:
- return this.Dimension();
- case PERCENTAGE$2:
- return this.Percentage();
- case NUMBER$8:
- return this.Number();
- case FUNCTION$4:
- return cmpStr$5(this.scanner.source, this.scanner.tokenStart, this.scanner.tokenEnd, 'url(')
- ? this.Url()
- : this.Function(this.readSequence, context.recognizer);
- case URL$2:
- return this.Url();
- case IDENT$f:
- // check for unicode range, it should start with u+ or U+
- if (cmpChar$5(this.scanner.source, this.scanner.tokenStart, U$2) &&
- cmpChar$5(this.scanner.source, this.scanner.tokenStart + 1, PLUSSIGN$7)) {
- return this.UnicodeRange();
- } else {
- return this.Identifier();
- }
- case DELIM$5:
- var code = this.scanner.source.charCodeAt(this.scanner.tokenStart);
- if (code === SOLIDUS$4 ||
- code === ASTERISK$5 ||
- code === PLUSSIGN$7 ||
- code === HYPHENMINUS$5) {
- return this.Operator(); // TODO: replace with Delim
- }
- // TODO: produce a node with Delim node type
- if (code === NUMBERSIGN$3) {
- this.error('Hex or identifier is expected', this.scanner.tokenStart + 1);
- }
- break;
- }
- };
- var atrulePrelude = {
- getNode: _default
- };
- var TYPE$E = tokenizer.TYPE;
- var DELIM$6 = TYPE$E.Delim;
- var IDENT$g = TYPE$E.Ident;
- var DIMENSION$7 = TYPE$E.Dimension;
- var PERCENTAGE$3 = TYPE$E.Percentage;
- var NUMBER$9 = TYPE$E.Number;
- var HASH$5 = TYPE$E.Hash;
- var COLON$5 = TYPE$E.Colon;
- var LEFTSQUAREBRACKET$4 = TYPE$E.LeftSquareBracket;
- var NUMBERSIGN$4 = 0x0023; // U+0023 NUMBER SIGN (#)
- var ASTERISK$6 = 0x002A; // U+002A ASTERISK (*)
- var PLUSSIGN$8 = 0x002B; // U+002B PLUS SIGN (+)
- var SOLIDUS$5 = 0x002F; // U+002F SOLIDUS (/)
- var FULLSTOP$2 = 0x002E; // U+002E FULL STOP (.)
- var GREATERTHANSIGN$2 = 0x003E; // U+003E GREATER-THAN SIGN (>)
- var VERTICALLINE$3 = 0x007C; // U+007C VERTICAL LINE (|)
- var TILDE$2 = 0x007E; // U+007E TILDE (~)
- function getNode(context) {
- switch (this.scanner.tokenType) {
- case LEFTSQUAREBRACKET$4:
- return this.AttributeSelector();
- case HASH$5:
- return this.IdSelector();
- case COLON$5:
- if (this.scanner.lookupType(1) === COLON$5) {
- return this.PseudoElementSelector();
- } else {
- return this.PseudoClassSelector();
- }
- case IDENT$g:
- return this.TypeSelector();
- case NUMBER$9:
- case PERCENTAGE$3:
- return this.Percentage();
- case DIMENSION$7:
- // throws when .123ident
- if (this.scanner.source.charCodeAt(this.scanner.tokenStart) === FULLSTOP$2) {
- this.error('Identifier is expected', this.scanner.tokenStart + 1);
- }
- break;
- case DELIM$6:
- var code = this.scanner.source.charCodeAt(this.scanner.tokenStart);
- switch (code) {
- case PLUSSIGN$8:
- case GREATERTHANSIGN$2:
- case TILDE$2:
- context.space = null;
- context.ignoreWSAfter = true;
- return this.Combinator();
- case SOLIDUS$5: // /deep/
- return this.Combinator();
- case FULLSTOP$2:
- return this.ClassSelector();
- case ASTERISK$6:
- case VERTICALLINE$3:
- return this.TypeSelector();
- case NUMBERSIGN$4:
- return this.IdSelector();
- }
- break;
- }
- }
- var selector = {
- getNode: getNode
- };
- // https://drafts.csswg.org/css-images-4/#element-notation
- // https://developer.mozilla.org/en-US/docs/Web/CSS/element
- var element = function() {
- this.scanner.skipSC();
- var children = this.createSingleNodeList(
- this.IdSelector()
- );
- this.scanner.skipSC();
- return children;
- };
- // legacy IE function
- // expression( <any-value> )
- var expression = function() {
- return this.createSingleNodeList(
- this.Raw(this.scanner.tokenIndex, null, false)
- );
- };
- var TYPE$F = tokenizer.TYPE;
- var rawMode$5 = Raw.mode;
- var COMMA$4 = TYPE$F.Comma;
- // var( <ident> , <value>? )
- var _var = function() {
- var children = this.createList();
- this.scanner.skipSC();
- // NOTE: Don't check more than a first argument is an ident, rest checks are for lexer
- children.push(this.Identifier());
- this.scanner.skipSC();
- if (this.scanner.tokenType === COMMA$4) {
- children.push(this.Operator());
- children.push(this.parseCustomProperty
- ? this.Value(null)
- : this.Raw(this.scanner.tokenIndex, rawMode$5.exclamationMarkOrSemicolon, false)
- );
- }
- return children;
- };
- var value = {
- getNode: _default,
- '-moz-element': element,
- 'element': element,
- 'expression': expression,
- 'var': _var
- };
- var scope = {
- AtrulePrelude: atrulePrelude,
- Selector: selector,
- Value: value
- };
- var fontFace = {
- parse: {
- prelude: null,
- block: function() {
- return this.Block(true);
- }
- }
- };
- var TYPE$G = tokenizer.TYPE;
- var STRING$3 = TYPE$G.String;
- var IDENT$h = TYPE$G.Ident;
- var URL$3 = TYPE$G.Url;
- var FUNCTION$5 = TYPE$G.Function;
- var LEFTPARENTHESIS$6 = TYPE$G.LeftParenthesis;
- var _import = {
- parse: {
- prelude: function() {
- var children = this.createList();
- this.scanner.skipSC();
- switch (this.scanner.tokenType) {
- case STRING$3:
- children.push(this.String());
- break;
- case URL$3:
- case FUNCTION$5:
- children.push(this.Url());
- break;
- default:
- this.error('String or url() is expected');
- }
- if (this.lookupNonWSType(0) === IDENT$h ||
- this.lookupNonWSType(0) === LEFTPARENTHESIS$6) {
- children.push(this.WhiteSpace());
- children.push(this.MediaQueryList());
- }
- return children;
- },
- block: null
- }
- };
- var media = {
- parse: {
- prelude: function() {
- return this.createSingleNodeList(
- this.MediaQueryList()
- );
- },
- block: function() {
- return this.Block(false);
- }
- }
- };
- var page = {
- parse: {
- prelude: function() {
- return this.createSingleNodeList(
- this.SelectorList()
- );
- },
- block: function() {
- return this.Block(true);
- }
- }
- };
- var TYPE$H = tokenizer.TYPE;
- var WHITESPACE$a = TYPE$H.WhiteSpace;
- var COMMENT$9 = TYPE$H.Comment;
- var IDENT$i = TYPE$H.Ident;
- var FUNCTION$6 = TYPE$H.Function;
- var COLON$6 = TYPE$H.Colon;
- var LEFTPARENTHESIS$7 = TYPE$H.LeftParenthesis;
- function consumeRaw$5() {
- return this.createSingleNodeList(
- this.Raw(this.scanner.tokenIndex, null, false)
- );
- }
- function parentheses() {
- this.scanner.skipSC();
- if (this.scanner.tokenType === IDENT$i &&
- this.lookupNonWSType(1) === COLON$6) {
- return this.createSingleNodeList(
- this.Declaration()
- );
- }
- return readSequence.call(this);
- }
- function readSequence() {
- var children = this.createList();
- var space = null;
- var child;
- this.scanner.skipSC();
- scan:
- while (!this.scanner.eof) {
- switch (this.scanner.tokenType) {
- case WHITESPACE$a:
- space = this.WhiteSpace();
- continue;
- case COMMENT$9:
- this.scanner.next();
- continue;
- case FUNCTION$6:
- child = this.Function(consumeRaw$5, this.scope.AtrulePrelude);
- break;
- case IDENT$i:
- child = this.Identifier();
- break;
- case LEFTPARENTHESIS$7:
- child = this.Parentheses(parentheses, this.scope.AtrulePrelude);
- break;
- default:
- break scan;
- }
- if (space !== null) {
- children.push(space);
- space = null;
- }
- children.push(child);
- }
- return children;
- }
- var supports = {
- parse: {
- prelude: function() {
- var children = readSequence.call(this);
- if (this.getFirstListNode(children) === null) {
- this.error('Condition is expected');
- }
- return children;
- },
- block: function() {
- return this.Block(false);
- }
- }
- };
- var atrule = {
- 'font-face': fontFace,
- 'import': _import,
- 'media': media,
- 'page': page,
- 'supports': supports
- };
- var dir = {
- parse: function() {
- return this.createSingleNodeList(
- this.Identifier()
- );
- }
- };
- var has$1 = {
- parse: function() {
- return this.createSingleNodeList(
- this.SelectorList()
- );
- }
- };
- var lang = {
- parse: function() {
- return this.createSingleNodeList(
- this.Identifier()
- );
- }
- };
- var selectorList = {
- parse: function selectorList() {
- return this.createSingleNodeList(
- this.SelectorList()
- );
- }
- };
- var matches = selectorList;
- var not = selectorList;
- var ALLOW_OF_CLAUSE = true;
- var nthWithOfClause = {
- parse: function nthWithOfClause() {
- return this.createSingleNodeList(
- this.Nth(ALLOW_OF_CLAUSE)
- );
- }
- };
- var nthChild = nthWithOfClause;
- var nthLastChild = nthWithOfClause;
- var DISALLOW_OF_CLAUSE = false;
- var nth = {
- parse: function nth() {
- return this.createSingleNodeList(
- this.Nth(DISALLOW_OF_CLAUSE)
- );
- }
- };
- var nthLastOfType = nth;
- var nthOfType = nth;
- var slotted = {
- parse: function compoundSelector() {
- return this.createSingleNodeList(
- this.Selector()
- );
- }
- };
- var pseudo = {
- 'dir': dir,
- 'has': has$1,
- 'lang': lang,
- 'matches': matches,
- 'not': not,
- 'nth-child': nthChild,
- 'nth-last-child': nthLastChild,
- 'nth-last-of-type': nthLastOfType,
- 'nth-of-type': nthOfType,
- 'slotted': slotted
- };
- var parser = {
- parseContext: {
- default: 'StyleSheet',
- stylesheet: 'StyleSheet',
- atrule: 'Atrule',
- atrulePrelude: function(options) {
- return this.AtrulePrelude(options.atrule ? String(options.atrule) : null);
- },
- mediaQueryList: 'MediaQueryList',
- mediaQuery: 'MediaQuery',
- rule: 'Rule',
- selectorList: 'SelectorList',
- selector: 'Selector',
- block: function() {
- return this.Block(true);
- },
- declarationList: 'DeclarationList',
- declaration: 'Declaration',
- value: 'Value'
- },
- scope: scope,
- atrule: atrule,
- pseudo: pseudo,
- node: node
- };
- var walker = {
- node: node
- };
- function merge() {
- var dest = {};
- for (var i = 0; i < arguments.length; i++) {
- var src = arguments[i];
- for (var key in src) {
- dest[key] = src[key];
- }
- }
- return dest;
- }
- var syntax = create$4.create(
- merge(
- lexer,
- parser,
- walker
- )
- );
- var lib = syntax;
- return lib;
- }));
|