vue.js 261 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595959695979598959996009601960296039604960596069607960896099610961196129613961496159616961796189619962096219622962396249625962696279628962996309631963296339634963596369637963896399640964196429643964496459646964796489649965096519652965396549655965696579658965996609661966296639664966596669667966896699670967196729673967496759676967796789679968096819682968396849685968696879688968996909691969296939694969596969697969896999700970197029703970497059706970797089709971097119712971397149715971697179718971997209721972297239724972597269727972897299730973197329733973497359736973797389739974097419742974397449745974697479748974997509751975297539754975597569757975897599760976197629763976497659766976797689769977097719772977397749775977697779778977997809781978297839784978597869787978897899790979197929793979497959796979797989799980098019802980398049805980698079808980998109811981298139814981598169817981898199820982198229823982498259826982798289829983098319832983398349835983698379838983998409841984298439844984598469847984898499850985198529853985498559856985798589859986098619862986398649865986698679868986998709871987298739874987598769877987898799880988198829883988498859886988798889889989098919892989398949895989698979898989999009901990299039904990599069907990899099910991199129913991499159916991799189919992099219922
  1. /*!
  2. * Vue.js v1.0.21
  3. * (c) 2016 Evan You
  4. * Released under the MIT License.
  5. */
  6. (function (global, factory) {
  7. typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
  8. typeof define === 'function' && define.amd ? define(factory) :
  9. (global.Vue = factory());
  10. }(this, function () { 'use strict';
  11. function set(obj, key, val) {
  12. if (hasOwn(obj, key)) {
  13. obj[key] = val;
  14. return;
  15. }
  16. if (obj._isVue) {
  17. set(obj._data, key, val);
  18. return;
  19. }
  20. var ob = obj.__ob__;
  21. if (!ob) {
  22. obj[key] = val;
  23. return;
  24. }
  25. ob.convert(key, val);
  26. ob.dep.notify();
  27. if (ob.vms) {
  28. var i = ob.vms.length;
  29. while (i--) {
  30. var vm = ob.vms[i];
  31. vm._proxy(key);
  32. vm._digest();
  33. }
  34. }
  35. return val;
  36. }
  37. /**
  38. * Delete a property and trigger change if necessary.
  39. *
  40. * @param {Object} obj
  41. * @param {String} key
  42. */
  43. function del(obj, key) {
  44. if (!hasOwn(obj, key)) {
  45. return;
  46. }
  47. delete obj[key];
  48. var ob = obj.__ob__;
  49. if (!ob) {
  50. return;
  51. }
  52. ob.dep.notify();
  53. if (ob.vms) {
  54. var i = ob.vms.length;
  55. while (i--) {
  56. var vm = ob.vms[i];
  57. vm._unproxy(key);
  58. vm._digest();
  59. }
  60. }
  61. }
  62. var hasOwnProperty = Object.prototype.hasOwnProperty;
  63. /**
  64. * Check whether the object has the property.
  65. *
  66. * @param {Object} obj
  67. * @param {String} key
  68. * @return {Boolean}
  69. */
  70. function hasOwn(obj, key) {
  71. return hasOwnProperty.call(obj, key);
  72. }
  73. /**
  74. * Check if an expression is a literal value.
  75. *
  76. * @param {String} exp
  77. * @return {Boolean}
  78. */
  79. var literalValueRE = /^\s?(true|false|-?[\d\.]+|'[^']*'|"[^"]*")\s?$/;
  80. function isLiteral(exp) {
  81. return literalValueRE.test(exp);
  82. }
  83. /**
  84. * Check if a string starts with $ or _
  85. *
  86. * @param {String} str
  87. * @return {Boolean}
  88. */
  89. function isReserved(str) {
  90. var c = (str + '').charCodeAt(0);
  91. return c === 0x24 || c === 0x5F;
  92. }
  93. /**
  94. * Guard text output, make sure undefined outputs
  95. * empty string
  96. *
  97. * @param {*} value
  98. * @return {String}
  99. */
  100. function _toString(value) {
  101. return value == null ? '' : value.toString();
  102. }
  103. /**
  104. * Check and convert possible numeric strings to numbers
  105. * before setting back to data
  106. *
  107. * @param {*} value
  108. * @return {*|Number}
  109. */
  110. function toNumber(value) {
  111. if (typeof value !== 'string') {
  112. return value;
  113. } else {
  114. var parsed = Number(value);
  115. return isNaN(parsed) ? value : parsed;
  116. }
  117. }
  118. /**
  119. * Convert string boolean literals into real booleans.
  120. *
  121. * @param {*} value
  122. * @return {*|Boolean}
  123. */
  124. function toBoolean(value) {
  125. return value === 'true' ? true : value === 'false' ? false : value;
  126. }
  127. /**
  128. * Strip quotes from a string
  129. *
  130. * @param {String} str
  131. * @return {String | false}
  132. */
  133. function stripQuotes(str) {
  134. var a = str.charCodeAt(0);
  135. var b = str.charCodeAt(str.length - 1);
  136. return a === b && (a === 0x22 || a === 0x27) ? str.slice(1, -1) : str;
  137. }
  138. /**
  139. * Camelize a hyphen-delmited string.
  140. *
  141. * @param {String} str
  142. * @return {String}
  143. */
  144. var camelizeRE = /-(\w)/g;
  145. function camelize(str) {
  146. return str.replace(camelizeRE, toUpper);
  147. }
  148. function toUpper(_, c) {
  149. return c ? c.toUpperCase() : '';
  150. }
  151. /**
  152. * Hyphenate a camelCase string.
  153. *
  154. * @param {String} str
  155. * @return {String}
  156. */
  157. var hyphenateRE = /([a-z\d])([A-Z])/g;
  158. function hyphenate(str) {
  159. return str.replace(hyphenateRE, '$1-$2').toLowerCase();
  160. }
  161. /**
  162. * Converts hyphen/underscore/slash delimitered names into
  163. * camelized classNames.
  164. *
  165. * e.g. my-component => MyComponent
  166. * some_else => SomeElse
  167. * some/comp => SomeComp
  168. *
  169. * @param {String} str
  170. * @return {String}
  171. */
  172. var classifyRE = /(?:^|[-_\/])(\w)/g;
  173. function classify(str) {
  174. return str.replace(classifyRE, toUpper);
  175. }
  176. /**
  177. * Simple bind, faster than native
  178. *
  179. * @param {Function} fn
  180. * @param {Object} ctx
  181. * @return {Function}
  182. */
  183. function bind(fn, ctx) {
  184. return function (a) {
  185. var l = arguments.length;
  186. return l ? l > 1 ? fn.apply(ctx, arguments) : fn.call(ctx, a) : fn.call(ctx);
  187. };
  188. }
  189. /**
  190. * Convert an Array-like object to a real Array.
  191. *
  192. * @param {Array-like} list
  193. * @param {Number} [start] - start index
  194. * @return {Array}
  195. */
  196. function toArray(list, start) {
  197. start = start || 0;
  198. var i = list.length - start;
  199. var ret = new Array(i);
  200. while (i--) {
  201. ret[i] = list[i + start];
  202. }
  203. return ret;
  204. }
  205. /**
  206. * Mix properties into target object.
  207. *
  208. * @param {Object} to
  209. * @param {Object} from
  210. */
  211. function extend(to, from) {
  212. var keys = Object.keys(from);
  213. var i = keys.length;
  214. while (i--) {
  215. to[keys[i]] = from[keys[i]];
  216. }
  217. return to;
  218. }
  219. /**
  220. * Quick object check - this is primarily used to tell
  221. * Objects from primitive values when we know the value
  222. * is a JSON-compliant type.
  223. *
  224. * @param {*} obj
  225. * @return {Boolean}
  226. */
  227. function isObject(obj) {
  228. return obj !== null && typeof obj === 'object';
  229. }
  230. /**
  231. * Strict object type check. Only returns true
  232. * for plain JavaScript objects.
  233. *
  234. * @param {*} obj
  235. * @return {Boolean}
  236. */
  237. var toString = Object.prototype.toString;
  238. var OBJECT_STRING = '[object Object]';
  239. function isPlainObject(obj) {
  240. return toString.call(obj) === OBJECT_STRING;
  241. }
  242. /**
  243. * Array type check.
  244. *
  245. * @param {*} obj
  246. * @return {Boolean}
  247. */
  248. var isArray = Array.isArray;
  249. /**
  250. * Define a property.
  251. *
  252. * @param {Object} obj
  253. * @param {String} key
  254. * @param {*} val
  255. * @param {Boolean} [enumerable]
  256. */
  257. function def(obj, key, val, enumerable) {
  258. Object.defineProperty(obj, key, {
  259. value: val,
  260. enumerable: !!enumerable,
  261. writable: true,
  262. configurable: true
  263. });
  264. }
  265. /**
  266. * Debounce a function so it only gets called after the
  267. * input stops arriving after the given wait period.
  268. *
  269. * @param {Function} func
  270. * @param {Number} wait
  271. * @return {Function} - the debounced function
  272. */
  273. function _debounce(func, wait) {
  274. var timeout, args, context, timestamp, result;
  275. var later = function later() {
  276. var last = Date.now() - timestamp;
  277. if (last < wait && last >= 0) {
  278. timeout = setTimeout(later, wait - last);
  279. } else {
  280. timeout = null;
  281. result = func.apply(context, args);
  282. if (!timeout) context = args = null;
  283. }
  284. };
  285. return function () {
  286. context = this;
  287. args = arguments;
  288. timestamp = Date.now();
  289. if (!timeout) {
  290. timeout = setTimeout(later, wait);
  291. }
  292. return result;
  293. };
  294. }
  295. /**
  296. * Manual indexOf because it's slightly faster than
  297. * native.
  298. *
  299. * @param {Array} arr
  300. * @param {*} obj
  301. */
  302. function indexOf(arr, obj) {
  303. var i = arr.length;
  304. while (i--) {
  305. if (arr[i] === obj) return i;
  306. }
  307. return -1;
  308. }
  309. /**
  310. * Make a cancellable version of an async callback.
  311. *
  312. * @param {Function} fn
  313. * @return {Function}
  314. */
  315. function cancellable(fn) {
  316. var cb = function cb() {
  317. if (!cb.cancelled) {
  318. return fn.apply(this, arguments);
  319. }
  320. };
  321. cb.cancel = function () {
  322. cb.cancelled = true;
  323. };
  324. return cb;
  325. }
  326. /**
  327. * Check if two values are loosely equal - that is,
  328. * if they are plain objects, do they have the same shape?
  329. *
  330. * @param {*} a
  331. * @param {*} b
  332. * @return {Boolean}
  333. */
  334. function looseEqual(a, b) {
  335. /* eslint-disable eqeqeq */
  336. return a == b || (isObject(a) && isObject(b) ? JSON.stringify(a) === JSON.stringify(b) : false);
  337. /* eslint-enable eqeqeq */
  338. }
  339. var hasProto = ('__proto__' in {});
  340. // Browser environment sniffing
  341. var inBrowser = typeof window !== 'undefined' && Object.prototype.toString.call(window) !== '[object Object]';
  342. // detect devtools
  343. var devtools = inBrowser && window.__VUE_DEVTOOLS_GLOBAL_HOOK__;
  344. // UA sniffing for working around browser-specific quirks
  345. var UA = inBrowser && window.navigator.userAgent.toLowerCase();
  346. var isIE9 = UA && UA.indexOf('msie 9.0') > 0;
  347. var isAndroid = UA && UA.indexOf('android') > 0;
  348. var transitionProp = undefined;
  349. var transitionEndEvent = undefined;
  350. var animationProp = undefined;
  351. var animationEndEvent = undefined;
  352. // Transition property/event sniffing
  353. if (inBrowser && !isIE9) {
  354. var isWebkitTrans = window.ontransitionend === undefined && window.onwebkittransitionend !== undefined;
  355. var isWebkitAnim = window.onanimationend === undefined && window.onwebkitanimationend !== undefined;
  356. transitionProp = isWebkitTrans ? 'WebkitTransition' : 'transition';
  357. transitionEndEvent = isWebkitTrans ? 'webkitTransitionEnd' : 'transitionend';
  358. animationProp = isWebkitAnim ? 'WebkitAnimation' : 'animation';
  359. animationEndEvent = isWebkitAnim ? 'webkitAnimationEnd' : 'animationend';
  360. }
  361. /**
  362. * Defer a task to execute it asynchronously. Ideally this
  363. * should be executed as a microtask, so we leverage
  364. * MutationObserver if it's available, and fallback to
  365. * setTimeout(0).
  366. *
  367. * @param {Function} cb
  368. * @param {Object} ctx
  369. */
  370. var nextTick = (function () {
  371. var callbacks = [];
  372. var pending = false;
  373. var timerFunc;
  374. function nextTickHandler() {
  375. pending = false;
  376. var copies = callbacks.slice(0);
  377. callbacks = [];
  378. for (var i = 0; i < copies.length; i++) {
  379. copies[i]();
  380. }
  381. }
  382. /* istanbul ignore if */
  383. if (typeof MutationObserver !== 'undefined') {
  384. var counter = 1;
  385. var observer = new MutationObserver(nextTickHandler);
  386. var textNode = document.createTextNode(counter);
  387. observer.observe(textNode, {
  388. characterData: true
  389. });
  390. timerFunc = function () {
  391. counter = (counter + 1) % 2;
  392. textNode.data = counter;
  393. };
  394. } else {
  395. // webpack attempts to inject a shim for setImmediate
  396. // if it is used as a global, so we have to work around that to
  397. // avoid bundling unnecessary code.
  398. var context = inBrowser ? window : typeof global !== 'undefined' ? global : {};
  399. timerFunc = context.setImmediate || setTimeout;
  400. }
  401. return function (cb, ctx) {
  402. var func = ctx ? function () {
  403. cb.call(ctx);
  404. } : cb;
  405. callbacks.push(func);
  406. if (pending) return;
  407. pending = true;
  408. timerFunc(nextTickHandler, 0);
  409. };
  410. })();
  411. function Cache(limit) {
  412. this.size = 0;
  413. this.limit = limit;
  414. this.head = this.tail = undefined;
  415. this._keymap = Object.create(null);
  416. }
  417. var p = Cache.prototype;
  418. /**
  419. * Put <value> into the cache associated with <key>.
  420. * Returns the entry which was removed to make room for
  421. * the new entry. Otherwise undefined is returned.
  422. * (i.e. if there was enough room already).
  423. *
  424. * @param {String} key
  425. * @param {*} value
  426. * @return {Entry|undefined}
  427. */
  428. p.put = function (key, value) {
  429. var removed;
  430. if (this.size === this.limit) {
  431. removed = this.shift();
  432. }
  433. var entry = this.get(key, true);
  434. if (!entry) {
  435. entry = {
  436. key: key
  437. };
  438. this._keymap[key] = entry;
  439. if (this.tail) {
  440. this.tail.newer = entry;
  441. entry.older = this.tail;
  442. } else {
  443. this.head = entry;
  444. }
  445. this.tail = entry;
  446. this.size++;
  447. }
  448. entry.value = value;
  449. return removed;
  450. };
  451. /**
  452. * Purge the least recently used (oldest) entry from the
  453. * cache. Returns the removed entry or undefined if the
  454. * cache was empty.
  455. */
  456. p.shift = function () {
  457. var entry = this.head;
  458. if (entry) {
  459. this.head = this.head.newer;
  460. this.head.older = undefined;
  461. entry.newer = entry.older = undefined;
  462. this._keymap[entry.key] = undefined;
  463. this.size--;
  464. }
  465. return entry;
  466. };
  467. /**
  468. * Get and register recent use of <key>. Returns the value
  469. * associated with <key> or undefined if not in cache.
  470. *
  471. * @param {String} key
  472. * @param {Boolean} returnEntry
  473. * @return {Entry|*}
  474. */
  475. p.get = function (key, returnEntry) {
  476. var entry = this._keymap[key];
  477. if (entry === undefined) return;
  478. if (entry === this.tail) {
  479. return returnEntry ? entry : entry.value;
  480. }
  481. // HEAD--------------TAIL
  482. // <.older .newer>
  483. // <--- add direction --
  484. // A B C <D> E
  485. if (entry.newer) {
  486. if (entry === this.head) {
  487. this.head = entry.newer;
  488. }
  489. entry.newer.older = entry.older; // C <-- E.
  490. }
  491. if (entry.older) {
  492. entry.older.newer = entry.newer; // C. --> E
  493. }
  494. entry.newer = undefined; // D --x
  495. entry.older = this.tail; // D. --> E
  496. if (this.tail) {
  497. this.tail.newer = entry; // E. <-- D
  498. }
  499. this.tail = entry;
  500. return returnEntry ? entry : entry.value;
  501. };
  502. var cache$1 = new Cache(1000);
  503. var filterTokenRE = /[^\s'"]+|'[^']*'|"[^"]*"/g;
  504. var reservedArgRE = /^in$|^-?\d+/;
  505. /**
  506. * Parser state
  507. */
  508. var str;
  509. var dir;
  510. var c;
  511. var prev;
  512. var i;
  513. var l;
  514. var lastFilterIndex;
  515. var inSingle;
  516. var inDouble;
  517. var curly;
  518. var square;
  519. var paren;
  520. /**
  521. * Push a filter to the current directive object
  522. */
  523. function pushFilter() {
  524. var exp = str.slice(lastFilterIndex, i).trim();
  525. var filter;
  526. if (exp) {
  527. filter = {};
  528. var tokens = exp.match(filterTokenRE);
  529. filter.name = tokens[0];
  530. if (tokens.length > 1) {
  531. filter.args = tokens.slice(1).map(processFilterArg);
  532. }
  533. }
  534. if (filter) {
  535. (dir.filters = dir.filters || []).push(filter);
  536. }
  537. lastFilterIndex = i + 1;
  538. }
  539. /**
  540. * Check if an argument is dynamic and strip quotes.
  541. *
  542. * @param {String} arg
  543. * @return {Object}
  544. */
  545. function processFilterArg(arg) {
  546. if (reservedArgRE.test(arg)) {
  547. return {
  548. value: toNumber(arg),
  549. dynamic: false
  550. };
  551. } else {
  552. var stripped = stripQuotes(arg);
  553. var dynamic = stripped === arg;
  554. return {
  555. value: dynamic ? arg : stripped,
  556. dynamic: dynamic
  557. };
  558. }
  559. }
  560. /**
  561. * Parse a directive value and extract the expression
  562. * and its filters into a descriptor.
  563. *
  564. * Example:
  565. *
  566. * "a + 1 | uppercase" will yield:
  567. * {
  568. * expression: 'a + 1',
  569. * filters: [
  570. * { name: 'uppercase', args: null }
  571. * ]
  572. * }
  573. *
  574. * @param {String} s
  575. * @return {Object}
  576. */
  577. function parseDirective(s) {
  578. var hit = cache$1.get(s);
  579. if (hit) {
  580. return hit;
  581. }
  582. // reset parser state
  583. str = s;
  584. inSingle = inDouble = false;
  585. curly = square = paren = 0;
  586. lastFilterIndex = 0;
  587. dir = {};
  588. for (i = 0, l = str.length; i < l; i++) {
  589. prev = c;
  590. c = str.charCodeAt(i);
  591. if (inSingle) {
  592. // check single quote
  593. if (c === 0x27 && prev !== 0x5C) inSingle = !inSingle;
  594. } else if (inDouble) {
  595. // check double quote
  596. if (c === 0x22 && prev !== 0x5C) inDouble = !inDouble;
  597. } else if (c === 0x7C && // pipe
  598. str.charCodeAt(i + 1) !== 0x7C && str.charCodeAt(i - 1) !== 0x7C) {
  599. if (dir.expression == null) {
  600. // first filter, end of expression
  601. lastFilterIndex = i + 1;
  602. dir.expression = str.slice(0, i).trim();
  603. } else {
  604. // already has filter
  605. pushFilter();
  606. }
  607. } else {
  608. switch (c) {
  609. case 0x22:
  610. inDouble = true;break; // "
  611. case 0x27:
  612. inSingle = true;break; // '
  613. case 0x28:
  614. paren++;break; // (
  615. case 0x29:
  616. paren--;break; // )
  617. case 0x5B:
  618. square++;break; // [
  619. case 0x5D:
  620. square--;break; // ]
  621. case 0x7B:
  622. curly++;break; // {
  623. case 0x7D:
  624. curly--;break; // }
  625. }
  626. }
  627. }
  628. if (dir.expression == null) {
  629. dir.expression = str.slice(0, i).trim();
  630. } else if (lastFilterIndex !== 0) {
  631. pushFilter();
  632. }
  633. cache$1.put(s, dir);
  634. return dir;
  635. }
  636. var directive = Object.freeze({
  637. parseDirective: parseDirective
  638. });
  639. var regexEscapeRE = /[-.*+?^${}()|[\]\/\\]/g;
  640. var cache = undefined;
  641. var tagRE = undefined;
  642. var htmlRE = undefined;
  643. /**
  644. * Escape a string so it can be used in a RegExp
  645. * constructor.
  646. *
  647. * @param {String} str
  648. */
  649. function escapeRegex(str) {
  650. return str.replace(regexEscapeRE, '\\$&');
  651. }
  652. function compileRegex() {
  653. var open = escapeRegex(config.delimiters[0]);
  654. var close = escapeRegex(config.delimiters[1]);
  655. var unsafeOpen = escapeRegex(config.unsafeDelimiters[0]);
  656. var unsafeClose = escapeRegex(config.unsafeDelimiters[1]);
  657. tagRE = new RegExp(unsafeOpen + '((?:.|\\n)+?)' + unsafeClose + '|' + open + '((?:.|\\n)+?)' + close, 'g');
  658. htmlRE = new RegExp('^' + unsafeOpen + '.*' + unsafeClose + '$');
  659. // reset cache
  660. cache = new Cache(1000);
  661. }
  662. /**
  663. * Parse a template text string into an array of tokens.
  664. *
  665. * @param {String} text
  666. * @return {Array<Object> | null}
  667. * - {String} type
  668. * - {String} value
  669. * - {Boolean} [html]
  670. * - {Boolean} [oneTime]
  671. */
  672. function parseText(text) {
  673. if (!cache) {
  674. compileRegex();
  675. }
  676. var hit = cache.get(text);
  677. if (hit) {
  678. return hit;
  679. }
  680. if (!tagRE.test(text)) {
  681. return null;
  682. }
  683. var tokens = [];
  684. var lastIndex = tagRE.lastIndex = 0;
  685. var match, index, html, value, first, oneTime;
  686. /* eslint-disable no-cond-assign */
  687. while (match = tagRE.exec(text)) {
  688. /* eslint-enable no-cond-assign */
  689. index = match.index;
  690. // push text token
  691. if (index > lastIndex) {
  692. tokens.push({
  693. value: text.slice(lastIndex, index)
  694. });
  695. }
  696. // tag token
  697. html = htmlRE.test(match[0]);
  698. value = html ? match[1] : match[2];
  699. first = value.charCodeAt(0);
  700. oneTime = first === 42; // *
  701. value = oneTime ? value.slice(1) : value;
  702. tokens.push({
  703. tag: true,
  704. value: value.trim(),
  705. html: html,
  706. oneTime: oneTime
  707. });
  708. lastIndex = index + match[0].length;
  709. }
  710. if (lastIndex < text.length) {
  711. tokens.push({
  712. value: text.slice(lastIndex)
  713. });
  714. }
  715. cache.put(text, tokens);
  716. return tokens;
  717. }
  718. /**
  719. * Format a list of tokens into an expression.
  720. * e.g. tokens parsed from 'a {{b}} c' can be serialized
  721. * into one single expression as '"a " + b + " c"'.
  722. *
  723. * @param {Array} tokens
  724. * @param {Vue} [vm]
  725. * @return {String}
  726. */
  727. function tokensToExp(tokens, vm) {
  728. if (tokens.length > 1) {
  729. return tokens.map(function (token) {
  730. return formatToken(token, vm);
  731. }).join('+');
  732. } else {
  733. return formatToken(tokens[0], vm, true);
  734. }
  735. }
  736. /**
  737. * Format a single token.
  738. *
  739. * @param {Object} token
  740. * @param {Vue} [vm]
  741. * @param {Boolean} [single]
  742. * @return {String}
  743. */
  744. function formatToken(token, vm, single) {
  745. return token.tag ? token.oneTime && vm ? '"' + vm.$eval(token.value) + '"' : inlineFilters(token.value, single) : '"' + token.value + '"';
  746. }
  747. /**
  748. * For an attribute with multiple interpolation tags,
  749. * e.g. attr="some-{{thing | filter}}", in order to combine
  750. * the whole thing into a single watchable expression, we
  751. * have to inline those filters. This function does exactly
  752. * that. This is a bit hacky but it avoids heavy changes
  753. * to directive parser and watcher mechanism.
  754. *
  755. * @param {String} exp
  756. * @param {Boolean} single
  757. * @return {String}
  758. */
  759. var filterRE = /[^|]\|[^|]/;
  760. function inlineFilters(exp, single) {
  761. if (!filterRE.test(exp)) {
  762. return single ? exp : '(' + exp + ')';
  763. } else {
  764. var dir = parseDirective(exp);
  765. if (!dir.filters) {
  766. return '(' + exp + ')';
  767. } else {
  768. return 'this._applyFilters(' + dir.expression + // value
  769. ',null,' + // oldValue (null for read)
  770. JSON.stringify(dir.filters) + // filter descriptors
  771. ',false)'; // write?
  772. }
  773. }
  774. }
  775. var text = Object.freeze({
  776. compileRegex: compileRegex,
  777. parseText: parseText,
  778. tokensToExp: tokensToExp
  779. });
  780. var delimiters = ['{{', '}}'];
  781. var unsafeDelimiters = ['{{{', '}}}'];
  782. var config = Object.defineProperties({
  783. /**
  784. * Whether to print debug messages.
  785. * Also enables stack trace for warnings.
  786. *
  787. * @type {Boolean}
  788. */
  789. debug: false,
  790. /**
  791. * Whether to suppress warnings.
  792. *
  793. * @type {Boolean}
  794. */
  795. silent: false,
  796. /**
  797. * Whether to use async rendering.
  798. */
  799. async: true,
  800. /**
  801. * Whether to warn against errors caught when evaluating
  802. * expressions.
  803. */
  804. warnExpressionErrors: true,
  805. /**
  806. * Whether to allow devtools inspection.
  807. * Disabled by default in production builds.
  808. */
  809. devtools: 'development' !== 'production',
  810. /**
  811. * Internal flag to indicate the delimiters have been
  812. * changed.
  813. *
  814. * @type {Boolean}
  815. */
  816. _delimitersChanged: true,
  817. /**
  818. * List of asset types that a component can own.
  819. *
  820. * @type {Array}
  821. */
  822. _assetTypes: ['component', 'directive', 'elementDirective', 'filter', 'transition', 'partial'],
  823. /**
  824. * prop binding modes
  825. */
  826. _propBindingModes: {
  827. ONE_WAY: 0,
  828. TWO_WAY: 1,
  829. ONE_TIME: 2
  830. },
  831. /**
  832. * Max circular updates allowed in a batcher flush cycle.
  833. */
  834. _maxUpdateCount: 100
  835. }, {
  836. delimiters: { /**
  837. * Interpolation delimiters. Changing these would trigger
  838. * the text parser to re-compile the regular expressions.
  839. *
  840. * @type {Array<String>}
  841. */
  842. get: function get() {
  843. return delimiters;
  844. },
  845. set: function set(val) {
  846. delimiters = val;
  847. compileRegex();
  848. },
  849. configurable: true,
  850. enumerable: true
  851. },
  852. unsafeDelimiters: {
  853. get: function get() {
  854. return unsafeDelimiters;
  855. },
  856. set: function set(val) {
  857. unsafeDelimiters = val;
  858. compileRegex();
  859. },
  860. configurable: true,
  861. enumerable: true
  862. }
  863. });
  864. var warn = undefined;
  865. var formatComponentName = undefined;
  866. if ('development' !== 'production') {
  867. (function () {
  868. var hasConsole = typeof console !== 'undefined';
  869. warn = function (msg, vm) {
  870. if (hasConsole && !config.silent) {
  871. console.error('[Vue warn]: ' + msg + (vm ? formatComponentName(vm) : ''));
  872. }
  873. };
  874. formatComponentName = function (vm) {
  875. var name = vm._isVue ? vm.$options.name : vm.name;
  876. return name ? ' (found in component: <' + hyphenate(name) + '>)' : '';
  877. };
  878. })();
  879. }
  880. /**
  881. * Append with transition.
  882. *
  883. * @param {Element} el
  884. * @param {Element} target
  885. * @param {Vue} vm
  886. * @param {Function} [cb]
  887. */
  888. function appendWithTransition(el, target, vm, cb) {
  889. applyTransition(el, 1, function () {
  890. target.appendChild(el);
  891. }, vm, cb);
  892. }
  893. /**
  894. * InsertBefore with transition.
  895. *
  896. * @param {Element} el
  897. * @param {Element} target
  898. * @param {Vue} vm
  899. * @param {Function} [cb]
  900. */
  901. function beforeWithTransition(el, target, vm, cb) {
  902. applyTransition(el, 1, function () {
  903. before(el, target);
  904. }, vm, cb);
  905. }
  906. /**
  907. * Remove with transition.
  908. *
  909. * @param {Element} el
  910. * @param {Vue} vm
  911. * @param {Function} [cb]
  912. */
  913. function removeWithTransition(el, vm, cb) {
  914. applyTransition(el, -1, function () {
  915. remove(el);
  916. }, vm, cb);
  917. }
  918. /**
  919. * Apply transitions with an operation callback.
  920. *
  921. * @param {Element} el
  922. * @param {Number} direction
  923. * 1: enter
  924. * -1: leave
  925. * @param {Function} op - the actual DOM operation
  926. * @param {Vue} vm
  927. * @param {Function} [cb]
  928. */
  929. function applyTransition(el, direction, op, vm, cb) {
  930. var transition = el.__v_trans;
  931. if (!transition ||
  932. // skip if there are no js hooks and CSS transition is
  933. // not supported
  934. !transition.hooks && !transitionEndEvent ||
  935. // skip transitions for initial compile
  936. !vm._isCompiled ||
  937. // if the vm is being manipulated by a parent directive
  938. // during the parent's compilation phase, skip the
  939. // animation.
  940. vm.$parent && !vm.$parent._isCompiled) {
  941. op();
  942. if (cb) cb();
  943. return;
  944. }
  945. var action = direction > 0 ? 'enter' : 'leave';
  946. transition[action](op, cb);
  947. }
  948. var transition = Object.freeze({
  949. appendWithTransition: appendWithTransition,
  950. beforeWithTransition: beforeWithTransition,
  951. removeWithTransition: removeWithTransition,
  952. applyTransition: applyTransition
  953. });
  954. /**
  955. * Query an element selector if it's not an element already.
  956. *
  957. * @param {String|Element} el
  958. * @return {Element}
  959. */
  960. function query(el) {
  961. if (typeof el === 'string') {
  962. var selector = el;
  963. el = document.querySelector(el);
  964. if (!el) {
  965. 'development' !== 'production' && warn('Cannot find element: ' + selector);
  966. }
  967. }
  968. return el;
  969. }
  970. /**
  971. * Check if a node is in the document.
  972. * Note: document.documentElement.contains should work here
  973. * but always returns false for comment nodes in phantomjs,
  974. * making unit tests difficult. This is fixed by doing the
  975. * contains() check on the node's parentNode instead of
  976. * the node itself.
  977. *
  978. * @param {Node} node
  979. * @return {Boolean}
  980. */
  981. function inDoc(node) {
  982. var doc = document.documentElement;
  983. var parent = node && node.parentNode;
  984. return doc === node || doc === parent || !!(parent && parent.nodeType === 1 && doc.contains(parent));
  985. }
  986. /**
  987. * Get and remove an attribute from a node.
  988. *
  989. * @param {Node} node
  990. * @param {String} _attr
  991. */
  992. function getAttr(node, _attr) {
  993. var val = node.getAttribute(_attr);
  994. if (val !== null) {
  995. node.removeAttribute(_attr);
  996. }
  997. return val;
  998. }
  999. /**
  1000. * Get an attribute with colon or v-bind: prefix.
  1001. *
  1002. * @param {Node} node
  1003. * @param {String} name
  1004. * @return {String|null}
  1005. */
  1006. function getBindAttr(node, name) {
  1007. var val = getAttr(node, ':' + name);
  1008. if (val === null) {
  1009. val = getAttr(node, 'v-bind:' + name);
  1010. }
  1011. return val;
  1012. }
  1013. /**
  1014. * Check the presence of a bind attribute.
  1015. *
  1016. * @param {Node} node
  1017. * @param {String} name
  1018. * @return {Boolean}
  1019. */
  1020. function hasBindAttr(node, name) {
  1021. return node.hasAttribute(name) || node.hasAttribute(':' + name) || node.hasAttribute('v-bind:' + name);
  1022. }
  1023. /**
  1024. * Insert el before target
  1025. *
  1026. * @param {Element} el
  1027. * @param {Element} target
  1028. */
  1029. function before(el, target) {
  1030. target.parentNode.insertBefore(el, target);
  1031. }
  1032. /**
  1033. * Insert el after target
  1034. *
  1035. * @param {Element} el
  1036. * @param {Element} target
  1037. */
  1038. function after(el, target) {
  1039. if (target.nextSibling) {
  1040. before(el, target.nextSibling);
  1041. } else {
  1042. target.parentNode.appendChild(el);
  1043. }
  1044. }
  1045. /**
  1046. * Remove el from DOM
  1047. *
  1048. * @param {Element} el
  1049. */
  1050. function remove(el) {
  1051. el.parentNode.removeChild(el);
  1052. }
  1053. /**
  1054. * Prepend el to target
  1055. *
  1056. * @param {Element} el
  1057. * @param {Element} target
  1058. */
  1059. function prepend(el, target) {
  1060. if (target.firstChild) {
  1061. before(el, target.firstChild);
  1062. } else {
  1063. target.appendChild(el);
  1064. }
  1065. }
  1066. /**
  1067. * Replace target with el
  1068. *
  1069. * @param {Element} target
  1070. * @param {Element} el
  1071. */
  1072. function replace(target, el) {
  1073. var parent = target.parentNode;
  1074. if (parent) {
  1075. parent.replaceChild(el, target);
  1076. }
  1077. }
  1078. /**
  1079. * Add event listener shorthand.
  1080. *
  1081. * @param {Element} el
  1082. * @param {String} event
  1083. * @param {Function} cb
  1084. * @param {Boolean} [useCapture]
  1085. */
  1086. function on(el, event, cb, useCapture) {
  1087. el.addEventListener(event, cb, useCapture);
  1088. }
  1089. /**
  1090. * Remove event listener shorthand.
  1091. *
  1092. * @param {Element} el
  1093. * @param {String} event
  1094. * @param {Function} cb
  1095. */
  1096. function off(el, event, cb) {
  1097. el.removeEventListener(event, cb);
  1098. }
  1099. /**
  1100. * For IE9 compat: when both class and :class are present
  1101. * getAttribute('class') returns wrong value...
  1102. *
  1103. * @param {Element} el
  1104. * @return {String}
  1105. */
  1106. function getClass(el) {
  1107. var classname = el.className;
  1108. if (typeof classname === 'object') {
  1109. classname = classname.baseVal || '';
  1110. }
  1111. return classname;
  1112. }
  1113. /**
  1114. * In IE9, setAttribute('class') will result in empty class
  1115. * if the element also has the :class attribute; However in
  1116. * PhantomJS, setting `className` does not work on SVG elements...
  1117. * So we have to do a conditional check here.
  1118. *
  1119. * @param {Element} el
  1120. * @param {String} cls
  1121. */
  1122. function setClass(el, cls) {
  1123. /* istanbul ignore if */
  1124. if (isIE9 && !/svg$/.test(el.namespaceURI)) {
  1125. el.className = cls;
  1126. } else {
  1127. el.setAttribute('class', cls);
  1128. }
  1129. }
  1130. /**
  1131. * Add class with compatibility for IE & SVG
  1132. *
  1133. * @param {Element} el
  1134. * @param {String} cls
  1135. */
  1136. function addClass(el, cls) {
  1137. if (el.classList) {
  1138. el.classList.add(cls);
  1139. } else {
  1140. var cur = ' ' + getClass(el) + ' ';
  1141. if (cur.indexOf(' ' + cls + ' ') < 0) {
  1142. setClass(el, (cur + cls).trim());
  1143. }
  1144. }
  1145. }
  1146. /**
  1147. * Remove class with compatibility for IE & SVG
  1148. *
  1149. * @param {Element} el
  1150. * @param {String} cls
  1151. */
  1152. function removeClass(el, cls) {
  1153. if (el.classList) {
  1154. el.classList.remove(cls);
  1155. } else {
  1156. var cur = ' ' + getClass(el) + ' ';
  1157. var tar = ' ' + cls + ' ';
  1158. while (cur.indexOf(tar) >= 0) {
  1159. cur = cur.replace(tar, ' ');
  1160. }
  1161. setClass(el, cur.trim());
  1162. }
  1163. if (!el.className) {
  1164. el.removeAttribute('class');
  1165. }
  1166. }
  1167. /**
  1168. * Extract raw content inside an element into a temporary
  1169. * container div
  1170. *
  1171. * @param {Element} el
  1172. * @param {Boolean} asFragment
  1173. * @return {Element|DocumentFragment}
  1174. */
  1175. function extractContent(el, asFragment) {
  1176. var child;
  1177. var rawContent;
  1178. /* istanbul ignore if */
  1179. if (isTemplate(el) && isFragment(el.content)) {
  1180. el = el.content;
  1181. }
  1182. if (el.hasChildNodes()) {
  1183. trimNode(el);
  1184. rawContent = asFragment ? document.createDocumentFragment() : document.createElement('div');
  1185. /* eslint-disable no-cond-assign */
  1186. while (child = el.firstChild) {
  1187. /* eslint-enable no-cond-assign */
  1188. rawContent.appendChild(child);
  1189. }
  1190. }
  1191. return rawContent;
  1192. }
  1193. /**
  1194. * Trim possible empty head/tail text and comment
  1195. * nodes inside a parent.
  1196. *
  1197. * @param {Node} node
  1198. */
  1199. function trimNode(node) {
  1200. var child;
  1201. /* eslint-disable no-sequences */
  1202. while ((child = node.firstChild, isTrimmable(child))) {
  1203. node.removeChild(child);
  1204. }
  1205. while ((child = node.lastChild, isTrimmable(child))) {
  1206. node.removeChild(child);
  1207. }
  1208. /* eslint-enable no-sequences */
  1209. }
  1210. function isTrimmable(node) {
  1211. return node && (node.nodeType === 3 && !node.data.trim() || node.nodeType === 8);
  1212. }
  1213. /**
  1214. * Check if an element is a template tag.
  1215. * Note if the template appears inside an SVG its tagName
  1216. * will be in lowercase.
  1217. *
  1218. * @param {Element} el
  1219. */
  1220. function isTemplate(el) {
  1221. return el.tagName && el.tagName.toLowerCase() === 'template';
  1222. }
  1223. /**
  1224. * Create an "anchor" for performing dom insertion/removals.
  1225. * This is used in a number of scenarios:
  1226. * - fragment instance
  1227. * - v-html
  1228. * - v-if
  1229. * - v-for
  1230. * - component
  1231. *
  1232. * @param {String} content
  1233. * @param {Boolean} persist - IE trashes empty textNodes on
  1234. * cloneNode(true), so in certain
  1235. * cases the anchor needs to be
  1236. * non-empty to be persisted in
  1237. * templates.
  1238. * @return {Comment|Text}
  1239. */
  1240. function createAnchor(content, persist) {
  1241. var anchor = config.debug ? document.createComment(content) : document.createTextNode(persist ? ' ' : '');
  1242. anchor.__v_anchor = true;
  1243. return anchor;
  1244. }
  1245. /**
  1246. * Find a component ref attribute that starts with $.
  1247. *
  1248. * @param {Element} node
  1249. * @return {String|undefined}
  1250. */
  1251. var refRE = /^v-ref:/;
  1252. function findRef(node) {
  1253. if (node.hasAttributes()) {
  1254. var attrs = node.attributes;
  1255. for (var i = 0, l = attrs.length; i < l; i++) {
  1256. var name = attrs[i].name;
  1257. if (refRE.test(name)) {
  1258. return camelize(name.replace(refRE, ''));
  1259. }
  1260. }
  1261. }
  1262. }
  1263. /**
  1264. * Map a function to a range of nodes .
  1265. *
  1266. * @param {Node} node
  1267. * @param {Node} end
  1268. * @param {Function} op
  1269. */
  1270. function mapNodeRange(node, end, op) {
  1271. var next;
  1272. while (node !== end) {
  1273. next = node.nextSibling;
  1274. op(node);
  1275. node = next;
  1276. }
  1277. op(end);
  1278. }
  1279. /**
  1280. * Remove a range of nodes with transition, store
  1281. * the nodes in a fragment with correct ordering,
  1282. * and call callback when done.
  1283. *
  1284. * @param {Node} start
  1285. * @param {Node} end
  1286. * @param {Vue} vm
  1287. * @param {DocumentFragment} frag
  1288. * @param {Function} cb
  1289. */
  1290. function removeNodeRange(start, end, vm, frag, cb) {
  1291. var done = false;
  1292. var removed = 0;
  1293. var nodes = [];
  1294. mapNodeRange(start, end, function (node) {
  1295. if (node === end) done = true;
  1296. nodes.push(node);
  1297. removeWithTransition(node, vm, onRemoved);
  1298. });
  1299. function onRemoved() {
  1300. removed++;
  1301. if (done && removed >= nodes.length) {
  1302. for (var i = 0; i < nodes.length; i++) {
  1303. frag.appendChild(nodes[i]);
  1304. }
  1305. cb && cb();
  1306. }
  1307. }
  1308. }
  1309. /**
  1310. * Check if a node is a DocumentFragment.
  1311. *
  1312. * @param {Node} node
  1313. * @return {Boolean}
  1314. */
  1315. function isFragment(node) {
  1316. return node && node.nodeType === 11;
  1317. }
  1318. /**
  1319. * Get outerHTML of elements, taking care
  1320. * of SVG elements in IE as well.
  1321. *
  1322. * @param {Element} el
  1323. * @return {String}
  1324. */
  1325. function getOuterHTML(el) {
  1326. if (el.outerHTML) {
  1327. return el.outerHTML;
  1328. } else {
  1329. var container = document.createElement('div');
  1330. container.appendChild(el.cloneNode(true));
  1331. return container.innerHTML;
  1332. }
  1333. }
  1334. var commonTagRE = /^(div|p|span|img|a|b|i|br|ul|ol|li|h1|h2|h3|h4|h5|h6|code|pre|table|th|td|tr|form|label|input|select|option|nav|article|section|header|footer)$/i;
  1335. var reservedTagRE = /^(slot|partial|component)$/i;
  1336. var isUnknownElement = undefined;
  1337. if ('development' !== 'production') {
  1338. isUnknownElement = function (el, tag) {
  1339. if (tag.indexOf('-') > -1) {
  1340. // http://stackoverflow.com/a/28210364/1070244
  1341. return el.constructor === window.HTMLUnknownElement || el.constructor === window.HTMLElement;
  1342. } else {
  1343. return (/HTMLUnknownElement/.test(el.toString()) &&
  1344. // Chrome returns unknown for several HTML5 elements.
  1345. // https://code.google.com/p/chromium/issues/detail?id=540526
  1346. !/^(data|time|rtc|rb)$/.test(tag)
  1347. );
  1348. }
  1349. };
  1350. }
  1351. /**
  1352. * Check if an element is a component, if yes return its
  1353. * component id.
  1354. *
  1355. * @param {Element} el
  1356. * @param {Object} options
  1357. * @return {Object|undefined}
  1358. */
  1359. function checkComponentAttr(el, options) {
  1360. var tag = el.tagName.toLowerCase();
  1361. var hasAttrs = el.hasAttributes();
  1362. if (!commonTagRE.test(tag) && !reservedTagRE.test(tag)) {
  1363. if (resolveAsset(options, 'components', tag)) {
  1364. return { id: tag };
  1365. } else {
  1366. var is = hasAttrs && getIsBinding(el);
  1367. if (is) {
  1368. return is;
  1369. } else if ('development' !== 'production') {
  1370. var expectedTag = options._componentNameMap && options._componentNameMap[tag];
  1371. if (expectedTag) {
  1372. warn('Unknown custom element: <' + tag + '> - ' + 'did you mean <' + expectedTag + '>? ' + 'HTML is case-insensitive, remember to use kebab-case in templates.');
  1373. } else if (isUnknownElement(el, tag)) {
  1374. warn('Unknown custom element: <' + tag + '> - did you ' + 'register the component correctly? For recursive components, ' + 'make sure to provide the "name" option.');
  1375. }
  1376. }
  1377. }
  1378. } else if (hasAttrs) {
  1379. return getIsBinding(el);
  1380. }
  1381. }
  1382. /**
  1383. * Get "is" binding from an element.
  1384. *
  1385. * @param {Element} el
  1386. * @return {Object|undefined}
  1387. */
  1388. function getIsBinding(el) {
  1389. // dynamic syntax
  1390. var exp = getAttr(el, 'is');
  1391. if (exp != null) {
  1392. return { id: exp };
  1393. } else {
  1394. exp = getBindAttr(el, 'is');
  1395. if (exp != null) {
  1396. return { id: exp, dynamic: true };
  1397. }
  1398. }
  1399. }
  1400. /**
  1401. * Option overwriting strategies are functions that handle
  1402. * how to merge a parent option value and a child option
  1403. * value into the final value.
  1404. *
  1405. * All strategy functions follow the same signature:
  1406. *
  1407. * @param {*} parentVal
  1408. * @param {*} childVal
  1409. * @param {Vue} [vm]
  1410. */
  1411. var strats = config.optionMergeStrategies = Object.create(null);
  1412. /**
  1413. * Helper that recursively merges two data objects together.
  1414. */
  1415. function mergeData(to, from) {
  1416. var key, toVal, fromVal;
  1417. for (key in from) {
  1418. toVal = to[key];
  1419. fromVal = from[key];
  1420. if (!hasOwn(to, key)) {
  1421. set(to, key, fromVal);
  1422. } else if (isObject(toVal) && isObject(fromVal)) {
  1423. mergeData(toVal, fromVal);
  1424. }
  1425. }
  1426. return to;
  1427. }
  1428. /**
  1429. * Data
  1430. */
  1431. strats.data = function (parentVal, childVal, vm) {
  1432. if (!vm) {
  1433. // in a Vue.extend merge, both should be functions
  1434. if (!childVal) {
  1435. return parentVal;
  1436. }
  1437. if (typeof childVal !== 'function') {
  1438. 'development' !== 'production' && warn('The "data" option should be a function ' + 'that returns a per-instance value in component ' + 'definitions.', vm);
  1439. return parentVal;
  1440. }
  1441. if (!parentVal) {
  1442. return childVal;
  1443. }
  1444. // when parentVal & childVal are both present,
  1445. // we need to return a function that returns the
  1446. // merged result of both functions... no need to
  1447. // check if parentVal is a function here because
  1448. // it has to be a function to pass previous merges.
  1449. return function mergedDataFn() {
  1450. return mergeData(childVal.call(this), parentVal.call(this));
  1451. };
  1452. } else if (parentVal || childVal) {
  1453. return function mergedInstanceDataFn() {
  1454. // instance merge
  1455. var instanceData = typeof childVal === 'function' ? childVal.call(vm) : childVal;
  1456. var defaultData = typeof parentVal === 'function' ? parentVal.call(vm) : undefined;
  1457. if (instanceData) {
  1458. return mergeData(instanceData, defaultData);
  1459. } else {
  1460. return defaultData;
  1461. }
  1462. };
  1463. }
  1464. };
  1465. /**
  1466. * El
  1467. */
  1468. strats.el = function (parentVal, childVal, vm) {
  1469. if (!vm && childVal && typeof childVal !== 'function') {
  1470. 'development' !== 'production' && warn('The "el" option should be a function ' + 'that returns a per-instance value in component ' + 'definitions.', vm);
  1471. return;
  1472. }
  1473. var ret = childVal || parentVal;
  1474. // invoke the element factory if this is instance merge
  1475. return vm && typeof ret === 'function' ? ret.call(vm) : ret;
  1476. };
  1477. /**
  1478. * Hooks and param attributes are merged as arrays.
  1479. */
  1480. strats.init = strats.created = strats.ready = strats.attached = strats.detached = strats.beforeCompile = strats.compiled = strats.beforeDestroy = strats.destroyed = strats.activate = function (parentVal, childVal) {
  1481. return childVal ? parentVal ? parentVal.concat(childVal) : isArray(childVal) ? childVal : [childVal] : parentVal;
  1482. };
  1483. /**
  1484. * Assets
  1485. *
  1486. * When a vm is present (instance creation), we need to do
  1487. * a three-way merge between constructor options, instance
  1488. * options and parent options.
  1489. */
  1490. function mergeAssets(parentVal, childVal) {
  1491. var res = Object.create(parentVal);
  1492. return childVal ? extend(res, guardArrayAssets(childVal)) : res;
  1493. }
  1494. config._assetTypes.forEach(function (type) {
  1495. strats[type + 's'] = mergeAssets;
  1496. });
  1497. /**
  1498. * Events & Watchers.
  1499. *
  1500. * Events & watchers hashes should not overwrite one
  1501. * another, so we merge them as arrays.
  1502. */
  1503. strats.watch = strats.events = function (parentVal, childVal) {
  1504. if (!childVal) return parentVal;
  1505. if (!parentVal) return childVal;
  1506. var ret = {};
  1507. extend(ret, parentVal);
  1508. for (var key in childVal) {
  1509. var parent = ret[key];
  1510. var child = childVal[key];
  1511. if (parent && !isArray(parent)) {
  1512. parent = [parent];
  1513. }
  1514. ret[key] = parent ? parent.concat(child) : [child];
  1515. }
  1516. return ret;
  1517. };
  1518. /**
  1519. * Other object hashes.
  1520. */
  1521. strats.props = strats.methods = strats.computed = function (parentVal, childVal) {
  1522. if (!childVal) return parentVal;
  1523. if (!parentVal) return childVal;
  1524. var ret = Object.create(null);
  1525. extend(ret, parentVal);
  1526. extend(ret, childVal);
  1527. return ret;
  1528. };
  1529. /**
  1530. * Default strategy.
  1531. */
  1532. var defaultStrat = function defaultStrat(parentVal, childVal) {
  1533. return childVal === undefined ? parentVal : childVal;
  1534. };
  1535. /**
  1536. * Make sure component options get converted to actual
  1537. * constructors.
  1538. *
  1539. * @param {Object} options
  1540. */
  1541. function guardComponents(options) {
  1542. if (options.components) {
  1543. var components = options.components = guardArrayAssets(options.components);
  1544. var ids = Object.keys(components);
  1545. var def;
  1546. if ('development' !== 'production') {
  1547. var map = options._componentNameMap = {};
  1548. }
  1549. for (var i = 0, l = ids.length; i < l; i++) {
  1550. var key = ids[i];
  1551. if (commonTagRE.test(key) || reservedTagRE.test(key)) {
  1552. 'development' !== 'production' && warn('Do not use built-in or reserved HTML elements as component ' + 'id: ' + key);
  1553. continue;
  1554. }
  1555. // record a all lowercase <-> kebab-case mapping for
  1556. // possible custom element case error warning
  1557. if ('development' !== 'production') {
  1558. map[key.replace(/-/g, '').toLowerCase()] = hyphenate(key);
  1559. }
  1560. def = components[key];
  1561. if (isPlainObject(def)) {
  1562. components[key] = Vue.extend(def);
  1563. }
  1564. }
  1565. }
  1566. }
  1567. /**
  1568. * Ensure all props option syntax are normalized into the
  1569. * Object-based format.
  1570. *
  1571. * @param {Object} options
  1572. */
  1573. function guardProps(options) {
  1574. var props = options.props;
  1575. var i, val;
  1576. if (isArray(props)) {
  1577. options.props = {};
  1578. i = props.length;
  1579. while (i--) {
  1580. val = props[i];
  1581. if (typeof val === 'string') {
  1582. options.props[val] = null;
  1583. } else if (val.name) {
  1584. options.props[val.name] = val;
  1585. }
  1586. }
  1587. } else if (isPlainObject(props)) {
  1588. var keys = Object.keys(props);
  1589. i = keys.length;
  1590. while (i--) {
  1591. val = props[keys[i]];
  1592. if (typeof val === 'function') {
  1593. props[keys[i]] = { type: val };
  1594. }
  1595. }
  1596. }
  1597. }
  1598. /**
  1599. * Guard an Array-format assets option and converted it
  1600. * into the key-value Object format.
  1601. *
  1602. * @param {Object|Array} assets
  1603. * @return {Object}
  1604. */
  1605. function guardArrayAssets(assets) {
  1606. if (isArray(assets)) {
  1607. var res = {};
  1608. var i = assets.length;
  1609. var asset;
  1610. while (i--) {
  1611. asset = assets[i];
  1612. var id = typeof asset === 'function' ? asset.options && asset.options.name || asset.id : asset.name || asset.id;
  1613. if (!id) {
  1614. 'development' !== 'production' && warn('Array-syntax assets must provide a "name" or "id" field.');
  1615. } else {
  1616. res[id] = asset;
  1617. }
  1618. }
  1619. return res;
  1620. }
  1621. return assets;
  1622. }
  1623. /**
  1624. * Merge two option objects into a new one.
  1625. * Core utility used in both instantiation and inheritance.
  1626. *
  1627. * @param {Object} parent
  1628. * @param {Object} child
  1629. * @param {Vue} [vm] - if vm is present, indicates this is
  1630. * an instantiation merge.
  1631. */
  1632. function mergeOptions(parent, child, vm) {
  1633. guardComponents(child);
  1634. guardProps(child);
  1635. var options = {};
  1636. var key;
  1637. if (child.mixins) {
  1638. for (var i = 0, l = child.mixins.length; i < l; i++) {
  1639. parent = mergeOptions(parent, child.mixins[i], vm);
  1640. }
  1641. }
  1642. for (key in parent) {
  1643. mergeField(key);
  1644. }
  1645. for (key in child) {
  1646. if (!hasOwn(parent, key)) {
  1647. mergeField(key);
  1648. }
  1649. }
  1650. function mergeField(key) {
  1651. var strat = strats[key] || defaultStrat;
  1652. options[key] = strat(parent[key], child[key], vm, key);
  1653. }
  1654. return options;
  1655. }
  1656. /**
  1657. * Resolve an asset.
  1658. * This function is used because child instances need access
  1659. * to assets defined in its ancestor chain.
  1660. *
  1661. * @param {Object} options
  1662. * @param {String} type
  1663. * @param {String} id
  1664. * @param {Boolean} warnMissing
  1665. * @return {Object|Function}
  1666. */
  1667. function resolveAsset(options, type, id, warnMissing) {
  1668. /* istanbul ignore if */
  1669. if (typeof id !== 'string') {
  1670. return;
  1671. }
  1672. var assets = options[type];
  1673. var camelizedId;
  1674. var res = assets[id] ||
  1675. // camelCase ID
  1676. assets[camelizedId = camelize(id)] ||
  1677. // Pascal Case ID
  1678. assets[camelizedId.charAt(0).toUpperCase() + camelizedId.slice(1)];
  1679. if ('development' !== 'production' && warnMissing && !res) {
  1680. warn('Failed to resolve ' + type.slice(0, -1) + ': ' + id, options);
  1681. }
  1682. return res;
  1683. }
  1684. var uid$1 = 0;
  1685. /**
  1686. * A dep is an observable that can have multiple
  1687. * directives subscribing to it.
  1688. *
  1689. * @constructor
  1690. */
  1691. function Dep() {
  1692. this.id = uid$1++;
  1693. this.subs = [];
  1694. }
  1695. // the current target watcher being evaluated.
  1696. // this is globally unique because there could be only one
  1697. // watcher being evaluated at any time.
  1698. Dep.target = null;
  1699. /**
  1700. * Add a directive subscriber.
  1701. *
  1702. * @param {Directive} sub
  1703. */
  1704. Dep.prototype.addSub = function (sub) {
  1705. this.subs.push(sub);
  1706. };
  1707. /**
  1708. * Remove a directive subscriber.
  1709. *
  1710. * @param {Directive} sub
  1711. */
  1712. Dep.prototype.removeSub = function (sub) {
  1713. this.subs.$remove(sub);
  1714. };
  1715. /**
  1716. * Add self as a dependency to the target watcher.
  1717. */
  1718. Dep.prototype.depend = function () {
  1719. Dep.target.addDep(this);
  1720. };
  1721. /**
  1722. * Notify all subscribers of a new value.
  1723. */
  1724. Dep.prototype.notify = function () {
  1725. // stablize the subscriber list first
  1726. var subs = toArray(this.subs);
  1727. for (var i = 0, l = subs.length; i < l; i++) {
  1728. subs[i].update();
  1729. }
  1730. };
  1731. var arrayProto = Array.prototype;
  1732. var arrayMethods = Object.create(arrayProto)
  1733. /**
  1734. * Intercept mutating methods and emit events
  1735. */
  1736. ;['push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse'].forEach(function (method) {
  1737. // cache original method
  1738. var original = arrayProto[method];
  1739. def(arrayMethods, method, function mutator() {
  1740. // avoid leaking arguments:
  1741. // http://jsperf.com/closure-with-arguments
  1742. var i = arguments.length;
  1743. var args = new Array(i);
  1744. while (i--) {
  1745. args[i] = arguments[i];
  1746. }
  1747. var result = original.apply(this, args);
  1748. var ob = this.__ob__;
  1749. var inserted;
  1750. switch (method) {
  1751. case 'push':
  1752. inserted = args;
  1753. break;
  1754. case 'unshift':
  1755. inserted = args;
  1756. break;
  1757. case 'splice':
  1758. inserted = args.slice(2);
  1759. break;
  1760. }
  1761. if (inserted) ob.observeArray(inserted);
  1762. // notify change
  1763. ob.dep.notify();
  1764. return result;
  1765. });
  1766. });
  1767. /**
  1768. * Swap the element at the given index with a new value
  1769. * and emits corresponding event.
  1770. *
  1771. * @param {Number} index
  1772. * @param {*} val
  1773. * @return {*} - replaced element
  1774. */
  1775. def(arrayProto, '$set', function $set(index, val) {
  1776. if (index >= this.length) {
  1777. this.length = Number(index) + 1;
  1778. }
  1779. return this.splice(index, 1, val)[0];
  1780. });
  1781. /**
  1782. * Convenience method to remove the element at given index or target element reference.
  1783. *
  1784. * @param {*} item
  1785. */
  1786. def(arrayProto, '$remove', function $remove(item) {
  1787. /* istanbul ignore if */
  1788. if (!this.length) return;
  1789. var index = indexOf(this, item);
  1790. if (index > -1) {
  1791. return this.splice(index, 1);
  1792. }
  1793. });
  1794. var arrayKeys = Object.getOwnPropertyNames(arrayMethods);
  1795. /**
  1796. * By default, when a reactive property is set, the new value is
  1797. * also converted to become reactive. However in certain cases, e.g.
  1798. * v-for scope alias and props, we don't want to force conversion
  1799. * because the value may be a nested value under a frozen data structure.
  1800. *
  1801. * So whenever we want to set a reactive property without forcing
  1802. * conversion on the new value, we wrap that call inside this function.
  1803. */
  1804. var shouldConvert = true;
  1805. function withoutConversion(fn) {
  1806. shouldConvert = false;
  1807. fn();
  1808. shouldConvert = true;
  1809. }
  1810. /**
  1811. * Observer class that are attached to each observed
  1812. * object. Once attached, the observer converts target
  1813. * object's property keys into getter/setters that
  1814. * collect dependencies and dispatches updates.
  1815. *
  1816. * @param {Array|Object} value
  1817. * @constructor
  1818. */
  1819. function Observer(value) {
  1820. this.value = value;
  1821. this.dep = new Dep();
  1822. def(value, '__ob__', this);
  1823. if (isArray(value)) {
  1824. var augment = hasProto ? protoAugment : copyAugment;
  1825. augment(value, arrayMethods, arrayKeys);
  1826. this.observeArray(value);
  1827. } else {
  1828. this.walk(value);
  1829. }
  1830. }
  1831. // Instance methods
  1832. /**
  1833. * Walk through each property and convert them into
  1834. * getter/setters. This method should only be called when
  1835. * value type is Object.
  1836. *
  1837. * @param {Object} obj
  1838. */
  1839. Observer.prototype.walk = function (obj) {
  1840. var keys = Object.keys(obj);
  1841. for (var i = 0, l = keys.length; i < l; i++) {
  1842. this.convert(keys[i], obj[keys[i]]);
  1843. }
  1844. };
  1845. /**
  1846. * Observe a list of Array items.
  1847. *
  1848. * @param {Array} items
  1849. */
  1850. Observer.prototype.observeArray = function (items) {
  1851. for (var i = 0, l = items.length; i < l; i++) {
  1852. observe(items[i]);
  1853. }
  1854. };
  1855. /**
  1856. * Convert a property into getter/setter so we can emit
  1857. * the events when the property is accessed/changed.
  1858. *
  1859. * @param {String} key
  1860. * @param {*} val
  1861. */
  1862. Observer.prototype.convert = function (key, val) {
  1863. defineReactive(this.value, key, val);
  1864. };
  1865. /**
  1866. * Add an owner vm, so that when $set/$delete mutations
  1867. * happen we can notify owner vms to proxy the keys and
  1868. * digest the watchers. This is only called when the object
  1869. * is observed as an instance's root $data.
  1870. *
  1871. * @param {Vue} vm
  1872. */
  1873. Observer.prototype.addVm = function (vm) {
  1874. (this.vms || (this.vms = [])).push(vm);
  1875. };
  1876. /**
  1877. * Remove an owner vm. This is called when the object is
  1878. * swapped out as an instance's $data object.
  1879. *
  1880. * @param {Vue} vm
  1881. */
  1882. Observer.prototype.removeVm = function (vm) {
  1883. this.vms.$remove(vm);
  1884. };
  1885. // helpers
  1886. /**
  1887. * Augment an target Object or Array by intercepting
  1888. * the prototype chain using __proto__
  1889. *
  1890. * @param {Object|Array} target
  1891. * @param {Object} src
  1892. */
  1893. function protoAugment(target, src) {
  1894. /* eslint-disable no-proto */
  1895. target.__proto__ = src;
  1896. /* eslint-enable no-proto */
  1897. }
  1898. /**
  1899. * Augment an target Object or Array by defining
  1900. * hidden properties.
  1901. *
  1902. * @param {Object|Array} target
  1903. * @param {Object} proto
  1904. */
  1905. function copyAugment(target, src, keys) {
  1906. for (var i = 0, l = keys.length; i < l; i++) {
  1907. var key = keys[i];
  1908. def(target, key, src[key]);
  1909. }
  1910. }
  1911. /**
  1912. * Attempt to create an observer instance for a value,
  1913. * returns the new observer if successfully observed,
  1914. * or the existing observer if the value already has one.
  1915. *
  1916. * @param {*} value
  1917. * @param {Vue} [vm]
  1918. * @return {Observer|undefined}
  1919. * @static
  1920. */
  1921. function observe(value, vm) {
  1922. if (!value || typeof value !== 'object') {
  1923. return;
  1924. }
  1925. var ob;
  1926. if (hasOwn(value, '__ob__') && value.__ob__ instanceof Observer) {
  1927. ob = value.__ob__;
  1928. } else if (shouldConvert && (isArray(value) || isPlainObject(value)) && Object.isExtensible(value) && !value._isVue) {
  1929. ob = new Observer(value);
  1930. }
  1931. if (ob && vm) {
  1932. ob.addVm(vm);
  1933. }
  1934. return ob;
  1935. }
  1936. /**
  1937. * Define a reactive property on an Object.
  1938. *
  1939. * @param {Object} obj
  1940. * @param {String} key
  1941. * @param {*} val
  1942. */
  1943. function defineReactive(obj, key, val) {
  1944. var dep = new Dep();
  1945. var property = Object.getOwnPropertyDescriptor(obj, key);
  1946. if (property && property.configurable === false) {
  1947. return;
  1948. }
  1949. // cater for pre-defined getter/setters
  1950. var getter = property && property.get;
  1951. var setter = property && property.set;
  1952. var childOb = observe(val);
  1953. Object.defineProperty(obj, key, {
  1954. enumerable: true,
  1955. configurable: true,
  1956. get: function reactiveGetter() {
  1957. var value = getter ? getter.call(obj) : val;
  1958. if (Dep.target) {
  1959. dep.depend();
  1960. if (childOb) {
  1961. childOb.dep.depend();
  1962. }
  1963. if (isArray(value)) {
  1964. for (var e, i = 0, l = value.length; i < l; i++) {
  1965. e = value[i];
  1966. e && e.__ob__ && e.__ob__.dep.depend();
  1967. }
  1968. }
  1969. }
  1970. return value;
  1971. },
  1972. set: function reactiveSetter(newVal) {
  1973. var value = getter ? getter.call(obj) : val;
  1974. if (newVal === value) {
  1975. return;
  1976. }
  1977. if (setter) {
  1978. setter.call(obj, newVal);
  1979. } else {
  1980. val = newVal;
  1981. }
  1982. childOb = observe(newVal);
  1983. dep.notify();
  1984. }
  1985. });
  1986. }
  1987. var util = Object.freeze({
  1988. defineReactive: defineReactive,
  1989. set: set,
  1990. del: del,
  1991. hasOwn: hasOwn,
  1992. isLiteral: isLiteral,
  1993. isReserved: isReserved,
  1994. _toString: _toString,
  1995. toNumber: toNumber,
  1996. toBoolean: toBoolean,
  1997. stripQuotes: stripQuotes,
  1998. camelize: camelize,
  1999. hyphenate: hyphenate,
  2000. classify: classify,
  2001. bind: bind,
  2002. toArray: toArray,
  2003. extend: extend,
  2004. isObject: isObject,
  2005. isPlainObject: isPlainObject,
  2006. def: def,
  2007. debounce: _debounce,
  2008. indexOf: indexOf,
  2009. cancellable: cancellable,
  2010. looseEqual: looseEqual,
  2011. isArray: isArray,
  2012. hasProto: hasProto,
  2013. inBrowser: inBrowser,
  2014. devtools: devtools,
  2015. isIE9: isIE9,
  2016. isAndroid: isAndroid,
  2017. get transitionProp () { return transitionProp; },
  2018. get transitionEndEvent () { return transitionEndEvent; },
  2019. get animationProp () { return animationProp; },
  2020. get animationEndEvent () { return animationEndEvent; },
  2021. nextTick: nextTick,
  2022. query: query,
  2023. inDoc: inDoc,
  2024. getAttr: getAttr,
  2025. getBindAttr: getBindAttr,
  2026. hasBindAttr: hasBindAttr,
  2027. before: before,
  2028. after: after,
  2029. remove: remove,
  2030. prepend: prepend,
  2031. replace: replace,
  2032. on: on,
  2033. off: off,
  2034. setClass: setClass,
  2035. addClass: addClass,
  2036. removeClass: removeClass,
  2037. extractContent: extractContent,
  2038. trimNode: trimNode,
  2039. isTemplate: isTemplate,
  2040. createAnchor: createAnchor,
  2041. findRef: findRef,
  2042. mapNodeRange: mapNodeRange,
  2043. removeNodeRange: removeNodeRange,
  2044. isFragment: isFragment,
  2045. getOuterHTML: getOuterHTML,
  2046. mergeOptions: mergeOptions,
  2047. resolveAsset: resolveAsset,
  2048. checkComponentAttr: checkComponentAttr,
  2049. commonTagRE: commonTagRE,
  2050. reservedTagRE: reservedTagRE,
  2051. get warn () { return warn; }
  2052. });
  2053. var uid = 0;
  2054. function initMixin (Vue) {
  2055. /**
  2056. * The main init sequence. This is called for every
  2057. * instance, including ones that are created from extended
  2058. * constructors.
  2059. *
  2060. * @param {Object} options - this options object should be
  2061. * the result of merging class
  2062. * options and the options passed
  2063. * in to the constructor.
  2064. */
  2065. Vue.prototype._init = function (options) {
  2066. options = options || {};
  2067. this.$el = null;
  2068. this.$parent = options.parent;
  2069. this.$root = this.$parent ? this.$parent.$root : this;
  2070. this.$children = [];
  2071. this.$refs = {}; // child vm references
  2072. this.$els = {}; // element references
  2073. this._watchers = []; // all watchers as an array
  2074. this._directives = []; // all directives
  2075. // a uid
  2076. this._uid = uid++;
  2077. // a flag to avoid this being observed
  2078. this._isVue = true;
  2079. // events bookkeeping
  2080. this._events = {}; // registered callbacks
  2081. this._eventsCount = {}; // for $broadcast optimization
  2082. // fragment instance properties
  2083. this._isFragment = false;
  2084. this._fragment = // @type {DocumentFragment}
  2085. this._fragmentStart = // @type {Text|Comment}
  2086. this._fragmentEnd = null; // @type {Text|Comment}
  2087. // lifecycle state
  2088. this._isCompiled = this._isDestroyed = this._isReady = this._isAttached = this._isBeingDestroyed = this._vForRemoving = false;
  2089. this._unlinkFn = null;
  2090. // context:
  2091. // if this is a transcluded component, context
  2092. // will be the common parent vm of this instance
  2093. // and its host.
  2094. this._context = options._context || this.$parent;
  2095. // scope:
  2096. // if this is inside an inline v-for, the scope
  2097. // will be the intermediate scope created for this
  2098. // repeat fragment. this is used for linking props
  2099. // and container directives.
  2100. this._scope = options._scope;
  2101. // fragment:
  2102. // if this instance is compiled inside a Fragment, it
  2103. // needs to reigster itself as a child of that fragment
  2104. // for attach/detach to work properly.
  2105. this._frag = options._frag;
  2106. if (this._frag) {
  2107. this._frag.children.push(this);
  2108. }
  2109. // push self into parent / transclusion host
  2110. if (this.$parent) {
  2111. this.$parent.$children.push(this);
  2112. }
  2113. // merge options.
  2114. options = this.$options = mergeOptions(this.constructor.options, options, this);
  2115. // set ref
  2116. this._updateRef();
  2117. // initialize data as empty object.
  2118. // it will be filled up in _initScope().
  2119. this._data = {};
  2120. // save raw constructor data before merge
  2121. // so that we know which properties are provided at
  2122. // instantiation.
  2123. this._runtimeData = options.data;
  2124. // call init hook
  2125. this._callHook('init');
  2126. // initialize data observation and scope inheritance.
  2127. this._initState();
  2128. // setup event system and option events.
  2129. this._initEvents();
  2130. // call created hook
  2131. this._callHook('created');
  2132. // if `el` option is passed, start compilation.
  2133. if (options.el) {
  2134. this.$mount(options.el);
  2135. }
  2136. };
  2137. }
  2138. var pathCache = new Cache(1000);
  2139. // actions
  2140. var APPEND = 0;
  2141. var PUSH = 1;
  2142. var INC_SUB_PATH_DEPTH = 2;
  2143. var PUSH_SUB_PATH = 3;
  2144. // states
  2145. var BEFORE_PATH = 0;
  2146. var IN_PATH = 1;
  2147. var BEFORE_IDENT = 2;
  2148. var IN_IDENT = 3;
  2149. var IN_SUB_PATH = 4;
  2150. var IN_SINGLE_QUOTE = 5;
  2151. var IN_DOUBLE_QUOTE = 6;
  2152. var AFTER_PATH = 7;
  2153. var ERROR = 8;
  2154. var pathStateMachine = [];
  2155. pathStateMachine[BEFORE_PATH] = {
  2156. 'ws': [BEFORE_PATH],
  2157. 'ident': [IN_IDENT, APPEND],
  2158. '[': [IN_SUB_PATH],
  2159. 'eof': [AFTER_PATH]
  2160. };
  2161. pathStateMachine[IN_PATH] = {
  2162. 'ws': [IN_PATH],
  2163. '.': [BEFORE_IDENT],
  2164. '[': [IN_SUB_PATH],
  2165. 'eof': [AFTER_PATH]
  2166. };
  2167. pathStateMachine[BEFORE_IDENT] = {
  2168. 'ws': [BEFORE_IDENT],
  2169. 'ident': [IN_IDENT, APPEND]
  2170. };
  2171. pathStateMachine[IN_IDENT] = {
  2172. 'ident': [IN_IDENT, APPEND],
  2173. '0': [IN_IDENT, APPEND],
  2174. 'number': [IN_IDENT, APPEND],
  2175. 'ws': [IN_PATH, PUSH],
  2176. '.': [BEFORE_IDENT, PUSH],
  2177. '[': [IN_SUB_PATH, PUSH],
  2178. 'eof': [AFTER_PATH, PUSH]
  2179. };
  2180. pathStateMachine[IN_SUB_PATH] = {
  2181. "'": [IN_SINGLE_QUOTE, APPEND],
  2182. '"': [IN_DOUBLE_QUOTE, APPEND],
  2183. '[': [IN_SUB_PATH, INC_SUB_PATH_DEPTH],
  2184. ']': [IN_PATH, PUSH_SUB_PATH],
  2185. 'eof': ERROR,
  2186. 'else': [IN_SUB_PATH, APPEND]
  2187. };
  2188. pathStateMachine[IN_SINGLE_QUOTE] = {
  2189. "'": [IN_SUB_PATH, APPEND],
  2190. 'eof': ERROR,
  2191. 'else': [IN_SINGLE_QUOTE, APPEND]
  2192. };
  2193. pathStateMachine[IN_DOUBLE_QUOTE] = {
  2194. '"': [IN_SUB_PATH, APPEND],
  2195. 'eof': ERROR,
  2196. 'else': [IN_DOUBLE_QUOTE, APPEND]
  2197. };
  2198. /**
  2199. * Determine the type of a character in a keypath.
  2200. *
  2201. * @param {Char} ch
  2202. * @return {String} type
  2203. */
  2204. function getPathCharType(ch) {
  2205. if (ch === undefined) {
  2206. return 'eof';
  2207. }
  2208. var code = ch.charCodeAt(0);
  2209. switch (code) {
  2210. case 0x5B: // [
  2211. case 0x5D: // ]
  2212. case 0x2E: // .
  2213. case 0x22: // "
  2214. case 0x27: // '
  2215. case 0x30:
  2216. // 0
  2217. return ch;
  2218. case 0x5F: // _
  2219. case 0x24:
  2220. // $
  2221. return 'ident';
  2222. case 0x20: // Space
  2223. case 0x09: // Tab
  2224. case 0x0A: // Newline
  2225. case 0x0D: // Return
  2226. case 0xA0: // No-break space
  2227. case 0xFEFF: // Byte Order Mark
  2228. case 0x2028: // Line Separator
  2229. case 0x2029:
  2230. // Paragraph Separator
  2231. return 'ws';
  2232. }
  2233. // a-z, A-Z
  2234. if (code >= 0x61 && code <= 0x7A || code >= 0x41 && code <= 0x5A) {
  2235. return 'ident';
  2236. }
  2237. // 1-9
  2238. if (code >= 0x31 && code <= 0x39) {
  2239. return 'number';
  2240. }
  2241. return 'else';
  2242. }
  2243. /**
  2244. * Format a subPath, return its plain form if it is
  2245. * a literal string or number. Otherwise prepend the
  2246. * dynamic indicator (*).
  2247. *
  2248. * @param {String} path
  2249. * @return {String}
  2250. */
  2251. function formatSubPath(path) {
  2252. var trimmed = path.trim();
  2253. // invalid leading 0
  2254. if (path.charAt(0) === '0' && isNaN(path)) {
  2255. return false;
  2256. }
  2257. return isLiteral(trimmed) ? stripQuotes(trimmed) : '*' + trimmed;
  2258. }
  2259. /**
  2260. * Parse a string path into an array of segments
  2261. *
  2262. * @param {String} path
  2263. * @return {Array|undefined}
  2264. */
  2265. function parse(path) {
  2266. var keys = [];
  2267. var index = -1;
  2268. var mode = BEFORE_PATH;
  2269. var subPathDepth = 0;
  2270. var c, newChar, key, type, transition, action, typeMap;
  2271. var actions = [];
  2272. actions[PUSH] = function () {
  2273. if (key !== undefined) {
  2274. keys.push(key);
  2275. key = undefined;
  2276. }
  2277. };
  2278. actions[APPEND] = function () {
  2279. if (key === undefined) {
  2280. key = newChar;
  2281. } else {
  2282. key += newChar;
  2283. }
  2284. };
  2285. actions[INC_SUB_PATH_DEPTH] = function () {
  2286. actions[APPEND]();
  2287. subPathDepth++;
  2288. };
  2289. actions[PUSH_SUB_PATH] = function () {
  2290. if (subPathDepth > 0) {
  2291. subPathDepth--;
  2292. mode = IN_SUB_PATH;
  2293. actions[APPEND]();
  2294. } else {
  2295. subPathDepth = 0;
  2296. key = formatSubPath(key);
  2297. if (key === false) {
  2298. return false;
  2299. } else {
  2300. actions[PUSH]();
  2301. }
  2302. }
  2303. };
  2304. function maybeUnescapeQuote() {
  2305. var nextChar = path[index + 1];
  2306. if (mode === IN_SINGLE_QUOTE && nextChar === "'" || mode === IN_DOUBLE_QUOTE && nextChar === '"') {
  2307. index++;
  2308. newChar = '\\' + nextChar;
  2309. actions[APPEND]();
  2310. return true;
  2311. }
  2312. }
  2313. while (mode != null) {
  2314. index++;
  2315. c = path[index];
  2316. if (c === '\\' && maybeUnescapeQuote()) {
  2317. continue;
  2318. }
  2319. type = getPathCharType(c);
  2320. typeMap = pathStateMachine[mode];
  2321. transition = typeMap[type] || typeMap['else'] || ERROR;
  2322. if (transition === ERROR) {
  2323. return; // parse error
  2324. }
  2325. mode = transition[0];
  2326. action = actions[transition[1]];
  2327. if (action) {
  2328. newChar = transition[2];
  2329. newChar = newChar === undefined ? c : newChar;
  2330. if (action() === false) {
  2331. return;
  2332. }
  2333. }
  2334. if (mode === AFTER_PATH) {
  2335. keys.raw = path;
  2336. return keys;
  2337. }
  2338. }
  2339. }
  2340. /**
  2341. * External parse that check for a cache hit first
  2342. *
  2343. * @param {String} path
  2344. * @return {Array|undefined}
  2345. */
  2346. function parsePath(path) {
  2347. var hit = pathCache.get(path);
  2348. if (!hit) {
  2349. hit = parse(path);
  2350. if (hit) {
  2351. pathCache.put(path, hit);
  2352. }
  2353. }
  2354. return hit;
  2355. }
  2356. /**
  2357. * Get from an object from a path string
  2358. *
  2359. * @param {Object} obj
  2360. * @param {String} path
  2361. */
  2362. function getPath(obj, path) {
  2363. return parseExpression(path).get(obj);
  2364. }
  2365. /**
  2366. * Warn against setting non-existent root path on a vm.
  2367. */
  2368. var warnNonExistent;
  2369. if ('development' !== 'production') {
  2370. warnNonExistent = function (path, vm) {
  2371. warn('You are setting a non-existent path "' + path.raw + '" ' + 'on a vm instance. Consider pre-initializing the property ' + 'with the "data" option for more reliable reactivity ' + 'and better performance.', vm);
  2372. };
  2373. }
  2374. /**
  2375. * Set on an object from a path
  2376. *
  2377. * @param {Object} obj
  2378. * @param {String | Array} path
  2379. * @param {*} val
  2380. */
  2381. function setPath(obj, path, val) {
  2382. var original = obj;
  2383. if (typeof path === 'string') {
  2384. path = parse(path);
  2385. }
  2386. if (!path || !isObject(obj)) {
  2387. return false;
  2388. }
  2389. var last, key;
  2390. for (var i = 0, l = path.length; i < l; i++) {
  2391. last = obj;
  2392. key = path[i];
  2393. if (key.charAt(0) === '*') {
  2394. key = parseExpression(key.slice(1)).get.call(original, original);
  2395. }
  2396. if (i < l - 1) {
  2397. obj = obj[key];
  2398. if (!isObject(obj)) {
  2399. obj = {};
  2400. if ('development' !== 'production' && last._isVue) {
  2401. warnNonExistent(path, last);
  2402. }
  2403. set(last, key, obj);
  2404. }
  2405. } else {
  2406. if (isArray(obj)) {
  2407. obj.$set(key, val);
  2408. } else if (key in obj) {
  2409. obj[key] = val;
  2410. } else {
  2411. if ('development' !== 'production' && obj._isVue) {
  2412. warnNonExistent(path, obj);
  2413. }
  2414. set(obj, key, val);
  2415. }
  2416. }
  2417. }
  2418. return true;
  2419. }
  2420. var path = Object.freeze({
  2421. parsePath: parsePath,
  2422. getPath: getPath,
  2423. setPath: setPath
  2424. });
  2425. var expressionCache = new Cache(1000);
  2426. var allowedKeywords = 'Math,Date,this,true,false,null,undefined,Infinity,NaN,' + 'isNaN,isFinite,decodeURI,decodeURIComponent,encodeURI,' + 'encodeURIComponent,parseInt,parseFloat';
  2427. var allowedKeywordsRE = new RegExp('^(' + allowedKeywords.replace(/,/g, '\\b|') + '\\b)');
  2428. // keywords that don't make sense inside expressions
  2429. var improperKeywords = 'break,case,class,catch,const,continue,debugger,default,' + 'delete,do,else,export,extends,finally,for,function,if,' + 'import,in,instanceof,let,return,super,switch,throw,try,' + 'var,while,with,yield,enum,await,implements,package,' + 'protected,static,interface,private,public';
  2430. var improperKeywordsRE = new RegExp('^(' + improperKeywords.replace(/,/g, '\\b|') + '\\b)');
  2431. var wsRE = /\s/g;
  2432. var newlineRE = /\n/g;
  2433. var saveRE = /[\{,]\s*[\w\$_]+\s*:|('(?:[^'\\]|\\.)*'|"(?:[^"\\]|\\.)*"|`(?:[^`\\]|\\.)*\$\{|\}(?:[^`\\]|\\.)*`|`(?:[^`\\]|\\.)*`)|new |typeof |void /g;
  2434. var restoreRE = /"(\d+)"/g;
  2435. var pathTestRE = /^[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*|\['.*?'\]|\[".*?"\]|\[\d+\]|\[[A-Za-z_$][\w$]*\])*$/;
  2436. var identRE = /[^\w$\.](?:[A-Za-z_$][\w$]*)/g;
  2437. var booleanLiteralRE = /^(?:true|false)$/;
  2438. /**
  2439. * Save / Rewrite / Restore
  2440. *
  2441. * When rewriting paths found in an expression, it is
  2442. * possible for the same letter sequences to be found in
  2443. * strings and Object literal property keys. Therefore we
  2444. * remove and store these parts in a temporary array, and
  2445. * restore them after the path rewrite.
  2446. */
  2447. var saved = [];
  2448. /**
  2449. * Save replacer
  2450. *
  2451. * The save regex can match two possible cases:
  2452. * 1. An opening object literal
  2453. * 2. A string
  2454. * If matched as a plain string, we need to escape its
  2455. * newlines, since the string needs to be preserved when
  2456. * generating the function body.
  2457. *
  2458. * @param {String} str
  2459. * @param {String} isString - str if matched as a string
  2460. * @return {String} - placeholder with index
  2461. */
  2462. function save(str, isString) {
  2463. var i = saved.length;
  2464. saved[i] = isString ? str.replace(newlineRE, '\\n') : str;
  2465. return '"' + i + '"';
  2466. }
  2467. /**
  2468. * Path rewrite replacer
  2469. *
  2470. * @param {String} raw
  2471. * @return {String}
  2472. */
  2473. function rewrite(raw) {
  2474. var c = raw.charAt(0);
  2475. var path = raw.slice(1);
  2476. if (allowedKeywordsRE.test(path)) {
  2477. return raw;
  2478. } else {
  2479. path = path.indexOf('"') > -1 ? path.replace(restoreRE, restore) : path;
  2480. return c + 'scope.' + path;
  2481. }
  2482. }
  2483. /**
  2484. * Restore replacer
  2485. *
  2486. * @param {String} str
  2487. * @param {String} i - matched save index
  2488. * @return {String}
  2489. */
  2490. function restore(str, i) {
  2491. return saved[i];
  2492. }
  2493. /**
  2494. * Rewrite an expression, prefixing all path accessors with
  2495. * `scope.` and generate getter/setter functions.
  2496. *
  2497. * @param {String} exp
  2498. * @return {Function}
  2499. */
  2500. function compileGetter(exp) {
  2501. if (improperKeywordsRE.test(exp)) {
  2502. 'development' !== 'production' && warn('Avoid using reserved keywords in expression: ' + exp);
  2503. }
  2504. // reset state
  2505. saved.length = 0;
  2506. // save strings and object literal keys
  2507. var body = exp.replace(saveRE, save).replace(wsRE, '');
  2508. // rewrite all paths
  2509. // pad 1 space here becaue the regex matches 1 extra char
  2510. body = (' ' + body).replace(identRE, rewrite).replace(restoreRE, restore);
  2511. return makeGetterFn(body);
  2512. }
  2513. /**
  2514. * Build a getter function. Requires eval.
  2515. *
  2516. * We isolate the try/catch so it doesn't affect the
  2517. * optimization of the parse function when it is not called.
  2518. *
  2519. * @param {String} body
  2520. * @return {Function|undefined}
  2521. */
  2522. function makeGetterFn(body) {
  2523. try {
  2524. /* eslint-disable no-new-func */
  2525. return new Function('scope', 'return ' + body + ';');
  2526. /* eslint-enable no-new-func */
  2527. } catch (e) {
  2528. 'development' !== 'production' && warn('Invalid expression. ' + 'Generated function body: ' + body);
  2529. }
  2530. }
  2531. /**
  2532. * Compile a setter function for the expression.
  2533. *
  2534. * @param {String} exp
  2535. * @return {Function|undefined}
  2536. */
  2537. function compileSetter(exp) {
  2538. var path = parsePath(exp);
  2539. if (path) {
  2540. return function (scope, val) {
  2541. setPath(scope, path, val);
  2542. };
  2543. } else {
  2544. 'development' !== 'production' && warn('Invalid setter expression: ' + exp);
  2545. }
  2546. }
  2547. /**
  2548. * Parse an expression into re-written getter/setters.
  2549. *
  2550. * @param {String} exp
  2551. * @param {Boolean} needSet
  2552. * @return {Function}
  2553. */
  2554. function parseExpression(exp, needSet) {
  2555. exp = exp.trim();
  2556. // try cache
  2557. var hit = expressionCache.get(exp);
  2558. if (hit) {
  2559. if (needSet && !hit.set) {
  2560. hit.set = compileSetter(hit.exp);
  2561. }
  2562. return hit;
  2563. }
  2564. var res = { exp: exp };
  2565. res.get = isSimplePath(exp) && exp.indexOf('[') < 0
  2566. // optimized super simple getter
  2567. ? makeGetterFn('scope.' + exp)
  2568. // dynamic getter
  2569. : compileGetter(exp);
  2570. if (needSet) {
  2571. res.set = compileSetter(exp);
  2572. }
  2573. expressionCache.put(exp, res);
  2574. return res;
  2575. }
  2576. /**
  2577. * Check if an expression is a simple path.
  2578. *
  2579. * @param {String} exp
  2580. * @return {Boolean}
  2581. */
  2582. function isSimplePath(exp) {
  2583. return pathTestRE.test(exp) &&
  2584. // don't treat true/false as paths
  2585. !booleanLiteralRE.test(exp) &&
  2586. // Math constants e.g. Math.PI, Math.E etc.
  2587. exp.slice(0, 5) !== 'Math.';
  2588. }
  2589. var expression = Object.freeze({
  2590. parseExpression: parseExpression,
  2591. isSimplePath: isSimplePath
  2592. });
  2593. // we have two separate queues: one for directive updates
  2594. // and one for user watcher registered via $watch().
  2595. // we want to guarantee directive updates to be called
  2596. // before user watchers so that when user watchers are
  2597. // triggered, the DOM would have already been in updated
  2598. // state.
  2599. var queueIndex;
  2600. var queue = [];
  2601. var userQueue = [];
  2602. var has = {};
  2603. var circular = {};
  2604. var waiting = false;
  2605. var internalQueueDepleted = false;
  2606. /**
  2607. * Reset the batcher's state.
  2608. */
  2609. function resetBatcherState() {
  2610. queue = [];
  2611. userQueue = [];
  2612. has = {};
  2613. circular = {};
  2614. waiting = internalQueueDepleted = false;
  2615. }
  2616. /**
  2617. * Flush both queues and run the watchers.
  2618. */
  2619. function flushBatcherQueue() {
  2620. runBatcherQueue(queue);
  2621. internalQueueDepleted = true;
  2622. runBatcherQueue(userQueue);
  2623. // dev tool hook
  2624. /* istanbul ignore if */
  2625. if (devtools && config.devtools) {
  2626. devtools.emit('flush');
  2627. }
  2628. resetBatcherState();
  2629. }
  2630. /**
  2631. * Run the watchers in a single queue.
  2632. *
  2633. * @param {Array} queue
  2634. */
  2635. function runBatcherQueue(queue) {
  2636. // do not cache length because more watchers might be pushed
  2637. // as we run existing watchers
  2638. for (queueIndex = 0; queueIndex < queue.length; queueIndex++) {
  2639. var watcher = queue[queueIndex];
  2640. var id = watcher.id;
  2641. has[id] = null;
  2642. watcher.run();
  2643. // in dev build, check and stop circular updates.
  2644. if ('development' !== 'production' && has[id] != null) {
  2645. circular[id] = (circular[id] || 0) + 1;
  2646. if (circular[id] > config._maxUpdateCount) {
  2647. warn('You may have an infinite update loop for watcher ' + 'with expression "' + watcher.expression + '"', watcher.vm);
  2648. break;
  2649. }
  2650. }
  2651. }
  2652. }
  2653. /**
  2654. * Push a watcher into the watcher queue.
  2655. * Jobs with duplicate IDs will be skipped unless it's
  2656. * pushed when the queue is being flushed.
  2657. *
  2658. * @param {Watcher} watcher
  2659. * properties:
  2660. * - {Number} id
  2661. * - {Function} run
  2662. */
  2663. function pushWatcher(watcher) {
  2664. var id = watcher.id;
  2665. if (has[id] == null) {
  2666. if (internalQueueDepleted && !watcher.user) {
  2667. // an internal watcher triggered by a user watcher...
  2668. // let's run it immediately after current user watcher is done.
  2669. userQueue.splice(queueIndex + 1, 0, watcher);
  2670. } else {
  2671. // push watcher into appropriate queue
  2672. var q = watcher.user ? userQueue : queue;
  2673. has[id] = q.length;
  2674. q.push(watcher);
  2675. // queue the flush
  2676. if (!waiting) {
  2677. waiting = true;
  2678. nextTick(flushBatcherQueue);
  2679. }
  2680. }
  2681. }
  2682. }
  2683. var uid$2 = 0;
  2684. /**
  2685. * A watcher parses an expression, collects dependencies,
  2686. * and fires callback when the expression value changes.
  2687. * This is used for both the $watch() api and directives.
  2688. *
  2689. * @param {Vue} vm
  2690. * @param {String|Function} expOrFn
  2691. * @param {Function} cb
  2692. * @param {Object} options
  2693. * - {Array} filters
  2694. * - {Boolean} twoWay
  2695. * - {Boolean} deep
  2696. * - {Boolean} user
  2697. * - {Boolean} sync
  2698. * - {Boolean} lazy
  2699. * - {Function} [preProcess]
  2700. * - {Function} [postProcess]
  2701. * @constructor
  2702. */
  2703. function Watcher(vm, expOrFn, cb, options) {
  2704. // mix in options
  2705. if (options) {
  2706. extend(this, options);
  2707. }
  2708. var isFn = typeof expOrFn === 'function';
  2709. this.vm = vm;
  2710. vm._watchers.push(this);
  2711. this.expression = expOrFn;
  2712. this.cb = cb;
  2713. this.id = ++uid$2; // uid for batching
  2714. this.active = true;
  2715. this.dirty = this.lazy; // for lazy watchers
  2716. this.deps = [];
  2717. this.newDeps = [];
  2718. this.depIds = Object.create(null);
  2719. this.newDepIds = null;
  2720. this.prevError = null; // for async error stacks
  2721. // parse expression for getter/setter
  2722. if (isFn) {
  2723. this.getter = expOrFn;
  2724. this.setter = undefined;
  2725. } else {
  2726. var res = parseExpression(expOrFn, this.twoWay);
  2727. this.getter = res.get;
  2728. this.setter = res.set;
  2729. }
  2730. this.value = this.lazy ? undefined : this.get();
  2731. // state for avoiding false triggers for deep and Array
  2732. // watchers during vm._digest()
  2733. this.queued = this.shallow = false;
  2734. }
  2735. /**
  2736. * Evaluate the getter, and re-collect dependencies.
  2737. */
  2738. Watcher.prototype.get = function () {
  2739. this.beforeGet();
  2740. var scope = this.scope || this.vm;
  2741. var value;
  2742. try {
  2743. value = this.getter.call(scope, scope);
  2744. } catch (e) {
  2745. if ('development' !== 'production' && config.warnExpressionErrors) {
  2746. warn('Error when evaluating expression ' + '"' + this.expression + '": ' + e.toString(), this.vm);
  2747. }
  2748. }
  2749. // "touch" every property so they are all tracked as
  2750. // dependencies for deep watching
  2751. if (this.deep) {
  2752. traverse(value);
  2753. }
  2754. if (this.preProcess) {
  2755. value = this.preProcess(value);
  2756. }
  2757. if (this.filters) {
  2758. value = scope._applyFilters(value, null, this.filters, false);
  2759. }
  2760. if (this.postProcess) {
  2761. value = this.postProcess(value);
  2762. }
  2763. this.afterGet();
  2764. return value;
  2765. };
  2766. /**
  2767. * Set the corresponding value with the setter.
  2768. *
  2769. * @param {*} value
  2770. */
  2771. Watcher.prototype.set = function (value) {
  2772. var scope = this.scope || this.vm;
  2773. if (this.filters) {
  2774. value = scope._applyFilters(value, this.value, this.filters, true);
  2775. }
  2776. try {
  2777. this.setter.call(scope, scope, value);
  2778. } catch (e) {
  2779. if ('development' !== 'production' && config.warnExpressionErrors) {
  2780. warn('Error when evaluating setter ' + '"' + this.expression + '": ' + e.toString(), this.vm);
  2781. }
  2782. }
  2783. // two-way sync for v-for alias
  2784. var forContext = scope.$forContext;
  2785. if (forContext && forContext.alias === this.expression) {
  2786. if (forContext.filters) {
  2787. 'development' !== 'production' && warn('It seems you are using two-way binding on ' + 'a v-for alias (' + this.expression + '), and the ' + 'v-for has filters. This will not work properly. ' + 'Either remove the filters or use an array of ' + 'objects and bind to object properties instead.', this.vm);
  2788. return;
  2789. }
  2790. forContext._withLock(function () {
  2791. if (scope.$key) {
  2792. // original is an object
  2793. forContext.rawValue[scope.$key] = value;
  2794. } else {
  2795. forContext.rawValue.$set(scope.$index, value);
  2796. }
  2797. });
  2798. }
  2799. };
  2800. /**
  2801. * Prepare for dependency collection.
  2802. */
  2803. Watcher.prototype.beforeGet = function () {
  2804. Dep.target = this;
  2805. this.newDepIds = Object.create(null);
  2806. this.newDeps.length = 0;
  2807. };
  2808. /**
  2809. * Add a dependency to this directive.
  2810. *
  2811. * @param {Dep} dep
  2812. */
  2813. Watcher.prototype.addDep = function (dep) {
  2814. var id = dep.id;
  2815. if (!this.newDepIds[id]) {
  2816. this.newDepIds[id] = true;
  2817. this.newDeps.push(dep);
  2818. if (!this.depIds[id]) {
  2819. dep.addSub(this);
  2820. }
  2821. }
  2822. };
  2823. /**
  2824. * Clean up for dependency collection.
  2825. */
  2826. Watcher.prototype.afterGet = function () {
  2827. Dep.target = null;
  2828. var i = this.deps.length;
  2829. while (i--) {
  2830. var dep = this.deps[i];
  2831. if (!this.newDepIds[dep.id]) {
  2832. dep.removeSub(this);
  2833. }
  2834. }
  2835. this.depIds = this.newDepIds;
  2836. var tmp = this.deps;
  2837. this.deps = this.newDeps;
  2838. this.newDeps = tmp;
  2839. };
  2840. /**
  2841. * Subscriber interface.
  2842. * Will be called when a dependency changes.
  2843. *
  2844. * @param {Boolean} shallow
  2845. */
  2846. Watcher.prototype.update = function (shallow) {
  2847. if (this.lazy) {
  2848. this.dirty = true;
  2849. } else if (this.sync || !config.async) {
  2850. this.run();
  2851. } else {
  2852. // if queued, only overwrite shallow with non-shallow,
  2853. // but not the other way around.
  2854. this.shallow = this.queued ? shallow ? this.shallow : false : !!shallow;
  2855. this.queued = true;
  2856. // record before-push error stack in debug mode
  2857. /* istanbul ignore if */
  2858. if ('development' !== 'production' && config.debug) {
  2859. this.prevError = new Error('[vue] async stack trace');
  2860. }
  2861. pushWatcher(this);
  2862. }
  2863. };
  2864. /**
  2865. * Batcher job interface.
  2866. * Will be called by the batcher.
  2867. */
  2868. Watcher.prototype.run = function () {
  2869. if (this.active) {
  2870. var value = this.get();
  2871. if (value !== this.value ||
  2872. // Deep watchers and watchers on Object/Arrays should fire even
  2873. // when the value is the same, because the value may
  2874. // have mutated; but only do so if this is a
  2875. // non-shallow update (caused by a vm digest).
  2876. (isObject(value) || this.deep) && !this.shallow) {
  2877. // set new value
  2878. var oldValue = this.value;
  2879. this.value = value;
  2880. // in debug + async mode, when a watcher callbacks
  2881. // throws, we also throw the saved before-push error
  2882. // so the full cross-tick stack trace is available.
  2883. var prevError = this.prevError;
  2884. /* istanbul ignore if */
  2885. if ('development' !== 'production' && config.debug && prevError) {
  2886. this.prevError = null;
  2887. try {
  2888. this.cb.call(this.vm, value, oldValue);
  2889. } catch (e) {
  2890. nextTick(function () {
  2891. throw prevError;
  2892. }, 0);
  2893. throw e;
  2894. }
  2895. } else {
  2896. this.cb.call(this.vm, value, oldValue);
  2897. }
  2898. }
  2899. this.queued = this.shallow = false;
  2900. }
  2901. };
  2902. /**
  2903. * Evaluate the value of the watcher.
  2904. * This only gets called for lazy watchers.
  2905. */
  2906. Watcher.prototype.evaluate = function () {
  2907. // avoid overwriting another watcher that is being
  2908. // collected.
  2909. var current = Dep.target;
  2910. this.value = this.get();
  2911. this.dirty = false;
  2912. Dep.target = current;
  2913. };
  2914. /**
  2915. * Depend on all deps collected by this watcher.
  2916. */
  2917. Watcher.prototype.depend = function () {
  2918. var i = this.deps.length;
  2919. while (i--) {
  2920. this.deps[i].depend();
  2921. }
  2922. };
  2923. /**
  2924. * Remove self from all dependencies' subcriber list.
  2925. */
  2926. Watcher.prototype.teardown = function () {
  2927. if (this.active) {
  2928. // remove self from vm's watcher list
  2929. // this is a somewhat expensive operation so we skip it
  2930. // if the vm is being destroyed or is performing a v-for
  2931. // re-render (the watcher list is then filtered by v-for).
  2932. if (!this.vm._isBeingDestroyed && !this.vm._vForRemoving) {
  2933. this.vm._watchers.$remove(this);
  2934. }
  2935. var i = this.deps.length;
  2936. while (i--) {
  2937. this.deps[i].removeSub(this);
  2938. }
  2939. this.active = false;
  2940. this.vm = this.cb = this.value = null;
  2941. }
  2942. };
  2943. /**
  2944. * Recrusively traverse an object to evoke all converted
  2945. * getters, so that every nested property inside the object
  2946. * is collected as a "deep" dependency.
  2947. *
  2948. * @param {*} val
  2949. */
  2950. function traverse(val) {
  2951. var i, keys;
  2952. if (isArray(val)) {
  2953. i = val.length;
  2954. while (i--) traverse(val[i]);
  2955. } else if (isObject(val)) {
  2956. keys = Object.keys(val);
  2957. i = keys.length;
  2958. while (i--) traverse(val[keys[i]]);
  2959. }
  2960. }
  2961. var text$1 = {
  2962. bind: function bind() {
  2963. this.attr = this.el.nodeType === 3 ? 'data' : 'textContent';
  2964. },
  2965. update: function update(value) {
  2966. this.el[this.attr] = _toString(value);
  2967. }
  2968. };
  2969. var templateCache = new Cache(1000);
  2970. var idSelectorCache = new Cache(1000);
  2971. var map = {
  2972. efault: [0, '', ''],
  2973. legend: [1, '<fieldset>', '</fieldset>'],
  2974. tr: [2, '<table><tbody>', '</tbody></table>'],
  2975. col: [2, '<table><tbody></tbody><colgroup>', '</colgroup></table>']
  2976. };
  2977. map.td = map.th = [3, '<table><tbody><tr>', '</tr></tbody></table>'];
  2978. map.option = map.optgroup = [1, '<select multiple="multiple">', '</select>'];
  2979. map.thead = map.tbody = map.colgroup = map.caption = map.tfoot = [1, '<table>', '</table>'];
  2980. map.g = map.defs = map.symbol = map.use = map.image = map.text = map.circle = map.ellipse = map.line = map.path = map.polygon = map.polyline = map.rect = [1, '<svg ' + 'xmlns="http://www.w3.org/2000/svg" ' + 'xmlns:xlink="http://www.w3.org/1999/xlink" ' + 'xmlns:ev="http://www.w3.org/2001/xml-events"' + 'version="1.1">', '</svg>'];
  2981. /**
  2982. * Check if a node is a supported template node with a
  2983. * DocumentFragment content.
  2984. *
  2985. * @param {Node} node
  2986. * @return {Boolean}
  2987. */
  2988. function isRealTemplate(node) {
  2989. return isTemplate(node) && isFragment(node.content);
  2990. }
  2991. var tagRE$1 = /<([\w:-]+)/;
  2992. var entityRE = /&#?\w+?;/;
  2993. /**
  2994. * Convert a string template to a DocumentFragment.
  2995. * Determines correct wrapping by tag types. Wrapping
  2996. * strategy found in jQuery & component/domify.
  2997. *
  2998. * @param {String} templateString
  2999. * @param {Boolean} raw
  3000. * @return {DocumentFragment}
  3001. */
  3002. function stringToFragment(templateString, raw) {
  3003. // try a cache hit first
  3004. var cacheKey = raw ? templateString : templateString.trim();
  3005. var hit = templateCache.get(cacheKey);
  3006. if (hit) {
  3007. return hit;
  3008. }
  3009. var frag = document.createDocumentFragment();
  3010. var tagMatch = templateString.match(tagRE$1);
  3011. var entityMatch = entityRE.test(templateString);
  3012. if (!tagMatch && !entityMatch) {
  3013. // text only, return a single text node.
  3014. frag.appendChild(document.createTextNode(templateString));
  3015. } else {
  3016. var tag = tagMatch && tagMatch[1];
  3017. var wrap = map[tag] || map.efault;
  3018. var depth = wrap[0];
  3019. var prefix = wrap[1];
  3020. var suffix = wrap[2];
  3021. var node = document.createElement('div');
  3022. node.innerHTML = prefix + templateString + suffix;
  3023. while (depth--) {
  3024. node = node.lastChild;
  3025. }
  3026. var child;
  3027. /* eslint-disable no-cond-assign */
  3028. while (child = node.firstChild) {
  3029. /* eslint-enable no-cond-assign */
  3030. frag.appendChild(child);
  3031. }
  3032. }
  3033. if (!raw) {
  3034. trimNode(frag);
  3035. }
  3036. templateCache.put(cacheKey, frag);
  3037. return frag;
  3038. }
  3039. /**
  3040. * Convert a template node to a DocumentFragment.
  3041. *
  3042. * @param {Node} node
  3043. * @return {DocumentFragment}
  3044. */
  3045. function nodeToFragment(node) {
  3046. // if its a template tag and the browser supports it,
  3047. // its content is already a document fragment.
  3048. if (isRealTemplate(node)) {
  3049. trimNode(node.content);
  3050. return node.content;
  3051. }
  3052. // script template
  3053. if (node.tagName === 'SCRIPT') {
  3054. return stringToFragment(node.textContent);
  3055. }
  3056. // normal node, clone it to avoid mutating the original
  3057. var clonedNode = cloneNode(node);
  3058. var frag = document.createDocumentFragment();
  3059. var child;
  3060. /* eslint-disable no-cond-assign */
  3061. while (child = clonedNode.firstChild) {
  3062. /* eslint-enable no-cond-assign */
  3063. frag.appendChild(child);
  3064. }
  3065. trimNode(frag);
  3066. return frag;
  3067. }
  3068. // Test for the presence of the Safari template cloning bug
  3069. // https://bugs.webkit.org/showug.cgi?id=137755
  3070. var hasBrokenTemplate = (function () {
  3071. /* istanbul ignore else */
  3072. if (inBrowser) {
  3073. var a = document.createElement('div');
  3074. a.innerHTML = '<template>1</template>';
  3075. return !a.cloneNode(true).firstChild.innerHTML;
  3076. } else {
  3077. return false;
  3078. }
  3079. })();
  3080. // Test for IE10/11 textarea placeholder clone bug
  3081. var hasTextareaCloneBug = (function () {
  3082. /* istanbul ignore else */
  3083. if (inBrowser) {
  3084. var t = document.createElement('textarea');
  3085. t.placeholder = 't';
  3086. return t.cloneNode(true).value === 't';
  3087. } else {
  3088. return false;
  3089. }
  3090. })();
  3091. /**
  3092. * 1. Deal with Safari cloning nested <template> bug by
  3093. * manually cloning all template instances.
  3094. * 2. Deal with IE10/11 textarea placeholder bug by setting
  3095. * the correct value after cloning.
  3096. *
  3097. * @param {Element|DocumentFragment} node
  3098. * @return {Element|DocumentFragment}
  3099. */
  3100. function cloneNode(node) {
  3101. /* istanbul ignore if */
  3102. if (!node.querySelectorAll) {
  3103. return node.cloneNode();
  3104. }
  3105. var res = node.cloneNode(true);
  3106. var i, original, cloned;
  3107. /* istanbul ignore if */
  3108. if (hasBrokenTemplate) {
  3109. var tempClone = res;
  3110. if (isRealTemplate(node)) {
  3111. node = node.content;
  3112. tempClone = res.content;
  3113. }
  3114. original = node.querySelectorAll('template');
  3115. if (original.length) {
  3116. cloned = tempClone.querySelectorAll('template');
  3117. i = cloned.length;
  3118. while (i--) {
  3119. cloned[i].parentNode.replaceChild(cloneNode(original[i]), cloned[i]);
  3120. }
  3121. }
  3122. }
  3123. /* istanbul ignore if */
  3124. if (hasTextareaCloneBug) {
  3125. if (node.tagName === 'TEXTAREA') {
  3126. res.value = node.value;
  3127. } else {
  3128. original = node.querySelectorAll('textarea');
  3129. if (original.length) {
  3130. cloned = res.querySelectorAll('textarea');
  3131. i = cloned.length;
  3132. while (i--) {
  3133. cloned[i].value = original[i].value;
  3134. }
  3135. }
  3136. }
  3137. }
  3138. return res;
  3139. }
  3140. /**
  3141. * Process the template option and normalizes it into a
  3142. * a DocumentFragment that can be used as a partial or a
  3143. * instance template.
  3144. *
  3145. * @param {*} template
  3146. * Possible values include:
  3147. * - DocumentFragment object
  3148. * - Node object of type Template
  3149. * - id selector: '#some-template-id'
  3150. * - template string: '<div><span>{{msg}}</span></div>'
  3151. * @param {Boolean} shouldClone
  3152. * @param {Boolean} raw
  3153. * inline HTML interpolation. Do not check for id
  3154. * selector and keep whitespace in the string.
  3155. * @return {DocumentFragment|undefined}
  3156. */
  3157. function parseTemplate(template, shouldClone, raw) {
  3158. var node, frag;
  3159. // if the template is already a document fragment,
  3160. // do nothing
  3161. if (isFragment(template)) {
  3162. trimNode(template);
  3163. return shouldClone ? cloneNode(template) : template;
  3164. }
  3165. if (typeof template === 'string') {
  3166. // id selector
  3167. if (!raw && template.charAt(0) === '#') {
  3168. // id selector can be cached too
  3169. frag = idSelectorCache.get(template);
  3170. if (!frag) {
  3171. node = document.getElementById(template.slice(1));
  3172. if (node) {
  3173. frag = nodeToFragment(node);
  3174. // save selector to cache
  3175. idSelectorCache.put(template, frag);
  3176. }
  3177. }
  3178. } else {
  3179. // normal string template
  3180. frag = stringToFragment(template, raw);
  3181. }
  3182. } else if (template.nodeType) {
  3183. // a direct node
  3184. frag = nodeToFragment(template);
  3185. }
  3186. return frag && shouldClone ? cloneNode(frag) : frag;
  3187. }
  3188. var template = Object.freeze({
  3189. cloneNode: cloneNode,
  3190. parseTemplate: parseTemplate
  3191. });
  3192. var html = {
  3193. bind: function bind() {
  3194. // a comment node means this is a binding for
  3195. // {{{ inline unescaped html }}}
  3196. if (this.el.nodeType === 8) {
  3197. // hold nodes
  3198. this.nodes = [];
  3199. // replace the placeholder with proper anchor
  3200. this.anchor = createAnchor('v-html');
  3201. replace(this.el, this.anchor);
  3202. }
  3203. },
  3204. update: function update(value) {
  3205. value = _toString(value);
  3206. if (this.nodes) {
  3207. this.swap(value);
  3208. } else {
  3209. this.el.innerHTML = value;
  3210. }
  3211. },
  3212. swap: function swap(value) {
  3213. // remove old nodes
  3214. var i = this.nodes.length;
  3215. while (i--) {
  3216. remove(this.nodes[i]);
  3217. }
  3218. // convert new value to a fragment
  3219. // do not attempt to retrieve from id selector
  3220. var frag = parseTemplate(value, true, true);
  3221. // save a reference to these nodes so we can remove later
  3222. this.nodes = toArray(frag.childNodes);
  3223. before(frag, this.anchor);
  3224. }
  3225. };
  3226. /**
  3227. * Abstraction for a partially-compiled fragment.
  3228. * Can optionally compile content with a child scope.
  3229. *
  3230. * @param {Function} linker
  3231. * @param {Vue} vm
  3232. * @param {DocumentFragment} frag
  3233. * @param {Vue} [host]
  3234. * @param {Object} [scope]
  3235. * @param {Fragment} [parentFrag]
  3236. */
  3237. function Fragment(linker, vm, frag, host, scope, parentFrag) {
  3238. this.children = [];
  3239. this.childFrags = [];
  3240. this.vm = vm;
  3241. this.scope = scope;
  3242. this.inserted = false;
  3243. this.parentFrag = parentFrag;
  3244. if (parentFrag) {
  3245. parentFrag.childFrags.push(this);
  3246. }
  3247. this.unlink = linker(vm, frag, host, scope, this);
  3248. var single = this.single = frag.childNodes.length === 1 &&
  3249. // do not go single mode if the only node is an anchor
  3250. !frag.childNodes[0].__v_anchor;
  3251. if (single) {
  3252. this.node = frag.childNodes[0];
  3253. this.before = singleBefore;
  3254. this.remove = singleRemove;
  3255. } else {
  3256. this.node = createAnchor('fragment-start');
  3257. this.end = createAnchor('fragment-end');
  3258. this.frag = frag;
  3259. prepend(this.node, frag);
  3260. frag.appendChild(this.end);
  3261. this.before = multiBefore;
  3262. this.remove = multiRemove;
  3263. }
  3264. this.node.__v_frag = this;
  3265. }
  3266. /**
  3267. * Call attach/detach for all components contained within
  3268. * this fragment. Also do so recursively for all child
  3269. * fragments.
  3270. *
  3271. * @param {Function} hook
  3272. */
  3273. Fragment.prototype.callHook = function (hook) {
  3274. var i, l;
  3275. for (i = 0, l = this.childFrags.length; i < l; i++) {
  3276. this.childFrags[i].callHook(hook);
  3277. }
  3278. for (i = 0, l = this.children.length; i < l; i++) {
  3279. hook(this.children[i]);
  3280. }
  3281. };
  3282. /**
  3283. * Insert fragment before target, single node version
  3284. *
  3285. * @param {Node} target
  3286. * @param {Boolean} withTransition
  3287. */
  3288. function singleBefore(target, withTransition) {
  3289. this.inserted = true;
  3290. var method = withTransition !== false ? beforeWithTransition : before;
  3291. method(this.node, target, this.vm);
  3292. if (inDoc(this.node)) {
  3293. this.callHook(attach);
  3294. }
  3295. }
  3296. /**
  3297. * Remove fragment, single node version
  3298. */
  3299. function singleRemove() {
  3300. this.inserted = false;
  3301. var shouldCallRemove = inDoc(this.node);
  3302. var self = this;
  3303. this.beforeRemove();
  3304. removeWithTransition(this.node, this.vm, function () {
  3305. if (shouldCallRemove) {
  3306. self.callHook(detach);
  3307. }
  3308. self.destroy();
  3309. });
  3310. }
  3311. /**
  3312. * Insert fragment before target, multi-nodes version
  3313. *
  3314. * @param {Node} target
  3315. * @param {Boolean} withTransition
  3316. */
  3317. function multiBefore(target, withTransition) {
  3318. this.inserted = true;
  3319. var vm = this.vm;
  3320. var method = withTransition !== false ? beforeWithTransition : before;
  3321. mapNodeRange(this.node, this.end, function (node) {
  3322. method(node, target, vm);
  3323. });
  3324. if (inDoc(this.node)) {
  3325. this.callHook(attach);
  3326. }
  3327. }
  3328. /**
  3329. * Remove fragment, multi-nodes version
  3330. */
  3331. function multiRemove() {
  3332. this.inserted = false;
  3333. var self = this;
  3334. var shouldCallRemove = inDoc(this.node);
  3335. this.beforeRemove();
  3336. removeNodeRange(this.node, this.end, this.vm, this.frag, function () {
  3337. if (shouldCallRemove) {
  3338. self.callHook(detach);
  3339. }
  3340. self.destroy();
  3341. });
  3342. }
  3343. /**
  3344. * Prepare the fragment for removal.
  3345. */
  3346. Fragment.prototype.beforeRemove = function () {
  3347. var i, l;
  3348. for (i = 0, l = this.childFrags.length; i < l; i++) {
  3349. // call the same method recursively on child
  3350. // fragments, depth-first
  3351. this.childFrags[i].beforeRemove(false);
  3352. }
  3353. for (i = 0, l = this.children.length; i < l; i++) {
  3354. // Call destroy for all contained instances,
  3355. // with remove:false and defer:true.
  3356. // Defer is necessary because we need to
  3357. // keep the children to call detach hooks
  3358. // on them.
  3359. this.children[i].$destroy(false, true);
  3360. }
  3361. var dirs = this.unlink.dirs;
  3362. for (i = 0, l = dirs.length; i < l; i++) {
  3363. // disable the watchers on all the directives
  3364. // so that the rendered content stays the same
  3365. // during removal.
  3366. dirs[i]._watcher && dirs[i]._watcher.teardown();
  3367. }
  3368. };
  3369. /**
  3370. * Destroy the fragment.
  3371. */
  3372. Fragment.prototype.destroy = function () {
  3373. if (this.parentFrag) {
  3374. this.parentFrag.childFrags.$remove(this);
  3375. }
  3376. this.node.__v_frag = null;
  3377. this.unlink();
  3378. };
  3379. /**
  3380. * Call attach hook for a Vue instance.
  3381. *
  3382. * @param {Vue} child
  3383. */
  3384. function attach(child) {
  3385. if (!child._isAttached && inDoc(child.$el)) {
  3386. child._callHook('attached');
  3387. }
  3388. }
  3389. /**
  3390. * Call detach hook for a Vue instance.
  3391. *
  3392. * @param {Vue} child
  3393. */
  3394. function detach(child) {
  3395. if (child._isAttached && !inDoc(child.$el)) {
  3396. child._callHook('detached');
  3397. }
  3398. }
  3399. var linkerCache = new Cache(5000);
  3400. /**
  3401. * A factory that can be used to create instances of a
  3402. * fragment. Caches the compiled linker if possible.
  3403. *
  3404. * @param {Vue} vm
  3405. * @param {Element|String} el
  3406. */
  3407. function FragmentFactory(vm, el) {
  3408. this.vm = vm;
  3409. var template;
  3410. var isString = typeof el === 'string';
  3411. if (isString || isTemplate(el)) {
  3412. template = parseTemplate(el, true);
  3413. } else {
  3414. template = document.createDocumentFragment();
  3415. template.appendChild(el);
  3416. }
  3417. this.template = template;
  3418. // linker can be cached, but only for components
  3419. var linker;
  3420. var cid = vm.constructor.cid;
  3421. if (cid > 0) {
  3422. var cacheId = cid + (isString ? el : getOuterHTML(el));
  3423. linker = linkerCache.get(cacheId);
  3424. if (!linker) {
  3425. linker = compile(template, vm.$options, true);
  3426. linkerCache.put(cacheId, linker);
  3427. }
  3428. } else {
  3429. linker = compile(template, vm.$options, true);
  3430. }
  3431. this.linker = linker;
  3432. }
  3433. /**
  3434. * Create a fragment instance with given host and scope.
  3435. *
  3436. * @param {Vue} host
  3437. * @param {Object} scope
  3438. * @param {Fragment} parentFrag
  3439. */
  3440. FragmentFactory.prototype.create = function (host, scope, parentFrag) {
  3441. var frag = cloneNode(this.template);
  3442. return new Fragment(this.linker, this.vm, frag, host, scope, parentFrag);
  3443. };
  3444. var ON = 700;
  3445. var MODEL = 800;
  3446. var BIND = 850;
  3447. var TRANSITION = 1100;
  3448. var EL = 1500;
  3449. var COMPONENT = 1500;
  3450. var PARTIAL = 1750;
  3451. var IF = 2100;
  3452. var FOR = 2200;
  3453. var SLOT = 2300;
  3454. var uid$3 = 0;
  3455. var vFor = {
  3456. priority: FOR,
  3457. terminal: true,
  3458. params: ['track-by', 'stagger', 'enter-stagger', 'leave-stagger'],
  3459. bind: function bind() {
  3460. // support "item in/of items" syntax
  3461. var inMatch = this.expression.match(/(.*) (?:in|of) (.*)/);
  3462. if (inMatch) {
  3463. var itMatch = inMatch[1].match(/\((.*),(.*)\)/);
  3464. if (itMatch) {
  3465. this.iterator = itMatch[1].trim();
  3466. this.alias = itMatch[2].trim();
  3467. } else {
  3468. this.alias = inMatch[1].trim();
  3469. }
  3470. this.expression = inMatch[2];
  3471. }
  3472. if (!this.alias) {
  3473. 'development' !== 'production' && warn('Invalid v-for expression "' + this.descriptor.raw + '": ' + 'alias is required.', this.vm);
  3474. return;
  3475. }
  3476. // uid as a cache identifier
  3477. this.id = '__v-for__' + ++uid$3;
  3478. // check if this is an option list,
  3479. // so that we know if we need to update the <select>'s
  3480. // v-model when the option list has changed.
  3481. // because v-model has a lower priority than v-for,
  3482. // the v-model is not bound here yet, so we have to
  3483. // retrive it in the actual updateModel() function.
  3484. var tag = this.el.tagName;
  3485. this.isOption = (tag === 'OPTION' || tag === 'OPTGROUP') && this.el.parentNode.tagName === 'SELECT';
  3486. // setup anchor nodes
  3487. this.start = createAnchor('v-for-start');
  3488. this.end = createAnchor('v-for-end');
  3489. replace(this.el, this.end);
  3490. before(this.start, this.end);
  3491. // cache
  3492. this.cache = Object.create(null);
  3493. // fragment factory
  3494. this.factory = new FragmentFactory(this.vm, this.el);
  3495. },
  3496. update: function update(data) {
  3497. this.diff(data);
  3498. this.updateRef();
  3499. this.updateModel();
  3500. },
  3501. /**
  3502. * Diff, based on new data and old data, determine the
  3503. * minimum amount of DOM manipulations needed to make the
  3504. * DOM reflect the new data Array.
  3505. *
  3506. * The algorithm diffs the new data Array by storing a
  3507. * hidden reference to an owner vm instance on previously
  3508. * seen data. This allows us to achieve O(n) which is
  3509. * better than a levenshtein distance based algorithm,
  3510. * which is O(m * n).
  3511. *
  3512. * @param {Array} data
  3513. */
  3514. diff: function diff(data) {
  3515. // check if the Array was converted from an Object
  3516. var item = data[0];
  3517. var convertedFromObject = this.fromObject = isObject(item) && hasOwn(item, '$key') && hasOwn(item, '$value');
  3518. var trackByKey = this.params.trackBy;
  3519. var oldFrags = this.frags;
  3520. var frags = this.frags = new Array(data.length);
  3521. var alias = this.alias;
  3522. var iterator = this.iterator;
  3523. var start = this.start;
  3524. var end = this.end;
  3525. var inDocument = inDoc(start);
  3526. var init = !oldFrags;
  3527. var i, l, frag, key, value, primitive;
  3528. // First pass, go through the new Array and fill up
  3529. // the new frags array. If a piece of data has a cached
  3530. // instance for it, we reuse it. Otherwise build a new
  3531. // instance.
  3532. for (i = 0, l = data.length; i < l; i++) {
  3533. item = data[i];
  3534. key = convertedFromObject ? item.$key : null;
  3535. value = convertedFromObject ? item.$value : item;
  3536. primitive = !isObject(value);
  3537. frag = !init && this.getCachedFrag(value, i, key);
  3538. if (frag) {
  3539. // reusable fragment
  3540. frag.reused = true;
  3541. // update $index
  3542. frag.scope.$index = i;
  3543. // update $key
  3544. if (key) {
  3545. frag.scope.$key = key;
  3546. }
  3547. // update iterator
  3548. if (iterator) {
  3549. frag.scope[iterator] = key !== null ? key : i;
  3550. }
  3551. // update data for track-by, object repeat &
  3552. // primitive values.
  3553. if (trackByKey || convertedFromObject || primitive) {
  3554. withoutConversion(function () {
  3555. frag.scope[alias] = value;
  3556. });
  3557. }
  3558. } else {
  3559. // new isntance
  3560. frag = this.create(value, alias, i, key);
  3561. frag.fresh = !init;
  3562. }
  3563. frags[i] = frag;
  3564. if (init) {
  3565. frag.before(end);
  3566. }
  3567. }
  3568. // we're done for the initial render.
  3569. if (init) {
  3570. return;
  3571. }
  3572. // Second pass, go through the old fragments and
  3573. // destroy those who are not reused (and remove them
  3574. // from cache)
  3575. var removalIndex = 0;
  3576. var totalRemoved = oldFrags.length - frags.length;
  3577. // when removing a large number of fragments, watcher removal
  3578. // turns out to be a perf bottleneck, so we batch the watcher
  3579. // removals into a single filter call!
  3580. this.vm._vForRemoving = true;
  3581. for (i = 0, l = oldFrags.length; i < l; i++) {
  3582. frag = oldFrags[i];
  3583. if (!frag.reused) {
  3584. this.deleteCachedFrag(frag);
  3585. this.remove(frag, removalIndex++, totalRemoved, inDocument);
  3586. }
  3587. }
  3588. this.vm._vForRemoving = false;
  3589. if (removalIndex) {
  3590. this.vm._watchers = this.vm._watchers.filter(function (w) {
  3591. return w.active;
  3592. });
  3593. }
  3594. // Final pass, move/insert new fragments into the
  3595. // right place.
  3596. var targetPrev, prevEl, currentPrev;
  3597. var insertionIndex = 0;
  3598. for (i = 0, l = frags.length; i < l; i++) {
  3599. frag = frags[i];
  3600. // this is the frag that we should be after
  3601. targetPrev = frags[i - 1];
  3602. prevEl = targetPrev ? targetPrev.staggerCb ? targetPrev.staggerAnchor : targetPrev.end || targetPrev.node : start;
  3603. if (frag.reused && !frag.staggerCb) {
  3604. currentPrev = findPrevFrag(frag, start, this.id);
  3605. if (currentPrev !== targetPrev && (!currentPrev ||
  3606. // optimization for moving a single item.
  3607. // thanks to suggestions by @livoras in #1807
  3608. findPrevFrag(currentPrev, start, this.id) !== targetPrev)) {
  3609. this.move(frag, prevEl);
  3610. }
  3611. } else {
  3612. // new instance, or still in stagger.
  3613. // insert with updated stagger index.
  3614. this.insert(frag, insertionIndex++, prevEl, inDocument);
  3615. }
  3616. frag.reused = frag.fresh = false;
  3617. }
  3618. },
  3619. /**
  3620. * Create a new fragment instance.
  3621. *
  3622. * @param {*} value
  3623. * @param {String} alias
  3624. * @param {Number} index
  3625. * @param {String} [key]
  3626. * @return {Fragment}
  3627. */
  3628. create: function create(value, alias, index, key) {
  3629. var host = this._host;
  3630. // create iteration scope
  3631. var parentScope = this._scope || this.vm;
  3632. var scope = Object.create(parentScope);
  3633. // ref holder for the scope
  3634. scope.$refs = Object.create(parentScope.$refs);
  3635. scope.$els = Object.create(parentScope.$els);
  3636. // make sure point $parent to parent scope
  3637. scope.$parent = parentScope;
  3638. // for two-way binding on alias
  3639. scope.$forContext = this;
  3640. // define scope properties
  3641. // important: define the scope alias without forced conversion
  3642. // so that frozen data structures remain non-reactive.
  3643. withoutConversion(function () {
  3644. defineReactive(scope, alias, value);
  3645. });
  3646. defineReactive(scope, '$index', index);
  3647. if (key) {
  3648. defineReactive(scope, '$key', key);
  3649. } else if (scope.$key) {
  3650. // avoid accidental fallback
  3651. def(scope, '$key', null);
  3652. }
  3653. if (this.iterator) {
  3654. defineReactive(scope, this.iterator, key !== null ? key : index);
  3655. }
  3656. var frag = this.factory.create(host, scope, this._frag);
  3657. frag.forId = this.id;
  3658. this.cacheFrag(value, frag, index, key);
  3659. return frag;
  3660. },
  3661. /**
  3662. * Update the v-ref on owner vm.
  3663. */
  3664. updateRef: function updateRef() {
  3665. var ref = this.descriptor.ref;
  3666. if (!ref) return;
  3667. var hash = (this._scope || this.vm).$refs;
  3668. var refs;
  3669. if (!this.fromObject) {
  3670. refs = this.frags.map(findVmFromFrag);
  3671. } else {
  3672. refs = {};
  3673. this.frags.forEach(function (frag) {
  3674. refs[frag.scope.$key] = findVmFromFrag(frag);
  3675. });
  3676. }
  3677. hash[ref] = refs;
  3678. },
  3679. /**
  3680. * For option lists, update the containing v-model on
  3681. * parent <select>.
  3682. */
  3683. updateModel: function updateModel() {
  3684. if (this.isOption) {
  3685. var parent = this.start.parentNode;
  3686. var model = parent && parent.__v_model;
  3687. if (model) {
  3688. model.forceUpdate();
  3689. }
  3690. }
  3691. },
  3692. /**
  3693. * Insert a fragment. Handles staggering.
  3694. *
  3695. * @param {Fragment} frag
  3696. * @param {Number} index
  3697. * @param {Node} prevEl
  3698. * @param {Boolean} inDocument
  3699. */
  3700. insert: function insert(frag, index, prevEl, inDocument) {
  3701. if (frag.staggerCb) {
  3702. frag.staggerCb.cancel();
  3703. frag.staggerCb = null;
  3704. }
  3705. var staggerAmount = this.getStagger(frag, index, null, 'enter');
  3706. if (inDocument && staggerAmount) {
  3707. // create an anchor and insert it synchronously,
  3708. // so that we can resolve the correct order without
  3709. // worrying about some elements not inserted yet
  3710. var anchor = frag.staggerAnchor;
  3711. if (!anchor) {
  3712. anchor = frag.staggerAnchor = createAnchor('stagger-anchor');
  3713. anchor.__v_frag = frag;
  3714. }
  3715. after(anchor, prevEl);
  3716. var op = frag.staggerCb = cancellable(function () {
  3717. frag.staggerCb = null;
  3718. frag.before(anchor);
  3719. remove(anchor);
  3720. });
  3721. setTimeout(op, staggerAmount);
  3722. } else {
  3723. frag.before(prevEl.nextSibling);
  3724. }
  3725. },
  3726. /**
  3727. * Remove a fragment. Handles staggering.
  3728. *
  3729. * @param {Fragment} frag
  3730. * @param {Number} index
  3731. * @param {Number} total
  3732. * @param {Boolean} inDocument
  3733. */
  3734. remove: function remove(frag, index, total, inDocument) {
  3735. if (frag.staggerCb) {
  3736. frag.staggerCb.cancel();
  3737. frag.staggerCb = null;
  3738. // it's not possible for the same frag to be removed
  3739. // twice, so if we have a pending stagger callback,
  3740. // it means this frag is queued for enter but removed
  3741. // before its transition started. Since it is already
  3742. // destroyed, we can just leave it in detached state.
  3743. return;
  3744. }
  3745. var staggerAmount = this.getStagger(frag, index, total, 'leave');
  3746. if (inDocument && staggerAmount) {
  3747. var op = frag.staggerCb = cancellable(function () {
  3748. frag.staggerCb = null;
  3749. frag.remove();
  3750. });
  3751. setTimeout(op, staggerAmount);
  3752. } else {
  3753. frag.remove();
  3754. }
  3755. },
  3756. /**
  3757. * Move a fragment to a new position.
  3758. * Force no transition.
  3759. *
  3760. * @param {Fragment} frag
  3761. * @param {Node} prevEl
  3762. */
  3763. move: function move(frag, prevEl) {
  3764. // fix a common issue with Sortable:
  3765. // if prevEl doesn't have nextSibling, this means it's
  3766. // been dragged after the end anchor. Just re-position
  3767. // the end anchor to the end of the container.
  3768. /* istanbul ignore if */
  3769. if (!prevEl.nextSibling) {
  3770. this.end.parentNode.appendChild(this.end);
  3771. }
  3772. frag.before(prevEl.nextSibling, false);
  3773. },
  3774. /**
  3775. * Cache a fragment using track-by or the object key.
  3776. *
  3777. * @param {*} value
  3778. * @param {Fragment} frag
  3779. * @param {Number} index
  3780. * @param {String} [key]
  3781. */
  3782. cacheFrag: function cacheFrag(value, frag, index, key) {
  3783. var trackByKey = this.params.trackBy;
  3784. var cache = this.cache;
  3785. var primitive = !isObject(value);
  3786. var id;
  3787. if (key || trackByKey || primitive) {
  3788. id = trackByKey ? trackByKey === '$index' ? index : getPath(value, trackByKey) : key || value;
  3789. if (!cache[id]) {
  3790. cache[id] = frag;
  3791. } else if (trackByKey !== '$index') {
  3792. 'development' !== 'production' && this.warnDuplicate(value);
  3793. }
  3794. } else {
  3795. id = this.id;
  3796. if (hasOwn(value, id)) {
  3797. if (value[id] === null) {
  3798. value[id] = frag;
  3799. } else {
  3800. 'development' !== 'production' && this.warnDuplicate(value);
  3801. }
  3802. } else {
  3803. def(value, id, frag);
  3804. }
  3805. }
  3806. frag.raw = value;
  3807. },
  3808. /**
  3809. * Get a cached fragment from the value/index/key
  3810. *
  3811. * @param {*} value
  3812. * @param {Number} index
  3813. * @param {String} key
  3814. * @return {Fragment}
  3815. */
  3816. getCachedFrag: function getCachedFrag(value, index, key) {
  3817. var trackByKey = this.params.trackBy;
  3818. var primitive = !isObject(value);
  3819. var frag;
  3820. if (key || trackByKey || primitive) {
  3821. var id = trackByKey ? trackByKey === '$index' ? index : getPath(value, trackByKey) : key || value;
  3822. frag = this.cache[id];
  3823. } else {
  3824. frag = value[this.id];
  3825. }
  3826. if (frag && (frag.reused || frag.fresh)) {
  3827. 'development' !== 'production' && this.warnDuplicate(value);
  3828. }
  3829. return frag;
  3830. },
  3831. /**
  3832. * Delete a fragment from cache.
  3833. *
  3834. * @param {Fragment} frag
  3835. */
  3836. deleteCachedFrag: function deleteCachedFrag(frag) {
  3837. var value = frag.raw;
  3838. var trackByKey = this.params.trackBy;
  3839. var scope = frag.scope;
  3840. var index = scope.$index;
  3841. // fix #948: avoid accidentally fall through to
  3842. // a parent repeater which happens to have $key.
  3843. var key = hasOwn(scope, '$key') && scope.$key;
  3844. var primitive = !isObject(value);
  3845. if (trackByKey || key || primitive) {
  3846. var id = trackByKey ? trackByKey === '$index' ? index : getPath(value, trackByKey) : key || value;
  3847. this.cache[id] = null;
  3848. } else {
  3849. value[this.id] = null;
  3850. frag.raw = null;
  3851. }
  3852. },
  3853. /**
  3854. * Get the stagger amount for an insertion/removal.
  3855. *
  3856. * @param {Fragment} frag
  3857. * @param {Number} index
  3858. * @param {Number} total
  3859. * @param {String} type
  3860. */
  3861. getStagger: function getStagger(frag, index, total, type) {
  3862. type = type + 'Stagger';
  3863. var trans = frag.node.__v_trans;
  3864. var hooks = trans && trans.hooks;
  3865. var hook = hooks && (hooks[type] || hooks.stagger);
  3866. return hook ? hook.call(frag, index, total) : index * parseInt(this.params[type] || this.params.stagger, 10);
  3867. },
  3868. /**
  3869. * Pre-process the value before piping it through the
  3870. * filters. This is passed to and called by the watcher.
  3871. */
  3872. _preProcess: function _preProcess(value) {
  3873. // regardless of type, store the un-filtered raw value.
  3874. this.rawValue = value;
  3875. return value;
  3876. },
  3877. /**
  3878. * Post-process the value after it has been piped through
  3879. * the filters. This is passed to and called by the watcher.
  3880. *
  3881. * It is necessary for this to be called during the
  3882. * wathcer's dependency collection phase because we want
  3883. * the v-for to update when the source Object is mutated.
  3884. */
  3885. _postProcess: function _postProcess(value) {
  3886. if (isArray(value)) {
  3887. return value;
  3888. } else if (isPlainObject(value)) {
  3889. // convert plain object to array.
  3890. var keys = Object.keys(value);
  3891. var i = keys.length;
  3892. var res = new Array(i);
  3893. var key;
  3894. while (i--) {
  3895. key = keys[i];
  3896. res[i] = {
  3897. $key: key,
  3898. $value: value[key]
  3899. };
  3900. }
  3901. return res;
  3902. } else {
  3903. if (typeof value === 'number' && !isNaN(value)) {
  3904. value = range(value);
  3905. }
  3906. return value || [];
  3907. }
  3908. },
  3909. unbind: function unbind() {
  3910. if (this.descriptor.ref) {
  3911. (this._scope || this.vm).$refs[this.descriptor.ref] = null;
  3912. }
  3913. if (this.frags) {
  3914. var i = this.frags.length;
  3915. var frag;
  3916. while (i--) {
  3917. frag = this.frags[i];
  3918. this.deleteCachedFrag(frag);
  3919. frag.destroy();
  3920. }
  3921. }
  3922. }
  3923. };
  3924. /**
  3925. * Helper to find the previous element that is a fragment
  3926. * anchor. This is necessary because a destroyed frag's
  3927. * element could still be lingering in the DOM before its
  3928. * leaving transition finishes, but its inserted flag
  3929. * should have been set to false so we can skip them.
  3930. *
  3931. * If this is a block repeat, we want to make sure we only
  3932. * return frag that is bound to this v-for. (see #929)
  3933. *
  3934. * @param {Fragment} frag
  3935. * @param {Comment|Text} anchor
  3936. * @param {String} id
  3937. * @return {Fragment}
  3938. */
  3939. function findPrevFrag(frag, anchor, id) {
  3940. var el = frag.node.previousSibling;
  3941. /* istanbul ignore if */
  3942. if (!el) return;
  3943. frag = el.__v_frag;
  3944. while ((!frag || frag.forId !== id || !frag.inserted) && el !== anchor) {
  3945. el = el.previousSibling;
  3946. /* istanbul ignore if */
  3947. if (!el) return;
  3948. frag = el.__v_frag;
  3949. }
  3950. return frag;
  3951. }
  3952. /**
  3953. * Find a vm from a fragment.
  3954. *
  3955. * @param {Fragment} frag
  3956. * @return {Vue|undefined}
  3957. */
  3958. function findVmFromFrag(frag) {
  3959. var node = frag.node;
  3960. // handle multi-node frag
  3961. if (frag.end) {
  3962. while (!node.__vue__ && node !== frag.end && node.nextSibling) {
  3963. node = node.nextSibling;
  3964. }
  3965. }
  3966. return node.__vue__;
  3967. }
  3968. /**
  3969. * Create a range array from given number.
  3970. *
  3971. * @param {Number} n
  3972. * @return {Array}
  3973. */
  3974. function range(n) {
  3975. var i = -1;
  3976. var ret = new Array(Math.floor(n));
  3977. while (++i < n) {
  3978. ret[i] = i;
  3979. }
  3980. return ret;
  3981. }
  3982. if ('development' !== 'production') {
  3983. vFor.warnDuplicate = function (value) {
  3984. warn('Duplicate value found in v-for="' + this.descriptor.raw + '": ' + JSON.stringify(value) + '. Use track-by="$index" if ' + 'you are expecting duplicate values.', this.vm);
  3985. };
  3986. }
  3987. var vIf = {
  3988. priority: IF,
  3989. terminal: true,
  3990. bind: function bind() {
  3991. var el = this.el;
  3992. if (!el.__vue__) {
  3993. // check else block
  3994. var next = el.nextElementSibling;
  3995. if (next && getAttr(next, 'v-else') !== null) {
  3996. remove(next);
  3997. this.elseEl = next;
  3998. }
  3999. // check main block
  4000. this.anchor = createAnchor('v-if');
  4001. replace(el, this.anchor);
  4002. } else {
  4003. 'development' !== 'production' && warn('v-if="' + this.expression + '" cannot be ' + 'used on an instance root element.', this.vm);
  4004. this.invalid = true;
  4005. }
  4006. },
  4007. update: function update(value) {
  4008. if (this.invalid) return;
  4009. if (value) {
  4010. if (!this.frag) {
  4011. this.insert();
  4012. }
  4013. } else {
  4014. this.remove();
  4015. }
  4016. },
  4017. insert: function insert() {
  4018. if (this.elseFrag) {
  4019. this.elseFrag.remove();
  4020. this.elseFrag = null;
  4021. }
  4022. // lazy init factory
  4023. if (!this.factory) {
  4024. this.factory = new FragmentFactory(this.vm, this.el);
  4025. }
  4026. this.frag = this.factory.create(this._host, this._scope, this._frag);
  4027. this.frag.before(this.anchor);
  4028. },
  4029. remove: function remove() {
  4030. if (this.frag) {
  4031. this.frag.remove();
  4032. this.frag = null;
  4033. }
  4034. if (this.elseEl && !this.elseFrag) {
  4035. if (!this.elseFactory) {
  4036. this.elseFactory = new FragmentFactory(this.elseEl._context || this.vm, this.elseEl);
  4037. }
  4038. this.elseFrag = this.elseFactory.create(this._host, this._scope, this._frag);
  4039. this.elseFrag.before(this.anchor);
  4040. }
  4041. },
  4042. unbind: function unbind() {
  4043. if (this.frag) {
  4044. this.frag.destroy();
  4045. }
  4046. if (this.elseFrag) {
  4047. this.elseFrag.destroy();
  4048. }
  4049. }
  4050. };
  4051. var show = {
  4052. bind: function bind() {
  4053. // check else block
  4054. var next = this.el.nextElementSibling;
  4055. if (next && getAttr(next, 'v-else') !== null) {
  4056. this.elseEl = next;
  4057. }
  4058. },
  4059. update: function update(value) {
  4060. this.apply(this.el, value);
  4061. if (this.elseEl) {
  4062. this.apply(this.elseEl, !value);
  4063. }
  4064. },
  4065. apply: function apply(el, value) {
  4066. if (inDoc(el)) {
  4067. applyTransition(el, value ? 1 : -1, toggle, this.vm);
  4068. } else {
  4069. toggle();
  4070. }
  4071. function toggle() {
  4072. el.style.display = value ? '' : 'none';
  4073. }
  4074. }
  4075. };
  4076. var text$2 = {
  4077. bind: function bind() {
  4078. var self = this;
  4079. var el = this.el;
  4080. var isRange = el.type === 'range';
  4081. var lazy = this.params.lazy;
  4082. var number = this.params.number;
  4083. var debounce = this.params.debounce;
  4084. // handle composition events.
  4085. // http://blog.evanyou.me/2014/01/03/composition-event/
  4086. // skip this for Android because it handles composition
  4087. // events quite differently. Android doesn't trigger
  4088. // composition events for language input methods e.g.
  4089. // Chinese, but instead triggers them for spelling
  4090. // suggestions... (see Discussion/#162)
  4091. var composing = false;
  4092. if (!isAndroid && !isRange) {
  4093. this.on('compositionstart', function () {
  4094. composing = true;
  4095. });
  4096. this.on('compositionend', function () {
  4097. composing = false;
  4098. // in IE11 the "compositionend" event fires AFTER
  4099. // the "input" event, so the input handler is blocked
  4100. // at the end... have to call it here.
  4101. //
  4102. // #1327: in lazy mode this is unecessary.
  4103. if (!lazy) {
  4104. self.listener();
  4105. }
  4106. });
  4107. }
  4108. // prevent messing with the input when user is typing,
  4109. // and force update on blur.
  4110. this.focused = false;
  4111. if (!isRange && !lazy) {
  4112. this.on('focus', function () {
  4113. self.focused = true;
  4114. });
  4115. this.on('blur', function () {
  4116. self.focused = false;
  4117. // do not sync value after fragment removal (#2017)
  4118. if (!self._frag || self._frag.inserted) {
  4119. self.rawListener();
  4120. }
  4121. });
  4122. }
  4123. // Now attach the main listener
  4124. this.listener = this.rawListener = function () {
  4125. if (composing || !self._bound) {
  4126. return;
  4127. }
  4128. var val = number || isRange ? toNumber(el.value) : el.value;
  4129. self.set(val);
  4130. // force update on next tick to avoid lock & same value
  4131. // also only update when user is not typing
  4132. nextTick(function () {
  4133. if (self._bound && !self.focused) {
  4134. self.update(self._watcher.value);
  4135. }
  4136. });
  4137. };
  4138. // apply debounce
  4139. if (debounce) {
  4140. this.listener = _debounce(this.listener, debounce);
  4141. }
  4142. // Support jQuery events, since jQuery.trigger() doesn't
  4143. // trigger native events in some cases and some plugins
  4144. // rely on $.trigger()
  4145. //
  4146. // We want to make sure if a listener is attached using
  4147. // jQuery, it is also removed with jQuery, that's why
  4148. // we do the check for each directive instance and
  4149. // store that check result on itself. This also allows
  4150. // easier test coverage control by unsetting the global
  4151. // jQuery variable in tests.
  4152. this.hasjQuery = typeof jQuery === 'function';
  4153. if (this.hasjQuery) {
  4154. var method = jQuery.fn.on ? 'on' : 'bind';
  4155. jQuery(el)[method]('change', this.rawListener);
  4156. if (!lazy) {
  4157. jQuery(el)[method]('input', this.listener);
  4158. }
  4159. } else {
  4160. this.on('change', this.rawListener);
  4161. if (!lazy) {
  4162. this.on('input', this.listener);
  4163. }
  4164. }
  4165. // IE9 doesn't fire input event on backspace/del/cut
  4166. if (!lazy && isIE9) {
  4167. this.on('cut', function () {
  4168. nextTick(self.listener);
  4169. });
  4170. this.on('keyup', function (e) {
  4171. if (e.keyCode === 46 || e.keyCode === 8) {
  4172. self.listener();
  4173. }
  4174. });
  4175. }
  4176. // set initial value if present
  4177. if (el.hasAttribute('value') || el.tagName === 'TEXTAREA' && el.value.trim()) {
  4178. this.afterBind = this.listener;
  4179. }
  4180. },
  4181. update: function update(value) {
  4182. this.el.value = _toString(value);
  4183. },
  4184. unbind: function unbind() {
  4185. var el = this.el;
  4186. if (this.hasjQuery) {
  4187. var method = jQuery.fn.off ? 'off' : 'unbind';
  4188. jQuery(el)[method]('change', this.listener);
  4189. jQuery(el)[method]('input', this.listener);
  4190. }
  4191. }
  4192. };
  4193. var radio = {
  4194. bind: function bind() {
  4195. var self = this;
  4196. var el = this.el;
  4197. this.getValue = function () {
  4198. // value overwrite via v-bind:value
  4199. if (el.hasOwnProperty('_value')) {
  4200. return el._value;
  4201. }
  4202. var val = el.value;
  4203. if (self.params.number) {
  4204. val = toNumber(val);
  4205. }
  4206. return val;
  4207. };
  4208. this.listener = function () {
  4209. self.set(self.getValue());
  4210. };
  4211. this.on('change', this.listener);
  4212. if (el.hasAttribute('checked')) {
  4213. this.afterBind = this.listener;
  4214. }
  4215. },
  4216. update: function update(value) {
  4217. this.el.checked = looseEqual(value, this.getValue());
  4218. }
  4219. };
  4220. var select = {
  4221. bind: function bind() {
  4222. var self = this;
  4223. var el = this.el;
  4224. // method to force update DOM using latest value.
  4225. this.forceUpdate = function () {
  4226. if (self._watcher) {
  4227. self.update(self._watcher.get());
  4228. }
  4229. };
  4230. // check if this is a multiple select
  4231. var multiple = this.multiple = el.hasAttribute('multiple');
  4232. // attach listener
  4233. this.listener = function () {
  4234. var value = getValue(el, multiple);
  4235. value = self.params.number ? isArray(value) ? value.map(toNumber) : toNumber(value) : value;
  4236. self.set(value);
  4237. };
  4238. this.on('change', this.listener);
  4239. // if has initial value, set afterBind
  4240. var initValue = getValue(el, multiple, true);
  4241. if (multiple && initValue.length || !multiple && initValue !== null) {
  4242. this.afterBind = this.listener;
  4243. }
  4244. // All major browsers except Firefox resets
  4245. // selectedIndex with value -1 to 0 when the element
  4246. // is appended to a new parent, therefore we have to
  4247. // force a DOM update whenever that happens...
  4248. this.vm.$on('hook:attached', this.forceUpdate);
  4249. },
  4250. update: function update(value) {
  4251. var el = this.el;
  4252. el.selectedIndex = -1;
  4253. var multi = this.multiple && isArray(value);
  4254. var options = el.options;
  4255. var i = options.length;
  4256. var op, val;
  4257. while (i--) {
  4258. op = options[i];
  4259. val = op.hasOwnProperty('_value') ? op._value : op.value;
  4260. /* eslint-disable eqeqeq */
  4261. op.selected = multi ? indexOf$1(value, val) > -1 : looseEqual(value, val);
  4262. /* eslint-enable eqeqeq */
  4263. }
  4264. },
  4265. unbind: function unbind() {
  4266. /* istanbul ignore next */
  4267. this.vm.$off('hook:attached', this.forceUpdate);
  4268. }
  4269. };
  4270. /**
  4271. * Get select value
  4272. *
  4273. * @param {SelectElement} el
  4274. * @param {Boolean} multi
  4275. * @param {Boolean} init
  4276. * @return {Array|*}
  4277. */
  4278. function getValue(el, multi, init) {
  4279. var res = multi ? [] : null;
  4280. var op, val, selected;
  4281. for (var i = 0, l = el.options.length; i < l; i++) {
  4282. op = el.options[i];
  4283. selected = init ? op.hasAttribute('selected') : op.selected;
  4284. if (selected) {
  4285. val = op.hasOwnProperty('_value') ? op._value : op.value;
  4286. if (multi) {
  4287. res.push(val);
  4288. } else {
  4289. return val;
  4290. }
  4291. }
  4292. }
  4293. return res;
  4294. }
  4295. /**
  4296. * Native Array.indexOf uses strict equal, but in this
  4297. * case we need to match string/numbers with custom equal.
  4298. *
  4299. * @param {Array} arr
  4300. * @param {*} val
  4301. */
  4302. function indexOf$1(arr, val) {
  4303. var i = arr.length;
  4304. while (i--) {
  4305. if (looseEqual(arr[i], val)) {
  4306. return i;
  4307. }
  4308. }
  4309. return -1;
  4310. }
  4311. var checkbox = {
  4312. bind: function bind() {
  4313. var self = this;
  4314. var el = this.el;
  4315. this.getValue = function () {
  4316. return el.hasOwnProperty('_value') ? el._value : self.params.number ? toNumber(el.value) : el.value;
  4317. };
  4318. function getBooleanValue() {
  4319. var val = el.checked;
  4320. if (val && el.hasOwnProperty('_trueValue')) {
  4321. return el._trueValue;
  4322. }
  4323. if (!val && el.hasOwnProperty('_falseValue')) {
  4324. return el._falseValue;
  4325. }
  4326. return val;
  4327. }
  4328. this.listener = function () {
  4329. var model = self._watcher.value;
  4330. if (isArray(model)) {
  4331. var val = self.getValue();
  4332. if (el.checked) {
  4333. if (indexOf(model, val) < 0) {
  4334. model.push(val);
  4335. }
  4336. } else {
  4337. model.$remove(val);
  4338. }
  4339. } else {
  4340. self.set(getBooleanValue());
  4341. }
  4342. };
  4343. this.on('change', this.listener);
  4344. if (el.hasAttribute('checked')) {
  4345. this.afterBind = this.listener;
  4346. }
  4347. },
  4348. update: function update(value) {
  4349. var el = this.el;
  4350. if (isArray(value)) {
  4351. el.checked = indexOf(value, this.getValue()) > -1;
  4352. } else {
  4353. if (el.hasOwnProperty('_trueValue')) {
  4354. el.checked = looseEqual(value, el._trueValue);
  4355. } else {
  4356. el.checked = !!value;
  4357. }
  4358. }
  4359. }
  4360. };
  4361. var handlers = {
  4362. text: text$2,
  4363. radio: radio,
  4364. select: select,
  4365. checkbox: checkbox
  4366. };
  4367. var model = {
  4368. priority: MODEL,
  4369. twoWay: true,
  4370. handlers: handlers,
  4371. params: ['lazy', 'number', 'debounce'],
  4372. /**
  4373. * Possible elements:
  4374. * <select>
  4375. * <textarea>
  4376. * <input type="*">
  4377. * - text
  4378. * - checkbox
  4379. * - radio
  4380. * - number
  4381. */
  4382. bind: function bind() {
  4383. // friendly warning...
  4384. this.checkFilters();
  4385. if (this.hasRead && !this.hasWrite) {
  4386. 'development' !== 'production' && warn('It seems you are using a read-only filter with ' + 'v-model="' + this.descriptor.raw + '". ' + 'You might want to use a two-way filter to ensure correct behavior.', this.vm);
  4387. }
  4388. var el = this.el;
  4389. var tag = el.tagName;
  4390. var handler;
  4391. if (tag === 'INPUT') {
  4392. handler = handlers[el.type] || handlers.text;
  4393. } else if (tag === 'SELECT') {
  4394. handler = handlers.select;
  4395. } else if (tag === 'TEXTAREA') {
  4396. handler = handlers.text;
  4397. } else {
  4398. 'development' !== 'production' && warn('v-model does not support element type: ' + tag, this.vm);
  4399. return;
  4400. }
  4401. el.__v_model = this;
  4402. handler.bind.call(this);
  4403. this.update = handler.update;
  4404. this._unbind = handler.unbind;
  4405. },
  4406. /**
  4407. * Check read/write filter stats.
  4408. */
  4409. checkFilters: function checkFilters() {
  4410. var filters = this.filters;
  4411. if (!filters) return;
  4412. var i = filters.length;
  4413. while (i--) {
  4414. var filter = resolveAsset(this.vm.$options, 'filters', filters[i].name);
  4415. if (typeof filter === 'function' || filter.read) {
  4416. this.hasRead = true;
  4417. }
  4418. if (filter.write) {
  4419. this.hasWrite = true;
  4420. }
  4421. }
  4422. },
  4423. unbind: function unbind() {
  4424. this.el.__v_model = null;
  4425. this._unbind && this._unbind();
  4426. }
  4427. };
  4428. // keyCode aliases
  4429. var keyCodes = {
  4430. esc: 27,
  4431. tab: 9,
  4432. enter: 13,
  4433. space: 32,
  4434. 'delete': [8, 46],
  4435. up: 38,
  4436. left: 37,
  4437. right: 39,
  4438. down: 40
  4439. };
  4440. function keyFilter(handler, keys) {
  4441. var codes = keys.map(function (key) {
  4442. var charCode = key.charCodeAt(0);
  4443. if (charCode > 47 && charCode < 58) {
  4444. return parseInt(key, 10);
  4445. }
  4446. if (key.length === 1) {
  4447. charCode = key.toUpperCase().charCodeAt(0);
  4448. if (charCode > 64 && charCode < 91) {
  4449. return charCode;
  4450. }
  4451. }
  4452. return keyCodes[key];
  4453. });
  4454. codes = [].concat.apply([], codes);
  4455. return function keyHandler(e) {
  4456. if (codes.indexOf(e.keyCode) > -1) {
  4457. return handler.call(this, e);
  4458. }
  4459. };
  4460. }
  4461. function stopFilter(handler) {
  4462. return function stopHandler(e) {
  4463. e.stopPropagation();
  4464. return handler.call(this, e);
  4465. };
  4466. }
  4467. function preventFilter(handler) {
  4468. return function preventHandler(e) {
  4469. e.preventDefault();
  4470. return handler.call(this, e);
  4471. };
  4472. }
  4473. function selfFilter(handler) {
  4474. return function selfHandler(e) {
  4475. if (e.target === e.currentTarget) {
  4476. return handler.call(this, e);
  4477. }
  4478. };
  4479. }
  4480. var on$1 = {
  4481. priority: ON,
  4482. acceptStatement: true,
  4483. keyCodes: keyCodes,
  4484. bind: function bind() {
  4485. // deal with iframes
  4486. if (this.el.tagName === 'IFRAME' && this.arg !== 'load') {
  4487. var self = this;
  4488. this.iframeBind = function () {
  4489. on(self.el.contentWindow, self.arg, self.handler, self.modifiers.capture);
  4490. };
  4491. this.on('load', this.iframeBind);
  4492. }
  4493. },
  4494. update: function update(handler) {
  4495. // stub a noop for v-on with no value,
  4496. // e.g. @mousedown.prevent
  4497. if (!this.descriptor.raw) {
  4498. handler = function () {};
  4499. }
  4500. if (typeof handler !== 'function') {
  4501. 'development' !== 'production' && warn('v-on:' + this.arg + '="' + this.expression + '" expects a function value, ' + 'got ' + handler, this.vm);
  4502. return;
  4503. }
  4504. // apply modifiers
  4505. if (this.modifiers.stop) {
  4506. handler = stopFilter(handler);
  4507. }
  4508. if (this.modifiers.prevent) {
  4509. handler = preventFilter(handler);
  4510. }
  4511. if (this.modifiers.self) {
  4512. handler = selfFilter(handler);
  4513. }
  4514. // key filter
  4515. var keys = Object.keys(this.modifiers).filter(function (key) {
  4516. return key !== 'stop' && key !== 'prevent' && key !== 'self';
  4517. });
  4518. if (keys.length) {
  4519. handler = keyFilter(handler, keys);
  4520. }
  4521. this.reset();
  4522. this.handler = handler;
  4523. if (this.iframeBind) {
  4524. this.iframeBind();
  4525. } else {
  4526. on(this.el, this.arg, this.handler, this.modifiers.capture);
  4527. }
  4528. },
  4529. reset: function reset() {
  4530. var el = this.iframeBind ? this.el.contentWindow : this.el;
  4531. if (this.handler) {
  4532. off(el, this.arg, this.handler);
  4533. }
  4534. },
  4535. unbind: function unbind() {
  4536. this.reset();
  4537. }
  4538. };
  4539. var prefixes = ['-webkit-', '-moz-', '-ms-'];
  4540. var camelPrefixes = ['Webkit', 'Moz', 'ms'];
  4541. var importantRE = /!important;?$/;
  4542. var propCache = Object.create(null);
  4543. var testEl = null;
  4544. var style = {
  4545. deep: true,
  4546. update: function update(value) {
  4547. if (typeof value === 'string') {
  4548. this.el.style.cssText = value;
  4549. } else if (isArray(value)) {
  4550. this.handleObject(value.reduce(extend, {}));
  4551. } else {
  4552. this.handleObject(value || {});
  4553. }
  4554. },
  4555. handleObject: function handleObject(value) {
  4556. // cache object styles so that only changed props
  4557. // are actually updated.
  4558. var cache = this.cache || (this.cache = {});
  4559. var name, val;
  4560. for (name in cache) {
  4561. if (!(name in value)) {
  4562. this.handleSingle(name, null);
  4563. delete cache[name];
  4564. }
  4565. }
  4566. for (name in value) {
  4567. val = value[name];
  4568. if (val !== cache[name]) {
  4569. cache[name] = val;
  4570. this.handleSingle(name, val);
  4571. }
  4572. }
  4573. },
  4574. handleSingle: function handleSingle(prop, value) {
  4575. prop = normalize(prop);
  4576. if (!prop) return; // unsupported prop
  4577. // cast possible numbers/booleans into strings
  4578. if (value != null) value += '';
  4579. if (value) {
  4580. var isImportant = importantRE.test(value) ? 'important' : '';
  4581. if (isImportant) {
  4582. /* istanbul ignore if */
  4583. if ('development' !== 'production') {
  4584. warn('It\'s probably a bad idea to use !important with inline rules. ' + 'This feature will be deprecated in a future version of Vue.');
  4585. }
  4586. value = value.replace(importantRE, '').trim();
  4587. this.el.style.setProperty(prop.kebab, value, isImportant);
  4588. } else {
  4589. this.el.style[prop.camel] = value;
  4590. }
  4591. } else {
  4592. this.el.style[prop.camel] = '';
  4593. }
  4594. }
  4595. };
  4596. /**
  4597. * Normalize a CSS property name.
  4598. * - cache result
  4599. * - auto prefix
  4600. * - camelCase -> dash-case
  4601. *
  4602. * @param {String} prop
  4603. * @return {String}
  4604. */
  4605. function normalize(prop) {
  4606. if (propCache[prop]) {
  4607. return propCache[prop];
  4608. }
  4609. var res = prefix(prop);
  4610. propCache[prop] = propCache[res] = res;
  4611. return res;
  4612. }
  4613. /**
  4614. * Auto detect the appropriate prefix for a CSS property.
  4615. * https://gist.github.com/paulirish/523692
  4616. *
  4617. * @param {String} prop
  4618. * @return {String}
  4619. */
  4620. function prefix(prop) {
  4621. prop = hyphenate(prop);
  4622. var camel = camelize(prop);
  4623. var upper = camel.charAt(0).toUpperCase() + camel.slice(1);
  4624. if (!testEl) {
  4625. testEl = document.createElement('div');
  4626. }
  4627. var i = prefixes.length;
  4628. var prefixed;
  4629. while (i--) {
  4630. prefixed = camelPrefixes[i] + upper;
  4631. if (prefixed in testEl.style) {
  4632. return {
  4633. kebab: prefixes[i] + prop,
  4634. camel: prefixed
  4635. };
  4636. }
  4637. }
  4638. if (camel in testEl.style) {
  4639. return {
  4640. kebab: prop,
  4641. camel: camel
  4642. };
  4643. }
  4644. }
  4645. // xlink
  4646. var xlinkNS = 'http://www.w3.org/1999/xlink';
  4647. var xlinkRE = /^xlink:/;
  4648. // check for attributes that prohibit interpolations
  4649. var disallowedInterpAttrRE = /^v-|^:|^@|^(?:is|transition|transition-mode|debounce|track-by|stagger|enter-stagger|leave-stagger)$/;
  4650. // these attributes should also set their corresponding properties
  4651. // because they only affect the initial state of the element
  4652. var attrWithPropsRE = /^(?:value|checked|selected|muted)$/;
  4653. // these attributes expect enumrated values of "true" or "false"
  4654. // but are not boolean attributes
  4655. var enumeratedAttrRE = /^(?:draggable|contenteditable|spellcheck)$/;
  4656. // these attributes should set a hidden property for
  4657. // binding v-model to object values
  4658. var modelProps = {
  4659. value: '_value',
  4660. 'true-value': '_trueValue',
  4661. 'false-value': '_falseValue'
  4662. };
  4663. var bind$1 = {
  4664. priority: BIND,
  4665. bind: function bind() {
  4666. var attr = this.arg;
  4667. var tag = this.el.tagName;
  4668. // should be deep watch on object mode
  4669. if (!attr) {
  4670. this.deep = true;
  4671. }
  4672. // handle interpolation bindings
  4673. var descriptor = this.descriptor;
  4674. var tokens = descriptor.interp;
  4675. if (tokens) {
  4676. // handle interpolations with one-time tokens
  4677. if (descriptor.hasOneTime) {
  4678. this.expression = tokensToExp(tokens, this._scope || this.vm);
  4679. }
  4680. // only allow binding on native attributes
  4681. if (disallowedInterpAttrRE.test(attr) || attr === 'name' && (tag === 'PARTIAL' || tag === 'SLOT')) {
  4682. 'development' !== 'production' && warn(attr + '="' + descriptor.raw + '": ' + 'attribute interpolation is not allowed in Vue.js ' + 'directives and special attributes.', this.vm);
  4683. this.el.removeAttribute(attr);
  4684. this.invalid = true;
  4685. }
  4686. /* istanbul ignore if */
  4687. if ('development' !== 'production') {
  4688. var raw = attr + '="' + descriptor.raw + '": ';
  4689. // warn src
  4690. if (attr === 'src') {
  4691. warn(raw + 'interpolation in "src" attribute will cause ' + 'a 404 request. Use v-bind:src instead.', this.vm);
  4692. }
  4693. // warn style
  4694. if (attr === 'style') {
  4695. warn(raw + 'interpolation in "style" attribute will cause ' + 'the attribute to be discarded in Internet Explorer. ' + 'Use v-bind:style instead.', this.vm);
  4696. }
  4697. }
  4698. }
  4699. },
  4700. update: function update(value) {
  4701. if (this.invalid) {
  4702. return;
  4703. }
  4704. var attr = this.arg;
  4705. if (this.arg) {
  4706. this.handleSingle(attr, value);
  4707. } else {
  4708. this.handleObject(value || {});
  4709. }
  4710. },
  4711. // share object handler with v-bind:class
  4712. handleObject: style.handleObject,
  4713. handleSingle: function handleSingle(attr, value) {
  4714. var el = this.el;
  4715. var interp = this.descriptor.interp;
  4716. if (this.modifiers.camel) {
  4717. attr = camelize(attr);
  4718. }
  4719. if (!interp && attrWithPropsRE.test(attr) && attr in el) {
  4720. el[attr] = attr === 'value' ? value == null // IE9 will set input.value to "null" for null...
  4721. ? '' : value : value;
  4722. }
  4723. // set model props
  4724. var modelProp = modelProps[attr];
  4725. if (!interp && modelProp) {
  4726. el[modelProp] = value;
  4727. // update v-model if present
  4728. var model = el.__v_model;
  4729. if (model) {
  4730. model.listener();
  4731. }
  4732. }
  4733. // do not set value attribute for textarea
  4734. if (attr === 'value' && el.tagName === 'TEXTAREA') {
  4735. el.removeAttribute(attr);
  4736. return;
  4737. }
  4738. // update attribute
  4739. if (enumeratedAttrRE.test(attr)) {
  4740. el.setAttribute(attr, value ? 'true' : 'false');
  4741. } else if (value != null && value !== false) {
  4742. if (attr === 'class') {
  4743. // handle edge case #1960:
  4744. // class interpolation should not overwrite Vue transition class
  4745. if (el.__v_trans) {
  4746. value += ' ' + el.__v_trans.id + '-transition';
  4747. }
  4748. setClass(el, value);
  4749. } else if (xlinkRE.test(attr)) {
  4750. el.setAttributeNS(xlinkNS, attr, value === true ? '' : value);
  4751. } else {
  4752. el.setAttribute(attr, value === true ? '' : value);
  4753. }
  4754. } else {
  4755. el.removeAttribute(attr);
  4756. }
  4757. }
  4758. };
  4759. var el = {
  4760. priority: EL,
  4761. bind: function bind() {
  4762. /* istanbul ignore if */
  4763. if (!this.arg) {
  4764. return;
  4765. }
  4766. var id = this.id = camelize(this.arg);
  4767. var refs = (this._scope || this.vm).$els;
  4768. if (hasOwn(refs, id)) {
  4769. refs[id] = this.el;
  4770. } else {
  4771. defineReactive(refs, id, this.el);
  4772. }
  4773. },
  4774. unbind: function unbind() {
  4775. var refs = (this._scope || this.vm).$els;
  4776. if (refs[this.id] === this.el) {
  4777. refs[this.id] = null;
  4778. }
  4779. }
  4780. };
  4781. var ref = {
  4782. bind: function bind() {
  4783. 'development' !== 'production' && warn('v-ref:' + this.arg + ' must be used on a child ' + 'component. Found on <' + this.el.tagName.toLowerCase() + '>.', this.vm);
  4784. }
  4785. };
  4786. var cloak = {
  4787. bind: function bind() {
  4788. var el = this.el;
  4789. this.vm.$once('pre-hook:compiled', function () {
  4790. el.removeAttribute('v-cloak');
  4791. });
  4792. }
  4793. };
  4794. // must export plain object
  4795. var directives = {
  4796. text: text$1,
  4797. html: html,
  4798. 'for': vFor,
  4799. 'if': vIf,
  4800. show: show,
  4801. model: model,
  4802. on: on$1,
  4803. bind: bind$1,
  4804. el: el,
  4805. ref: ref,
  4806. cloak: cloak
  4807. };
  4808. var vClass = {
  4809. deep: true,
  4810. update: function update(value) {
  4811. if (value && typeof value === 'string') {
  4812. this.handleObject(stringToObject(value));
  4813. } else if (isPlainObject(value)) {
  4814. this.handleObject(value);
  4815. } else if (isArray(value)) {
  4816. this.handleArray(value);
  4817. } else {
  4818. this.cleanup();
  4819. }
  4820. },
  4821. handleObject: function handleObject(value) {
  4822. this.cleanup(value);
  4823. this.prevKeys = Object.keys(value);
  4824. setObjectClasses(this.el, value);
  4825. },
  4826. handleArray: function handleArray(value) {
  4827. this.cleanup(value);
  4828. for (var i = 0, l = value.length; i < l; i++) {
  4829. var val = value[i];
  4830. if (val && isPlainObject(val)) {
  4831. setObjectClasses(this.el, val);
  4832. } else if (val && typeof val === 'string') {
  4833. addClass(this.el, val);
  4834. }
  4835. }
  4836. this.prevKeys = value.slice();
  4837. },
  4838. cleanup: function cleanup(value) {
  4839. if (!this.prevKeys) return;
  4840. var i = this.prevKeys.length;
  4841. while (i--) {
  4842. var key = this.prevKeys[i];
  4843. if (!key) continue;
  4844. var keys = isPlainObject(key) ? Object.keys(key) : [key];
  4845. for (var j = 0, l = keys.length; j < l; j++) {
  4846. toggleClasses(this.el, keys[j], removeClass);
  4847. }
  4848. }
  4849. }
  4850. };
  4851. function setObjectClasses(el, obj) {
  4852. var keys = Object.keys(obj);
  4853. for (var i = 0, l = keys.length; i < l; i++) {
  4854. var key = keys[i];
  4855. if (!obj[key]) continue;
  4856. toggleClasses(el, key, addClass);
  4857. }
  4858. }
  4859. function stringToObject(value) {
  4860. var res = {};
  4861. var keys = value.trim().split(/\s+/);
  4862. for (var i = 0, l = keys.length; i < l; i++) {
  4863. res[keys[i]] = true;
  4864. }
  4865. return res;
  4866. }
  4867. /**
  4868. * Add or remove a class/classes on an element
  4869. *
  4870. * @param {Element} el
  4871. * @param {String} key The class name. This may or may not
  4872. * contain a space character, in such a
  4873. * case we'll deal with multiple class
  4874. * names at once.
  4875. * @param {Function} fn
  4876. */
  4877. function toggleClasses(el, key, fn) {
  4878. key = key.trim();
  4879. if (key.indexOf(' ') === -1) {
  4880. fn(el, key);
  4881. return;
  4882. }
  4883. // The key contains one or more space characters.
  4884. // Since a class name doesn't accept such characters, we
  4885. // treat it as multiple classes.
  4886. var keys = key.split(/\s+/);
  4887. for (var i = 0, l = keys.length; i < l; i++) {
  4888. fn(el, keys[i]);
  4889. }
  4890. }
  4891. var component = {
  4892. priority: COMPONENT,
  4893. params: ['keep-alive', 'transition-mode', 'inline-template'],
  4894. /**
  4895. * Setup. Two possible usages:
  4896. *
  4897. * - static:
  4898. * <comp> or <div v-component="comp">
  4899. *
  4900. * - dynamic:
  4901. * <component :is="view">
  4902. */
  4903. bind: function bind() {
  4904. if (!this.el.__vue__) {
  4905. // keep-alive cache
  4906. this.keepAlive = this.params.keepAlive;
  4907. if (this.keepAlive) {
  4908. this.cache = {};
  4909. }
  4910. // check inline-template
  4911. if (this.params.inlineTemplate) {
  4912. // extract inline template as a DocumentFragment
  4913. this.inlineTemplate = extractContent(this.el, true);
  4914. }
  4915. // component resolution related state
  4916. this.pendingComponentCb = this.Component = null;
  4917. // transition related state
  4918. this.pendingRemovals = 0;
  4919. this.pendingRemovalCb = null;
  4920. // create a ref anchor
  4921. this.anchor = createAnchor('v-component');
  4922. replace(this.el, this.anchor);
  4923. // remove is attribute.
  4924. // this is removed during compilation, but because compilation is
  4925. // cached, when the component is used elsewhere this attribute
  4926. // will remain at link time.
  4927. this.el.removeAttribute('is');
  4928. // remove ref, same as above
  4929. if (this.descriptor.ref) {
  4930. this.el.removeAttribute('v-ref:' + hyphenate(this.descriptor.ref));
  4931. }
  4932. // if static, build right now.
  4933. if (this.literal) {
  4934. this.setComponent(this.expression);
  4935. }
  4936. } else {
  4937. 'development' !== 'production' && warn('cannot mount component "' + this.expression + '" ' + 'on already mounted element: ' + this.el);
  4938. }
  4939. },
  4940. /**
  4941. * Public update, called by the watcher in the dynamic
  4942. * literal scenario, e.g. <component :is="view">
  4943. */
  4944. update: function update(value) {
  4945. if (!this.literal) {
  4946. this.setComponent(value);
  4947. }
  4948. },
  4949. /**
  4950. * Switch dynamic components. May resolve the component
  4951. * asynchronously, and perform transition based on
  4952. * specified transition mode. Accepts a few additional
  4953. * arguments specifically for vue-router.
  4954. *
  4955. * The callback is called when the full transition is
  4956. * finished.
  4957. *
  4958. * @param {String} value
  4959. * @param {Function} [cb]
  4960. */
  4961. setComponent: function setComponent(value, cb) {
  4962. this.invalidatePending();
  4963. if (!value) {
  4964. // just remove current
  4965. this.unbuild(true);
  4966. this.remove(this.childVM, cb);
  4967. this.childVM = null;
  4968. } else {
  4969. var self = this;
  4970. this.resolveComponent(value, function () {
  4971. self.mountComponent(cb);
  4972. });
  4973. }
  4974. },
  4975. /**
  4976. * Resolve the component constructor to use when creating
  4977. * the child vm.
  4978. *
  4979. * @param {String|Function} value
  4980. * @param {Function} cb
  4981. */
  4982. resolveComponent: function resolveComponent(value, cb) {
  4983. var self = this;
  4984. this.pendingComponentCb = cancellable(function (Component) {
  4985. self.ComponentName = Component.options.name || (typeof value === 'string' ? value : null);
  4986. self.Component = Component;
  4987. cb();
  4988. });
  4989. this.vm._resolveComponent(value, this.pendingComponentCb);
  4990. },
  4991. /**
  4992. * Create a new instance using the current constructor and
  4993. * replace the existing instance. This method doesn't care
  4994. * whether the new component and the old one are actually
  4995. * the same.
  4996. *
  4997. * @param {Function} [cb]
  4998. */
  4999. mountComponent: function mountComponent(cb) {
  5000. // actual mount
  5001. this.unbuild(true);
  5002. var self = this;
  5003. var activateHooks = this.Component.options.activate;
  5004. var cached = this.getCached();
  5005. var newComponent = this.build();
  5006. if (activateHooks && !cached) {
  5007. this.waitingFor = newComponent;
  5008. callActivateHooks(activateHooks, newComponent, function () {
  5009. if (self.waitingFor !== newComponent) {
  5010. return;
  5011. }
  5012. self.waitingFor = null;
  5013. self.transition(newComponent, cb);
  5014. });
  5015. } else {
  5016. // update ref for kept-alive component
  5017. if (cached) {
  5018. newComponent._updateRef();
  5019. }
  5020. this.transition(newComponent, cb);
  5021. }
  5022. },
  5023. /**
  5024. * When the component changes or unbinds before an async
  5025. * constructor is resolved, we need to invalidate its
  5026. * pending callback.
  5027. */
  5028. invalidatePending: function invalidatePending() {
  5029. if (this.pendingComponentCb) {
  5030. this.pendingComponentCb.cancel();
  5031. this.pendingComponentCb = null;
  5032. }
  5033. },
  5034. /**
  5035. * Instantiate/insert a new child vm.
  5036. * If keep alive and has cached instance, insert that
  5037. * instance; otherwise build a new one and cache it.
  5038. *
  5039. * @param {Object} [extraOptions]
  5040. * @return {Vue} - the created instance
  5041. */
  5042. build: function build(extraOptions) {
  5043. var cached = this.getCached();
  5044. if (cached) {
  5045. return cached;
  5046. }
  5047. if (this.Component) {
  5048. // default options
  5049. var options = {
  5050. name: this.ComponentName,
  5051. el: cloneNode(this.el),
  5052. template: this.inlineTemplate,
  5053. // make sure to add the child with correct parent
  5054. // if this is a transcluded component, its parent
  5055. // should be the transclusion host.
  5056. parent: this._host || this.vm,
  5057. // if no inline-template, then the compiled
  5058. // linker can be cached for better performance.
  5059. _linkerCachable: !this.inlineTemplate,
  5060. _ref: this.descriptor.ref,
  5061. _asComponent: true,
  5062. _isRouterView: this._isRouterView,
  5063. // if this is a transcluded component, context
  5064. // will be the common parent vm of this instance
  5065. // and its host.
  5066. _context: this.vm,
  5067. // if this is inside an inline v-for, the scope
  5068. // will be the intermediate scope created for this
  5069. // repeat fragment. this is used for linking props
  5070. // and container directives.
  5071. _scope: this._scope,
  5072. // pass in the owner fragment of this component.
  5073. // this is necessary so that the fragment can keep
  5074. // track of its contained components in order to
  5075. // call attach/detach hooks for them.
  5076. _frag: this._frag
  5077. };
  5078. // extra options
  5079. // in 1.0.0 this is used by vue-router only
  5080. /* istanbul ignore if */
  5081. if (extraOptions) {
  5082. extend(options, extraOptions);
  5083. }
  5084. var child = new this.Component(options);
  5085. if (this.keepAlive) {
  5086. this.cache[this.Component.cid] = child;
  5087. }
  5088. /* istanbul ignore if */
  5089. if ('development' !== 'production' && this.el.hasAttribute('transition') && child._isFragment) {
  5090. warn('Transitions will not work on a fragment instance. ' + 'Template: ' + child.$options.template, child);
  5091. }
  5092. return child;
  5093. }
  5094. },
  5095. /**
  5096. * Try to get a cached instance of the current component.
  5097. *
  5098. * @return {Vue|undefined}
  5099. */
  5100. getCached: function getCached() {
  5101. return this.keepAlive && this.cache[this.Component.cid];
  5102. },
  5103. /**
  5104. * Teardown the current child, but defers cleanup so
  5105. * that we can separate the destroy and removal steps.
  5106. *
  5107. * @param {Boolean} defer
  5108. */
  5109. unbuild: function unbuild(defer) {
  5110. if (this.waitingFor) {
  5111. if (!this.keepAlive) {
  5112. this.waitingFor.$destroy();
  5113. }
  5114. this.waitingFor = null;
  5115. }
  5116. var child = this.childVM;
  5117. if (!child || this.keepAlive) {
  5118. if (child) {
  5119. // remove ref
  5120. child._inactive = true;
  5121. child._updateRef(true);
  5122. }
  5123. return;
  5124. }
  5125. // the sole purpose of `deferCleanup` is so that we can
  5126. // "deactivate" the vm right now and perform DOM removal
  5127. // later.
  5128. child.$destroy(false, defer);
  5129. },
  5130. /**
  5131. * Remove current destroyed child and manually do
  5132. * the cleanup after removal.
  5133. *
  5134. * @param {Function} cb
  5135. */
  5136. remove: function remove(child, cb) {
  5137. var keepAlive = this.keepAlive;
  5138. if (child) {
  5139. // we may have a component switch when a previous
  5140. // component is still being transitioned out.
  5141. // we want to trigger only one lastest insertion cb
  5142. // when the existing transition finishes. (#1119)
  5143. this.pendingRemovals++;
  5144. this.pendingRemovalCb = cb;
  5145. var self = this;
  5146. child.$remove(function () {
  5147. self.pendingRemovals--;
  5148. if (!keepAlive) child._cleanup();
  5149. if (!self.pendingRemovals && self.pendingRemovalCb) {
  5150. self.pendingRemovalCb();
  5151. self.pendingRemovalCb = null;
  5152. }
  5153. });
  5154. } else if (cb) {
  5155. cb();
  5156. }
  5157. },
  5158. /**
  5159. * Actually swap the components, depending on the
  5160. * transition mode. Defaults to simultaneous.
  5161. *
  5162. * @param {Vue} target
  5163. * @param {Function} [cb]
  5164. */
  5165. transition: function transition(target, cb) {
  5166. var self = this;
  5167. var current = this.childVM;
  5168. // for devtool inspection
  5169. if (current) current._inactive = true;
  5170. target._inactive = false;
  5171. this.childVM = target;
  5172. switch (self.params.transitionMode) {
  5173. case 'in-out':
  5174. target.$before(self.anchor, function () {
  5175. self.remove(current, cb);
  5176. });
  5177. break;
  5178. case 'out-in':
  5179. self.remove(current, function () {
  5180. target.$before(self.anchor, cb);
  5181. });
  5182. break;
  5183. default:
  5184. self.remove(current);
  5185. target.$before(self.anchor, cb);
  5186. }
  5187. },
  5188. /**
  5189. * Unbind.
  5190. */
  5191. unbind: function unbind() {
  5192. this.invalidatePending();
  5193. // Do not defer cleanup when unbinding
  5194. this.unbuild();
  5195. // destroy all keep-alive cached instances
  5196. if (this.cache) {
  5197. for (var key in this.cache) {
  5198. this.cache[key].$destroy();
  5199. }
  5200. this.cache = null;
  5201. }
  5202. }
  5203. };
  5204. /**
  5205. * Call activate hooks in order (asynchronous)
  5206. *
  5207. * @param {Array} hooks
  5208. * @param {Vue} vm
  5209. * @param {Function} cb
  5210. */
  5211. function callActivateHooks(hooks, vm, cb) {
  5212. var total = hooks.length;
  5213. var called = 0;
  5214. hooks[0].call(vm, next);
  5215. function next() {
  5216. if (++called >= total) {
  5217. cb();
  5218. } else {
  5219. hooks[called].call(vm, next);
  5220. }
  5221. }
  5222. }
  5223. var propBindingModes = config._propBindingModes;
  5224. var empty = {};
  5225. // regexes
  5226. var identRE$1 = /^[$_a-zA-Z]+[\w$]*$/;
  5227. var settablePathRE = /^[A-Za-z_$][\w$]*(\.[A-Za-z_$][\w$]*|\[[^\[\]]+\])*$/;
  5228. /**
  5229. * Compile props on a root element and return
  5230. * a props link function.
  5231. *
  5232. * @param {Element|DocumentFragment} el
  5233. * @param {Array} propOptions
  5234. * @param {Vue} vm
  5235. * @return {Function} propsLinkFn
  5236. */
  5237. function compileProps(el, propOptions, vm) {
  5238. var props = [];
  5239. var names = Object.keys(propOptions);
  5240. var i = names.length;
  5241. var options, name, attr, value, path, parsed, prop;
  5242. while (i--) {
  5243. name = names[i];
  5244. options = propOptions[name] || empty;
  5245. if ('development' !== 'production' && name === '$data') {
  5246. warn('Do not use $data as prop.', vm);
  5247. continue;
  5248. }
  5249. // props could contain dashes, which will be
  5250. // interpreted as minus calculations by the parser
  5251. // so we need to camelize the path here
  5252. path = camelize(name);
  5253. if (!identRE$1.test(path)) {
  5254. 'development' !== 'production' && warn('Invalid prop key: "' + name + '". Prop keys ' + 'must be valid identifiers.', vm);
  5255. continue;
  5256. }
  5257. prop = {
  5258. name: name,
  5259. path: path,
  5260. options: options,
  5261. mode: propBindingModes.ONE_WAY,
  5262. raw: null
  5263. };
  5264. attr = hyphenate(name);
  5265. // first check dynamic version
  5266. if ((value = getBindAttr(el, attr)) === null) {
  5267. if ((value = getBindAttr(el, attr + '.sync')) !== null) {
  5268. prop.mode = propBindingModes.TWO_WAY;
  5269. } else if ((value = getBindAttr(el, attr + '.once')) !== null) {
  5270. prop.mode = propBindingModes.ONE_TIME;
  5271. }
  5272. }
  5273. if (value !== null) {
  5274. // has dynamic binding!
  5275. prop.raw = value;
  5276. parsed = parseDirective(value);
  5277. value = parsed.expression;
  5278. prop.filters = parsed.filters;
  5279. // check binding type
  5280. if (isLiteral(value) && !parsed.filters) {
  5281. // for expressions containing literal numbers and
  5282. // booleans, there's no need to setup a prop binding,
  5283. // so we can optimize them as a one-time set.
  5284. prop.optimizedLiteral = true;
  5285. } else {
  5286. prop.dynamic = true;
  5287. // check non-settable path for two-way bindings
  5288. if ('development' !== 'production' && prop.mode === propBindingModes.TWO_WAY && !settablePathRE.test(value)) {
  5289. prop.mode = propBindingModes.ONE_WAY;
  5290. warn('Cannot bind two-way prop with non-settable ' + 'parent path: ' + value, vm);
  5291. }
  5292. }
  5293. prop.parentPath = value;
  5294. // warn required two-way
  5295. if ('development' !== 'production' && options.twoWay && prop.mode !== propBindingModes.TWO_WAY) {
  5296. warn('Prop "' + name + '" expects a two-way binding type.', vm);
  5297. }
  5298. } else if ((value = getAttr(el, attr)) !== null) {
  5299. // has literal binding!
  5300. prop.raw = value;
  5301. } else if ('development' !== 'production') {
  5302. // check possible camelCase prop usage
  5303. var lowerCaseName = path.toLowerCase();
  5304. value = /[A-Z\-]/.test(name) && (el.getAttribute(lowerCaseName) || el.getAttribute(':' + lowerCaseName) || el.getAttribute('v-bind:' + lowerCaseName) || el.getAttribute(':' + lowerCaseName + '.once') || el.getAttribute('v-bind:' + lowerCaseName + '.once') || el.getAttribute(':' + lowerCaseName + '.sync') || el.getAttribute('v-bind:' + lowerCaseName + '.sync'));
  5305. if (value) {
  5306. warn('Possible usage error for prop `' + lowerCaseName + '` - ' + 'did you mean `' + attr + '`? HTML is case-insensitive, remember to use ' + 'kebab-case for props in templates.', vm);
  5307. } else if (options.required) {
  5308. // warn missing required
  5309. warn('Missing required prop: ' + name, vm);
  5310. }
  5311. }
  5312. // push prop
  5313. props.push(prop);
  5314. }
  5315. return makePropsLinkFn(props);
  5316. }
  5317. /**
  5318. * Build a function that applies props to a vm.
  5319. *
  5320. * @param {Array} props
  5321. * @return {Function} propsLinkFn
  5322. */
  5323. function makePropsLinkFn(props) {
  5324. return function propsLinkFn(vm, scope) {
  5325. // store resolved props info
  5326. vm._props = {};
  5327. var i = props.length;
  5328. var prop, path, options, value, raw;
  5329. while (i--) {
  5330. prop = props[i];
  5331. raw = prop.raw;
  5332. path = prop.path;
  5333. options = prop.options;
  5334. vm._props[path] = prop;
  5335. if (raw === null) {
  5336. // initialize absent prop
  5337. initProp(vm, prop, undefined);
  5338. } else if (prop.dynamic) {
  5339. // dynamic prop
  5340. if (prop.mode === propBindingModes.ONE_TIME) {
  5341. // one time binding
  5342. value = (scope || vm._context || vm).$get(prop.parentPath);
  5343. initProp(vm, prop, value);
  5344. } else {
  5345. if (vm._context) {
  5346. // dynamic binding
  5347. vm._bindDir({
  5348. name: 'prop',
  5349. def: propDef,
  5350. prop: prop
  5351. }, null, null, scope); // el, host, scope
  5352. } else {
  5353. // root instance
  5354. initProp(vm, prop, vm.$get(prop.parentPath));
  5355. }
  5356. }
  5357. } else if (prop.optimizedLiteral) {
  5358. // optimized literal, cast it and just set once
  5359. var stripped = stripQuotes(raw);
  5360. value = stripped === raw ? toBoolean(toNumber(raw)) : stripped;
  5361. initProp(vm, prop, value);
  5362. } else {
  5363. // string literal, but we need to cater for
  5364. // Boolean props with no value, or with same
  5365. // literal value (e.g. disabled="disabled")
  5366. // see https://github.com/vuejs/vue-loader/issues/182
  5367. value = options.type === Boolean && (raw === '' || raw === hyphenate(prop.name)) ? true : raw;
  5368. initProp(vm, prop, value);
  5369. }
  5370. }
  5371. };
  5372. }
  5373. /**
  5374. * Process a prop with a rawValue, applying necessary coersions,
  5375. * default values & assertions and call the given callback with
  5376. * processed value.
  5377. *
  5378. * @param {Vue} vm
  5379. * @param {Object} prop
  5380. * @param {*} rawValue
  5381. * @param {Function} fn
  5382. */
  5383. function processPropValue(vm, prop, rawValue, fn) {
  5384. var isSimple = prop.dynamic && isSimplePath(prop.parentPath);
  5385. var value = rawValue;
  5386. if (value === undefined) {
  5387. value = getPropDefaultValue(vm, prop);
  5388. }
  5389. value = coerceProp(prop, value);
  5390. var coerced = value !== rawValue;
  5391. if (!assertProp(prop, value, vm)) {
  5392. value = undefined;
  5393. }
  5394. if (isSimple && !coerced) {
  5395. withoutConversion(function () {
  5396. fn(value);
  5397. });
  5398. } else {
  5399. fn(value);
  5400. }
  5401. }
  5402. /**
  5403. * Set a prop's initial value on a vm and its data object.
  5404. *
  5405. * @param {Vue} vm
  5406. * @param {Object} prop
  5407. * @param {*} value
  5408. */
  5409. function initProp(vm, prop, value) {
  5410. processPropValue(vm, prop, value, function (value) {
  5411. defineReactive(vm, prop.path, value);
  5412. });
  5413. }
  5414. /**
  5415. * Update a prop's value on a vm.
  5416. *
  5417. * @param {Vue} vm
  5418. * @param {Object} prop
  5419. * @param {*} value
  5420. */
  5421. function updateProp(vm, prop, value) {
  5422. processPropValue(vm, prop, value, function (value) {
  5423. vm[prop.path] = value;
  5424. });
  5425. }
  5426. /**
  5427. * Get the default value of a prop.
  5428. *
  5429. * @param {Vue} vm
  5430. * @param {Object} prop
  5431. * @return {*}
  5432. */
  5433. function getPropDefaultValue(vm, prop) {
  5434. // no default, return undefined
  5435. var options = prop.options;
  5436. if (!hasOwn(options, 'default')) {
  5437. // absent boolean value defaults to false
  5438. return options.type === Boolean ? false : undefined;
  5439. }
  5440. var def = options['default'];
  5441. // warn against non-factory defaults for Object & Array
  5442. if (isObject(def)) {
  5443. 'development' !== 'production' && warn('Invalid default value for prop "' + prop.name + '": ' + 'Props with type Object/Array must use a factory function ' + 'to return the default value.', vm);
  5444. }
  5445. // call factory function for non-Function types
  5446. return typeof def === 'function' && options.type !== Function ? def.call(vm) : def;
  5447. }
  5448. /**
  5449. * Assert whether a prop is valid.
  5450. *
  5451. * @param {Object} prop
  5452. * @param {*} value
  5453. * @param {Vue} vm
  5454. */
  5455. function assertProp(prop, value, vm) {
  5456. if (!prop.options.required && ( // non-required
  5457. prop.raw === null || // abscent
  5458. value == null) // null or undefined
  5459. ) {
  5460. return true;
  5461. }
  5462. var options = prop.options;
  5463. var type = options.type;
  5464. var valid = !type;
  5465. var expectedTypes = [];
  5466. if (type) {
  5467. if (!isArray(type)) {
  5468. type = [type];
  5469. }
  5470. for (var i = 0; i < type.length && !valid; i++) {
  5471. var assertedType = assertType(value, type[i]);
  5472. expectedTypes.push(assertedType.expectedType);
  5473. valid = assertedType.valid;
  5474. }
  5475. }
  5476. if (!valid) {
  5477. if ('development' !== 'production') {
  5478. warn('Invalid prop: type check failed for prop "' + prop.name + '".' + ' Expected ' + expectedTypes.map(formatType).join(', ') + ', got ' + formatValue(value) + '.', vm);
  5479. }
  5480. return false;
  5481. }
  5482. var validator = options.validator;
  5483. if (validator) {
  5484. if (!validator(value)) {
  5485. 'development' !== 'production' && warn('Invalid prop: custom validator check failed for prop "' + prop.name + '".', vm);
  5486. return false;
  5487. }
  5488. }
  5489. return true;
  5490. }
  5491. /**
  5492. * Force parsing value with coerce option.
  5493. *
  5494. * @param {*} value
  5495. * @param {Object} options
  5496. * @return {*}
  5497. */
  5498. function coerceProp(prop, value) {
  5499. var coerce = prop.options.coerce;
  5500. if (!coerce) {
  5501. return value;
  5502. }
  5503. // coerce is a function
  5504. return coerce(value);
  5505. }
  5506. /**
  5507. * Assert the type of a value
  5508. *
  5509. * @param {*} value
  5510. * @param {Function} type
  5511. * @return {Object}
  5512. */
  5513. function assertType(value, type) {
  5514. var valid;
  5515. var expectedType;
  5516. if (type === String) {
  5517. expectedType = 'string';
  5518. valid = typeof value === expectedType;
  5519. } else if (type === Number) {
  5520. expectedType = 'number';
  5521. valid = typeof value === expectedType;
  5522. } else if (type === Boolean) {
  5523. expectedType = 'boolean';
  5524. valid = typeof value === expectedType;
  5525. } else if (type === Function) {
  5526. expectedType = 'function';
  5527. valid = typeof value === expectedType;
  5528. } else if (type === Object) {
  5529. expectedType = 'object';
  5530. valid = isPlainObject(value);
  5531. } else if (type === Array) {
  5532. expectedType = 'array';
  5533. valid = isArray(value);
  5534. } else {
  5535. valid = value instanceof type;
  5536. }
  5537. return {
  5538. valid: valid,
  5539. expectedType: expectedType
  5540. };
  5541. }
  5542. /**
  5543. * Format type for output
  5544. *
  5545. * @param {String} type
  5546. * @return {String}
  5547. */
  5548. function formatType(type) {
  5549. return type ? type.charAt(0).toUpperCase() + type.slice(1) : 'custom type';
  5550. }
  5551. /**
  5552. * Format value
  5553. *
  5554. * @param {*} value
  5555. * @return {String}
  5556. */
  5557. function formatValue(val) {
  5558. return Object.prototype.toString.call(val).slice(8, -1);
  5559. }
  5560. var bindingModes = config._propBindingModes;
  5561. var propDef = {
  5562. bind: function bind() {
  5563. var child = this.vm;
  5564. var parent = child._context;
  5565. // passed in from compiler directly
  5566. var prop = this.descriptor.prop;
  5567. var childKey = prop.path;
  5568. var parentKey = prop.parentPath;
  5569. var twoWay = prop.mode === bindingModes.TWO_WAY;
  5570. var parentWatcher = this.parentWatcher = new Watcher(parent, parentKey, function (val) {
  5571. updateProp(child, prop, val);
  5572. }, {
  5573. twoWay: twoWay,
  5574. filters: prop.filters,
  5575. // important: props need to be observed on the
  5576. // v-for scope if present
  5577. scope: this._scope
  5578. });
  5579. // set the child initial value.
  5580. initProp(child, prop, parentWatcher.value);
  5581. // setup two-way binding
  5582. if (twoWay) {
  5583. // important: defer the child watcher creation until
  5584. // the created hook (after data observation)
  5585. var self = this;
  5586. child.$once('pre-hook:created', function () {
  5587. self.childWatcher = new Watcher(child, childKey, function (val) {
  5588. parentWatcher.set(val);
  5589. }, {
  5590. // ensure sync upward before parent sync down.
  5591. // this is necessary in cases e.g. the child
  5592. // mutates a prop array, then replaces it. (#1683)
  5593. sync: true
  5594. });
  5595. });
  5596. }
  5597. },
  5598. unbind: function unbind() {
  5599. this.parentWatcher.teardown();
  5600. if (this.childWatcher) {
  5601. this.childWatcher.teardown();
  5602. }
  5603. }
  5604. };
  5605. var queue$1 = [];
  5606. var queued = false;
  5607. /**
  5608. * Push a job into the queue.
  5609. *
  5610. * @param {Function} job
  5611. */
  5612. function pushJob(job) {
  5613. queue$1.push(job);
  5614. if (!queued) {
  5615. queued = true;
  5616. nextTick(flush);
  5617. }
  5618. }
  5619. /**
  5620. * Flush the queue, and do one forced reflow before
  5621. * triggering transitions.
  5622. */
  5623. function flush() {
  5624. // Force layout
  5625. var f = document.documentElement.offsetHeight;
  5626. for (var i = 0; i < queue$1.length; i++) {
  5627. queue$1[i]();
  5628. }
  5629. queue$1 = [];
  5630. queued = false;
  5631. // dummy return, so js linters don't complain about
  5632. // unused variable f
  5633. return f;
  5634. }
  5635. var TYPE_TRANSITION = 'transition';
  5636. var TYPE_ANIMATION = 'animation';
  5637. var transDurationProp = transitionProp + 'Duration';
  5638. var animDurationProp = animationProp + 'Duration';
  5639. /**
  5640. * If a just-entered element is applied the
  5641. * leave class while its enter transition hasn't started yet,
  5642. * and the transitioned property has the same value for both
  5643. * enter/leave, then the leave transition will be skipped and
  5644. * the transitionend event never fires. This function ensures
  5645. * its callback to be called after a transition has started
  5646. * by waiting for double raf.
  5647. *
  5648. * It falls back to setTimeout on devices that support CSS
  5649. * transitions but not raf (e.g. Android 4.2 browser) - since
  5650. * these environments are usually slow, we are giving it a
  5651. * relatively large timeout.
  5652. */
  5653. var raf = inBrowser && window.requestAnimationFrame;
  5654. var waitForTransitionStart = raf
  5655. /* istanbul ignore next */
  5656. ? function (fn) {
  5657. raf(function () {
  5658. raf(fn);
  5659. });
  5660. } : function (fn) {
  5661. setTimeout(fn, 50);
  5662. };
  5663. /**
  5664. * A Transition object that encapsulates the state and logic
  5665. * of the transition.
  5666. *
  5667. * @param {Element} el
  5668. * @param {String} id
  5669. * @param {Object} hooks
  5670. * @param {Vue} vm
  5671. */
  5672. function Transition(el, id, hooks, vm) {
  5673. this.id = id;
  5674. this.el = el;
  5675. this.enterClass = hooks && hooks.enterClass || id + '-enter';
  5676. this.leaveClass = hooks && hooks.leaveClass || id + '-leave';
  5677. this.hooks = hooks;
  5678. this.vm = vm;
  5679. // async state
  5680. this.pendingCssEvent = this.pendingCssCb = this.cancel = this.pendingJsCb = this.op = this.cb = null;
  5681. this.justEntered = false;
  5682. this.entered = this.left = false;
  5683. this.typeCache = {};
  5684. // check css transition type
  5685. this.type = hooks && hooks.type;
  5686. /* istanbul ignore if */
  5687. if ('development' !== 'production') {
  5688. if (this.type && this.type !== TYPE_TRANSITION && this.type !== TYPE_ANIMATION) {
  5689. warn('invalid CSS transition type for transition="' + this.id + '": ' + this.type, vm);
  5690. }
  5691. }
  5692. // bind
  5693. var self = this;['enterNextTick', 'enterDone', 'leaveNextTick', 'leaveDone'].forEach(function (m) {
  5694. self[m] = bind(self[m], self);
  5695. });
  5696. }
  5697. var p$1 = Transition.prototype;
  5698. /**
  5699. * Start an entering transition.
  5700. *
  5701. * 1. enter transition triggered
  5702. * 2. call beforeEnter hook
  5703. * 3. add enter class
  5704. * 4. insert/show element
  5705. * 5. call enter hook (with possible explicit js callback)
  5706. * 6. reflow
  5707. * 7. based on transition type:
  5708. * - transition:
  5709. * remove class now, wait for transitionend,
  5710. * then done if there's no explicit js callback.
  5711. * - animation:
  5712. * wait for animationend, remove class,
  5713. * then done if there's no explicit js callback.
  5714. * - no css transition:
  5715. * done now if there's no explicit js callback.
  5716. * 8. wait for either done or js callback, then call
  5717. * afterEnter hook.
  5718. *
  5719. * @param {Function} op - insert/show the element
  5720. * @param {Function} [cb]
  5721. */
  5722. p$1.enter = function (op, cb) {
  5723. this.cancelPending();
  5724. this.callHook('beforeEnter');
  5725. this.cb = cb;
  5726. addClass(this.el, this.enterClass);
  5727. op();
  5728. this.entered = false;
  5729. this.callHookWithCb('enter');
  5730. if (this.entered) {
  5731. return; // user called done synchronously.
  5732. }
  5733. this.cancel = this.hooks && this.hooks.enterCancelled;
  5734. pushJob(this.enterNextTick);
  5735. };
  5736. /**
  5737. * The "nextTick" phase of an entering transition, which is
  5738. * to be pushed into a queue and executed after a reflow so
  5739. * that removing the class can trigger a CSS transition.
  5740. */
  5741. p$1.enterNextTick = function () {
  5742. var _this = this;
  5743. // prevent transition skipping
  5744. this.justEntered = true;
  5745. waitForTransitionStart(function () {
  5746. _this.justEntered = false;
  5747. });
  5748. var enterDone = this.enterDone;
  5749. var type = this.getCssTransitionType(this.enterClass);
  5750. if (!this.pendingJsCb) {
  5751. if (type === TYPE_TRANSITION) {
  5752. // trigger transition by removing enter class now
  5753. removeClass(this.el, this.enterClass);
  5754. this.setupCssCb(transitionEndEvent, enterDone);
  5755. } else if (type === TYPE_ANIMATION) {
  5756. this.setupCssCb(animationEndEvent, enterDone);
  5757. } else {
  5758. enterDone();
  5759. }
  5760. } else if (type === TYPE_TRANSITION) {
  5761. removeClass(this.el, this.enterClass);
  5762. }
  5763. };
  5764. /**
  5765. * The "cleanup" phase of an entering transition.
  5766. */
  5767. p$1.enterDone = function () {
  5768. this.entered = true;
  5769. this.cancel = this.pendingJsCb = null;
  5770. removeClass(this.el, this.enterClass);
  5771. this.callHook('afterEnter');
  5772. if (this.cb) this.cb();
  5773. };
  5774. /**
  5775. * Start a leaving transition.
  5776. *
  5777. * 1. leave transition triggered.
  5778. * 2. call beforeLeave hook
  5779. * 3. add leave class (trigger css transition)
  5780. * 4. call leave hook (with possible explicit js callback)
  5781. * 5. reflow if no explicit js callback is provided
  5782. * 6. based on transition type:
  5783. * - transition or animation:
  5784. * wait for end event, remove class, then done if
  5785. * there's no explicit js callback.
  5786. * - no css transition:
  5787. * done if there's no explicit js callback.
  5788. * 7. wait for either done or js callback, then call
  5789. * afterLeave hook.
  5790. *
  5791. * @param {Function} op - remove/hide the element
  5792. * @param {Function} [cb]
  5793. */
  5794. p$1.leave = function (op, cb) {
  5795. this.cancelPending();
  5796. this.callHook('beforeLeave');
  5797. this.op = op;
  5798. this.cb = cb;
  5799. addClass(this.el, this.leaveClass);
  5800. this.left = false;
  5801. this.callHookWithCb('leave');
  5802. if (this.left) {
  5803. return; // user called done synchronously.
  5804. }
  5805. this.cancel = this.hooks && this.hooks.leaveCancelled;
  5806. // only need to handle leaveDone if
  5807. // 1. the transition is already done (synchronously called
  5808. // by the user, which causes this.op set to null)
  5809. // 2. there's no explicit js callback
  5810. if (this.op && !this.pendingJsCb) {
  5811. // if a CSS transition leaves immediately after enter,
  5812. // the transitionend event never fires. therefore we
  5813. // detect such cases and end the leave immediately.
  5814. if (this.justEntered) {
  5815. this.leaveDone();
  5816. } else {
  5817. pushJob(this.leaveNextTick);
  5818. }
  5819. }
  5820. };
  5821. /**
  5822. * The "nextTick" phase of a leaving transition.
  5823. */
  5824. p$1.leaveNextTick = function () {
  5825. var type = this.getCssTransitionType(this.leaveClass);
  5826. if (type) {
  5827. var event = type === TYPE_TRANSITION ? transitionEndEvent : animationEndEvent;
  5828. this.setupCssCb(event, this.leaveDone);
  5829. } else {
  5830. this.leaveDone();
  5831. }
  5832. };
  5833. /**
  5834. * The "cleanup" phase of a leaving transition.
  5835. */
  5836. p$1.leaveDone = function () {
  5837. this.left = true;
  5838. this.cancel = this.pendingJsCb = null;
  5839. this.op();
  5840. removeClass(this.el, this.leaveClass);
  5841. this.callHook('afterLeave');
  5842. if (this.cb) this.cb();
  5843. this.op = null;
  5844. };
  5845. /**
  5846. * Cancel any pending callbacks from a previously running
  5847. * but not finished transition.
  5848. */
  5849. p$1.cancelPending = function () {
  5850. this.op = this.cb = null;
  5851. var hasPending = false;
  5852. if (this.pendingCssCb) {
  5853. hasPending = true;
  5854. off(this.el, this.pendingCssEvent, this.pendingCssCb);
  5855. this.pendingCssEvent = this.pendingCssCb = null;
  5856. }
  5857. if (this.pendingJsCb) {
  5858. hasPending = true;
  5859. this.pendingJsCb.cancel();
  5860. this.pendingJsCb = null;
  5861. }
  5862. if (hasPending) {
  5863. removeClass(this.el, this.enterClass);
  5864. removeClass(this.el, this.leaveClass);
  5865. }
  5866. if (this.cancel) {
  5867. this.cancel.call(this.vm, this.el);
  5868. this.cancel = null;
  5869. }
  5870. };
  5871. /**
  5872. * Call a user-provided synchronous hook function.
  5873. *
  5874. * @param {String} type
  5875. */
  5876. p$1.callHook = function (type) {
  5877. if (this.hooks && this.hooks[type]) {
  5878. this.hooks[type].call(this.vm, this.el);
  5879. }
  5880. };
  5881. /**
  5882. * Call a user-provided, potentially-async hook function.
  5883. * We check for the length of arguments to see if the hook
  5884. * expects a `done` callback. If true, the transition's end
  5885. * will be determined by when the user calls that callback;
  5886. * otherwise, the end is determined by the CSS transition or
  5887. * animation.
  5888. *
  5889. * @param {String} type
  5890. */
  5891. p$1.callHookWithCb = function (type) {
  5892. var hook = this.hooks && this.hooks[type];
  5893. if (hook) {
  5894. if (hook.length > 1) {
  5895. this.pendingJsCb = cancellable(this[type + 'Done']);
  5896. }
  5897. hook.call(this.vm, this.el, this.pendingJsCb);
  5898. }
  5899. };
  5900. /**
  5901. * Get an element's transition type based on the
  5902. * calculated styles.
  5903. *
  5904. * @param {String} className
  5905. * @return {Number}
  5906. */
  5907. p$1.getCssTransitionType = function (className) {
  5908. /* istanbul ignore if */
  5909. if (!transitionEndEvent ||
  5910. // skip CSS transitions if page is not visible -
  5911. // this solves the issue of transitionend events not
  5912. // firing until the page is visible again.
  5913. // pageVisibility API is supported in IE10+, same as
  5914. // CSS transitions.
  5915. document.hidden ||
  5916. // explicit js-only transition
  5917. this.hooks && this.hooks.css === false ||
  5918. // element is hidden
  5919. isHidden(this.el)) {
  5920. return;
  5921. }
  5922. var type = this.type || this.typeCache[className];
  5923. if (type) return type;
  5924. var inlineStyles = this.el.style;
  5925. var computedStyles = window.getComputedStyle(this.el);
  5926. var transDuration = inlineStyles[transDurationProp] || computedStyles[transDurationProp];
  5927. if (transDuration && transDuration !== '0s') {
  5928. type = TYPE_TRANSITION;
  5929. } else {
  5930. var animDuration = inlineStyles[animDurationProp] || computedStyles[animDurationProp];
  5931. if (animDuration && animDuration !== '0s') {
  5932. type = TYPE_ANIMATION;
  5933. }
  5934. }
  5935. if (type) {
  5936. this.typeCache[className] = type;
  5937. }
  5938. return type;
  5939. };
  5940. /**
  5941. * Setup a CSS transitionend/animationend callback.
  5942. *
  5943. * @param {String} event
  5944. * @param {Function} cb
  5945. */
  5946. p$1.setupCssCb = function (event, cb) {
  5947. this.pendingCssEvent = event;
  5948. var self = this;
  5949. var el = this.el;
  5950. var onEnd = this.pendingCssCb = function (e) {
  5951. if (e.target === el) {
  5952. off(el, event, onEnd);
  5953. self.pendingCssEvent = self.pendingCssCb = null;
  5954. if (!self.pendingJsCb && cb) {
  5955. cb();
  5956. }
  5957. }
  5958. };
  5959. on(el, event, onEnd);
  5960. };
  5961. /**
  5962. * Check if an element is hidden - in that case we can just
  5963. * skip the transition alltogether.
  5964. *
  5965. * @param {Element} el
  5966. * @return {Boolean}
  5967. */
  5968. function isHidden(el) {
  5969. if (/svg$/.test(el.namespaceURI)) {
  5970. // SVG elements do not have offset(Width|Height)
  5971. // so we need to check the client rect
  5972. var rect = el.getBoundingClientRect();
  5973. return !(rect.width || rect.height);
  5974. } else {
  5975. return !(el.offsetWidth || el.offsetHeight || el.getClientRects().length);
  5976. }
  5977. }
  5978. var transition$1 = {
  5979. priority: TRANSITION,
  5980. update: function update(id, oldId) {
  5981. var el = this.el;
  5982. // resolve on owner vm
  5983. var hooks = resolveAsset(this.vm.$options, 'transitions', id);
  5984. id = id || 'v';
  5985. el.__v_trans = new Transition(el, id, hooks, this.vm);
  5986. if (oldId) {
  5987. removeClass(el, oldId + '-transition');
  5988. }
  5989. addClass(el, id + '-transition');
  5990. }
  5991. };
  5992. var internalDirectives = {
  5993. style: style,
  5994. 'class': vClass,
  5995. component: component,
  5996. prop: propDef,
  5997. transition: transition$1
  5998. };
  5999. // special binding prefixes
  6000. var bindRE = /^v-bind:|^:/;
  6001. var onRE = /^v-on:|^@/;
  6002. var dirAttrRE = /^v-([^:]+)(?:$|:(.*)$)/;
  6003. var modifierRE = /\.[^\.]+/g;
  6004. var transitionRE = /^(v-bind:|:)?transition$/;
  6005. // default directive priority
  6006. var DEFAULT_PRIORITY = 1000;
  6007. var DEFAULT_TERMINAL_PRIORITY = 2000;
  6008. /**
  6009. * Compile a template and return a reusable composite link
  6010. * function, which recursively contains more link functions
  6011. * inside. This top level compile function would normally
  6012. * be called on instance root nodes, but can also be used
  6013. * for partial compilation if the partial argument is true.
  6014. *
  6015. * The returned composite link function, when called, will
  6016. * return an unlink function that tearsdown all directives
  6017. * created during the linking phase.
  6018. *
  6019. * @param {Element|DocumentFragment} el
  6020. * @param {Object} options
  6021. * @param {Boolean} partial
  6022. * @return {Function}
  6023. */
  6024. function compile(el, options, partial) {
  6025. // link function for the node itself.
  6026. var nodeLinkFn = partial || !options._asComponent ? compileNode(el, options) : null;
  6027. // link function for the childNodes
  6028. var childLinkFn = !(nodeLinkFn && nodeLinkFn.terminal) && el.tagName !== 'SCRIPT' && el.hasChildNodes() ? compileNodeList(el.childNodes, options) : null;
  6029. /**
  6030. * A composite linker function to be called on a already
  6031. * compiled piece of DOM, which instantiates all directive
  6032. * instances.
  6033. *
  6034. * @param {Vue} vm
  6035. * @param {Element|DocumentFragment} el
  6036. * @param {Vue} [host] - host vm of transcluded content
  6037. * @param {Object} [scope] - v-for scope
  6038. * @param {Fragment} [frag] - link context fragment
  6039. * @return {Function|undefined}
  6040. */
  6041. return function compositeLinkFn(vm, el, host, scope, frag) {
  6042. // cache childNodes before linking parent, fix #657
  6043. var childNodes = toArray(el.childNodes);
  6044. // link
  6045. var dirs = linkAndCapture(function compositeLinkCapturer() {
  6046. if (nodeLinkFn) nodeLinkFn(vm, el, host, scope, frag);
  6047. if (childLinkFn) childLinkFn(vm, childNodes, host, scope, frag);
  6048. }, vm);
  6049. return makeUnlinkFn(vm, dirs);
  6050. };
  6051. }
  6052. /**
  6053. * Apply a linker to a vm/element pair and capture the
  6054. * directives created during the process.
  6055. *
  6056. * @param {Function} linker
  6057. * @param {Vue} vm
  6058. */
  6059. function linkAndCapture(linker, vm) {
  6060. /* istanbul ignore if */
  6061. if ('development' === 'production') {}
  6062. var originalDirCount = vm._directives.length;
  6063. linker();
  6064. var dirs = vm._directives.slice(originalDirCount);
  6065. dirs.sort(directiveComparator);
  6066. for (var i = 0, l = dirs.length; i < l; i++) {
  6067. dirs[i]._bind();
  6068. }
  6069. return dirs;
  6070. }
  6071. /**
  6072. * Directive priority sort comparator
  6073. *
  6074. * @param {Object} a
  6075. * @param {Object} b
  6076. */
  6077. function directiveComparator(a, b) {
  6078. a = a.descriptor.def.priority || DEFAULT_PRIORITY;
  6079. b = b.descriptor.def.priority || DEFAULT_PRIORITY;
  6080. return a > b ? -1 : a === b ? 0 : 1;
  6081. }
  6082. /**
  6083. * Linker functions return an unlink function that
  6084. * tearsdown all directives instances generated during
  6085. * the process.
  6086. *
  6087. * We create unlink functions with only the necessary
  6088. * information to avoid retaining additional closures.
  6089. *
  6090. * @param {Vue} vm
  6091. * @param {Array} dirs
  6092. * @param {Vue} [context]
  6093. * @param {Array} [contextDirs]
  6094. * @return {Function}
  6095. */
  6096. function makeUnlinkFn(vm, dirs, context, contextDirs) {
  6097. function unlink(destroying) {
  6098. teardownDirs(vm, dirs, destroying);
  6099. if (context && contextDirs) {
  6100. teardownDirs(context, contextDirs);
  6101. }
  6102. }
  6103. // expose linked directives
  6104. unlink.dirs = dirs;
  6105. return unlink;
  6106. }
  6107. /**
  6108. * Teardown partial linked directives.
  6109. *
  6110. * @param {Vue} vm
  6111. * @param {Array} dirs
  6112. * @param {Boolean} destroying
  6113. */
  6114. function teardownDirs(vm, dirs, destroying) {
  6115. var i = dirs.length;
  6116. while (i--) {
  6117. dirs[i]._teardown();
  6118. if ('development' !== 'production' && !destroying) {
  6119. vm._directives.$remove(dirs[i]);
  6120. }
  6121. }
  6122. }
  6123. /**
  6124. * Compile link props on an instance.
  6125. *
  6126. * @param {Vue} vm
  6127. * @param {Element} el
  6128. * @param {Object} props
  6129. * @param {Object} [scope]
  6130. * @return {Function}
  6131. */
  6132. function compileAndLinkProps(vm, el, props, scope) {
  6133. var propsLinkFn = compileProps(el, props, vm);
  6134. var propDirs = linkAndCapture(function () {
  6135. propsLinkFn(vm, scope);
  6136. }, vm);
  6137. return makeUnlinkFn(vm, propDirs);
  6138. }
  6139. /**
  6140. * Compile the root element of an instance.
  6141. *
  6142. * 1. attrs on context container (context scope)
  6143. * 2. attrs on the component template root node, if
  6144. * replace:true (child scope)
  6145. *
  6146. * If this is a fragment instance, we only need to compile 1.
  6147. *
  6148. * @param {Element} el
  6149. * @param {Object} options
  6150. * @param {Object} contextOptions
  6151. * @return {Function}
  6152. */
  6153. function compileRoot(el, options, contextOptions) {
  6154. var containerAttrs = options._containerAttrs;
  6155. var replacerAttrs = options._replacerAttrs;
  6156. var contextLinkFn, replacerLinkFn;
  6157. // only need to compile other attributes for
  6158. // non-fragment instances
  6159. if (el.nodeType !== 11) {
  6160. // for components, container and replacer need to be
  6161. // compiled separately and linked in different scopes.
  6162. if (options._asComponent) {
  6163. // 2. container attributes
  6164. if (containerAttrs && contextOptions) {
  6165. contextLinkFn = compileDirectives(containerAttrs, contextOptions);
  6166. }
  6167. if (replacerAttrs) {
  6168. // 3. replacer attributes
  6169. replacerLinkFn = compileDirectives(replacerAttrs, options);
  6170. }
  6171. } else {
  6172. // non-component, just compile as a normal element.
  6173. replacerLinkFn = compileDirectives(el.attributes, options);
  6174. }
  6175. } else if ('development' !== 'production' && containerAttrs) {
  6176. // warn container directives for fragment instances
  6177. var names = containerAttrs.filter(function (attr) {
  6178. // allow vue-loader/vueify scoped css attributes
  6179. return attr.name.indexOf('_v-') < 0 &&
  6180. // allow event listeners
  6181. !onRE.test(attr.name) &&
  6182. // allow slots
  6183. attr.name !== 'slot';
  6184. }).map(function (attr) {
  6185. return '"' + attr.name + '"';
  6186. });
  6187. if (names.length) {
  6188. var plural = names.length > 1;
  6189. warn('Attribute' + (plural ? 's ' : ' ') + names.join(', ') + (plural ? ' are' : ' is') + ' ignored on component ' + '<' + options.el.tagName.toLowerCase() + '> because ' + 'the component is a fragment instance: ' + 'http://vuejs.org/guide/components.html#Fragment_Instance');
  6190. }
  6191. }
  6192. options._containerAttrs = options._replacerAttrs = null;
  6193. return function rootLinkFn(vm, el, scope) {
  6194. // link context scope dirs
  6195. var context = vm._context;
  6196. var contextDirs;
  6197. if (context && contextLinkFn) {
  6198. contextDirs = linkAndCapture(function () {
  6199. contextLinkFn(context, el, null, scope);
  6200. }, context);
  6201. }
  6202. // link self
  6203. var selfDirs = linkAndCapture(function () {
  6204. if (replacerLinkFn) replacerLinkFn(vm, el);
  6205. }, vm);
  6206. // return the unlink function that tearsdown context
  6207. // container directives.
  6208. return makeUnlinkFn(vm, selfDirs, context, contextDirs);
  6209. };
  6210. }
  6211. /**
  6212. * Compile a node and return a nodeLinkFn based on the
  6213. * node type.
  6214. *
  6215. * @param {Node} node
  6216. * @param {Object} options
  6217. * @return {Function|null}
  6218. */
  6219. function compileNode(node, options) {
  6220. var type = node.nodeType;
  6221. if (type === 1 && node.tagName !== 'SCRIPT') {
  6222. return compileElement(node, options);
  6223. } else if (type === 3 && node.data.trim()) {
  6224. return compileTextNode(node, options);
  6225. } else {
  6226. return null;
  6227. }
  6228. }
  6229. /**
  6230. * Compile an element and return a nodeLinkFn.
  6231. *
  6232. * @param {Element} el
  6233. * @param {Object} options
  6234. * @return {Function|null}
  6235. */
  6236. function compileElement(el, options) {
  6237. // preprocess textareas.
  6238. // textarea treats its text content as the initial value.
  6239. // just bind it as an attr directive for value.
  6240. if (el.tagName === 'TEXTAREA') {
  6241. var tokens = parseText(el.value);
  6242. if (tokens) {
  6243. el.setAttribute(':value', tokensToExp(tokens));
  6244. el.value = '';
  6245. }
  6246. }
  6247. var linkFn;
  6248. var hasAttrs = el.hasAttributes();
  6249. var attrs = hasAttrs && toArray(el.attributes);
  6250. // check terminal directives (for & if)
  6251. if (hasAttrs) {
  6252. linkFn = checkTerminalDirectives(el, attrs, options);
  6253. }
  6254. // check element directives
  6255. if (!linkFn) {
  6256. linkFn = checkElementDirectives(el, options);
  6257. }
  6258. // check component
  6259. if (!linkFn) {
  6260. linkFn = checkComponent(el, options);
  6261. }
  6262. // normal directives
  6263. if (!linkFn && hasAttrs) {
  6264. linkFn = compileDirectives(attrs, options);
  6265. }
  6266. return linkFn;
  6267. }
  6268. /**
  6269. * Compile a textNode and return a nodeLinkFn.
  6270. *
  6271. * @param {TextNode} node
  6272. * @param {Object} options
  6273. * @return {Function|null} textNodeLinkFn
  6274. */
  6275. function compileTextNode(node, options) {
  6276. // skip marked text nodes
  6277. if (node._skip) {
  6278. return removeText;
  6279. }
  6280. var tokens = parseText(node.wholeText);
  6281. if (!tokens) {
  6282. return null;
  6283. }
  6284. // mark adjacent text nodes as skipped,
  6285. // because we are using node.wholeText to compile
  6286. // all adjacent text nodes together. This fixes
  6287. // issues in IE where sometimes it splits up a single
  6288. // text node into multiple ones.
  6289. var next = node.nextSibling;
  6290. while (next && next.nodeType === 3) {
  6291. next._skip = true;
  6292. next = next.nextSibling;
  6293. }
  6294. var frag = document.createDocumentFragment();
  6295. var el, token;
  6296. for (var i = 0, l = tokens.length; i < l; i++) {
  6297. token = tokens[i];
  6298. el = token.tag ? processTextToken(token, options) : document.createTextNode(token.value);
  6299. frag.appendChild(el);
  6300. }
  6301. return makeTextNodeLinkFn(tokens, frag, options);
  6302. }
  6303. /**
  6304. * Linker for an skipped text node.
  6305. *
  6306. * @param {Vue} vm
  6307. * @param {Text} node
  6308. */
  6309. function removeText(vm, node) {
  6310. remove(node);
  6311. }
  6312. /**
  6313. * Process a single text token.
  6314. *
  6315. * @param {Object} token
  6316. * @param {Object} options
  6317. * @return {Node}
  6318. */
  6319. function processTextToken(token, options) {
  6320. var el;
  6321. if (token.oneTime) {
  6322. el = document.createTextNode(token.value);
  6323. } else {
  6324. if (token.html) {
  6325. el = document.createComment('v-html');
  6326. setTokenType('html');
  6327. } else {
  6328. // IE will clean up empty textNodes during
  6329. // frag.cloneNode(true), so we have to give it
  6330. // something here...
  6331. el = document.createTextNode(' ');
  6332. setTokenType('text');
  6333. }
  6334. }
  6335. function setTokenType(type) {
  6336. if (token.descriptor) return;
  6337. var parsed = parseDirective(token.value);
  6338. token.descriptor = {
  6339. name: type,
  6340. def: directives[type],
  6341. expression: parsed.expression,
  6342. filters: parsed.filters
  6343. };
  6344. }
  6345. return el;
  6346. }
  6347. /**
  6348. * Build a function that processes a textNode.
  6349. *
  6350. * @param {Array<Object>} tokens
  6351. * @param {DocumentFragment} frag
  6352. */
  6353. function makeTextNodeLinkFn(tokens, frag) {
  6354. return function textNodeLinkFn(vm, el, host, scope) {
  6355. var fragClone = frag.cloneNode(true);
  6356. var childNodes = toArray(fragClone.childNodes);
  6357. var token, value, node;
  6358. for (var i = 0, l = tokens.length; i < l; i++) {
  6359. token = tokens[i];
  6360. value = token.value;
  6361. if (token.tag) {
  6362. node = childNodes[i];
  6363. if (token.oneTime) {
  6364. value = (scope || vm).$eval(value);
  6365. if (token.html) {
  6366. replace(node, parseTemplate(value, true));
  6367. } else {
  6368. node.data = value;
  6369. }
  6370. } else {
  6371. vm._bindDir(token.descriptor, node, host, scope);
  6372. }
  6373. }
  6374. }
  6375. replace(el, fragClone);
  6376. };
  6377. }
  6378. /**
  6379. * Compile a node list and return a childLinkFn.
  6380. *
  6381. * @param {NodeList} nodeList
  6382. * @param {Object} options
  6383. * @return {Function|undefined}
  6384. */
  6385. function compileNodeList(nodeList, options) {
  6386. var linkFns = [];
  6387. var nodeLinkFn, childLinkFn, node;
  6388. for (var i = 0, l = nodeList.length; i < l; i++) {
  6389. node = nodeList[i];
  6390. nodeLinkFn = compileNode(node, options);
  6391. childLinkFn = !(nodeLinkFn && nodeLinkFn.terminal) && node.tagName !== 'SCRIPT' && node.hasChildNodes() ? compileNodeList(node.childNodes, options) : null;
  6392. linkFns.push(nodeLinkFn, childLinkFn);
  6393. }
  6394. return linkFns.length ? makeChildLinkFn(linkFns) : null;
  6395. }
  6396. /**
  6397. * Make a child link function for a node's childNodes.
  6398. *
  6399. * @param {Array<Function>} linkFns
  6400. * @return {Function} childLinkFn
  6401. */
  6402. function makeChildLinkFn(linkFns) {
  6403. return function childLinkFn(vm, nodes, host, scope, frag) {
  6404. var node, nodeLinkFn, childrenLinkFn;
  6405. for (var i = 0, n = 0, l = linkFns.length; i < l; n++) {
  6406. node = nodes[n];
  6407. nodeLinkFn = linkFns[i++];
  6408. childrenLinkFn = linkFns[i++];
  6409. // cache childNodes before linking parent, fix #657
  6410. var childNodes = toArray(node.childNodes);
  6411. if (nodeLinkFn) {
  6412. nodeLinkFn(vm, node, host, scope, frag);
  6413. }
  6414. if (childrenLinkFn) {
  6415. childrenLinkFn(vm, childNodes, host, scope, frag);
  6416. }
  6417. }
  6418. };
  6419. }
  6420. /**
  6421. * Check for element directives (custom elements that should
  6422. * be resovled as terminal directives).
  6423. *
  6424. * @param {Element} el
  6425. * @param {Object} options
  6426. */
  6427. function checkElementDirectives(el, options) {
  6428. var tag = el.tagName.toLowerCase();
  6429. if (commonTagRE.test(tag)) {
  6430. return;
  6431. }
  6432. var def = resolveAsset(options, 'elementDirectives', tag);
  6433. if (def) {
  6434. return makeTerminalNodeLinkFn(el, tag, '', options, def);
  6435. }
  6436. }
  6437. /**
  6438. * Check if an element is a component. If yes, return
  6439. * a component link function.
  6440. *
  6441. * @param {Element} el
  6442. * @param {Object} options
  6443. * @return {Function|undefined}
  6444. */
  6445. function checkComponent(el, options) {
  6446. var component = checkComponentAttr(el, options);
  6447. if (component) {
  6448. var ref = findRef(el);
  6449. var descriptor = {
  6450. name: 'component',
  6451. ref: ref,
  6452. expression: component.id,
  6453. def: internalDirectives.component,
  6454. modifiers: {
  6455. literal: !component.dynamic
  6456. }
  6457. };
  6458. var componentLinkFn = function componentLinkFn(vm, el, host, scope, frag) {
  6459. if (ref) {
  6460. defineReactive((scope || vm).$refs, ref, null);
  6461. }
  6462. vm._bindDir(descriptor, el, host, scope, frag);
  6463. };
  6464. componentLinkFn.terminal = true;
  6465. return componentLinkFn;
  6466. }
  6467. }
  6468. /**
  6469. * Check an element for terminal directives in fixed order.
  6470. * If it finds one, return a terminal link function.
  6471. *
  6472. * @param {Element} el
  6473. * @param {Array} attrs
  6474. * @param {Object} options
  6475. * @return {Function} terminalLinkFn
  6476. */
  6477. function checkTerminalDirectives(el, attrs, options) {
  6478. // skip v-pre
  6479. if (getAttr(el, 'v-pre') !== null) {
  6480. return skip;
  6481. }
  6482. // skip v-else block, but only if following v-if
  6483. if (el.hasAttribute('v-else')) {
  6484. var prev = el.previousElementSibling;
  6485. if (prev && prev.hasAttribute('v-if')) {
  6486. return skip;
  6487. }
  6488. }
  6489. var attr, name, value, modifiers, matched, dirName, rawName, arg, def, termDef;
  6490. for (var i = 0, j = attrs.length; i < j; i++) {
  6491. attr = attrs[i];
  6492. modifiers = parseModifiers(attr.name);
  6493. name = attr.name.replace(modifierRE, '');
  6494. if (matched = name.match(dirAttrRE)) {
  6495. def = resolveAsset(options, 'directives', matched[1]);
  6496. if (def && def.terminal) {
  6497. if (!termDef || (def.priority || DEFAULT_TERMINAL_PRIORITY) > termDef.priority) {
  6498. termDef = def;
  6499. rawName = attr.name;
  6500. value = attr.value;
  6501. dirName = matched[1];
  6502. arg = matched[2];
  6503. }
  6504. }
  6505. }
  6506. }
  6507. if (termDef) {
  6508. return makeTerminalNodeLinkFn(el, dirName, value, options, termDef, rawName, arg, modifiers);
  6509. }
  6510. }
  6511. function skip() {}
  6512. skip.terminal = true;
  6513. /**
  6514. * Build a node link function for a terminal directive.
  6515. * A terminal link function terminates the current
  6516. * compilation recursion and handles compilation of the
  6517. * subtree in the directive.
  6518. *
  6519. * @param {Element} el
  6520. * @param {String} dirName
  6521. * @param {String} value
  6522. * @param {Object} options
  6523. * @param {Object} def
  6524. * @param {String} [rawName]
  6525. * @param {String} [arg]
  6526. * @param {Object} [modifiers]
  6527. * @return {Function} terminalLinkFn
  6528. */
  6529. function makeTerminalNodeLinkFn(el, dirName, value, options, def, rawName, arg, modifiers) {
  6530. var parsed = parseDirective(value);
  6531. var descriptor = {
  6532. name: dirName,
  6533. arg: arg,
  6534. expression: parsed.expression,
  6535. filters: parsed.filters,
  6536. raw: value,
  6537. attr: rawName,
  6538. modifiers: modifiers,
  6539. def: def
  6540. };
  6541. // check ref for v-for and router-view
  6542. if (dirName === 'for' || dirName === 'router-view') {
  6543. descriptor.ref = findRef(el);
  6544. }
  6545. var fn = function terminalNodeLinkFn(vm, el, host, scope, frag) {
  6546. if (descriptor.ref) {
  6547. defineReactive((scope || vm).$refs, descriptor.ref, null);
  6548. }
  6549. vm._bindDir(descriptor, el, host, scope, frag);
  6550. };
  6551. fn.terminal = true;
  6552. return fn;
  6553. }
  6554. /**
  6555. * Compile the directives on an element and return a linker.
  6556. *
  6557. * @param {Array|NamedNodeMap} attrs
  6558. * @param {Object} options
  6559. * @return {Function}
  6560. */
  6561. function compileDirectives(attrs, options) {
  6562. var i = attrs.length;
  6563. var dirs = [];
  6564. var attr, name, value, rawName, rawValue, dirName, arg, modifiers, dirDef, tokens, matched;
  6565. while (i--) {
  6566. attr = attrs[i];
  6567. name = rawName = attr.name;
  6568. value = rawValue = attr.value;
  6569. tokens = parseText(value);
  6570. // reset arg
  6571. arg = null;
  6572. // check modifiers
  6573. modifiers = parseModifiers(name);
  6574. name = name.replace(modifierRE, '');
  6575. // attribute interpolations
  6576. if (tokens) {
  6577. value = tokensToExp(tokens);
  6578. arg = name;
  6579. pushDir('bind', directives.bind, tokens);
  6580. // warn against mixing mustaches with v-bind
  6581. if ('development' !== 'production') {
  6582. if (name === 'class' && Array.prototype.some.call(attrs, function (attr) {
  6583. return attr.name === ':class' || attr.name === 'v-bind:class';
  6584. })) {
  6585. warn('class="' + rawValue + '": Do not mix mustache interpolation ' + 'and v-bind for "class" on the same element. Use one or the other.', options);
  6586. }
  6587. }
  6588. } else
  6589. // special attribute: transition
  6590. if (transitionRE.test(name)) {
  6591. modifiers.literal = !bindRE.test(name);
  6592. pushDir('transition', internalDirectives.transition);
  6593. } else
  6594. // event handlers
  6595. if (onRE.test(name)) {
  6596. arg = name.replace(onRE, '');
  6597. pushDir('on', directives.on);
  6598. } else
  6599. // attribute bindings
  6600. if (bindRE.test(name)) {
  6601. dirName = name.replace(bindRE, '');
  6602. if (dirName === 'style' || dirName === 'class') {
  6603. pushDir(dirName, internalDirectives[dirName]);
  6604. } else {
  6605. arg = dirName;
  6606. pushDir('bind', directives.bind);
  6607. }
  6608. } else
  6609. // normal directives
  6610. if (matched = name.match(dirAttrRE)) {
  6611. dirName = matched[1];
  6612. arg = matched[2];
  6613. // skip v-else (when used with v-show)
  6614. if (dirName === 'else') {
  6615. continue;
  6616. }
  6617. dirDef = resolveAsset(options, 'directives', dirName, true);
  6618. if (dirDef) {
  6619. pushDir(dirName, dirDef);
  6620. }
  6621. }
  6622. }
  6623. /**
  6624. * Push a directive.
  6625. *
  6626. * @param {String} dirName
  6627. * @param {Object|Function} def
  6628. * @param {Array} [interpTokens]
  6629. */
  6630. function pushDir(dirName, def, interpTokens) {
  6631. var hasOneTimeToken = interpTokens && hasOneTime(interpTokens);
  6632. var parsed = !hasOneTimeToken && parseDirective(value);
  6633. dirs.push({
  6634. name: dirName,
  6635. attr: rawName,
  6636. raw: rawValue,
  6637. def: def,
  6638. arg: arg,
  6639. modifiers: modifiers,
  6640. // conversion from interpolation strings with one-time token
  6641. // to expression is differed until directive bind time so that we
  6642. // have access to the actual vm context for one-time bindings.
  6643. expression: parsed && parsed.expression,
  6644. filters: parsed && parsed.filters,
  6645. interp: interpTokens,
  6646. hasOneTime: hasOneTimeToken
  6647. });
  6648. }
  6649. if (dirs.length) {
  6650. return makeNodeLinkFn(dirs);
  6651. }
  6652. }
  6653. /**
  6654. * Parse modifiers from directive attribute name.
  6655. *
  6656. * @param {String} name
  6657. * @return {Object}
  6658. */
  6659. function parseModifiers(name) {
  6660. var res = Object.create(null);
  6661. var match = name.match(modifierRE);
  6662. if (match) {
  6663. var i = match.length;
  6664. while (i--) {
  6665. res[match[i].slice(1)] = true;
  6666. }
  6667. }
  6668. return res;
  6669. }
  6670. /**
  6671. * Build a link function for all directives on a single node.
  6672. *
  6673. * @param {Array} directives
  6674. * @return {Function} directivesLinkFn
  6675. */
  6676. function makeNodeLinkFn(directives) {
  6677. return function nodeLinkFn(vm, el, host, scope, frag) {
  6678. // reverse apply because it's sorted low to high
  6679. var i = directives.length;
  6680. while (i--) {
  6681. vm._bindDir(directives[i], el, host, scope, frag);
  6682. }
  6683. };
  6684. }
  6685. /**
  6686. * Check if an interpolation string contains one-time tokens.
  6687. *
  6688. * @param {Array} tokens
  6689. * @return {Boolean}
  6690. */
  6691. function hasOneTime(tokens) {
  6692. var i = tokens.length;
  6693. while (i--) {
  6694. if (tokens[i].oneTime) return true;
  6695. }
  6696. }
  6697. var specialCharRE = /[^\w\-:\.]/;
  6698. /**
  6699. * Process an element or a DocumentFragment based on a
  6700. * instance option object. This allows us to transclude
  6701. * a template node/fragment before the instance is created,
  6702. * so the processed fragment can then be cloned and reused
  6703. * in v-for.
  6704. *
  6705. * @param {Element} el
  6706. * @param {Object} options
  6707. * @return {Element|DocumentFragment}
  6708. */
  6709. function transclude(el, options) {
  6710. // extract container attributes to pass them down
  6711. // to compiler, because they need to be compiled in
  6712. // parent scope. we are mutating the options object here
  6713. // assuming the same object will be used for compile
  6714. // right after this.
  6715. if (options) {
  6716. options._containerAttrs = extractAttrs(el);
  6717. }
  6718. // for template tags, what we want is its content as
  6719. // a documentFragment (for fragment instances)
  6720. if (isTemplate(el)) {
  6721. el = parseTemplate(el);
  6722. }
  6723. if (options) {
  6724. if (options._asComponent && !options.template) {
  6725. options.template = '<slot></slot>';
  6726. }
  6727. if (options.template) {
  6728. options._content = extractContent(el);
  6729. el = transcludeTemplate(el, options);
  6730. }
  6731. }
  6732. if (isFragment(el)) {
  6733. // anchors for fragment instance
  6734. // passing in `persist: true` to avoid them being
  6735. // discarded by IE during template cloning
  6736. prepend(createAnchor('v-start', true), el);
  6737. el.appendChild(createAnchor('v-end', true));
  6738. }
  6739. return el;
  6740. }
  6741. /**
  6742. * Process the template option.
  6743. * If the replace option is true this will swap the $el.
  6744. *
  6745. * @param {Element} el
  6746. * @param {Object} options
  6747. * @return {Element|DocumentFragment}
  6748. */
  6749. function transcludeTemplate(el, options) {
  6750. var template = options.template;
  6751. var frag = parseTemplate(template, true);
  6752. if (frag) {
  6753. var replacer = frag.firstChild;
  6754. var tag = replacer.tagName && replacer.tagName.toLowerCase();
  6755. if (options.replace) {
  6756. /* istanbul ignore if */
  6757. if (el === document.body) {
  6758. 'development' !== 'production' && warn('You are mounting an instance with a template to ' + '<body>. This will replace <body> entirely. You ' + 'should probably use `replace: false` here.');
  6759. }
  6760. // there are many cases where the instance must
  6761. // become a fragment instance: basically anything that
  6762. // can create more than 1 root nodes.
  6763. if (
  6764. // multi-children template
  6765. frag.childNodes.length > 1 ||
  6766. // non-element template
  6767. replacer.nodeType !== 1 ||
  6768. // single nested component
  6769. tag === 'component' || resolveAsset(options, 'components', tag) || hasBindAttr(replacer, 'is') ||
  6770. // element directive
  6771. resolveAsset(options, 'elementDirectives', tag) ||
  6772. // for block
  6773. replacer.hasAttribute('v-for') ||
  6774. // if block
  6775. replacer.hasAttribute('v-if')) {
  6776. return frag;
  6777. } else {
  6778. options._replacerAttrs = extractAttrs(replacer);
  6779. mergeAttrs(el, replacer);
  6780. return replacer;
  6781. }
  6782. } else {
  6783. el.appendChild(frag);
  6784. return el;
  6785. }
  6786. } else {
  6787. 'development' !== 'production' && warn('Invalid template option: ' + template);
  6788. }
  6789. }
  6790. /**
  6791. * Helper to extract a component container's attributes
  6792. * into a plain object array.
  6793. *
  6794. * @param {Element} el
  6795. * @return {Array}
  6796. */
  6797. function extractAttrs(el) {
  6798. if (el.nodeType === 1 && el.hasAttributes()) {
  6799. return toArray(el.attributes);
  6800. }
  6801. }
  6802. /**
  6803. * Merge the attributes of two elements, and make sure
  6804. * the class names are merged properly.
  6805. *
  6806. * @param {Element} from
  6807. * @param {Element} to
  6808. */
  6809. function mergeAttrs(from, to) {
  6810. var attrs = from.attributes;
  6811. var i = attrs.length;
  6812. var name, value;
  6813. while (i--) {
  6814. name = attrs[i].name;
  6815. value = attrs[i].value;
  6816. if (!to.hasAttribute(name) && !specialCharRE.test(name)) {
  6817. to.setAttribute(name, value);
  6818. } else if (name === 'class' && !parseText(value)) {
  6819. value.trim().split(/\s+/).forEach(function (cls) {
  6820. addClass(to, cls);
  6821. });
  6822. }
  6823. }
  6824. }
  6825. /**
  6826. * Scan and determine slot content distribution.
  6827. * We do this during transclusion instead at compile time so that
  6828. * the distribution is decoupled from the compilation order of
  6829. * the slots.
  6830. *
  6831. * @param {Element|DocumentFragment} template
  6832. * @param {Element} content
  6833. * @param {Vue} vm
  6834. */
  6835. function resolveSlots(vm, content) {
  6836. if (!content) {
  6837. return;
  6838. }
  6839. var contents = vm._slotContents = Object.create(null);
  6840. var el, name;
  6841. for (var i = 0, l = content.children.length; i < l; i++) {
  6842. el = content.children[i];
  6843. /* eslint-disable no-cond-assign */
  6844. if (name = el.getAttribute('slot')) {
  6845. (contents[name] || (contents[name] = [])).push(el);
  6846. }
  6847. /* eslint-enable no-cond-assign */
  6848. if ('development' !== 'production' && getBindAttr(el, 'slot')) {
  6849. warn('The "slot" attribute must be static.', vm.$parent);
  6850. }
  6851. }
  6852. for (name in contents) {
  6853. contents[name] = extractFragment(contents[name], content);
  6854. }
  6855. if (content.hasChildNodes()) {
  6856. contents['default'] = extractFragment(content.childNodes, content);
  6857. }
  6858. }
  6859. /**
  6860. * Extract qualified content nodes from a node list.
  6861. *
  6862. * @param {NodeList} nodes
  6863. * @return {DocumentFragment}
  6864. */
  6865. function extractFragment(nodes, parent) {
  6866. var frag = document.createDocumentFragment();
  6867. nodes = toArray(nodes);
  6868. for (var i = 0, l = nodes.length; i < l; i++) {
  6869. var node = nodes[i];
  6870. if (isTemplate(node) && !node.hasAttribute('v-if') && !node.hasAttribute('v-for')) {
  6871. parent.removeChild(node);
  6872. node = parseTemplate(node);
  6873. }
  6874. frag.appendChild(node);
  6875. }
  6876. return frag;
  6877. }
  6878. var compiler = Object.freeze({
  6879. compile: compile,
  6880. compileAndLinkProps: compileAndLinkProps,
  6881. compileRoot: compileRoot,
  6882. transclude: transclude,
  6883. resolveSlots: resolveSlots
  6884. });
  6885. function stateMixin (Vue) {
  6886. /**
  6887. * Accessor for `$data` property, since setting $data
  6888. * requires observing the new object and updating
  6889. * proxied properties.
  6890. */
  6891. Object.defineProperty(Vue.prototype, '$data', {
  6892. get: function get() {
  6893. return this._data;
  6894. },
  6895. set: function set(newData) {
  6896. if (newData !== this._data) {
  6897. this._setData(newData);
  6898. }
  6899. }
  6900. });
  6901. /**
  6902. * Setup the scope of an instance, which contains:
  6903. * - observed data
  6904. * - computed properties
  6905. * - user methods
  6906. * - meta properties
  6907. */
  6908. Vue.prototype._initState = function () {
  6909. this._initProps();
  6910. this._initMeta();
  6911. this._initMethods();
  6912. this._initData();
  6913. this._initComputed();
  6914. };
  6915. /**
  6916. * Initialize props.
  6917. */
  6918. Vue.prototype._initProps = function () {
  6919. var options = this.$options;
  6920. var el = options.el;
  6921. var props = options.props;
  6922. if (props && !el) {
  6923. 'development' !== 'production' && warn('Props will not be compiled if no `el` option is ' + 'provided at instantiation.', this);
  6924. }
  6925. // make sure to convert string selectors into element now
  6926. el = options.el = query(el);
  6927. this._propsUnlinkFn = el && el.nodeType === 1 && props
  6928. // props must be linked in proper scope if inside v-for
  6929. ? compileAndLinkProps(this, el, props, this._scope) : null;
  6930. };
  6931. /**
  6932. * Initialize the data.
  6933. */
  6934. Vue.prototype._initData = function () {
  6935. var dataFn = this.$options.data;
  6936. var data = this._data = dataFn ? dataFn() : {};
  6937. if (!isPlainObject(data)) {
  6938. data = {};
  6939. 'development' !== 'production' && warn('data functions should return an object.', this);
  6940. }
  6941. var props = this._props;
  6942. var runtimeData = this._runtimeData ? typeof this._runtimeData === 'function' ? this._runtimeData() : this._runtimeData : null;
  6943. // proxy data on instance
  6944. var keys = Object.keys(data);
  6945. var i, key;
  6946. i = keys.length;
  6947. while (i--) {
  6948. key = keys[i];
  6949. // there are two scenarios where we can proxy a data key:
  6950. // 1. it's not already defined as a prop
  6951. // 2. it's provided via a instantiation option AND there are no
  6952. // template prop present
  6953. if (!props || !hasOwn(props, key) || runtimeData && hasOwn(runtimeData, key) && props[key].raw === null) {
  6954. this._proxy(key);
  6955. } else if ('development' !== 'production') {
  6956. warn('Data field "' + key + '" is already defined ' + 'as a prop. Use prop default value instead.', this);
  6957. }
  6958. }
  6959. // observe data
  6960. observe(data, this);
  6961. };
  6962. /**
  6963. * Swap the instance's $data. Called in $data's setter.
  6964. *
  6965. * @param {Object} newData
  6966. */
  6967. Vue.prototype._setData = function (newData) {
  6968. newData = newData || {};
  6969. var oldData = this._data;
  6970. this._data = newData;
  6971. var keys, key, i;
  6972. // unproxy keys not present in new data
  6973. keys = Object.keys(oldData);
  6974. i = keys.length;
  6975. while (i--) {
  6976. key = keys[i];
  6977. if (!(key in newData)) {
  6978. this._unproxy(key);
  6979. }
  6980. }
  6981. // proxy keys not already proxied,
  6982. // and trigger change for changed values
  6983. keys = Object.keys(newData);
  6984. i = keys.length;
  6985. while (i--) {
  6986. key = keys[i];
  6987. if (!hasOwn(this, key)) {
  6988. // new property
  6989. this._proxy(key);
  6990. }
  6991. }
  6992. oldData.__ob__.removeVm(this);
  6993. observe(newData, this);
  6994. this._digest();
  6995. };
  6996. /**
  6997. * Proxy a property, so that
  6998. * vm.prop === vm._data.prop
  6999. *
  7000. * @param {String} key
  7001. */
  7002. Vue.prototype._proxy = function (key) {
  7003. if (!isReserved(key)) {
  7004. // need to store ref to self here
  7005. // because these getter/setters might
  7006. // be called by child scopes via
  7007. // prototype inheritance.
  7008. var self = this;
  7009. Object.defineProperty(self, key, {
  7010. configurable: true,
  7011. enumerable: true,
  7012. get: function proxyGetter() {
  7013. return self._data[key];
  7014. },
  7015. set: function proxySetter(val) {
  7016. self._data[key] = val;
  7017. }
  7018. });
  7019. }
  7020. };
  7021. /**
  7022. * Unproxy a property.
  7023. *
  7024. * @param {String} key
  7025. */
  7026. Vue.prototype._unproxy = function (key) {
  7027. if (!isReserved(key)) {
  7028. delete this[key];
  7029. }
  7030. };
  7031. /**
  7032. * Force update on every watcher in scope.
  7033. */
  7034. Vue.prototype._digest = function () {
  7035. for (var i = 0, l = this._watchers.length; i < l; i++) {
  7036. this._watchers[i].update(true); // shallow updates
  7037. }
  7038. };
  7039. /**
  7040. * Setup computed properties. They are essentially
  7041. * special getter/setters
  7042. */
  7043. function noop() {}
  7044. Vue.prototype._initComputed = function () {
  7045. var computed = this.$options.computed;
  7046. if (computed) {
  7047. for (var key in computed) {
  7048. var userDef = computed[key];
  7049. var def = {
  7050. enumerable: true,
  7051. configurable: true
  7052. };
  7053. if (typeof userDef === 'function') {
  7054. def.get = makeComputedGetter(userDef, this);
  7055. def.set = noop;
  7056. } else {
  7057. def.get = userDef.get ? userDef.cache !== false ? makeComputedGetter(userDef.get, this) : bind(userDef.get, this) : noop;
  7058. def.set = userDef.set ? bind(userDef.set, this) : noop;
  7059. }
  7060. Object.defineProperty(this, key, def);
  7061. }
  7062. }
  7063. };
  7064. function makeComputedGetter(getter, owner) {
  7065. var watcher = new Watcher(owner, getter, null, {
  7066. lazy: true
  7067. });
  7068. return function computedGetter() {
  7069. if (watcher.dirty) {
  7070. watcher.evaluate();
  7071. }
  7072. if (Dep.target) {
  7073. watcher.depend();
  7074. }
  7075. return watcher.value;
  7076. };
  7077. }
  7078. /**
  7079. * Setup instance methods. Methods must be bound to the
  7080. * instance since they might be passed down as a prop to
  7081. * child components.
  7082. */
  7083. Vue.prototype._initMethods = function () {
  7084. var methods = this.$options.methods;
  7085. if (methods) {
  7086. for (var key in methods) {
  7087. this[key] = bind(methods[key], this);
  7088. }
  7089. }
  7090. };
  7091. /**
  7092. * Initialize meta information like $index, $key & $value.
  7093. */
  7094. Vue.prototype._initMeta = function () {
  7095. var metas = this.$options._meta;
  7096. if (metas) {
  7097. for (var key in metas) {
  7098. defineReactive(this, key, metas[key]);
  7099. }
  7100. }
  7101. };
  7102. }
  7103. var eventRE = /^v-on:|^@/;
  7104. function eventsMixin (Vue) {
  7105. /**
  7106. * Setup the instance's option events & watchers.
  7107. * If the value is a string, we pull it from the
  7108. * instance's methods by name.
  7109. */
  7110. Vue.prototype._initEvents = function () {
  7111. var options = this.$options;
  7112. if (options._asComponent) {
  7113. registerComponentEvents(this, options.el);
  7114. }
  7115. registerCallbacks(this, '$on', options.events);
  7116. registerCallbacks(this, '$watch', options.watch);
  7117. };
  7118. /**
  7119. * Register v-on events on a child component
  7120. *
  7121. * @param {Vue} vm
  7122. * @param {Element} el
  7123. */
  7124. function registerComponentEvents(vm, el) {
  7125. var attrs = el.attributes;
  7126. var name, handler;
  7127. for (var i = 0, l = attrs.length; i < l; i++) {
  7128. name = attrs[i].name;
  7129. if (eventRE.test(name)) {
  7130. name = name.replace(eventRE, '');
  7131. handler = (vm._scope || vm._context).$eval(attrs[i].value, true);
  7132. if (typeof handler === 'function') {
  7133. handler._fromParent = true;
  7134. vm.$on(name.replace(eventRE), handler);
  7135. } else if ('development' !== 'production') {
  7136. warn('v-on:' + name + '="' + attrs[i].value + '" ' + 'expects a function value, got ' + handler, vm);
  7137. }
  7138. }
  7139. }
  7140. }
  7141. /**
  7142. * Register callbacks for option events and watchers.
  7143. *
  7144. * @param {Vue} vm
  7145. * @param {String} action
  7146. * @param {Object} hash
  7147. */
  7148. function registerCallbacks(vm, action, hash) {
  7149. if (!hash) return;
  7150. var handlers, key, i, j;
  7151. for (key in hash) {
  7152. handlers = hash[key];
  7153. if (isArray(handlers)) {
  7154. for (i = 0, j = handlers.length; i < j; i++) {
  7155. register(vm, action, key, handlers[i]);
  7156. }
  7157. } else {
  7158. register(vm, action, key, handlers);
  7159. }
  7160. }
  7161. }
  7162. /**
  7163. * Helper to register an event/watch callback.
  7164. *
  7165. * @param {Vue} vm
  7166. * @param {String} action
  7167. * @param {String} key
  7168. * @param {Function|String|Object} handler
  7169. * @param {Object} [options]
  7170. */
  7171. function register(vm, action, key, handler, options) {
  7172. var type = typeof handler;
  7173. if (type === 'function') {
  7174. vm[action](key, handler, options);
  7175. } else if (type === 'string') {
  7176. var methods = vm.$options.methods;
  7177. var method = methods && methods[handler];
  7178. if (method) {
  7179. vm[action](key, method, options);
  7180. } else {
  7181. 'development' !== 'production' && warn('Unknown method: "' + handler + '" when ' + 'registering callback for ' + action + ': "' + key + '".', vm);
  7182. }
  7183. } else if (handler && type === 'object') {
  7184. register(vm, action, key, handler.handler, handler);
  7185. }
  7186. }
  7187. /**
  7188. * Setup recursive attached/detached calls
  7189. */
  7190. Vue.prototype._initDOMHooks = function () {
  7191. this.$on('hook:attached', onAttached);
  7192. this.$on('hook:detached', onDetached);
  7193. };
  7194. /**
  7195. * Callback to recursively call attached hook on children
  7196. */
  7197. function onAttached() {
  7198. if (!this._isAttached) {
  7199. this._isAttached = true;
  7200. this.$children.forEach(callAttach);
  7201. }
  7202. }
  7203. /**
  7204. * Iterator to call attached hook
  7205. *
  7206. * @param {Vue} child
  7207. */
  7208. function callAttach(child) {
  7209. if (!child._isAttached && inDoc(child.$el)) {
  7210. child._callHook('attached');
  7211. }
  7212. }
  7213. /**
  7214. * Callback to recursively call detached hook on children
  7215. */
  7216. function onDetached() {
  7217. if (this._isAttached) {
  7218. this._isAttached = false;
  7219. this.$children.forEach(callDetach);
  7220. }
  7221. }
  7222. /**
  7223. * Iterator to call detached hook
  7224. *
  7225. * @param {Vue} child
  7226. */
  7227. function callDetach(child) {
  7228. if (child._isAttached && !inDoc(child.$el)) {
  7229. child._callHook('detached');
  7230. }
  7231. }
  7232. /**
  7233. * Trigger all handlers for a hook
  7234. *
  7235. * @param {String} hook
  7236. */
  7237. Vue.prototype._callHook = function (hook) {
  7238. this.$emit('pre-hook:' + hook);
  7239. var handlers = this.$options[hook];
  7240. if (handlers) {
  7241. for (var i = 0, j = handlers.length; i < j; i++) {
  7242. handlers[i].call(this);
  7243. }
  7244. }
  7245. this.$emit('hook:' + hook);
  7246. };
  7247. }
  7248. function noop() {}
  7249. /**
  7250. * A directive links a DOM element with a piece of data,
  7251. * which is the result of evaluating an expression.
  7252. * It registers a watcher with the expression and calls
  7253. * the DOM update function when a change is triggered.
  7254. *
  7255. * @param {Object} descriptor
  7256. * - {String} name
  7257. * - {Object} def
  7258. * - {String} expression
  7259. * - {Array<Object>} [filters]
  7260. * - {Object} [modifiers]
  7261. * - {Boolean} literal
  7262. * - {String} attr
  7263. * - {String} arg
  7264. * - {String} raw
  7265. * - {String} [ref]
  7266. * - {Array<Object>} [interp]
  7267. * - {Boolean} [hasOneTime]
  7268. * @param {Vue} vm
  7269. * @param {Node} el
  7270. * @param {Vue} [host] - transclusion host component
  7271. * @param {Object} [scope] - v-for scope
  7272. * @param {Fragment} [frag] - owner fragment
  7273. * @constructor
  7274. */
  7275. function Directive(descriptor, vm, el, host, scope, frag) {
  7276. this.vm = vm;
  7277. this.el = el;
  7278. // copy descriptor properties
  7279. this.descriptor = descriptor;
  7280. this.name = descriptor.name;
  7281. this.expression = descriptor.expression;
  7282. this.arg = descriptor.arg;
  7283. this.modifiers = descriptor.modifiers;
  7284. this.filters = descriptor.filters;
  7285. this.literal = this.modifiers && this.modifiers.literal;
  7286. // private
  7287. this._locked = false;
  7288. this._bound = false;
  7289. this._listeners = null;
  7290. // link context
  7291. this._host = host;
  7292. this._scope = scope;
  7293. this._frag = frag;
  7294. // store directives on node in dev mode
  7295. if ('development' !== 'production' && this.el) {
  7296. this.el._vue_directives = this.el._vue_directives || [];
  7297. this.el._vue_directives.push(this);
  7298. }
  7299. }
  7300. /**
  7301. * Initialize the directive, mixin definition properties,
  7302. * setup the watcher, call definition bind() and update()
  7303. * if present.
  7304. */
  7305. Directive.prototype._bind = function () {
  7306. var name = this.name;
  7307. var descriptor = this.descriptor;
  7308. // remove attribute
  7309. if ((name !== 'cloak' || this.vm._isCompiled) && this.el && this.el.removeAttribute) {
  7310. var attr = descriptor.attr || 'v-' + name;
  7311. this.el.removeAttribute(attr);
  7312. }
  7313. // copy def properties
  7314. var def = descriptor.def;
  7315. if (typeof def === 'function') {
  7316. this.update = def;
  7317. } else {
  7318. extend(this, def);
  7319. }
  7320. // setup directive params
  7321. this._setupParams();
  7322. // initial bind
  7323. if (this.bind) {
  7324. this.bind();
  7325. }
  7326. this._bound = true;
  7327. if (this.literal) {
  7328. this.update && this.update(descriptor.raw);
  7329. } else if ((this.expression || this.modifiers) && (this.update || this.twoWay) && !this._checkStatement()) {
  7330. // wrapped updater for context
  7331. var dir = this;
  7332. if (this.update) {
  7333. this._update = function (val, oldVal) {
  7334. if (!dir._locked) {
  7335. dir.update(val, oldVal);
  7336. }
  7337. };
  7338. } else {
  7339. this._update = noop;
  7340. }
  7341. var preProcess = this._preProcess ? bind(this._preProcess, this) : null;
  7342. var postProcess = this._postProcess ? bind(this._postProcess, this) : null;
  7343. var watcher = this._watcher = new Watcher(this.vm, this.expression, this._update, // callback
  7344. {
  7345. filters: this.filters,
  7346. twoWay: this.twoWay,
  7347. deep: this.deep,
  7348. preProcess: preProcess,
  7349. postProcess: postProcess,
  7350. scope: this._scope
  7351. });
  7352. // v-model with inital inline value need to sync back to
  7353. // model instead of update to DOM on init. They would
  7354. // set the afterBind hook to indicate that.
  7355. if (this.afterBind) {
  7356. this.afterBind();
  7357. } else if (this.update) {
  7358. this.update(watcher.value);
  7359. }
  7360. }
  7361. };
  7362. /**
  7363. * Setup all param attributes, e.g. track-by,
  7364. * transition-mode, etc...
  7365. */
  7366. Directive.prototype._setupParams = function () {
  7367. if (!this.params) {
  7368. return;
  7369. }
  7370. var params = this.params;
  7371. // swap the params array with a fresh object.
  7372. this.params = Object.create(null);
  7373. var i = params.length;
  7374. var key, val, mappedKey;
  7375. while (i--) {
  7376. key = hyphenate(params[i]);
  7377. mappedKey = camelize(key);
  7378. val = getBindAttr(this.el, key);
  7379. if (val != null) {
  7380. // dynamic
  7381. this._setupParamWatcher(mappedKey, val);
  7382. } else {
  7383. // static
  7384. val = getAttr(this.el, key);
  7385. if (val != null) {
  7386. this.params[mappedKey] = val === '' ? true : val;
  7387. }
  7388. }
  7389. }
  7390. };
  7391. /**
  7392. * Setup a watcher for a dynamic param.
  7393. *
  7394. * @param {String} key
  7395. * @param {String} expression
  7396. */
  7397. Directive.prototype._setupParamWatcher = function (key, expression) {
  7398. var self = this;
  7399. var called = false;
  7400. var unwatch = (this._scope || this.vm).$watch(expression, function (val, oldVal) {
  7401. self.params[key] = val;
  7402. // since we are in immediate mode,
  7403. // only call the param change callbacks if this is not the first update.
  7404. if (called) {
  7405. var cb = self.paramWatchers && self.paramWatchers[key];
  7406. if (cb) {
  7407. cb.call(self, val, oldVal);
  7408. }
  7409. } else {
  7410. called = true;
  7411. }
  7412. }, {
  7413. immediate: true,
  7414. user: false
  7415. });(this._paramUnwatchFns || (this._paramUnwatchFns = [])).push(unwatch);
  7416. };
  7417. /**
  7418. * Check if the directive is a function caller
  7419. * and if the expression is a callable one. If both true,
  7420. * we wrap up the expression and use it as the event
  7421. * handler.
  7422. *
  7423. * e.g. on-click="a++"
  7424. *
  7425. * @return {Boolean}
  7426. */
  7427. Directive.prototype._checkStatement = function () {
  7428. var expression = this.expression;
  7429. if (expression && this.acceptStatement && !isSimplePath(expression)) {
  7430. var fn = parseExpression(expression).get;
  7431. var scope = this._scope || this.vm;
  7432. var handler = function handler(e) {
  7433. scope.$event = e;
  7434. fn.call(scope, scope);
  7435. scope.$event = null;
  7436. };
  7437. if (this.filters) {
  7438. handler = scope._applyFilters(handler, null, this.filters);
  7439. }
  7440. this.update(handler);
  7441. return true;
  7442. }
  7443. };
  7444. /**
  7445. * Set the corresponding value with the setter.
  7446. * This should only be used in two-way directives
  7447. * e.g. v-model.
  7448. *
  7449. * @param {*} value
  7450. * @public
  7451. */
  7452. Directive.prototype.set = function (value) {
  7453. /* istanbul ignore else */
  7454. if (this.twoWay) {
  7455. this._withLock(function () {
  7456. this._watcher.set(value);
  7457. });
  7458. } else if ('development' !== 'production') {
  7459. warn('Directive.set() can only be used inside twoWay' + 'directives.');
  7460. }
  7461. };
  7462. /**
  7463. * Execute a function while preventing that function from
  7464. * triggering updates on this directive instance.
  7465. *
  7466. * @param {Function} fn
  7467. */
  7468. Directive.prototype._withLock = function (fn) {
  7469. var self = this;
  7470. self._locked = true;
  7471. fn.call(self);
  7472. nextTick(function () {
  7473. self._locked = false;
  7474. });
  7475. };
  7476. /**
  7477. * Convenience method that attaches a DOM event listener
  7478. * to the directive element and autometically tears it down
  7479. * during unbind.
  7480. *
  7481. * @param {String} event
  7482. * @param {Function} handler
  7483. * @param {Boolean} [useCapture]
  7484. */
  7485. Directive.prototype.on = function (event, handler, useCapture) {
  7486. on(this.el, event, handler, useCapture);(this._listeners || (this._listeners = [])).push([event, handler]);
  7487. };
  7488. /**
  7489. * Teardown the watcher and call unbind.
  7490. */
  7491. Directive.prototype._teardown = function () {
  7492. if (this._bound) {
  7493. this._bound = false;
  7494. if (this.unbind) {
  7495. this.unbind();
  7496. }
  7497. if (this._watcher) {
  7498. this._watcher.teardown();
  7499. }
  7500. var listeners = this._listeners;
  7501. var i;
  7502. if (listeners) {
  7503. i = listeners.length;
  7504. while (i--) {
  7505. off(this.el, listeners[i][0], listeners[i][1]);
  7506. }
  7507. }
  7508. var unwatchFns = this._paramUnwatchFns;
  7509. if (unwatchFns) {
  7510. i = unwatchFns.length;
  7511. while (i--) {
  7512. unwatchFns[i]();
  7513. }
  7514. }
  7515. if ('development' !== 'production' && this.el) {
  7516. this.el._vue_directives.$remove(this);
  7517. }
  7518. this.vm = this.el = this._watcher = this._listeners = null;
  7519. }
  7520. };
  7521. function lifecycleMixin (Vue) {
  7522. /**
  7523. * Update v-ref for component.
  7524. *
  7525. * @param {Boolean} remove
  7526. */
  7527. Vue.prototype._updateRef = function (remove) {
  7528. var ref = this.$options._ref;
  7529. if (ref) {
  7530. var refs = (this._scope || this._context).$refs;
  7531. if (remove) {
  7532. if (refs[ref] === this) {
  7533. refs[ref] = null;
  7534. }
  7535. } else {
  7536. refs[ref] = this;
  7537. }
  7538. }
  7539. };
  7540. /**
  7541. * Transclude, compile and link element.
  7542. *
  7543. * If a pre-compiled linker is available, that means the
  7544. * passed in element will be pre-transcluded and compiled
  7545. * as well - all we need to do is to call the linker.
  7546. *
  7547. * Otherwise we need to call transclude/compile/link here.
  7548. *
  7549. * @param {Element} el
  7550. */
  7551. Vue.prototype._compile = function (el) {
  7552. var options = this.$options;
  7553. // transclude and init element
  7554. // transclude can potentially replace original
  7555. // so we need to keep reference; this step also injects
  7556. // the template and caches the original attributes
  7557. // on the container node and replacer node.
  7558. var original = el;
  7559. el = transclude(el, options);
  7560. this._initElement(el);
  7561. // handle v-pre on root node (#2026)
  7562. if (el.nodeType === 1 && getAttr(el, 'v-pre') !== null) {
  7563. return;
  7564. }
  7565. // root is always compiled per-instance, because
  7566. // container attrs and props can be different every time.
  7567. var contextOptions = this._context && this._context.$options;
  7568. var rootLinker = compileRoot(el, options, contextOptions);
  7569. // resolve slot distribution
  7570. resolveSlots(this, options._content);
  7571. // compile and link the rest
  7572. var contentLinkFn;
  7573. var ctor = this.constructor;
  7574. // component compilation can be cached
  7575. // as long as it's not using inline-template
  7576. if (options._linkerCachable) {
  7577. contentLinkFn = ctor.linker;
  7578. if (!contentLinkFn) {
  7579. contentLinkFn = ctor.linker = compile(el, options);
  7580. }
  7581. }
  7582. // link phase
  7583. // make sure to link root with prop scope!
  7584. var rootUnlinkFn = rootLinker(this, el, this._scope);
  7585. var contentUnlinkFn = contentLinkFn ? contentLinkFn(this, el) : compile(el, options)(this, el);
  7586. // register composite unlink function
  7587. // to be called during instance destruction
  7588. this._unlinkFn = function () {
  7589. rootUnlinkFn();
  7590. // passing destroying: true to avoid searching and
  7591. // splicing the directives
  7592. contentUnlinkFn(true);
  7593. };
  7594. // finally replace original
  7595. if (options.replace) {
  7596. replace(original, el);
  7597. }
  7598. this._isCompiled = true;
  7599. this._callHook('compiled');
  7600. };
  7601. /**
  7602. * Initialize instance element. Called in the public
  7603. * $mount() method.
  7604. *
  7605. * @param {Element} el
  7606. */
  7607. Vue.prototype._initElement = function (el) {
  7608. if (isFragment(el)) {
  7609. this._isFragment = true;
  7610. this.$el = this._fragmentStart = el.firstChild;
  7611. this._fragmentEnd = el.lastChild;
  7612. // set persisted text anchors to empty
  7613. if (this._fragmentStart.nodeType === 3) {
  7614. this._fragmentStart.data = this._fragmentEnd.data = '';
  7615. }
  7616. this._fragment = el;
  7617. } else {
  7618. this.$el = el;
  7619. }
  7620. this.$el.__vue__ = this;
  7621. this._callHook('beforeCompile');
  7622. };
  7623. /**
  7624. * Create and bind a directive to an element.
  7625. *
  7626. * @param {Object} descriptor - parsed directive descriptor
  7627. * @param {Node} node - target node
  7628. * @param {Vue} [host] - transclusion host component
  7629. * @param {Object} [scope] - v-for scope
  7630. * @param {Fragment} [frag] - owner fragment
  7631. */
  7632. Vue.prototype._bindDir = function (descriptor, node, host, scope, frag) {
  7633. this._directives.push(new Directive(descriptor, this, node, host, scope, frag));
  7634. };
  7635. /**
  7636. * Teardown an instance, unobserves the data, unbind all the
  7637. * directives, turn off all the event listeners, etc.
  7638. *
  7639. * @param {Boolean} remove - whether to remove the DOM node.
  7640. * @param {Boolean} deferCleanup - if true, defer cleanup to
  7641. * be called later
  7642. */
  7643. Vue.prototype._destroy = function (remove, deferCleanup) {
  7644. if (this._isBeingDestroyed) {
  7645. if (!deferCleanup) {
  7646. this._cleanup();
  7647. }
  7648. return;
  7649. }
  7650. var destroyReady;
  7651. var pendingRemoval;
  7652. var self = this;
  7653. // Cleanup should be called either synchronously or asynchronoysly as
  7654. // callback of this.$remove(), or if remove and deferCleanup are false.
  7655. // In any case it should be called after all other removing, unbinding and
  7656. // turning of is done
  7657. var cleanupIfPossible = function cleanupIfPossible() {
  7658. if (destroyReady && !pendingRemoval && !deferCleanup) {
  7659. self._cleanup();
  7660. }
  7661. };
  7662. // remove DOM element
  7663. if (remove && this.$el) {
  7664. pendingRemoval = true;
  7665. this.$remove(function () {
  7666. pendingRemoval = false;
  7667. cleanupIfPossible();
  7668. });
  7669. }
  7670. this._callHook('beforeDestroy');
  7671. this._isBeingDestroyed = true;
  7672. var i;
  7673. // remove self from parent. only necessary
  7674. // if parent is not being destroyed as well.
  7675. var parent = this.$parent;
  7676. if (parent && !parent._isBeingDestroyed) {
  7677. parent.$children.$remove(this);
  7678. // unregister ref (remove: true)
  7679. this._updateRef(true);
  7680. }
  7681. // destroy all children.
  7682. i = this.$children.length;
  7683. while (i--) {
  7684. this.$children[i].$destroy();
  7685. }
  7686. // teardown props
  7687. if (this._propsUnlinkFn) {
  7688. this._propsUnlinkFn();
  7689. }
  7690. // teardown all directives. this also tearsdown all
  7691. // directive-owned watchers.
  7692. if (this._unlinkFn) {
  7693. this._unlinkFn();
  7694. }
  7695. i = this._watchers.length;
  7696. while (i--) {
  7697. this._watchers[i].teardown();
  7698. }
  7699. // remove reference to self on $el
  7700. if (this.$el) {
  7701. this.$el.__vue__ = null;
  7702. }
  7703. destroyReady = true;
  7704. cleanupIfPossible();
  7705. };
  7706. /**
  7707. * Clean up to ensure garbage collection.
  7708. * This is called after the leave transition if there
  7709. * is any.
  7710. */
  7711. Vue.prototype._cleanup = function () {
  7712. if (this._isDestroyed) {
  7713. return;
  7714. }
  7715. // remove self from owner fragment
  7716. // do it in cleanup so that we can call $destroy with
  7717. // defer right when a fragment is about to be removed.
  7718. if (this._frag) {
  7719. this._frag.children.$remove(this);
  7720. }
  7721. // remove reference from data ob
  7722. // frozen object may not have observer.
  7723. if (this._data.__ob__) {
  7724. this._data.__ob__.removeVm(this);
  7725. }
  7726. // Clean up references to private properties and other
  7727. // instances. preserve reference to _data so that proxy
  7728. // accessors still work. The only potential side effect
  7729. // here is that mutating the instance after it's destroyed
  7730. // may affect the state of other components that are still
  7731. // observing the same object, but that seems to be a
  7732. // reasonable responsibility for the user rather than
  7733. // always throwing an error on them.
  7734. this.$el = this.$parent = this.$root = this.$children = this._watchers = this._context = this._scope = this._directives = null;
  7735. // call the last hook...
  7736. this._isDestroyed = true;
  7737. this._callHook('destroyed');
  7738. // turn off all instance listeners.
  7739. this.$off();
  7740. };
  7741. }
  7742. function miscMixin (Vue) {
  7743. /**
  7744. * Apply a list of filter (descriptors) to a value.
  7745. * Using plain for loops here because this will be called in
  7746. * the getter of any watcher with filters so it is very
  7747. * performance sensitive.
  7748. *
  7749. * @param {*} value
  7750. * @param {*} [oldValue]
  7751. * @param {Array} filters
  7752. * @param {Boolean} write
  7753. * @return {*}
  7754. */
  7755. Vue.prototype._applyFilters = function (value, oldValue, filters, write) {
  7756. var filter, fn, args, arg, offset, i, l, j, k;
  7757. for (i = 0, l = filters.length; i < l; i++) {
  7758. filter = filters[write ? l - i - 1 : i];
  7759. fn = resolveAsset(this.$options, 'filters', filter.name, true);
  7760. if (!fn) continue;
  7761. fn = write ? fn.write : fn.read || fn;
  7762. if (typeof fn !== 'function') continue;
  7763. args = write ? [value, oldValue] : [value];
  7764. offset = write ? 2 : 1;
  7765. if (filter.args) {
  7766. for (j = 0, k = filter.args.length; j < k; j++) {
  7767. arg = filter.args[j];
  7768. args[j + offset] = arg.dynamic ? this.$get(arg.value) : arg.value;
  7769. }
  7770. }
  7771. value = fn.apply(this, args);
  7772. }
  7773. return value;
  7774. };
  7775. /**
  7776. * Resolve a component, depending on whether the component
  7777. * is defined normally or using an async factory function.
  7778. * Resolves synchronously if already resolved, otherwise
  7779. * resolves asynchronously and caches the resolved
  7780. * constructor on the factory.
  7781. *
  7782. * @param {String|Function} value
  7783. * @param {Function} cb
  7784. */
  7785. Vue.prototype._resolveComponent = function (value, cb) {
  7786. var factory;
  7787. if (typeof value === 'function') {
  7788. factory = value;
  7789. } else {
  7790. factory = resolveAsset(this.$options, 'components', value, true);
  7791. }
  7792. if (!factory) {
  7793. return;
  7794. }
  7795. // async component factory
  7796. if (!factory.options) {
  7797. if (factory.resolved) {
  7798. // cached
  7799. cb(factory.resolved);
  7800. } else if (factory.requested) {
  7801. // pool callbacks
  7802. factory.pendingCallbacks.push(cb);
  7803. } else {
  7804. factory.requested = true;
  7805. var cbs = factory.pendingCallbacks = [cb];
  7806. factory.call(this, function resolve(res) {
  7807. if (isPlainObject(res)) {
  7808. res = Vue.extend(res);
  7809. }
  7810. // cache resolved
  7811. factory.resolved = res;
  7812. // invoke callbacks
  7813. for (var i = 0, l = cbs.length; i < l; i++) {
  7814. cbs[i](res);
  7815. }
  7816. }, function reject(reason) {
  7817. 'development' !== 'production' && warn('Failed to resolve async component' + (typeof value === 'string' ? ': ' + value : '') + '. ' + (reason ? '\nReason: ' + reason : ''));
  7818. });
  7819. }
  7820. } else {
  7821. // normal component
  7822. cb(factory);
  7823. }
  7824. };
  7825. }
  7826. var filterRE$1 = /[^|]\|[^|]/;
  7827. function dataAPI (Vue) {
  7828. /**
  7829. * Get the value from an expression on this vm.
  7830. *
  7831. * @param {String} exp
  7832. * @param {Boolean} [asStatement]
  7833. * @return {*}
  7834. */
  7835. Vue.prototype.$get = function (exp, asStatement) {
  7836. var res = parseExpression(exp);
  7837. if (res) {
  7838. if (asStatement && !isSimplePath(exp)) {
  7839. var self = this;
  7840. return function statementHandler() {
  7841. self.$arguments = toArray(arguments);
  7842. var result = res.get.call(self, self);
  7843. self.$arguments = null;
  7844. return result;
  7845. };
  7846. } else {
  7847. try {
  7848. return res.get.call(this, this);
  7849. } catch (e) {}
  7850. }
  7851. }
  7852. };
  7853. /**
  7854. * Set the value from an expression on this vm.
  7855. * The expression must be a valid left-hand
  7856. * expression in an assignment.
  7857. *
  7858. * @param {String} exp
  7859. * @param {*} val
  7860. */
  7861. Vue.prototype.$set = function (exp, val) {
  7862. var res = parseExpression(exp, true);
  7863. if (res && res.set) {
  7864. res.set.call(this, this, val);
  7865. }
  7866. };
  7867. /**
  7868. * Delete a property on the VM
  7869. *
  7870. * @param {String} key
  7871. */
  7872. Vue.prototype.$delete = function (key) {
  7873. del(this._data, key);
  7874. };
  7875. /**
  7876. * Watch an expression, trigger callback when its
  7877. * value changes.
  7878. *
  7879. * @param {String|Function} expOrFn
  7880. * @param {Function} cb
  7881. * @param {Object} [options]
  7882. * - {Boolean} deep
  7883. * - {Boolean} immediate
  7884. * @return {Function} - unwatchFn
  7885. */
  7886. Vue.prototype.$watch = function (expOrFn, cb, options) {
  7887. var vm = this;
  7888. var parsed;
  7889. if (typeof expOrFn === 'string') {
  7890. parsed = parseDirective(expOrFn);
  7891. expOrFn = parsed.expression;
  7892. }
  7893. var watcher = new Watcher(vm, expOrFn, cb, {
  7894. deep: options && options.deep,
  7895. sync: options && options.sync,
  7896. filters: parsed && parsed.filters,
  7897. user: !options || options.user !== false
  7898. });
  7899. if (options && options.immediate) {
  7900. cb.call(vm, watcher.value);
  7901. }
  7902. return function unwatchFn() {
  7903. watcher.teardown();
  7904. };
  7905. };
  7906. /**
  7907. * Evaluate a text directive, including filters.
  7908. *
  7909. * @param {String} text
  7910. * @param {Boolean} [asStatement]
  7911. * @return {String}
  7912. */
  7913. Vue.prototype.$eval = function (text, asStatement) {
  7914. // check for filters.
  7915. if (filterRE$1.test(text)) {
  7916. var dir = parseDirective(text);
  7917. // the filter regex check might give false positive
  7918. // for pipes inside strings, so it's possible that
  7919. // we don't get any filters here
  7920. var val = this.$get(dir.expression, asStatement);
  7921. return dir.filters ? this._applyFilters(val, null, dir.filters) : val;
  7922. } else {
  7923. // no filter
  7924. return this.$get(text, asStatement);
  7925. }
  7926. };
  7927. /**
  7928. * Interpolate a piece of template text.
  7929. *
  7930. * @param {String} text
  7931. * @return {String}
  7932. */
  7933. Vue.prototype.$interpolate = function (text) {
  7934. var tokens = parseText(text);
  7935. var vm = this;
  7936. if (tokens) {
  7937. if (tokens.length === 1) {
  7938. return vm.$eval(tokens[0].value) + '';
  7939. } else {
  7940. return tokens.map(function (token) {
  7941. return token.tag ? vm.$eval(token.value) : token.value;
  7942. }).join('');
  7943. }
  7944. } else {
  7945. return text;
  7946. }
  7947. };
  7948. /**
  7949. * Log instance data as a plain JS object
  7950. * so that it is easier to inspect in console.
  7951. * This method assumes console is available.
  7952. *
  7953. * @param {String} [path]
  7954. */
  7955. Vue.prototype.$log = function (path) {
  7956. var data = path ? getPath(this._data, path) : this._data;
  7957. if (data) {
  7958. data = clean(data);
  7959. }
  7960. // include computed fields
  7961. if (!path) {
  7962. var key;
  7963. for (key in this.$options.computed) {
  7964. data[key] = clean(this[key]);
  7965. }
  7966. if (this._props) {
  7967. for (key in this._props) {
  7968. data[key] = clean(this[key]);
  7969. }
  7970. }
  7971. }
  7972. console.log(data);
  7973. };
  7974. /**
  7975. * "clean" a getter/setter converted object into a plain
  7976. * object copy.
  7977. *
  7978. * @param {Object} - obj
  7979. * @return {Object}
  7980. */
  7981. function clean(obj) {
  7982. return JSON.parse(JSON.stringify(obj));
  7983. }
  7984. }
  7985. function domAPI (Vue) {
  7986. /**
  7987. * Convenience on-instance nextTick. The callback is
  7988. * auto-bound to the instance, and this avoids component
  7989. * modules having to rely on the global Vue.
  7990. *
  7991. * @param {Function} fn
  7992. */
  7993. Vue.prototype.$nextTick = function (fn) {
  7994. nextTick(fn, this);
  7995. };
  7996. /**
  7997. * Append instance to target
  7998. *
  7999. * @param {Node} target
  8000. * @param {Function} [cb]
  8001. * @param {Boolean} [withTransition] - defaults to true
  8002. */
  8003. Vue.prototype.$appendTo = function (target, cb, withTransition) {
  8004. return insert(this, target, cb, withTransition, append, appendWithTransition);
  8005. };
  8006. /**
  8007. * Prepend instance to target
  8008. *
  8009. * @param {Node} target
  8010. * @param {Function} [cb]
  8011. * @param {Boolean} [withTransition] - defaults to true
  8012. */
  8013. Vue.prototype.$prependTo = function (target, cb, withTransition) {
  8014. target = query(target);
  8015. if (target.hasChildNodes()) {
  8016. this.$before(target.firstChild, cb, withTransition);
  8017. } else {
  8018. this.$appendTo(target, cb, withTransition);
  8019. }
  8020. return this;
  8021. };
  8022. /**
  8023. * Insert instance before target
  8024. *
  8025. * @param {Node} target
  8026. * @param {Function} [cb]
  8027. * @param {Boolean} [withTransition] - defaults to true
  8028. */
  8029. Vue.prototype.$before = function (target, cb, withTransition) {
  8030. return insert(this, target, cb, withTransition, beforeWithCb, beforeWithTransition);
  8031. };
  8032. /**
  8033. * Insert instance after target
  8034. *
  8035. * @param {Node} target
  8036. * @param {Function} [cb]
  8037. * @param {Boolean} [withTransition] - defaults to true
  8038. */
  8039. Vue.prototype.$after = function (target, cb, withTransition) {
  8040. target = query(target);
  8041. if (target.nextSibling) {
  8042. this.$before(target.nextSibling, cb, withTransition);
  8043. } else {
  8044. this.$appendTo(target.parentNode, cb, withTransition);
  8045. }
  8046. return this;
  8047. };
  8048. /**
  8049. * Remove instance from DOM
  8050. *
  8051. * @param {Function} [cb]
  8052. * @param {Boolean} [withTransition] - defaults to true
  8053. */
  8054. Vue.prototype.$remove = function (cb, withTransition) {
  8055. if (!this.$el.parentNode) {
  8056. return cb && cb();
  8057. }
  8058. var inDocument = this._isAttached && inDoc(this.$el);
  8059. // if we are not in document, no need to check
  8060. // for transitions
  8061. if (!inDocument) withTransition = false;
  8062. var self = this;
  8063. var realCb = function realCb() {
  8064. if (inDocument) self._callHook('detached');
  8065. if (cb) cb();
  8066. };
  8067. if (this._isFragment) {
  8068. removeNodeRange(this._fragmentStart, this._fragmentEnd, this, this._fragment, realCb);
  8069. } else {
  8070. var op = withTransition === false ? removeWithCb : removeWithTransition;
  8071. op(this.$el, this, realCb);
  8072. }
  8073. return this;
  8074. };
  8075. /**
  8076. * Shared DOM insertion function.
  8077. *
  8078. * @param {Vue} vm
  8079. * @param {Element} target
  8080. * @param {Function} [cb]
  8081. * @param {Boolean} [withTransition]
  8082. * @param {Function} op1 - op for non-transition insert
  8083. * @param {Function} op2 - op for transition insert
  8084. * @return vm
  8085. */
  8086. function insert(vm, target, cb, withTransition, op1, op2) {
  8087. target = query(target);
  8088. var targetIsDetached = !inDoc(target);
  8089. var op = withTransition === false || targetIsDetached ? op1 : op2;
  8090. var shouldCallHook = !targetIsDetached && !vm._isAttached && !inDoc(vm.$el);
  8091. if (vm._isFragment) {
  8092. mapNodeRange(vm._fragmentStart, vm._fragmentEnd, function (node) {
  8093. op(node, target, vm);
  8094. });
  8095. cb && cb();
  8096. } else {
  8097. op(vm.$el, target, vm, cb);
  8098. }
  8099. if (shouldCallHook) {
  8100. vm._callHook('attached');
  8101. }
  8102. return vm;
  8103. }
  8104. /**
  8105. * Check for selectors
  8106. *
  8107. * @param {String|Element} el
  8108. */
  8109. function query(el) {
  8110. return typeof el === 'string' ? document.querySelector(el) : el;
  8111. }
  8112. /**
  8113. * Append operation that takes a callback.
  8114. *
  8115. * @param {Node} el
  8116. * @param {Node} target
  8117. * @param {Vue} vm - unused
  8118. * @param {Function} [cb]
  8119. */
  8120. function append(el, target, vm, cb) {
  8121. target.appendChild(el);
  8122. if (cb) cb();
  8123. }
  8124. /**
  8125. * InsertBefore operation that takes a callback.
  8126. *
  8127. * @param {Node} el
  8128. * @param {Node} target
  8129. * @param {Vue} vm - unused
  8130. * @param {Function} [cb]
  8131. */
  8132. function beforeWithCb(el, target, vm, cb) {
  8133. before(el, target);
  8134. if (cb) cb();
  8135. }
  8136. /**
  8137. * Remove operation that takes a callback.
  8138. *
  8139. * @param {Node} el
  8140. * @param {Vue} vm - unused
  8141. * @param {Function} [cb]
  8142. */
  8143. function removeWithCb(el, vm, cb) {
  8144. remove(el);
  8145. if (cb) cb();
  8146. }
  8147. }
  8148. function eventsAPI (Vue) {
  8149. /**
  8150. * Listen on the given `event` with `fn`.
  8151. *
  8152. * @param {String} event
  8153. * @param {Function} fn
  8154. */
  8155. Vue.prototype.$on = function (event, fn) {
  8156. (this._events[event] || (this._events[event] = [])).push(fn);
  8157. modifyListenerCount(this, event, 1);
  8158. return this;
  8159. };
  8160. /**
  8161. * Adds an `event` listener that will be invoked a single
  8162. * time then automatically removed.
  8163. *
  8164. * @param {String} event
  8165. * @param {Function} fn
  8166. */
  8167. Vue.prototype.$once = function (event, fn) {
  8168. var self = this;
  8169. function on() {
  8170. self.$off(event, on);
  8171. fn.apply(this, arguments);
  8172. }
  8173. on.fn = fn;
  8174. this.$on(event, on);
  8175. return this;
  8176. };
  8177. /**
  8178. * Remove the given callback for `event` or all
  8179. * registered callbacks.
  8180. *
  8181. * @param {String} event
  8182. * @param {Function} fn
  8183. */
  8184. Vue.prototype.$off = function (event, fn) {
  8185. var cbs;
  8186. // all
  8187. if (!arguments.length) {
  8188. if (this.$parent) {
  8189. for (event in this._events) {
  8190. cbs = this._events[event];
  8191. if (cbs) {
  8192. modifyListenerCount(this, event, -cbs.length);
  8193. }
  8194. }
  8195. }
  8196. this._events = {};
  8197. return this;
  8198. }
  8199. // specific event
  8200. cbs = this._events[event];
  8201. if (!cbs) {
  8202. return this;
  8203. }
  8204. if (arguments.length === 1) {
  8205. modifyListenerCount(this, event, -cbs.length);
  8206. this._events[event] = null;
  8207. return this;
  8208. }
  8209. // specific handler
  8210. var cb;
  8211. var i = cbs.length;
  8212. while (i--) {
  8213. cb = cbs[i];
  8214. if (cb === fn || cb.fn === fn) {
  8215. modifyListenerCount(this, event, -1);
  8216. cbs.splice(i, 1);
  8217. break;
  8218. }
  8219. }
  8220. return this;
  8221. };
  8222. /**
  8223. * Trigger an event on self.
  8224. *
  8225. * @param {String|Object} event
  8226. * @return {Boolean} shouldPropagate
  8227. */
  8228. Vue.prototype.$emit = function (event) {
  8229. var isSource = typeof event === 'string';
  8230. event = isSource ? event : event.name;
  8231. var cbs = this._events[event];
  8232. var shouldPropagate = isSource || !cbs;
  8233. if (cbs) {
  8234. cbs = cbs.length > 1 ? toArray(cbs) : cbs;
  8235. // this is a somewhat hacky solution to the question raised
  8236. // in #2102: for an inline component listener like <comp @test="doThis">,
  8237. // the propagation handling is somewhat broken. Therefore we
  8238. // need to treat these inline callbacks differently.
  8239. var hasParentCbs = isSource && cbs.some(function (cb) {
  8240. return cb._fromParent;
  8241. });
  8242. if (hasParentCbs) {
  8243. shouldPropagate = false;
  8244. }
  8245. var args = toArray(arguments, 1);
  8246. for (var i = 0, l = cbs.length; i < l; i++) {
  8247. var cb = cbs[i];
  8248. var res = cb.apply(this, args);
  8249. if (res === true && (!hasParentCbs || cb._fromParent)) {
  8250. shouldPropagate = true;
  8251. }
  8252. }
  8253. }
  8254. return shouldPropagate;
  8255. };
  8256. /**
  8257. * Recursively broadcast an event to all children instances.
  8258. *
  8259. * @param {String|Object} event
  8260. * @param {...*} additional arguments
  8261. */
  8262. Vue.prototype.$broadcast = function (event) {
  8263. var isSource = typeof event === 'string';
  8264. event = isSource ? event : event.name;
  8265. // if no child has registered for this event,
  8266. // then there's no need to broadcast.
  8267. if (!this._eventsCount[event]) return;
  8268. var children = this.$children;
  8269. var args = toArray(arguments);
  8270. if (isSource) {
  8271. // use object event to indicate non-source emit
  8272. // on children
  8273. args[0] = { name: event, source: this };
  8274. }
  8275. for (var i = 0, l = children.length; i < l; i++) {
  8276. var child = children[i];
  8277. var shouldPropagate = child.$emit.apply(child, args);
  8278. if (shouldPropagate) {
  8279. child.$broadcast.apply(child, args);
  8280. }
  8281. }
  8282. return this;
  8283. };
  8284. /**
  8285. * Recursively propagate an event up the parent chain.
  8286. *
  8287. * @param {String} event
  8288. * @param {...*} additional arguments
  8289. */
  8290. Vue.prototype.$dispatch = function (event) {
  8291. var shouldPropagate = this.$emit.apply(this, arguments);
  8292. if (!shouldPropagate) return;
  8293. var parent = this.$parent;
  8294. var args = toArray(arguments);
  8295. // use object event to indicate non-source emit
  8296. // on parents
  8297. args[0] = { name: event, source: this };
  8298. while (parent) {
  8299. shouldPropagate = parent.$emit.apply(parent, args);
  8300. parent = shouldPropagate ? parent.$parent : null;
  8301. }
  8302. return this;
  8303. };
  8304. /**
  8305. * Modify the listener counts on all parents.
  8306. * This bookkeeping allows $broadcast to return early when
  8307. * no child has listened to a certain event.
  8308. *
  8309. * @param {Vue} vm
  8310. * @param {String} event
  8311. * @param {Number} count
  8312. */
  8313. var hookRE = /^hook:/;
  8314. function modifyListenerCount(vm, event, count) {
  8315. var parent = vm.$parent;
  8316. // hooks do not get broadcasted so no need
  8317. // to do bookkeeping for them
  8318. if (!parent || !count || hookRE.test(event)) return;
  8319. while (parent) {
  8320. parent._eventsCount[event] = (parent._eventsCount[event] || 0) + count;
  8321. parent = parent.$parent;
  8322. }
  8323. }
  8324. }
  8325. function lifecycleAPI (Vue) {
  8326. /**
  8327. * Set instance target element and kick off the compilation
  8328. * process. The passed in `el` can be a selector string, an
  8329. * existing Element, or a DocumentFragment (for block
  8330. * instances).
  8331. *
  8332. * @param {Element|DocumentFragment|string} el
  8333. * @public
  8334. */
  8335. Vue.prototype.$mount = function (el) {
  8336. if (this._isCompiled) {
  8337. 'development' !== 'production' && warn('$mount() should be called only once.', this);
  8338. return;
  8339. }
  8340. el = query(el);
  8341. if (!el) {
  8342. el = document.createElement('div');
  8343. }
  8344. this._compile(el);
  8345. this._initDOMHooks();
  8346. if (inDoc(this.$el)) {
  8347. this._callHook('attached');
  8348. ready.call(this);
  8349. } else {
  8350. this.$once('hook:attached', ready);
  8351. }
  8352. return this;
  8353. };
  8354. /**
  8355. * Mark an instance as ready.
  8356. */
  8357. function ready() {
  8358. this._isAttached = true;
  8359. this._isReady = true;
  8360. this._callHook('ready');
  8361. }
  8362. /**
  8363. * Teardown the instance, simply delegate to the internal
  8364. * _destroy.
  8365. *
  8366. * @param {Boolean} remove
  8367. * @param {Boolean} deferCleanup
  8368. */
  8369. Vue.prototype.$destroy = function (remove, deferCleanup) {
  8370. this._destroy(remove, deferCleanup);
  8371. };
  8372. /**
  8373. * Partially compile a piece of DOM and return a
  8374. * decompile function.
  8375. *
  8376. * @param {Element|DocumentFragment} el
  8377. * @param {Vue} [host]
  8378. * @param {Object} [scope]
  8379. * @param {Fragment} [frag]
  8380. * @return {Function}
  8381. */
  8382. Vue.prototype.$compile = function (el, host, scope, frag) {
  8383. return compile(el, this.$options, true)(this, el, host, scope, frag);
  8384. };
  8385. }
  8386. /**
  8387. * The exposed Vue constructor.
  8388. *
  8389. * API conventions:
  8390. * - public API methods/properties are prefixed with `$`
  8391. * - internal methods/properties are prefixed with `_`
  8392. * - non-prefixed properties are assumed to be proxied user
  8393. * data.
  8394. *
  8395. * @constructor
  8396. * @param {Object} [options]
  8397. * @public
  8398. */
  8399. function Vue(options) {
  8400. this._init(options);
  8401. }
  8402. // install internals
  8403. initMixin(Vue);
  8404. stateMixin(Vue);
  8405. eventsMixin(Vue);
  8406. lifecycleMixin(Vue);
  8407. miscMixin(Vue);
  8408. // install instance APIs
  8409. dataAPI(Vue);
  8410. domAPI(Vue);
  8411. eventsAPI(Vue);
  8412. lifecycleAPI(Vue);
  8413. var slot = {
  8414. priority: SLOT,
  8415. params: ['name'],
  8416. bind: function bind() {
  8417. // this was resolved during component transclusion
  8418. var name = this.params.name || 'default';
  8419. var content = this.vm._slotContents && this.vm._slotContents[name];
  8420. if (!content || !content.hasChildNodes()) {
  8421. this.fallback();
  8422. } else {
  8423. this.compile(content.cloneNode(true), this.vm._context, this.vm);
  8424. }
  8425. },
  8426. compile: function compile(content, context, host) {
  8427. if (content && context) {
  8428. if (this.el.hasChildNodes() && content.childNodes.length === 1 && content.childNodes[0].nodeType === 1 && content.childNodes[0].hasAttribute('v-if')) {
  8429. // if the inserted slot has v-if
  8430. // inject fallback content as the v-else
  8431. var elseBlock = document.createElement('template');
  8432. elseBlock.setAttribute('v-else', '');
  8433. elseBlock.innerHTML = this.el.innerHTML;
  8434. // the else block should be compiled in child scope
  8435. elseBlock._context = this.vm;
  8436. content.appendChild(elseBlock);
  8437. }
  8438. var scope = host ? host._scope : this._scope;
  8439. this.unlink = context.$compile(content, host, scope, this._frag);
  8440. }
  8441. if (content) {
  8442. replace(this.el, content);
  8443. } else {
  8444. remove(this.el);
  8445. }
  8446. },
  8447. fallback: function fallback() {
  8448. this.compile(extractContent(this.el, true), this.vm);
  8449. },
  8450. unbind: function unbind() {
  8451. if (this.unlink) {
  8452. this.unlink();
  8453. }
  8454. }
  8455. };
  8456. var partial = {
  8457. priority: PARTIAL,
  8458. params: ['name'],
  8459. // watch changes to name for dynamic partials
  8460. paramWatchers: {
  8461. name: function name(value) {
  8462. vIf.remove.call(this);
  8463. if (value) {
  8464. this.insert(value);
  8465. }
  8466. }
  8467. },
  8468. bind: function bind() {
  8469. this.anchor = createAnchor('v-partial');
  8470. replace(this.el, this.anchor);
  8471. this.insert(this.params.name);
  8472. },
  8473. insert: function insert(id) {
  8474. var partial = resolveAsset(this.vm.$options, 'partials', id, true);
  8475. if (partial) {
  8476. this.factory = new FragmentFactory(this.vm, partial);
  8477. vIf.insert.call(this);
  8478. }
  8479. },
  8480. unbind: function unbind() {
  8481. if (this.frag) {
  8482. this.frag.destroy();
  8483. }
  8484. }
  8485. };
  8486. var elementDirectives = {
  8487. slot: slot,
  8488. partial: partial
  8489. };
  8490. var convertArray = vFor._postProcess;
  8491. /**
  8492. * Limit filter for arrays
  8493. *
  8494. * @param {Number} n
  8495. * @param {Number} offset (Decimal expected)
  8496. */
  8497. function limitBy(arr, n, offset) {
  8498. offset = offset ? parseInt(offset, 10) : 0;
  8499. n = toNumber(n);
  8500. return typeof n === 'number' ? arr.slice(offset, offset + n) : arr;
  8501. }
  8502. /**
  8503. * Filter filter for arrays
  8504. *
  8505. * @param {String} search
  8506. * @param {String} [delimiter]
  8507. * @param {String} ...dataKeys
  8508. */
  8509. function filterBy(arr, search, delimiter) {
  8510. arr = convertArray(arr);
  8511. if (search == null) {
  8512. return arr;
  8513. }
  8514. if (typeof search === 'function') {
  8515. return arr.filter(search);
  8516. }
  8517. // cast to lowercase string
  8518. search = ('' + search).toLowerCase();
  8519. // allow optional `in` delimiter
  8520. // because why not
  8521. var n = delimiter === 'in' ? 3 : 2;
  8522. // extract and flatten keys
  8523. var keys = Array.prototype.concat.apply([], toArray(arguments, n));
  8524. var res = [];
  8525. var item, key, val, j;
  8526. for (var i = 0, l = arr.length; i < l; i++) {
  8527. item = arr[i];
  8528. val = item && item.$value || item;
  8529. j = keys.length;
  8530. if (j) {
  8531. while (j--) {
  8532. key = keys[j];
  8533. if (key === '$key' && contains(item.$key, search) || contains(getPath(val, key), search)) {
  8534. res.push(item);
  8535. break;
  8536. }
  8537. }
  8538. } else if (contains(item, search)) {
  8539. res.push(item);
  8540. }
  8541. }
  8542. return res;
  8543. }
  8544. /**
  8545. * Filter filter for arrays
  8546. *
  8547. * @param {String|Array<String>|Function} ...sortKeys
  8548. * @param {Number} [order]
  8549. */
  8550. function orderBy(arr) {
  8551. var comparator = null;
  8552. var sortKeys = undefined;
  8553. arr = convertArray(arr);
  8554. // determine order (last argument)
  8555. var args = toArray(arguments, 1);
  8556. var order = args[args.length - 1];
  8557. if (typeof order === 'number') {
  8558. order = order < 0 ? -1 : 1;
  8559. args = args.length > 1 ? args.slice(0, -1) : args;
  8560. } else {
  8561. order = 1;
  8562. }
  8563. // determine sortKeys & comparator
  8564. var firstArg = args[0];
  8565. if (!firstArg) {
  8566. return arr;
  8567. } else if (typeof firstArg === 'function') {
  8568. // custom comparator
  8569. comparator = function (a, b) {
  8570. return firstArg(a, b) * order;
  8571. };
  8572. } else {
  8573. // string keys. flatten first
  8574. sortKeys = Array.prototype.concat.apply([], args);
  8575. comparator = function (a, b, i) {
  8576. i = i || 0;
  8577. return i >= sortKeys.length - 1 ? baseCompare(a, b, i) : baseCompare(a, b, i) || comparator(a, b, i + 1);
  8578. };
  8579. }
  8580. function baseCompare(a, b, sortKeyIndex) {
  8581. var sortKey = sortKeys[sortKeyIndex];
  8582. if (sortKey) {
  8583. if (sortKey !== '$key') {
  8584. if (isObject(a) && '$value' in a) a = a.$value;
  8585. if (isObject(b) && '$value' in b) b = b.$value;
  8586. }
  8587. a = isObject(a) ? getPath(a, sortKey) : a;
  8588. b = isObject(b) ? getPath(b, sortKey) : b;
  8589. }
  8590. return a === b ? 0 : a > b ? order : -order;
  8591. }
  8592. // sort on a copy to avoid mutating original array
  8593. return arr.slice().sort(comparator);
  8594. }
  8595. /**
  8596. * String contain helper
  8597. *
  8598. * @param {*} val
  8599. * @param {String} search
  8600. */
  8601. function contains(val, search) {
  8602. var i;
  8603. if (isPlainObject(val)) {
  8604. var keys = Object.keys(val);
  8605. i = keys.length;
  8606. while (i--) {
  8607. if (contains(val[keys[i]], search)) {
  8608. return true;
  8609. }
  8610. }
  8611. } else if (isArray(val)) {
  8612. i = val.length;
  8613. while (i--) {
  8614. if (contains(val[i], search)) {
  8615. return true;
  8616. }
  8617. }
  8618. } else if (val != null) {
  8619. return val.toString().toLowerCase().indexOf(search) > -1;
  8620. }
  8621. }
  8622. var digitsRE = /(\d{3})(?=\d)/g;
  8623. // asset collections must be a plain object.
  8624. var filters = {
  8625. orderBy: orderBy,
  8626. filterBy: filterBy,
  8627. limitBy: limitBy,
  8628. /**
  8629. * Stringify value.
  8630. *
  8631. * @param {Number} indent
  8632. */
  8633. json: {
  8634. read: function read(value, indent) {
  8635. return typeof value === 'string' ? value : JSON.stringify(value, null, Number(indent) || 2);
  8636. },
  8637. write: function write(value) {
  8638. try {
  8639. return JSON.parse(value);
  8640. } catch (e) {
  8641. return value;
  8642. }
  8643. }
  8644. },
  8645. /**
  8646. * 'abc' => 'Abc'
  8647. */
  8648. capitalize: function capitalize(value) {
  8649. if (!value && value !== 0) return '';
  8650. value = value.toString();
  8651. return value.charAt(0).toUpperCase() + value.slice(1);
  8652. },
  8653. /**
  8654. * 'abc' => 'ABC'
  8655. */
  8656. uppercase: function uppercase(value) {
  8657. return value || value === 0 ? value.toString().toUpperCase() : '';
  8658. },
  8659. /**
  8660. * 'AbC' => 'abc'
  8661. */
  8662. lowercase: function lowercase(value) {
  8663. return value || value === 0 ? value.toString().toLowerCase() : '';
  8664. },
  8665. /**
  8666. * 12345 => $12,345.00
  8667. *
  8668. * @param {String} sign
  8669. */
  8670. currency: function currency(value, _currency) {
  8671. value = parseFloat(value);
  8672. if (!isFinite(value) || !value && value !== 0) return '';
  8673. _currency = _currency != null ? _currency : '$';
  8674. var stringified = Math.abs(value).toFixed(2);
  8675. var _int = stringified.slice(0, -3);
  8676. var i = _int.length % 3;
  8677. var head = i > 0 ? _int.slice(0, i) + (_int.length > 3 ? ',' : '') : '';
  8678. var _float = stringified.slice(-3);
  8679. var sign = value < 0 ? '-' : '';
  8680. return sign + _currency + head + _int.slice(i).replace(digitsRE, '$1,') + _float;
  8681. },
  8682. /**
  8683. * 'item' => 'items'
  8684. *
  8685. * @params
  8686. * an array of strings corresponding to
  8687. * the single, double, triple ... forms of the word to
  8688. * be pluralized. When the number to be pluralized
  8689. * exceeds the length of the args, it will use the last
  8690. * entry in the array.
  8691. *
  8692. * e.g. ['single', 'double', 'triple', 'multiple']
  8693. */
  8694. pluralize: function pluralize(value) {
  8695. var args = toArray(arguments, 1);
  8696. return args.length > 1 ? args[value % 10 - 1] || args[args.length - 1] : args[0] + (value === 1 ? '' : 's');
  8697. },
  8698. /**
  8699. * Debounce a handler function.
  8700. *
  8701. * @param {Function} handler
  8702. * @param {Number} delay = 300
  8703. * @return {Function}
  8704. */
  8705. debounce: function debounce(handler, delay) {
  8706. if (!handler) return;
  8707. if (!delay) {
  8708. delay = 300;
  8709. }
  8710. return _debounce(handler, delay);
  8711. }
  8712. };
  8713. function installGlobalAPI (Vue) {
  8714. /**
  8715. * Vue and every constructor that extends Vue has an
  8716. * associated options object, which can be accessed during
  8717. * compilation steps as `this.constructor.options`.
  8718. *
  8719. * These can be seen as the default options of every
  8720. * Vue instance.
  8721. */
  8722. Vue.options = {
  8723. directives: directives,
  8724. elementDirectives: elementDirectives,
  8725. filters: filters,
  8726. transitions: {},
  8727. components: {},
  8728. partials: {},
  8729. replace: true
  8730. };
  8731. /**
  8732. * Expose useful internals
  8733. */
  8734. Vue.util = util;
  8735. Vue.config = config;
  8736. Vue.set = set;
  8737. Vue['delete'] = del;
  8738. Vue.nextTick = nextTick;
  8739. /**
  8740. * The following are exposed for advanced usage / plugins
  8741. */
  8742. Vue.compiler = compiler;
  8743. Vue.FragmentFactory = FragmentFactory;
  8744. Vue.internalDirectives = internalDirectives;
  8745. Vue.parsers = {
  8746. path: path,
  8747. text: text,
  8748. template: template,
  8749. directive: directive,
  8750. expression: expression
  8751. };
  8752. /**
  8753. * Each instance constructor, including Vue, has a unique
  8754. * cid. This enables us to create wrapped "child
  8755. * constructors" for prototypal inheritance and cache them.
  8756. */
  8757. Vue.cid = 0;
  8758. var cid = 1;
  8759. /**
  8760. * Class inheritance
  8761. *
  8762. * @param {Object} extendOptions
  8763. */
  8764. Vue.extend = function (extendOptions) {
  8765. extendOptions = extendOptions || {};
  8766. var Super = this;
  8767. var isFirstExtend = Super.cid === 0;
  8768. if (isFirstExtend && extendOptions._Ctor) {
  8769. return extendOptions._Ctor;
  8770. }
  8771. var name = extendOptions.name || Super.options.name;
  8772. if ('development' !== 'production') {
  8773. if (!/^[a-zA-Z][\w-]*$/.test(name)) {
  8774. warn('Invalid component name: "' + name + '". Component names ' + 'can only contain alphanumeric characaters and the hyphen.');
  8775. name = null;
  8776. }
  8777. }
  8778. var Sub = createClass(name || 'VueComponent');
  8779. Sub.prototype = Object.create(Super.prototype);
  8780. Sub.prototype.constructor = Sub;
  8781. Sub.cid = cid++;
  8782. Sub.options = mergeOptions(Super.options, extendOptions);
  8783. Sub['super'] = Super;
  8784. // allow further extension
  8785. Sub.extend = Super.extend;
  8786. // create asset registers, so extended classes
  8787. // can have their private assets too.
  8788. config._assetTypes.forEach(function (type) {
  8789. Sub[type] = Super[type];
  8790. });
  8791. // enable recursive self-lookup
  8792. if (name) {
  8793. Sub.options.components[name] = Sub;
  8794. }
  8795. // cache constructor
  8796. if (isFirstExtend) {
  8797. extendOptions._Ctor = Sub;
  8798. }
  8799. return Sub;
  8800. };
  8801. /**
  8802. * A function that returns a sub-class constructor with the
  8803. * given name. This gives us much nicer output when
  8804. * logging instances in the console.
  8805. *
  8806. * @param {String} name
  8807. * @return {Function}
  8808. */
  8809. function createClass(name) {
  8810. /* eslint-disable no-new-func */
  8811. return new Function('return function ' + classify(name) + ' (options) { this._init(options) }')();
  8812. /* eslint-enable no-new-func */
  8813. }
  8814. /**
  8815. * Plugin system
  8816. *
  8817. * @param {Object} plugin
  8818. */
  8819. Vue.use = function (plugin) {
  8820. /* istanbul ignore if */
  8821. if (plugin.installed) {
  8822. return;
  8823. }
  8824. // additional parameters
  8825. var args = toArray(arguments, 1);
  8826. args.unshift(this);
  8827. if (typeof plugin.install === 'function') {
  8828. plugin.install.apply(plugin, args);
  8829. } else {
  8830. plugin.apply(null, args);
  8831. }
  8832. plugin.installed = true;
  8833. return this;
  8834. };
  8835. /**
  8836. * Apply a global mixin by merging it into the default
  8837. * options.
  8838. */
  8839. Vue.mixin = function (mixin) {
  8840. Vue.options = mergeOptions(Vue.options, mixin);
  8841. };
  8842. /**
  8843. * Create asset registration methods with the following
  8844. * signature:
  8845. *
  8846. * @param {String} id
  8847. * @param {*} definition
  8848. */
  8849. config._assetTypes.forEach(function (type) {
  8850. Vue[type] = function (id, definition) {
  8851. if (!definition) {
  8852. return this.options[type + 's'][id];
  8853. } else {
  8854. /* istanbul ignore if */
  8855. if ('development' !== 'production') {
  8856. if (type === 'component' && (commonTagRE.test(id) || reservedTagRE.test(id))) {
  8857. warn('Do not use built-in or reserved HTML elements as component ' + 'id: ' + id);
  8858. }
  8859. }
  8860. if (type === 'component' && isPlainObject(definition)) {
  8861. definition.name = id;
  8862. definition = Vue.extend(definition);
  8863. }
  8864. this.options[type + 's'][id] = definition;
  8865. return definition;
  8866. }
  8867. };
  8868. });
  8869. // expose internal transition API
  8870. extend(Vue.transition, transition);
  8871. }
  8872. installGlobalAPI(Vue);
  8873. Vue.version = '1.0.21';
  8874. // devtools global hook
  8875. /* istanbul ignore next */
  8876. setTimeout(function () {
  8877. if (config.devtools) {
  8878. if (devtools) {
  8879. devtools.emit('init', Vue);
  8880. } else if ('development' !== 'production' && inBrowser && /Chrome\/\d+/.test(window.navigator.userAgent)) {
  8881. console.log('Download the Vue Devtools for a better development experience:\n' + 'https://github.com/vuejs/vue-devtools');
  8882. }
  8883. }
  8884. }, 0);
  8885. return Vue;
  8886. }));