runtime-dom.esm-bundler.js 43 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248
  1. import { camelize, warn, callWithAsyncErrorHandling, getCurrentInstance, onMounted, watchEffect, onUpdated, unref, Fragment, h, BaseTransition, useTransitionState, getTransitionRawChildren, setTransitionHooks, resolveTransitionHooks, createVNode, createRenderer, createHydrationRenderer } from '@vue/runtime-core';
  2. export * from '@vue/runtime-core';
  3. import { isString, isArray, hyphenate, capitalize, isSpecialBooleanAttr, isOn, isModelListener, isFunction, EMPTY_OBJ, extend, isObject, toNumber, invokeArrayFns, looseIndexOf, isSet, looseEqual, isHTMLTag, isSVGTag } from '@vue/shared';
  4. const svgNS = 'http://www.w3.org/2000/svg';
  5. const doc = (typeof document !== 'undefined' ? document : null);
  6. let tempContainer;
  7. let tempSVGContainer;
  8. const nodeOps = {
  9. insert: (child, parent, anchor) => {
  10. parent.insertBefore(child, anchor || null);
  11. },
  12. remove: child => {
  13. const parent = child.parentNode;
  14. if (parent) {
  15. parent.removeChild(child);
  16. }
  17. },
  18. createElement: (tag, isSVG, is) => isSVG
  19. ? doc.createElementNS(svgNS, tag)
  20. : doc.createElement(tag, is ? { is } : undefined),
  21. createText: text => doc.createTextNode(text),
  22. createComment: text => doc.createComment(text),
  23. setText: (node, text) => {
  24. node.nodeValue = text;
  25. },
  26. setElementText: (el, text) => {
  27. el.textContent = text;
  28. },
  29. parentNode: node => node.parentNode,
  30. nextSibling: node => node.nextSibling,
  31. querySelector: selector => doc.querySelector(selector),
  32. setScopeId(el, id) {
  33. el.setAttribute(id, '');
  34. },
  35. cloneNode(el) {
  36. return el.cloneNode(true);
  37. },
  38. // __UNSAFE__
  39. // Reason: innerHTML.
  40. // Static content here can only come from compiled templates.
  41. // As long as the user only uses trusted templates, this is safe.
  42. insertStaticContent(content, parent, anchor, isSVG) {
  43. const temp = isSVG
  44. ? tempSVGContainer ||
  45. (tempSVGContainer = doc.createElementNS(svgNS, 'svg'))
  46. : tempContainer || (tempContainer = doc.createElement('div'));
  47. temp.innerHTML = content;
  48. const first = temp.firstChild;
  49. let node = first;
  50. let last = node;
  51. while (node) {
  52. last = node;
  53. nodeOps.insert(node, parent, anchor);
  54. node = temp.firstChild;
  55. }
  56. return [first, last];
  57. }
  58. };
  59. // compiler should normalize class + :class bindings on the same element
  60. // into a single binding ['staticClass', dynamic]
  61. function patchClass(el, value, isSVG) {
  62. if (value == null) {
  63. value = '';
  64. }
  65. if (isSVG) {
  66. el.setAttribute('class', value);
  67. }
  68. else {
  69. // directly setting className should be faster than setAttribute in theory
  70. // if this is an element during a transition, take the temporary transition
  71. // classes into account.
  72. const transitionClasses = el._vtc;
  73. if (transitionClasses) {
  74. value = (value
  75. ? [value, ...transitionClasses]
  76. : [...transitionClasses]).join(' ');
  77. }
  78. el.className = value;
  79. }
  80. }
  81. function patchStyle(el, prev, next) {
  82. const style = el.style;
  83. if (!next) {
  84. el.removeAttribute('style');
  85. }
  86. else if (isString(next)) {
  87. if (prev !== next) {
  88. style.cssText = next;
  89. }
  90. }
  91. else {
  92. for (const key in next) {
  93. setStyle(style, key, next[key]);
  94. }
  95. if (prev && !isString(prev)) {
  96. for (const key in prev) {
  97. if (next[key] == null) {
  98. setStyle(style, key, '');
  99. }
  100. }
  101. }
  102. }
  103. }
  104. const importantRE = /\s*!important$/;
  105. function setStyle(style, name, val) {
  106. if (isArray(val)) {
  107. val.forEach(v => setStyle(style, name, v));
  108. }
  109. else {
  110. if (name.startsWith('--')) {
  111. // custom property definition
  112. style.setProperty(name, val);
  113. }
  114. else {
  115. const prefixed = autoPrefix(style, name);
  116. if (importantRE.test(val)) {
  117. // !important
  118. style.setProperty(hyphenate(prefixed), val.replace(importantRE, ''), 'important');
  119. }
  120. else {
  121. style[prefixed] = val;
  122. }
  123. }
  124. }
  125. }
  126. const prefixes = ['Webkit', 'Moz', 'ms'];
  127. const prefixCache = {};
  128. function autoPrefix(style, rawName) {
  129. const cached = prefixCache[rawName];
  130. if (cached) {
  131. return cached;
  132. }
  133. let name = camelize(rawName);
  134. if (name !== 'filter' && name in style) {
  135. return (prefixCache[rawName] = name);
  136. }
  137. name = capitalize(name);
  138. for (let i = 0; i < prefixes.length; i++) {
  139. const prefixed = prefixes[i] + name;
  140. if (prefixed in style) {
  141. return (prefixCache[rawName] = prefixed);
  142. }
  143. }
  144. return rawName;
  145. }
  146. const xlinkNS = 'http://www.w3.org/1999/xlink';
  147. function patchAttr(el, key, value, isSVG) {
  148. if (isSVG && key.startsWith('xlink:')) {
  149. if (value == null) {
  150. el.removeAttributeNS(xlinkNS, key.slice(6, key.length));
  151. }
  152. else {
  153. el.setAttributeNS(xlinkNS, key, value);
  154. }
  155. }
  156. else {
  157. // note we are only checking boolean attributes that don't have a
  158. // corresponding dom prop of the same name here.
  159. const isBoolean = isSpecialBooleanAttr(key);
  160. if (value == null || (isBoolean && value === false)) {
  161. el.removeAttribute(key);
  162. }
  163. else {
  164. el.setAttribute(key, isBoolean ? '' : value);
  165. }
  166. }
  167. }
  168. // __UNSAFE__
  169. // functions. The user is responsible for using them with only trusted content.
  170. function patchDOMProp(el, key, value,
  171. // the following args are passed only due to potential innerHTML/textContent
  172. // overriding existing VNodes, in which case the old tree must be properly
  173. // unmounted.
  174. prevChildren, parentComponent, parentSuspense, unmountChildren) {
  175. if (key === 'innerHTML' || key === 'textContent') {
  176. if (prevChildren) {
  177. unmountChildren(prevChildren, parentComponent, parentSuspense);
  178. }
  179. el[key] = value == null ? '' : value;
  180. return;
  181. }
  182. if (key === 'value' && el.tagName !== 'PROGRESS') {
  183. // store value as _value as well since
  184. // non-string values will be stringified.
  185. el._value = value;
  186. const newValue = value == null ? '' : value;
  187. if (el.value !== newValue) {
  188. el.value = newValue;
  189. }
  190. return;
  191. }
  192. if (value === '' && typeof el[key] === 'boolean') {
  193. // e.g. <select multiple> compiles to { multiple: '' }
  194. el[key] = true;
  195. }
  196. else if (value == null && typeof el[key] === 'string') {
  197. // e.g. <div :id="null">
  198. el[key] = '';
  199. el.removeAttribute(key);
  200. }
  201. else {
  202. // some properties perform value validation and throw
  203. try {
  204. el[key] = value;
  205. }
  206. catch (e) {
  207. if ((process.env.NODE_ENV !== 'production')) {
  208. warn(`Failed setting prop "${key}" on <${el.tagName.toLowerCase()}>: ` +
  209. `value ${value} is invalid.`, e);
  210. }
  211. }
  212. }
  213. }
  214. // Async edge case fix requires storing an event listener's attach timestamp.
  215. let _getNow = Date.now;
  216. // Determine what event timestamp the browser is using. Annoyingly, the
  217. // timestamp can either be hi-res (relative to page load) or low-res
  218. // (relative to UNIX epoch), so in order to compare time we have to use the
  219. // same timestamp type when saving the flush timestamp.
  220. if (typeof document !== 'undefined' &&
  221. _getNow() > document.createEvent('Event').timeStamp) {
  222. // if the low-res timestamp which is bigger than the event timestamp
  223. // (which is evaluated AFTER) it means the event is using a hi-res timestamp,
  224. // and we need to use the hi-res version for event listeners as well.
  225. _getNow = () => performance.now();
  226. }
  227. // To avoid the overhead of repeatedly calling performance.now(), we cache
  228. // and use the same timestamp for all event listeners attached in the same tick.
  229. let cachedNow = 0;
  230. const p = Promise.resolve();
  231. const reset = () => {
  232. cachedNow = 0;
  233. };
  234. const getNow = () => cachedNow || (p.then(reset), (cachedNow = _getNow()));
  235. function addEventListener(el, event, handler, options) {
  236. el.addEventListener(event, handler, options);
  237. }
  238. function removeEventListener(el, event, handler, options) {
  239. el.removeEventListener(event, handler, options);
  240. }
  241. function patchEvent(el, rawName, prevValue, nextValue, instance = null) {
  242. // vei = vue event invokers
  243. const invokers = el._vei || (el._vei = {});
  244. const existingInvoker = invokers[rawName];
  245. if (nextValue && existingInvoker) {
  246. // patch
  247. existingInvoker.value = nextValue;
  248. }
  249. else {
  250. const [name, options] = parseName(rawName);
  251. if (nextValue) {
  252. // add
  253. const invoker = (invokers[rawName] = createInvoker(nextValue, instance));
  254. addEventListener(el, name, invoker, options);
  255. }
  256. else if (existingInvoker) {
  257. // remove
  258. removeEventListener(el, name, existingInvoker, options);
  259. invokers[rawName] = undefined;
  260. }
  261. }
  262. }
  263. const optionsModifierRE = /(?:Once|Passive|Capture)$/;
  264. function parseName(name) {
  265. let options;
  266. if (optionsModifierRE.test(name)) {
  267. options = {};
  268. let m;
  269. while ((m = name.match(optionsModifierRE))) {
  270. name = name.slice(0, name.length - m[0].length);
  271. options[m[0].toLowerCase()] = true;
  272. }
  273. }
  274. return [name.slice(2).toLowerCase(), options];
  275. }
  276. function createInvoker(initialValue, instance) {
  277. const invoker = (e) => {
  278. // async edge case #6566: inner click event triggers patch, event handler
  279. // attached to outer element during patch, and triggered again. This
  280. // happens because browsers fire microtask ticks between event propagation.
  281. // the solution is simple: we save the timestamp when a handler is attached,
  282. // and the handler would only fire if the event passed to it was fired
  283. // AFTER it was attached.
  284. const timeStamp = e.timeStamp || _getNow();
  285. if (timeStamp >= invoker.attached - 1) {
  286. callWithAsyncErrorHandling(patchStopImmediatePropagation(e, invoker.value), instance, 5 /* NATIVE_EVENT_HANDLER */, [e]);
  287. }
  288. };
  289. invoker.value = initialValue;
  290. invoker.attached = getNow();
  291. return invoker;
  292. }
  293. function patchStopImmediatePropagation(e, value) {
  294. if (isArray(value)) {
  295. const originalStop = e.stopImmediatePropagation;
  296. e.stopImmediatePropagation = () => {
  297. originalStop.call(e);
  298. e._stopped = true;
  299. };
  300. return value.map(fn => (e) => !e._stopped && fn(e));
  301. }
  302. else {
  303. return value;
  304. }
  305. }
  306. const nativeOnRE = /^on[a-z]/;
  307. const forcePatchProp = (_, key) => key === 'value';
  308. const patchProp = (el, key, prevValue, nextValue, isSVG = false, prevChildren, parentComponent, parentSuspense, unmountChildren) => {
  309. switch (key) {
  310. // special
  311. case 'class':
  312. patchClass(el, nextValue, isSVG);
  313. break;
  314. case 'style':
  315. patchStyle(el, prevValue, nextValue);
  316. break;
  317. default:
  318. if (isOn(key)) {
  319. // ignore v-model listeners
  320. if (!isModelListener(key)) {
  321. patchEvent(el, key, prevValue, nextValue, parentComponent);
  322. }
  323. }
  324. else if (shouldSetAsProp(el, key, nextValue, isSVG)) {
  325. patchDOMProp(el, key, nextValue, prevChildren, parentComponent, parentSuspense, unmountChildren);
  326. }
  327. else {
  328. // special case for <input v-model type="checkbox"> with
  329. // :true-value & :false-value
  330. // store value as dom properties since non-string values will be
  331. // stringified.
  332. if (key === 'true-value') {
  333. el._trueValue = nextValue;
  334. }
  335. else if (key === 'false-value') {
  336. el._falseValue = nextValue;
  337. }
  338. patchAttr(el, key, nextValue, isSVG);
  339. }
  340. break;
  341. }
  342. };
  343. function shouldSetAsProp(el, key, value, isSVG) {
  344. if (isSVG) {
  345. // most keys must be set as attribute on svg elements to work
  346. // ...except innerHTML
  347. if (key === 'innerHTML') {
  348. return true;
  349. }
  350. // or native onclick with function values
  351. if (key in el && nativeOnRE.test(key) && isFunction(value)) {
  352. return true;
  353. }
  354. return false;
  355. }
  356. // spellcheck and draggable are numerated attrs, however their
  357. // corresponding DOM properties are actually booleans - this leads to
  358. // setting it with a string "false" value leading it to be coerced to
  359. // `true`, so we need to always treat them as attributes.
  360. // Note that `contentEditable` doesn't have this problem: its DOM
  361. // property is also enumerated string values.
  362. if (key === 'spellcheck' || key === 'draggable') {
  363. return false;
  364. }
  365. // #1787 form as an attribute must be a string, while it accepts an Element as
  366. // a prop
  367. if (key === 'form' && typeof value === 'string') {
  368. return false;
  369. }
  370. // #1526 <input list> must be set as attribute
  371. if (key === 'list' && el.tagName === 'INPUT') {
  372. return false;
  373. }
  374. // native onclick with string value, must be set as attribute
  375. if (nativeOnRE.test(key) && isString(value)) {
  376. return false;
  377. }
  378. return key in el;
  379. }
  380. function useCssModule(name = '$style') {
  381. /* istanbul ignore else */
  382. {
  383. const instance = getCurrentInstance();
  384. if (!instance) {
  385. (process.env.NODE_ENV !== 'production') && warn(`useCssModule must be called inside setup()`);
  386. return EMPTY_OBJ;
  387. }
  388. const modules = instance.type.__cssModules;
  389. if (!modules) {
  390. (process.env.NODE_ENV !== 'production') && warn(`Current instance does not have CSS modules injected.`);
  391. return EMPTY_OBJ;
  392. }
  393. const mod = modules[name];
  394. if (!mod) {
  395. (process.env.NODE_ENV !== 'production') &&
  396. warn(`Current instance does not have CSS module named "${name}".`);
  397. return EMPTY_OBJ;
  398. }
  399. return mod;
  400. }
  401. }
  402. function useCssVars(getter, scoped = false) {
  403. const instance = getCurrentInstance();
  404. /* istanbul ignore next */
  405. if (!instance) {
  406. (process.env.NODE_ENV !== 'production') &&
  407. warn(`useCssVars is called without current active component instance.`);
  408. return;
  409. }
  410. const prefix = scoped && instance.type.__scopeId
  411. ? `${instance.type.__scopeId.replace(/^data-v-/, '')}-`
  412. : ``;
  413. const setVars = () => setVarsOnVNode(instance.subTree, getter(instance.proxy), prefix);
  414. onMounted(() => watchEffect(setVars));
  415. onUpdated(setVars);
  416. }
  417. function setVarsOnVNode(vnode, vars, prefix) {
  418. if ( vnode.shapeFlag & 128 /* SUSPENSE */) {
  419. const suspense = vnode.suspense;
  420. vnode = suspense.activeBranch;
  421. if (suspense.pendingBranch && !suspense.isHydrating) {
  422. suspense.effects.push(() => {
  423. setVarsOnVNode(suspense.activeBranch, vars, prefix);
  424. });
  425. }
  426. }
  427. // drill down HOCs until it's a non-component vnode
  428. while (vnode.component) {
  429. vnode = vnode.component.subTree;
  430. }
  431. if (vnode.shapeFlag & 1 /* ELEMENT */ && vnode.el) {
  432. const style = vnode.el.style;
  433. for (const key in vars) {
  434. style.setProperty(`--${prefix}${key}`, unref(vars[key]));
  435. }
  436. }
  437. else if (vnode.type === Fragment) {
  438. vnode.children.forEach(c => setVarsOnVNode(c, vars, prefix));
  439. }
  440. }
  441. const TRANSITION = 'transition';
  442. const ANIMATION = 'animation';
  443. // DOM Transition is a higher-order-component based on the platform-agnostic
  444. // base Transition component, with DOM-specific logic.
  445. const Transition = (props, { slots }) => h(BaseTransition, resolveTransitionProps(props), slots);
  446. Transition.displayName = 'Transition';
  447. const DOMTransitionPropsValidators = {
  448. name: String,
  449. type: String,
  450. css: {
  451. type: Boolean,
  452. default: true
  453. },
  454. duration: [String, Number, Object],
  455. enterFromClass: String,
  456. enterActiveClass: String,
  457. enterToClass: String,
  458. appearFromClass: String,
  459. appearActiveClass: String,
  460. appearToClass: String,
  461. leaveFromClass: String,
  462. leaveActiveClass: String,
  463. leaveToClass: String
  464. };
  465. const TransitionPropsValidators = (Transition.props = /*#__PURE__*/ extend({}, BaseTransition.props, DOMTransitionPropsValidators));
  466. function resolveTransitionProps(rawProps) {
  467. let { name = 'v', type, css = true, duration, enterFromClass = `${name}-enter-from`, enterActiveClass = `${name}-enter-active`, enterToClass = `${name}-enter-to`, appearFromClass = enterFromClass, appearActiveClass = enterActiveClass, appearToClass = enterToClass, leaveFromClass = `${name}-leave-from`, leaveActiveClass = `${name}-leave-active`, leaveToClass = `${name}-leave-to` } = rawProps;
  468. const baseProps = {};
  469. for (const key in rawProps) {
  470. if (!(key in DOMTransitionPropsValidators)) {
  471. baseProps[key] = rawProps[key];
  472. }
  473. }
  474. if (!css) {
  475. return baseProps;
  476. }
  477. const durations = normalizeDuration(duration);
  478. const enterDuration = durations && durations[0];
  479. const leaveDuration = durations && durations[1];
  480. const { onBeforeEnter, onEnter, onEnterCancelled, onLeave, onLeaveCancelled, onBeforeAppear = onBeforeEnter, onAppear = onEnter, onAppearCancelled = onEnterCancelled } = baseProps;
  481. const finishEnter = (el, isAppear, done) => {
  482. removeTransitionClass(el, isAppear ? appearToClass : enterToClass);
  483. removeTransitionClass(el, isAppear ? appearActiveClass : enterActiveClass);
  484. done && done();
  485. };
  486. const finishLeave = (el, done) => {
  487. removeTransitionClass(el, leaveToClass);
  488. removeTransitionClass(el, leaveActiveClass);
  489. done && done();
  490. };
  491. const makeEnterHook = (isAppear) => {
  492. return (el, done) => {
  493. const hook = isAppear ? onAppear : onEnter;
  494. const resolve = () => finishEnter(el, isAppear, done);
  495. hook && hook(el, resolve);
  496. nextFrame(() => {
  497. removeTransitionClass(el, isAppear ? appearFromClass : enterFromClass);
  498. addTransitionClass(el, isAppear ? appearToClass : enterToClass);
  499. if (!(hook && hook.length > 1)) {
  500. if (enterDuration) {
  501. setTimeout(resolve, enterDuration);
  502. }
  503. else {
  504. whenTransitionEnds(el, type, resolve);
  505. }
  506. }
  507. });
  508. };
  509. };
  510. return extend(baseProps, {
  511. onBeforeEnter(el) {
  512. onBeforeEnter && onBeforeEnter(el);
  513. addTransitionClass(el, enterActiveClass);
  514. addTransitionClass(el, enterFromClass);
  515. },
  516. onBeforeAppear(el) {
  517. onBeforeAppear && onBeforeAppear(el);
  518. addTransitionClass(el, appearActiveClass);
  519. addTransitionClass(el, appearFromClass);
  520. },
  521. onEnter: makeEnterHook(false),
  522. onAppear: makeEnterHook(true),
  523. onLeave(el, done) {
  524. const resolve = () => finishLeave(el, done);
  525. addTransitionClass(el, leaveActiveClass);
  526. addTransitionClass(el, leaveFromClass);
  527. nextFrame(() => {
  528. removeTransitionClass(el, leaveFromClass);
  529. addTransitionClass(el, leaveToClass);
  530. if (!(onLeave && onLeave.length > 1)) {
  531. if (leaveDuration) {
  532. setTimeout(resolve, leaveDuration);
  533. }
  534. else {
  535. whenTransitionEnds(el, type, resolve);
  536. }
  537. }
  538. });
  539. onLeave && onLeave(el, resolve);
  540. },
  541. onEnterCancelled(el) {
  542. finishEnter(el, false);
  543. onEnterCancelled && onEnterCancelled(el);
  544. },
  545. onAppearCancelled(el) {
  546. finishEnter(el, true);
  547. onAppearCancelled && onAppearCancelled(el);
  548. },
  549. onLeaveCancelled(el) {
  550. finishLeave(el);
  551. onLeaveCancelled && onLeaveCancelled(el);
  552. }
  553. });
  554. }
  555. function normalizeDuration(duration) {
  556. if (duration == null) {
  557. return null;
  558. }
  559. else if (isObject(duration)) {
  560. return [NumberOf(duration.enter), NumberOf(duration.leave)];
  561. }
  562. else {
  563. const n = NumberOf(duration);
  564. return [n, n];
  565. }
  566. }
  567. function NumberOf(val) {
  568. const res = toNumber(val);
  569. if ((process.env.NODE_ENV !== 'production'))
  570. validateDuration(res);
  571. return res;
  572. }
  573. function validateDuration(val) {
  574. if (typeof val !== 'number') {
  575. warn(`<transition> explicit duration is not a valid number - ` +
  576. `got ${JSON.stringify(val)}.`);
  577. }
  578. else if (isNaN(val)) {
  579. warn(`<transition> explicit duration is NaN - ` +
  580. 'the duration expression might be incorrect.');
  581. }
  582. }
  583. function addTransitionClass(el, cls) {
  584. cls.split(/\s+/).forEach(c => c && el.classList.add(c));
  585. (el._vtc ||
  586. (el._vtc = new Set())).add(cls);
  587. }
  588. function removeTransitionClass(el, cls) {
  589. cls.split(/\s+/).forEach(c => c && el.classList.remove(c));
  590. const { _vtc } = el;
  591. if (_vtc) {
  592. _vtc.delete(cls);
  593. if (!_vtc.size) {
  594. el._vtc = undefined;
  595. }
  596. }
  597. }
  598. function nextFrame(cb) {
  599. requestAnimationFrame(() => {
  600. requestAnimationFrame(cb);
  601. });
  602. }
  603. function whenTransitionEnds(el, expectedType, cb) {
  604. const { type, timeout, propCount } = getTransitionInfo(el, expectedType);
  605. if (!type) {
  606. return cb();
  607. }
  608. const endEvent = type + 'end';
  609. let ended = 0;
  610. const end = () => {
  611. el.removeEventListener(endEvent, onEnd);
  612. cb();
  613. };
  614. const onEnd = (e) => {
  615. if (e.target === el) {
  616. if (++ended >= propCount) {
  617. end();
  618. }
  619. }
  620. };
  621. setTimeout(() => {
  622. if (ended < propCount) {
  623. end();
  624. }
  625. }, timeout + 1);
  626. el.addEventListener(endEvent, onEnd);
  627. }
  628. function getTransitionInfo(el, expectedType) {
  629. const styles = window.getComputedStyle(el);
  630. // JSDOM may return undefined for transition properties
  631. const getStyleProperties = (key) => (styles[key] || '').split(', ');
  632. const transitionDelays = getStyleProperties(TRANSITION + 'Delay');
  633. const transitionDurations = getStyleProperties(TRANSITION + 'Duration');
  634. const transitionTimeout = getTimeout(transitionDelays, transitionDurations);
  635. const animationDelays = getStyleProperties(ANIMATION + 'Delay');
  636. const animationDurations = getStyleProperties(ANIMATION + 'Duration');
  637. const animationTimeout = getTimeout(animationDelays, animationDurations);
  638. let type = null;
  639. let timeout = 0;
  640. let propCount = 0;
  641. /* istanbul ignore if */
  642. if (expectedType === TRANSITION) {
  643. if (transitionTimeout > 0) {
  644. type = TRANSITION;
  645. timeout = transitionTimeout;
  646. propCount = transitionDurations.length;
  647. }
  648. }
  649. else if (expectedType === ANIMATION) {
  650. if (animationTimeout > 0) {
  651. type = ANIMATION;
  652. timeout = animationTimeout;
  653. propCount = animationDurations.length;
  654. }
  655. }
  656. else {
  657. timeout = Math.max(transitionTimeout, animationTimeout);
  658. type =
  659. timeout > 0
  660. ? transitionTimeout > animationTimeout
  661. ? TRANSITION
  662. : ANIMATION
  663. : null;
  664. propCount = type
  665. ? type === TRANSITION
  666. ? transitionDurations.length
  667. : animationDurations.length
  668. : 0;
  669. }
  670. const hasTransform = type === TRANSITION &&
  671. /\b(transform|all)(,|$)/.test(styles[TRANSITION + 'Property']);
  672. return {
  673. type,
  674. timeout,
  675. propCount,
  676. hasTransform
  677. };
  678. }
  679. function getTimeout(delays, durations) {
  680. while (delays.length < durations.length) {
  681. delays = delays.concat(delays);
  682. }
  683. return Math.max(...durations.map((d, i) => toMs(d) + toMs(delays[i])));
  684. }
  685. // Old versions of Chromium (below 61.0.3163.100) formats floating pointer
  686. // numbers in a locale-dependent way, using a comma instead of a dot.
  687. // If comma is not replaced with a dot, the input will be rounded down
  688. // (i.e. acting as a floor function) causing unexpected behaviors
  689. function toMs(s) {
  690. return Number(s.slice(0, -1).replace(',', '.')) * 1000;
  691. }
  692. function toRaw(observed) {
  693. return ((observed && toRaw(observed["__v_raw" /* RAW */])) || observed);
  694. }
  695. const positionMap = new WeakMap();
  696. const newPositionMap = new WeakMap();
  697. const TransitionGroupImpl = {
  698. name: 'TransitionGroup',
  699. props: /*#__PURE__*/ extend({}, TransitionPropsValidators, {
  700. tag: String,
  701. moveClass: String
  702. }),
  703. setup(props, { slots }) {
  704. const instance = getCurrentInstance();
  705. const state = useTransitionState();
  706. let prevChildren;
  707. let children;
  708. onUpdated(() => {
  709. // children is guaranteed to exist after initial render
  710. if (!prevChildren.length) {
  711. return;
  712. }
  713. const moveClass = props.moveClass || `${props.name || 'v'}-move`;
  714. if (!hasCSSTransform(prevChildren[0].el, instance.vnode.el, moveClass)) {
  715. return;
  716. }
  717. // we divide the work into three loops to avoid mixing DOM reads and writes
  718. // in each iteration - which helps prevent layout thrashing.
  719. prevChildren.forEach(callPendingCbs);
  720. prevChildren.forEach(recordPosition);
  721. const movedChildren = prevChildren.filter(applyTranslation);
  722. // force reflow to put everything in position
  723. forceReflow();
  724. movedChildren.forEach(c => {
  725. const el = c.el;
  726. const style = el.style;
  727. addTransitionClass(el, moveClass);
  728. style.transform = style.webkitTransform = style.transitionDuration = '';
  729. const cb = (el._moveCb = (e) => {
  730. if (e && e.target !== el) {
  731. return;
  732. }
  733. if (!e || /transform$/.test(e.propertyName)) {
  734. el.removeEventListener('transitionend', cb);
  735. el._moveCb = null;
  736. removeTransitionClass(el, moveClass);
  737. }
  738. });
  739. el.addEventListener('transitionend', cb);
  740. });
  741. });
  742. return () => {
  743. const rawProps = toRaw(props);
  744. const cssTransitionProps = resolveTransitionProps(rawProps);
  745. const tag = rawProps.tag || Fragment;
  746. prevChildren = children;
  747. children = slots.default ? getTransitionRawChildren(slots.default()) : [];
  748. for (let i = 0; i < children.length; i++) {
  749. const child = children[i];
  750. if (child.key != null) {
  751. setTransitionHooks(child, resolveTransitionHooks(child, cssTransitionProps, state, instance));
  752. }
  753. else if ((process.env.NODE_ENV !== 'production')) {
  754. warn(`<TransitionGroup> children must be keyed.`);
  755. }
  756. }
  757. if (prevChildren) {
  758. for (let i = 0; i < prevChildren.length; i++) {
  759. const child = prevChildren[i];
  760. setTransitionHooks(child, resolveTransitionHooks(child, cssTransitionProps, state, instance));
  761. positionMap.set(child, child.el.getBoundingClientRect());
  762. }
  763. }
  764. return createVNode(tag, null, children);
  765. };
  766. }
  767. };
  768. const TransitionGroup = TransitionGroupImpl;
  769. function callPendingCbs(c) {
  770. const el = c.el;
  771. if (el._moveCb) {
  772. el._moveCb();
  773. }
  774. if (el._enterCb) {
  775. el._enterCb();
  776. }
  777. }
  778. function recordPosition(c) {
  779. newPositionMap.set(c, c.el.getBoundingClientRect());
  780. }
  781. function applyTranslation(c) {
  782. const oldPos = positionMap.get(c);
  783. const newPos = newPositionMap.get(c);
  784. const dx = oldPos.left - newPos.left;
  785. const dy = oldPos.top - newPos.top;
  786. if (dx || dy) {
  787. const s = c.el.style;
  788. s.transform = s.webkitTransform = `translate(${dx}px,${dy}px)`;
  789. s.transitionDuration = '0s';
  790. return c;
  791. }
  792. }
  793. // this is put in a dedicated function to avoid the line from being treeshaken
  794. function forceReflow() {
  795. return document.body.offsetHeight;
  796. }
  797. function hasCSSTransform(el, root, moveClass) {
  798. // Detect whether an element with the move class applied has
  799. // CSS transitions. Since the element may be inside an entering
  800. // transition at this very moment, we make a clone of it and remove
  801. // all other transition classes applied to ensure only the move class
  802. // is applied.
  803. const clone = el.cloneNode();
  804. if (el._vtc) {
  805. el._vtc.forEach(cls => {
  806. cls.split(/\s+/).forEach(c => c && clone.classList.remove(c));
  807. });
  808. }
  809. moveClass.split(/\s+/).forEach(c => c && clone.classList.add(c));
  810. clone.style.display = 'none';
  811. const container = (root.nodeType === 1
  812. ? root
  813. : root.parentNode);
  814. container.appendChild(clone);
  815. const { hasTransform } = getTransitionInfo(clone);
  816. container.removeChild(clone);
  817. return hasTransform;
  818. }
  819. const getModelAssigner = (vnode) => {
  820. const fn = vnode.props['onUpdate:modelValue'];
  821. return isArray(fn) ? value => invokeArrayFns(fn, value) : fn;
  822. };
  823. function onCompositionStart(e) {
  824. e.target.composing = true;
  825. }
  826. function onCompositionEnd(e) {
  827. const target = e.target;
  828. if (target.composing) {
  829. target.composing = false;
  830. trigger(target, 'input');
  831. }
  832. }
  833. function trigger(el, type) {
  834. const e = document.createEvent('HTMLEvents');
  835. e.initEvent(type, true, true);
  836. el.dispatchEvent(e);
  837. }
  838. // We are exporting the v-model runtime directly as vnode hooks so that it can
  839. // be tree-shaken in case v-model is never used.
  840. const vModelText = {
  841. created(el, { modifiers: { lazy, trim, number } }, vnode) {
  842. el._assign = getModelAssigner(vnode);
  843. const castToNumber = number || el.type === 'number';
  844. addEventListener(el, lazy ? 'change' : 'input', e => {
  845. if (e.target.composing)
  846. return;
  847. let domValue = el.value;
  848. if (trim) {
  849. domValue = domValue.trim();
  850. }
  851. else if (castToNumber) {
  852. domValue = toNumber(domValue);
  853. }
  854. el._assign(domValue);
  855. });
  856. if (trim) {
  857. addEventListener(el, 'change', () => {
  858. el.value = el.value.trim();
  859. });
  860. }
  861. if (!lazy) {
  862. addEventListener(el, 'compositionstart', onCompositionStart);
  863. addEventListener(el, 'compositionend', onCompositionEnd);
  864. // Safari < 10.2 & UIWebView doesn't fire compositionend when
  865. // switching focus before confirming composition choice
  866. // this also fixes the issue where some browsers e.g. iOS Chrome
  867. // fires "change" instead of "input" on autocomplete.
  868. addEventListener(el, 'change', onCompositionEnd);
  869. }
  870. },
  871. // set value on mounted so it's after min/max for type="range"
  872. mounted(el, { value }) {
  873. el.value = value == null ? '' : value;
  874. },
  875. beforeUpdate(el, { value, modifiers: { trim, number } }, vnode) {
  876. el._assign = getModelAssigner(vnode);
  877. // avoid clearing unresolved text. #2302
  878. if (el.composing)
  879. return;
  880. if (document.activeElement === el) {
  881. if (trim && el.value.trim() === value) {
  882. return;
  883. }
  884. if ((number || el.type === 'number') && toNumber(el.value) === value) {
  885. return;
  886. }
  887. }
  888. const newValue = value == null ? '' : value;
  889. if (el.value !== newValue) {
  890. el.value = newValue;
  891. }
  892. }
  893. };
  894. const vModelCheckbox = {
  895. created(el, binding, vnode) {
  896. setChecked(el, binding, vnode);
  897. el._assign = getModelAssigner(vnode);
  898. addEventListener(el, 'change', () => {
  899. const modelValue = el._modelValue;
  900. const elementValue = getValue(el);
  901. const checked = el.checked;
  902. const assign = el._assign;
  903. if (isArray(modelValue)) {
  904. const index = looseIndexOf(modelValue, elementValue);
  905. const found = index !== -1;
  906. if (checked && !found) {
  907. assign(modelValue.concat(elementValue));
  908. }
  909. else if (!checked && found) {
  910. const filtered = [...modelValue];
  911. filtered.splice(index, 1);
  912. assign(filtered);
  913. }
  914. }
  915. else if (isSet(modelValue)) {
  916. if (checked) {
  917. modelValue.add(elementValue);
  918. }
  919. else {
  920. modelValue.delete(elementValue);
  921. }
  922. }
  923. else {
  924. assign(getCheckboxValue(el, checked));
  925. }
  926. });
  927. },
  928. beforeUpdate(el, binding, vnode) {
  929. el._assign = getModelAssigner(vnode);
  930. setChecked(el, binding, vnode);
  931. }
  932. };
  933. function setChecked(el, { value, oldValue }, vnode) {
  934. el._modelValue = value;
  935. if (isArray(value)) {
  936. el.checked = looseIndexOf(value, vnode.props.value) > -1;
  937. }
  938. else if (isSet(value)) {
  939. el.checked = value.has(vnode.props.value);
  940. }
  941. else if (value !== oldValue) {
  942. el.checked = looseEqual(value, getCheckboxValue(el, true));
  943. }
  944. }
  945. const vModelRadio = {
  946. created(el, { value }, vnode) {
  947. el.checked = looseEqual(value, vnode.props.value);
  948. el._assign = getModelAssigner(vnode);
  949. addEventListener(el, 'change', () => {
  950. el._assign(getValue(el));
  951. });
  952. },
  953. beforeUpdate(el, { value, oldValue }, vnode) {
  954. el._assign = getModelAssigner(vnode);
  955. if (value !== oldValue) {
  956. el.checked = looseEqual(value, vnode.props.value);
  957. }
  958. }
  959. };
  960. const vModelSelect = {
  961. created(el, { modifiers: { number } }, vnode) {
  962. addEventListener(el, 'change', () => {
  963. const selectedVal = Array.prototype.filter
  964. .call(el.options, (o) => o.selected)
  965. .map((o) => number ? toNumber(getValue(o)) : getValue(o));
  966. el._assign(el.multiple ? selectedVal : selectedVal[0]);
  967. });
  968. el._assign = getModelAssigner(vnode);
  969. },
  970. // set value in mounted & updated because <select> relies on its children
  971. // <option>s.
  972. mounted(el, { value }) {
  973. setSelected(el, value);
  974. },
  975. beforeUpdate(el, _binding, vnode) {
  976. el._assign = getModelAssigner(vnode);
  977. },
  978. updated(el, { value }) {
  979. setSelected(el, value);
  980. }
  981. };
  982. function setSelected(el, value) {
  983. const isMultiple = el.multiple;
  984. if (isMultiple && !isArray(value) && !isSet(value)) {
  985. (process.env.NODE_ENV !== 'production') &&
  986. warn(`<select multiple v-model> expects an Array or Set value for its binding, ` +
  987. `but got ${Object.prototype.toString.call(value).slice(8, -1)}.`);
  988. return;
  989. }
  990. for (let i = 0, l = el.options.length; i < l; i++) {
  991. const option = el.options[i];
  992. const optionValue = getValue(option);
  993. if (isMultiple) {
  994. if (isArray(value)) {
  995. option.selected = looseIndexOf(value, optionValue) > -1;
  996. }
  997. else {
  998. option.selected = value.has(optionValue);
  999. }
  1000. }
  1001. else {
  1002. if (looseEqual(getValue(option), value)) {
  1003. el.selectedIndex = i;
  1004. return;
  1005. }
  1006. }
  1007. }
  1008. if (!isMultiple) {
  1009. el.selectedIndex = -1;
  1010. }
  1011. }
  1012. // retrieve raw value set via :value bindings
  1013. function getValue(el) {
  1014. return '_value' in el ? el._value : el.value;
  1015. }
  1016. // retrieve raw value for true-value and false-value set via :true-value or :false-value bindings
  1017. function getCheckboxValue(el, checked) {
  1018. const key = checked ? '_trueValue' : '_falseValue';
  1019. return key in el ? el[key] : checked;
  1020. }
  1021. const vModelDynamic = {
  1022. created(el, binding, vnode) {
  1023. callModelHook(el, binding, vnode, null, 'created');
  1024. },
  1025. mounted(el, binding, vnode) {
  1026. callModelHook(el, binding, vnode, null, 'mounted');
  1027. },
  1028. beforeUpdate(el, binding, vnode, prevVNode) {
  1029. callModelHook(el, binding, vnode, prevVNode, 'beforeUpdate');
  1030. },
  1031. updated(el, binding, vnode, prevVNode) {
  1032. callModelHook(el, binding, vnode, prevVNode, 'updated');
  1033. }
  1034. };
  1035. function callModelHook(el, binding, vnode, prevVNode, hook) {
  1036. let modelToUse;
  1037. switch (el.tagName) {
  1038. case 'SELECT':
  1039. modelToUse = vModelSelect;
  1040. break;
  1041. case 'TEXTAREA':
  1042. modelToUse = vModelText;
  1043. break;
  1044. default:
  1045. switch (vnode.props && vnode.props.type) {
  1046. case 'checkbox':
  1047. modelToUse = vModelCheckbox;
  1048. break;
  1049. case 'radio':
  1050. modelToUse = vModelRadio;
  1051. break;
  1052. default:
  1053. modelToUse = vModelText;
  1054. }
  1055. }
  1056. const fn = modelToUse[hook];
  1057. fn && fn(el, binding, vnode, prevVNode);
  1058. }
  1059. const systemModifiers = ['ctrl', 'shift', 'alt', 'meta'];
  1060. const modifierGuards = {
  1061. stop: e => e.stopPropagation(),
  1062. prevent: e => e.preventDefault(),
  1063. self: e => e.target !== e.currentTarget,
  1064. ctrl: e => !e.ctrlKey,
  1065. shift: e => !e.shiftKey,
  1066. alt: e => !e.altKey,
  1067. meta: e => !e.metaKey,
  1068. left: e => 'button' in e && e.button !== 0,
  1069. middle: e => 'button' in e && e.button !== 1,
  1070. right: e => 'button' in e && e.button !== 2,
  1071. exact: (e, modifiers) => systemModifiers.some(m => e[`${m}Key`] && !modifiers.includes(m))
  1072. };
  1073. /**
  1074. * @private
  1075. */
  1076. const withModifiers = (fn, modifiers) => {
  1077. return (event, ...args) => {
  1078. for (let i = 0; i < modifiers.length; i++) {
  1079. const guard = modifierGuards[modifiers[i]];
  1080. if (guard && guard(event, modifiers))
  1081. return;
  1082. }
  1083. return fn(event, ...args);
  1084. };
  1085. };
  1086. // Kept for 2.x compat.
  1087. // Note: IE11 compat for `spacebar` and `del` is removed for now.
  1088. const keyNames = {
  1089. esc: 'escape',
  1090. space: ' ',
  1091. up: 'arrow-up',
  1092. left: 'arrow-left',
  1093. right: 'arrow-right',
  1094. down: 'arrow-down',
  1095. delete: 'backspace'
  1096. };
  1097. /**
  1098. * @private
  1099. */
  1100. const withKeys = (fn, modifiers) => {
  1101. return (event) => {
  1102. if (!('key' in event))
  1103. return;
  1104. const eventKey = hyphenate(event.key);
  1105. if (
  1106. // None of the provided key modifiers match the current event key
  1107. !modifiers.some(k => k === eventKey || keyNames[k] === eventKey)) {
  1108. return;
  1109. }
  1110. return fn(event);
  1111. };
  1112. };
  1113. const vShow = {
  1114. beforeMount(el, { value }, { transition }) {
  1115. el._vod = el.style.display === 'none' ? '' : el.style.display;
  1116. if (transition && value) {
  1117. transition.beforeEnter(el);
  1118. }
  1119. else {
  1120. setDisplay(el, value);
  1121. }
  1122. },
  1123. mounted(el, { value }, { transition }) {
  1124. if (transition && value) {
  1125. transition.enter(el);
  1126. }
  1127. },
  1128. updated(el, { value, oldValue }, { transition }) {
  1129. if (!value === !oldValue)
  1130. return;
  1131. if (transition) {
  1132. if (value) {
  1133. transition.beforeEnter(el);
  1134. setDisplay(el, true);
  1135. transition.enter(el);
  1136. }
  1137. else {
  1138. transition.leave(el, () => {
  1139. setDisplay(el, false);
  1140. });
  1141. }
  1142. }
  1143. else {
  1144. setDisplay(el, value);
  1145. }
  1146. },
  1147. beforeUnmount(el, { value }) {
  1148. setDisplay(el, value);
  1149. }
  1150. };
  1151. function setDisplay(el, value) {
  1152. el.style.display = value ? el._vod : 'none';
  1153. }
  1154. const rendererOptions = extend({ patchProp, forcePatchProp }, nodeOps);
  1155. // lazy create the renderer - this makes core renderer logic tree-shakable
  1156. // in case the user only imports reactivity utilities from Vue.
  1157. let renderer;
  1158. let enabledHydration = false;
  1159. function ensureRenderer() {
  1160. return renderer || (renderer = createRenderer(rendererOptions));
  1161. }
  1162. function ensureHydrationRenderer() {
  1163. renderer = enabledHydration
  1164. ? renderer
  1165. : createHydrationRenderer(rendererOptions);
  1166. enabledHydration = true;
  1167. return renderer;
  1168. }
  1169. // use explicit type casts here to avoid import() calls in rolled-up d.ts
  1170. const render = ((...args) => {
  1171. ensureRenderer().render(...args);
  1172. });
  1173. const hydrate = ((...args) => {
  1174. ensureHydrationRenderer().hydrate(...args);
  1175. });
  1176. const createApp = ((...args) => {
  1177. const app = ensureRenderer().createApp(...args);
  1178. if ((process.env.NODE_ENV !== 'production')) {
  1179. injectNativeTagCheck(app);
  1180. }
  1181. const { mount } = app;
  1182. app.mount = (containerOrSelector) => {
  1183. const container = normalizeContainer(containerOrSelector);
  1184. if (!container)
  1185. return;
  1186. const component = app._component;
  1187. if (!isFunction(component) && !component.render && !component.template) {
  1188. component.template = container.innerHTML;
  1189. }
  1190. // clear content before mounting
  1191. container.innerHTML = '';
  1192. const proxy = mount(container);
  1193. container.removeAttribute('v-cloak');
  1194. container.setAttribute('data-v-app', '');
  1195. return proxy;
  1196. };
  1197. return app;
  1198. });
  1199. const createSSRApp = ((...args) => {
  1200. const app = ensureHydrationRenderer().createApp(...args);
  1201. if ((process.env.NODE_ENV !== 'production')) {
  1202. injectNativeTagCheck(app);
  1203. }
  1204. const { mount } = app;
  1205. app.mount = (containerOrSelector) => {
  1206. const container = normalizeContainer(containerOrSelector);
  1207. if (container) {
  1208. return mount(container, true);
  1209. }
  1210. };
  1211. return app;
  1212. });
  1213. function injectNativeTagCheck(app) {
  1214. // Inject `isNativeTag`
  1215. // this is used for component name validation (dev only)
  1216. Object.defineProperty(app.config, 'isNativeTag', {
  1217. value: (tag) => isHTMLTag(tag) || isSVGTag(tag),
  1218. writable: false
  1219. });
  1220. }
  1221. function normalizeContainer(container) {
  1222. if (isString(container)) {
  1223. const res = document.querySelector(container);
  1224. if ((process.env.NODE_ENV !== 'production') && !res) {
  1225. warn(`Failed to mount app: mount target selector returned null.`);
  1226. }
  1227. return res;
  1228. }
  1229. return container;
  1230. }
  1231. export { Transition, TransitionGroup, createApp, createSSRApp, hydrate, render, useCssModule, useCssVars, vModelCheckbox, vModelDynamic, vModelRadio, vModelSelect, vModelText, vShow, withKeys, withModifiers };