@vue/compat 3.2.22 → 3.2.26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -40,7 +40,7 @@ const specialBooleanAttrs = `itemscope,allowfullscreen,formnovalidate,ismap,nomo
40
40
  const isSpecialBooleanAttr = /*#__PURE__*/ makeMap(specialBooleanAttrs);
41
41
  /**
42
42
  * Boolean attributes should be included if the value is truthy or ''.
43
- * e.g. <select multiple> compiles to { multiple: '' }
43
+ * e.g. `<select multiple>` compiles to `{ multiple: '' }`
44
44
  */
45
45
  function includeBooleanAttr(value) {
46
46
  return !!value || value === '';
@@ -404,7 +404,7 @@ const isIntegerKey = (key) => isString(key) &&
404
404
  '' + parseInt(key, 10) === key;
405
405
  const isReservedProp = /*#__PURE__*/ makeMap(
406
406
  // the leading comma is intentional so empty string "" is also included
407
- ',key,ref,' +
407
+ ',key,ref,ref_for,ref_key,' +
408
408
  'onVnodeBeforeMount,onVnodeMounted,' +
409
409
  'onVnodeBeforeUpdate,onVnodeUpdated,' +
410
410
  'onVnodeBeforeUnmount,onVnodeUnmounted');
@@ -582,7 +582,7 @@ const targetMap = new WeakMap();
582
582
  let effectTrackDepth = 0;
583
583
  let trackOpBit = 1;
584
584
  /**
585
- * The bitwise track markers support at most 30 levels op recursion.
585
+ * The bitwise track markers support at most 30 levels of recursion.
586
586
  * This value is chosen to enable modern JS engines to use a SMI on all platforms.
587
587
  * When recursion depth is greater, fall back to using a full cleanup.
588
588
  */
@@ -891,7 +891,7 @@ const shallowSet = /*#__PURE__*/ createSetter(true);
891
891
  function createSetter(shallow = false) {
892
892
  return function set(target, key, value, receiver) {
893
893
  let oldValue = target[key];
894
- if (!shallow) {
894
+ if (!shallow && !isReadonly(value)) {
895
895
  value = toRaw(value);
896
896
  oldValue = toRaw(oldValue);
897
897
  if (!isArray(target) && isRef(oldValue) && !isRef(value)) {
@@ -1430,21 +1430,25 @@ function toRefs(object) {
1430
1430
  return ret;
1431
1431
  }
1432
1432
  class ObjectRefImpl {
1433
- constructor(_object, _key) {
1433
+ constructor(_object, _key, _defaultValue) {
1434
1434
  this._object = _object;
1435
1435
  this._key = _key;
1436
+ this._defaultValue = _defaultValue;
1436
1437
  this.__v_isRef = true;
1437
1438
  }
1438
1439
  get value() {
1439
- return this._object[this._key];
1440
+ const val = this._object[this._key];
1441
+ return val === undefined ? this._defaultValue : val;
1440
1442
  }
1441
1443
  set value(newVal) {
1442
1444
  this._object[this._key] = newVal;
1443
1445
  }
1444
1446
  }
1445
- function toRef(object, key) {
1447
+ function toRef(object, key, defaultValue) {
1446
1448
  const val = object[key];
1447
- return isRef(val) ? val : new ObjectRefImpl(object, key);
1449
+ return isRef(val)
1450
+ ? val
1451
+ : new ObjectRefImpl(object, key, defaultValue);
1448
1452
  }
1449
1453
 
1450
1454
  class ComputedRefImpl {
@@ -3207,7 +3211,7 @@ function registerKeepAliveHook(hook, type, target = currentInstance) {
3207
3211
  }
3208
3212
  current = current.parent;
3209
3213
  }
3210
- hook();
3214
+ return hook();
3211
3215
  });
3212
3216
  injectHook(type, wrappedHook, target);
3213
3217
  // In addition to registering it on the target instance, we walk up the parent
@@ -3879,7 +3883,7 @@ function setFullProps(instance, rawProps, props, attrs) {
3879
3883
  continue;
3880
3884
  }
3881
3885
  }
3882
- if (value !== attrs[key]) {
3886
+ if (!(key in attrs) || value !== attrs[key]) {
3883
3887
  attrs[key] = value;
3884
3888
  hasAttrsChanged = true;
3885
3889
  }
@@ -4269,7 +4273,7 @@ function createCompatVue(createApp, createSingletonApp) {
4269
4273
  return vm;
4270
4274
  }
4271
4275
  }
4272
- Vue.version = "3.2.22";
4276
+ Vue.version = "3.2.26";
4273
4277
  Vue.config = singletonApp.config;
4274
4278
  Vue.use = (p, ...options) => {
4275
4279
  if (p && isFunction(p.install)) {
@@ -4580,7 +4584,7 @@ const methodsToPatch = [
4580
4584
  ];
4581
4585
  const patched = new WeakSet();
4582
4586
  function defineReactive(obj, key, val) {
4583
- // it's possible for the orignial object to be mutated after being defined
4587
+ // it's possible for the original object to be mutated after being defined
4584
4588
  // and expecting reactivity... we are covering it here because this seems to
4585
4589
  // be a bit more common.
4586
4590
  if (isObject(val) && !isReactive(val) && !patched.has(val)) {
@@ -4748,6 +4752,92 @@ function createAppAPI(render, hydrate) {
4748
4752
  };
4749
4753
  }
4750
4754
 
4755
+ /**
4756
+ * Function for handling a template ref
4757
+ */
4758
+ function setRef(rawRef, oldRawRef, parentSuspense, vnode, isUnmount = false) {
4759
+ if (isArray(rawRef)) {
4760
+ rawRef.forEach((r, i) => setRef(r, oldRawRef && (isArray(oldRawRef) ? oldRawRef[i] : oldRawRef), parentSuspense, vnode, isUnmount));
4761
+ return;
4762
+ }
4763
+ if (isAsyncWrapper(vnode) && !isUnmount) {
4764
+ // when mounting async components, nothing needs to be done,
4765
+ // because the template ref is forwarded to inner component
4766
+ return;
4767
+ }
4768
+ const refValue = vnode.shapeFlag & 4 /* STATEFUL_COMPONENT */
4769
+ ? getExposeProxy(vnode.component) || vnode.component.proxy
4770
+ : vnode.el;
4771
+ const value = isUnmount ? null : refValue;
4772
+ const { i: owner, r: ref } = rawRef;
4773
+ const oldRef = oldRawRef && oldRawRef.r;
4774
+ const refs = owner.refs === EMPTY_OBJ ? (owner.refs = {}) : owner.refs;
4775
+ const setupState = owner.setupState;
4776
+ // dynamic ref changed. unset old ref
4777
+ if (oldRef != null && oldRef !== ref) {
4778
+ if (isString(oldRef)) {
4779
+ refs[oldRef] = null;
4780
+ if (hasOwn(setupState, oldRef)) {
4781
+ setupState[oldRef] = null;
4782
+ }
4783
+ }
4784
+ else if (isRef(oldRef)) {
4785
+ oldRef.value = null;
4786
+ }
4787
+ }
4788
+ if (isFunction(ref)) {
4789
+ callWithErrorHandling(ref, owner, 12 /* FUNCTION_REF */, [value, refs]);
4790
+ }
4791
+ else {
4792
+ const _isString = isString(ref);
4793
+ const _isRef = isRef(ref);
4794
+ if (_isString || _isRef) {
4795
+ const doSet = () => {
4796
+ if (rawRef.f) {
4797
+ const existing = _isString ? refs[ref] : ref.value;
4798
+ if (isUnmount) {
4799
+ isArray(existing) && remove(existing, refValue);
4800
+ }
4801
+ else {
4802
+ if (!isArray(existing)) {
4803
+ if (_isString) {
4804
+ refs[ref] = [refValue];
4805
+ }
4806
+ else {
4807
+ ref.value = [refValue];
4808
+ if (rawRef.k)
4809
+ refs[rawRef.k] = ref.value;
4810
+ }
4811
+ }
4812
+ else if (!existing.includes(refValue)) {
4813
+ existing.push(refValue);
4814
+ }
4815
+ }
4816
+ }
4817
+ else if (_isString) {
4818
+ refs[ref] = value;
4819
+ if (hasOwn(setupState, ref)) {
4820
+ setupState[ref] = value;
4821
+ }
4822
+ }
4823
+ else if (isRef(ref)) {
4824
+ ref.value = value;
4825
+ if (rawRef.k)
4826
+ refs[rawRef.k] = value;
4827
+ }
4828
+ else ;
4829
+ };
4830
+ if (value) {
4831
+ doSet.id = -1;
4832
+ queuePostRenderEffect(doSet, parentSuspense);
4833
+ }
4834
+ else {
4835
+ doSet();
4836
+ }
4837
+ }
4838
+ }
4839
+ }
4840
+
4751
4841
  let hasMismatch = false;
4752
4842
  const isSVGContainer = (container) => /svg/.test(container.namespaceURI) && container.tagName !== 'foreignObject';
4753
4843
  const isComment = (node) => node.nodeType === 8 /* COMMENT */;
@@ -5043,43 +5133,6 @@ function createHydrationFunctions(rendererInternals) {
5043
5133
  return [hydrate, hydrateNode];
5044
5134
  }
5045
5135
 
5046
- function convertLegacyRefInFor(vnode) {
5047
- // refInFor
5048
- if (vnode.props && vnode.props.refInFor) {
5049
- delete vnode.props.refInFor;
5050
- if (vnode.ref) {
5051
- if (isArray(vnode.ref)) {
5052
- vnode.ref.forEach(r => (r.f = true));
5053
- }
5054
- else {
5055
- vnode.ref.f = true;
5056
- }
5057
- }
5058
- }
5059
- }
5060
- function registerLegacyRef(refs, key, value, owner, isInFor, isUnmount) {
5061
- const existing = refs[key];
5062
- if (isUnmount) {
5063
- if (isArray(existing)) {
5064
- remove(existing, value);
5065
- }
5066
- else {
5067
- refs[key] = null;
5068
- }
5069
- }
5070
- else if (isInFor) {
5071
- if (!isArray(existing)) {
5072
- refs[key] = [value];
5073
- }
5074
- else if (!existing.includes(value)) {
5075
- existing.push(value);
5076
- }
5077
- }
5078
- else {
5079
- refs[key] = value;
5080
- }
5081
- }
5082
-
5083
5136
  const queuePostRenderEffect = queueEffectWithSuspense
5084
5137
  ;
5085
5138
  /**
@@ -5321,12 +5374,15 @@ function baseCreateRenderer(options, createHydrationFns) {
5321
5374
  const oldProps = n1.props || EMPTY_OBJ;
5322
5375
  const newProps = n2.props || EMPTY_OBJ;
5323
5376
  let vnodeHook;
5377
+ // disable recurse in beforeUpdate hooks
5378
+ parentComponent && toggleRecurse(parentComponent, false);
5324
5379
  if ((vnodeHook = newProps.onVnodeBeforeUpdate)) {
5325
5380
  invokeVNodeHook(vnodeHook, parentComponent, n2, n1);
5326
5381
  }
5327
5382
  if (dirs) {
5328
5383
  invokeDirectiveHook(n2, n1, parentComponent, 'beforeUpdate');
5329
5384
  }
5385
+ parentComponent && toggleRecurse(parentComponent, true);
5330
5386
  const areChildrenSVG = isSVG && n2.type !== 'foreignObject';
5331
5387
  if (dynamicChildren) {
5332
5388
  patchBlockChildren(n1.dynamicChildren, dynamicChildren, el, parentComponent, parentSuspense, areChildrenSVG, slotScopeIds);
@@ -5567,7 +5623,7 @@ function baseCreateRenderer(options, createHydrationFns) {
5567
5623
  const { el, props } = initialVNode;
5568
5624
  const { bm, m, parent } = instance;
5569
5625
  const isAsyncWrapperVNode = isAsyncWrapper(initialVNode);
5570
- effect.allowRecurse = false;
5626
+ toggleRecurse(instance, false);
5571
5627
  // beforeMount hook
5572
5628
  if (bm) {
5573
5629
  invokeArrayFns(bm);
@@ -5580,7 +5636,7 @@ function baseCreateRenderer(options, createHydrationFns) {
5580
5636
  if (isCompatEnabled("INSTANCE_EVENT_HOOKS" /* INSTANCE_EVENT_HOOKS */, instance)) {
5581
5637
  instance.emit('hook:beforeMount');
5582
5638
  }
5583
- effect.allowRecurse = true;
5639
+ toggleRecurse(instance, true);
5584
5640
  if (el && hydrateNode) {
5585
5641
  // vnode has adopted host node - perform hydration instead of mount.
5586
5642
  const hydrateSubTree = () => {
@@ -5638,7 +5694,7 @@ function baseCreateRenderer(options, createHydrationFns) {
5638
5694
  let originNext = next;
5639
5695
  let vnodeHook;
5640
5696
  // Disallow component effect recursion during pre-lifecycle hooks.
5641
- effect.allowRecurse = false;
5697
+ toggleRecurse(instance, false);
5642
5698
  if (next) {
5643
5699
  next.el = vnode.el;
5644
5700
  updateComponentPreRender(instance, next, optimized);
@@ -5657,7 +5713,7 @@ function baseCreateRenderer(options, createHydrationFns) {
5657
5713
  if (isCompatEnabled("INSTANCE_EVENT_HOOKS" /* INSTANCE_EVENT_HOOKS */, instance)) {
5658
5714
  instance.emit('hook:beforeUpdate');
5659
5715
  }
5660
- effect.allowRecurse = true;
5716
+ toggleRecurse(instance, true);
5661
5717
  const nextTree = renderComponentRoot(instance);
5662
5718
  const prevTree = instance.subTree;
5663
5719
  instance.subTree = nextTree;
@@ -5687,13 +5743,13 @@ function baseCreateRenderer(options, createHydrationFns) {
5687
5743
  }
5688
5744
  };
5689
5745
  // create reactive effect for rendering
5690
- const effect = new ReactiveEffect(componentUpdateFn, () => queueJob(instance.update), instance.scope // track it in component's effect scope
5691
- );
5746
+ const effect = (instance.effect = new ReactiveEffect(componentUpdateFn, () => queueJob(instance.update), instance.scope // track it in component's effect scope
5747
+ ));
5692
5748
  const update = (instance.update = effect.run.bind(effect));
5693
5749
  update.id = instance.uid;
5694
5750
  // allowRecurse
5695
5751
  // #1801, #2043 component render effects should allow recursive updates
5696
- effect.allowRecurse = update.allowRecurse = true;
5752
+ toggleRecurse(instance, true);
5697
5753
  update();
5698
5754
  };
5699
5755
  const updateComponentPreRender = (instance, nextVNode, optimized) => {
@@ -6204,81 +6260,8 @@ function baseCreateRenderer(options, createHydrationFns) {
6204
6260
  createApp: createAppAPI(render, hydrate)
6205
6261
  };
6206
6262
  }
6207
- function setRef(rawRef, oldRawRef, parentSuspense, vnode, isUnmount = false) {
6208
- if (isArray(rawRef)) {
6209
- rawRef.forEach((r, i) => setRef(r, oldRawRef && (isArray(oldRawRef) ? oldRawRef[i] : oldRawRef), parentSuspense, vnode, isUnmount));
6210
- return;
6211
- }
6212
- if (isAsyncWrapper(vnode) && !isUnmount) {
6213
- // when mounting async components, nothing needs to be done,
6214
- // because the template ref is forwarded to inner component
6215
- return;
6216
- }
6217
- const refValue = vnode.shapeFlag & 4 /* STATEFUL_COMPONENT */
6218
- ? getExposeProxy(vnode.component) || vnode.component.proxy
6219
- : vnode.el;
6220
- const value = isUnmount ? null : refValue;
6221
- const { i: owner, r: ref } = rawRef;
6222
- const oldRef = oldRawRef && oldRawRef.r;
6223
- const refs = owner.refs === EMPTY_OBJ ? (owner.refs = {}) : owner.refs;
6224
- const setupState = owner.setupState;
6225
- // dynamic ref changed. unset old ref
6226
- if (oldRef != null && oldRef !== ref) {
6227
- if (isString(oldRef)) {
6228
- refs[oldRef] = null;
6229
- if (hasOwn(setupState, oldRef)) {
6230
- setupState[oldRef] = null;
6231
- }
6232
- }
6233
- else if (isRef(oldRef)) {
6234
- oldRef.value = null;
6235
- }
6236
- }
6237
- if (isString(ref)) {
6238
- const doSet = () => {
6239
- if (isCompatEnabled("V_FOR_REF" /* V_FOR_REF */, owner)) {
6240
- registerLegacyRef(refs, ref, refValue, owner, rawRef.f, isUnmount);
6241
- }
6242
- else {
6243
- refs[ref] = value;
6244
- }
6245
- if (hasOwn(setupState, ref)) {
6246
- setupState[ref] = value;
6247
- }
6248
- };
6249
- // #1789: for non-null values, set them after render
6250
- // null values means this is unmount and it should not overwrite another
6251
- // ref with the same key
6252
- if (value) {
6253
- doSet.id = -1;
6254
- queuePostRenderEffect(doSet, parentSuspense);
6255
- }
6256
- else {
6257
- doSet();
6258
- }
6259
- }
6260
- else if (isRef(ref)) {
6261
- const doSet = () => {
6262
- ref.value = value;
6263
- };
6264
- if (value) {
6265
- doSet.id = -1;
6266
- queuePostRenderEffect(doSet, parentSuspense);
6267
- }
6268
- else {
6269
- doSet();
6270
- }
6271
- }
6272
- else if (isFunction(ref)) {
6273
- callWithErrorHandling(ref, owner, 12 /* FUNCTION_REF */, [value, refs]);
6274
- }
6275
- else ;
6276
- }
6277
- function invokeVNodeHook(hook, instance, vnode, prevVNode = null) {
6278
- callWithAsyncErrorHandling(hook, instance, 7 /* VNODE_HOOK */, [
6279
- vnode,
6280
- prevVNode
6281
- ]);
6263
+ function toggleRecurse({ effect, update }, allowed) {
6264
+ effect.allowRecurse = update.allowRecurse = allowed;
6282
6265
  }
6283
6266
  /**
6284
6267
  * #1156
@@ -6886,6 +6869,7 @@ function convertLegacyFunctionalComponent(comp) {
6886
6869
  };
6887
6870
  Func.props = comp.props;
6888
6871
  Func.displayName = comp.name;
6872
+ Func.compatConfig = comp.compatConfig;
6889
6873
  // v2 functional components do not inherit attrs
6890
6874
  Func.inheritAttrs = false;
6891
6875
  normalizedFunctionalComponentMap.set(comp, Func);
@@ -7019,10 +7003,10 @@ function transformVNodeArgs(transformer) {
7019
7003
  }
7020
7004
  const InternalObjectKey = `__vInternal`;
7021
7005
  const normalizeKey = ({ key }) => key != null ? key : null;
7022
- const normalizeRef = ({ ref }) => {
7006
+ const normalizeRef = ({ ref, ref_key, ref_for }) => {
7023
7007
  return (ref != null
7024
7008
  ? isString(ref) || isRef(ref) || isFunction(ref)
7025
- ? { i: currentRenderingInstance, r: ref }
7009
+ ? { i: currentRenderingInstance, r: ref, k: ref_key, f: !!ref_for }
7026
7010
  : ref
7027
7011
  : null);
7028
7012
  };
@@ -7086,7 +7070,6 @@ function createBaseVNode(type, props = null, children = null, patchFlag = 0, dyn
7086
7070
  }
7087
7071
  {
7088
7072
  convertLegacyVModelProps(vnode);
7089
- convertLegacyRefInFor(vnode);
7090
7073
  defineLegacyVNodeProperties(vnode);
7091
7074
  }
7092
7075
  return vnode;
@@ -7349,6 +7332,12 @@ function mergeProps(...args) {
7349
7332
  }
7350
7333
  }
7351
7334
  return ret;
7335
+ }
7336
+ function invokeVNodeHook(hook, instance, vnode, prevVNode = null) {
7337
+ callWithAsyncErrorHandling(hook, instance, 7 /* VNODE_HOOK */, [
7338
+ vnode,
7339
+ prevVNode
7340
+ ]);
7352
7341
  }
7353
7342
 
7354
7343
  function getCompatChildren(instance) {
@@ -7754,23 +7743,23 @@ const PublicInstanceProxyHandlers = {
7754
7743
  const n = accessCache[key];
7755
7744
  if (n !== undefined) {
7756
7745
  switch (n) {
7757
- case 0 /* SETUP */:
7746
+ case 1 /* SETUP */:
7758
7747
  return setupState[key];
7759
- case 1 /* DATA */:
7748
+ case 2 /* DATA */:
7760
7749
  return data[key];
7761
- case 3 /* CONTEXT */:
7750
+ case 4 /* CONTEXT */:
7762
7751
  return ctx[key];
7763
- case 2 /* PROPS */:
7752
+ case 3 /* PROPS */:
7764
7753
  return props[key];
7765
7754
  // default: just fallthrough
7766
7755
  }
7767
7756
  }
7768
7757
  else if (setupState !== EMPTY_OBJ && hasOwn(setupState, key)) {
7769
- accessCache[key] = 0 /* SETUP */;
7758
+ accessCache[key] = 1 /* SETUP */;
7770
7759
  return setupState[key];
7771
7760
  }
7772
7761
  else if (data !== EMPTY_OBJ && hasOwn(data, key)) {
7773
- accessCache[key] = 1 /* DATA */;
7762
+ accessCache[key] = 2 /* DATA */;
7774
7763
  return data[key];
7775
7764
  }
7776
7765
  else if (
@@ -7778,15 +7767,15 @@ const PublicInstanceProxyHandlers = {
7778
7767
  // props
7779
7768
  (normalizedProps = instance.propsOptions[0]) &&
7780
7769
  hasOwn(normalizedProps, key)) {
7781
- accessCache[key] = 2 /* PROPS */;
7770
+ accessCache[key] = 3 /* PROPS */;
7782
7771
  return props[key];
7783
7772
  }
7784
7773
  else if (ctx !== EMPTY_OBJ && hasOwn(ctx, key)) {
7785
- accessCache[key] = 3 /* CONTEXT */;
7774
+ accessCache[key] = 4 /* CONTEXT */;
7786
7775
  return ctx[key];
7787
7776
  }
7788
7777
  else if (shouldCacheAccess) {
7789
- accessCache[key] = 4 /* OTHER */;
7778
+ accessCache[key] = 0 /* OTHER */;
7790
7779
  }
7791
7780
  }
7792
7781
  const publicGetter = publicPropertiesMap[key];
@@ -7806,7 +7795,7 @@ const PublicInstanceProxyHandlers = {
7806
7795
  }
7807
7796
  else if (ctx !== EMPTY_OBJ && hasOwn(ctx, key)) {
7808
7797
  // user may set custom properties to `this` that start with `$`
7809
- accessCache[key] = 3 /* CONTEXT */;
7798
+ accessCache[key] = 4 /* CONTEXT */;
7810
7799
  return ctx[key];
7811
7800
  }
7812
7801
  else if (
@@ -7849,7 +7838,7 @@ const PublicInstanceProxyHandlers = {
7849
7838
  },
7850
7839
  has({ _: { data, setupState, accessCache, ctx, appContext, propsOptions } }, key) {
7851
7840
  let normalizedProps;
7852
- return (accessCache[key] !== undefined ||
7841
+ return (!!accessCache[key] ||
7853
7842
  (data !== EMPTY_OBJ && hasOwn(data, key)) ||
7854
7843
  (setupState !== EMPTY_OBJ && hasOwn(setupState, key)) ||
7855
7844
  ((normalizedProps = propsOptions[0]) && hasOwn(normalizedProps, key)) ||
@@ -7887,6 +7876,7 @@ function createComponentInstance(vnode, parent, suspense) {
7887
7876
  root: null,
7888
7877
  next: null,
7889
7878
  subTree: null,
7879
+ effect: null,
7890
7880
  update: null,
7891
7881
  scope: new EffectScope(true /* detached */),
7892
7882
  render: null,
@@ -8964,7 +8954,7 @@ function isMemoSame(cached, memo) {
8964
8954
  }
8965
8955
 
8966
8956
  // Core API ------------------------------------------------------------------
8967
- const version = "3.2.22";
8957
+ const version = "3.2.26";
8968
8958
  const _ssrUtils = {
8969
8959
  createComponentInstance,
8970
8960
  setupComponent,
@@ -9239,12 +9229,19 @@ prevChildren, parentComponent, parentSuspense, unmountChildren) {
9239
9229
  el[key] = value == null ? '' : value;
9240
9230
  return;
9241
9231
  }
9242
- if (key === 'value' && el.tagName !== 'PROGRESS') {
9232
+ if (key === 'value' &&
9233
+ el.tagName !== 'PROGRESS' &&
9234
+ // custom elements may use _value internally
9235
+ !el.tagName.includes('-')) {
9243
9236
  // store value as _value as well since
9244
9237
  // non-string values will be stringified.
9245
9238
  el._value = value;
9246
9239
  const newValue = value == null ? '' : value;
9247
- if (el.value !== newValue) {
9240
+ if (el.value !== newValue ||
9241
+ // #4956: always set for OPTION elements because its value falls back to
9242
+ // textContent if no value attribute is present. And setting .value for
9243
+ // OPTION has no side effect
9244
+ el.tagName === 'OPTION') {
9248
9245
  el.value = newValue;
9249
9246
  }
9250
9247
  if (value == null) {
@@ -11165,12 +11162,12 @@ function findProp(node, name, dynamicOnly = false, allowEmpty = false) {
11165
11162
  }
11166
11163
  else if (p.name === 'bind' &&
11167
11164
  (p.exp || allowEmpty) &&
11168
- isBindKey(p.arg, name)) {
11165
+ isStaticArgOf(p.arg, name)) {
11169
11166
  return p;
11170
11167
  }
11171
11168
  }
11172
11169
  }
11173
- function isBindKey(arg, name) {
11170
+ function isStaticArgOf(arg, name) {
11174
11171
  return !!(arg && isStaticExp(arg) && arg.content === name);
11175
11172
  }
11176
11173
  function hasDynamicKeyVBind(node) {
@@ -11213,7 +11210,6 @@ function getUnnormalizedProps(props, callPath = []) {
11213
11210
  }
11214
11211
  function injectProp(node, prop, context) {
11215
11212
  let propsWithInjection;
11216
- const originalProps = node.type === 13 /* VNODE_CALL */ ? node.props : node.arguments[2];
11217
11213
  /**
11218
11214
  * 1. mergeProps(...)
11219
11215
  * 2. toHandlers(...)
@@ -11222,7 +11218,7 @@ function injectProp(node, prop, context) {
11222
11218
  *
11223
11219
  * we need to get the real props before normalization
11224
11220
  */
11225
- let props = originalProps;
11221
+ let props = node.type === 13 /* VNODE_CALL */ ? node.props : node.arguments[2];
11226
11222
  let callPath = [];
11227
11223
  let parentCall;
11228
11224
  if (props &&
@@ -11832,7 +11828,7 @@ function isComponent(tag, props, context) {
11832
11828
  else if (
11833
11829
  // :is on plain element - only treat as component in compat mode
11834
11830
  p.name === 'bind' &&
11835
- isBindKey(p.arg, 'is') &&
11831
+ isStaticArgOf(p.arg, 'is') &&
11836
11832
  true &&
11837
11833
  checkCompatEnabled$1("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context, p.loc)) {
11838
11834
  return true;
@@ -12189,15 +12185,6 @@ function isSingleElementRoot(root, child) {
12189
12185
  !isSlotOutlet(child));
12190
12186
  }
12191
12187
  function walk$1(node, context, doNotHoistNode = false) {
12192
- // Some transforms, e.g. transformAssetUrls from @vue/compiler-sfc, replaces
12193
- // static bindings with expressions. These expressions are guaranteed to be
12194
- // constant so they are still eligible for hoisting, but they are only
12195
- // available at runtime and therefore cannot be evaluated ahead of time.
12196
- // This is only a concern for pre-stringification (via transformHoist by
12197
- // @vue/compiler-dom), but doing it here allows us to perform only one full
12198
- // walk of the AST and allow `stringifyStatic` to stop walking as soon as its
12199
- // stringification threshold is met.
12200
- let canStringify = true;
12201
12188
  const { children } = node;
12202
12189
  const originalCount = children.length;
12203
12190
  let hoistedCount = 0;
@@ -12210,9 +12197,6 @@ function walk$1(node, context, doNotHoistNode = false) {
12210
12197
  ? 0 /* NOT_CONSTANT */
12211
12198
  : getConstantType(child, context);
12212
12199
  if (constantType > 0 /* NOT_CONSTANT */) {
12213
- if (constantType < 3 /* CAN_STRINGIFY */) {
12214
- canStringify = false;
12215
- }
12216
12200
  if (constantType >= 2 /* CAN_HOIST */) {
12217
12201
  child.codegenNode.patchFlag =
12218
12202
  -1 /* HOISTED */ + (``);
@@ -12243,17 +12227,10 @@ function walk$1(node, context, doNotHoistNode = false) {
12243
12227
  }
12244
12228
  }
12245
12229
  }
12246
- else if (child.type === 12 /* TEXT_CALL */) {
12247
- const contentType = getConstantType(child.content, context);
12248
- if (contentType > 0) {
12249
- if (contentType < 3 /* CAN_STRINGIFY */) {
12250
- canStringify = false;
12251
- }
12252
- if (contentType >= 2 /* CAN_HOIST */) {
12253
- child.codegenNode = context.hoist(child.codegenNode);
12254
- hoistedCount++;
12255
- }
12256
- }
12230
+ else if (child.type === 12 /* TEXT_CALL */ &&
12231
+ getConstantType(child.content, context) >= 2 /* CAN_HOIST */) {
12232
+ child.codegenNode = context.hoist(child.codegenNode);
12233
+ hoistedCount++;
12257
12234
  }
12258
12235
  // walk further
12259
12236
  if (child.type === 1 /* ELEMENT */) {
@@ -12277,7 +12254,7 @@ function walk$1(node, context, doNotHoistNode = false) {
12277
12254
  }
12278
12255
  }
12279
12256
  }
12280
- if (canStringify && hoistedCount && context.transformHoist) {
12257
+ if (hoistedCount && context.transformHoist) {
12281
12258
  context.transformHoist(children, context, node);
12282
12259
  }
12283
12260
  // all children were hoisted - the entire children array is hoistable.
@@ -12306,6 +12283,11 @@ function getConstantType(node, context) {
12306
12283
  if (codegenNode.type !== 13 /* VNODE_CALL */) {
12307
12284
  return 0 /* NOT_CONSTANT */;
12308
12285
  }
12286
+ if (codegenNode.isBlock &&
12287
+ node.tag !== 'svg' &&
12288
+ node.tag !== 'foreignObject') {
12289
+ return 0 /* NOT_CONSTANT */;
12290
+ }
12309
12291
  const flag = getPatchFlag(codegenNode);
12310
12292
  if (!flag) {
12311
12293
  let returnType = 3 /* CAN_STRINGIFY */;
@@ -12442,7 +12424,7 @@ function getGeneratedPropsConstantType(node, context) {
12442
12424
  else if (value.type === 14 /* JS_CALL_EXPRESSION */) {
12443
12425
  // some helper calls can be hoisted,
12444
12426
  // such as the `normalizeProps` generated by the compiler for pre-normalize class,
12445
- // in this case we need to respect the ConstantType of the helper's argments
12427
+ // in this case we need to respect the ConstantType of the helper's arguments
12446
12428
  valueType = getConstantTypeOfHelperCall(value, context);
12447
12429
  }
12448
12430
  else {
@@ -14839,10 +14821,7 @@ const transformElement = (node, context) => {
14839
14821
  // updates inside get proper isSVG flag at runtime. (#639, #643)
14840
14822
  // This is technically web-specific, but splitting the logic out of core
14841
14823
  // leads to too much unnecessary complexity.
14842
- (tag === 'svg' ||
14843
- tag === 'foreignObject' ||
14844
- // #938: elements with dynamic keys should be forced into blocks
14845
- findProp(node, 'key', true)));
14824
+ (tag === 'svg' || tag === 'foreignObject'));
14846
14825
  // props
14847
14826
  if (props.length > 0) {
14848
14827
  const propsBuildResult = buildProps(node, context);
@@ -14854,6 +14833,9 @@ const transformElement = (node, context) => {
14854
14833
  directives && directives.length
14855
14834
  ? createArrayExpression(directives.map(dir => buildDirectiveArgs(dir, context)))
14856
14835
  : undefined;
14836
+ if (propsBuildResult.shouldUseBlock) {
14837
+ shouldUseBlock = true;
14838
+ }
14857
14839
  }
14858
14840
  // children
14859
14841
  if (node.children.length > 0) {
@@ -15024,11 +15006,13 @@ function resolveSetupReference(name, context) {
15024
15006
  }
15025
15007
  }
15026
15008
  function buildProps(node, context, props = node.props, ssr = false) {
15027
- const { tag, loc: elementLoc } = node;
15009
+ const { tag, loc: elementLoc, children } = node;
15028
15010
  const isComponent = node.tagType === 1 /* COMPONENT */;
15029
15011
  let properties = [];
15030
15012
  const mergeArgs = [];
15031
15013
  const runtimeDirectives = [];
15014
+ const hasChildren = children.length > 0;
15015
+ let shouldUseBlock = false;
15032
15016
  // patchFlag analysis
15033
15017
  let patchFlag = 0;
15034
15018
  let hasRef = false;
@@ -15091,15 +15075,20 @@ function buildProps(node, context, props = node.props, ssr = false) {
15091
15075
  const prop = props[i];
15092
15076
  if (prop.type === 6 /* ATTRIBUTE */) {
15093
15077
  const { loc, name, value } = prop;
15094
- let valueNode = createSimpleExpression(value ? value.content : '', true, value ? value.loc : loc);
15078
+ let isStatic = true;
15095
15079
  if (name === 'ref') {
15096
15080
  hasRef = true;
15081
+ if (context.scopes.vFor > 0) {
15082
+ properties.push(createObjectProperty(createSimpleExpression('ref_for', true), createSimpleExpression('true')));
15083
+ }
15097
15084
  // in inline mode there is no setupState object, so we can't use string
15098
15085
  // keys to set the ref. Instead, we need to transform it to pass the
15099
15086
  // actual ref instead.
15100
- if (context.inline && (value === null || value === void 0 ? void 0 : value.content)) {
15101
- valueNode = createFunctionExpression(['_value', '_refs']);
15102
- valueNode.body = createBlockStatement(processInlineRef(context, value.content));
15087
+ if (value &&
15088
+ context.inline &&
15089
+ context.bindingMetadata[value.content]) {
15090
+ isStatic = false;
15091
+ properties.push(createObjectProperty(createSimpleExpression('ref_key', true), createSimpleExpression(value.content, true, value.loc)));
15103
15092
  }
15104
15093
  }
15105
15094
  // skip is on <component>, or is="vue:xxx"
@@ -15109,7 +15098,7 @@ function buildProps(node, context, props = node.props, ssr = false) {
15109
15098
  (isCompatEnabled$1("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context)))) {
15110
15099
  continue;
15111
15100
  }
15112
- properties.push(createObjectProperty(createSimpleExpression(name, true, getInnerRange(loc, 0, name.length)), valueNode));
15101
+ properties.push(createObjectProperty(createSimpleExpression(name, true, getInnerRange(loc, 0, name.length)), createSimpleExpression(value ? value.content : '', isStatic, value ? value.loc : loc)));
15113
15102
  }
15114
15103
  else {
15115
15104
  // directives
@@ -15130,7 +15119,7 @@ function buildProps(node, context, props = node.props, ssr = false) {
15130
15119
  // skip v-is and :is on <component>
15131
15120
  if (name === 'is' ||
15132
15121
  (isVBind &&
15133
- isBindKey(arg, 'is') &&
15122
+ isStaticArgOf(arg, 'is') &&
15134
15123
  (isComponentTag(tag) ||
15135
15124
  (isCompatEnabled$1("COMPILER_IS_ON_ELEMENT" /* COMPILER_IS_ON_ELEMENT */, context))))) {
15136
15125
  continue;
@@ -15139,6 +15128,17 @@ function buildProps(node, context, props = node.props, ssr = false) {
15139
15128
  if (isVOn && ssr) {
15140
15129
  continue;
15141
15130
  }
15131
+ if (
15132
+ // #938: elements with dynamic keys should be forced into blocks
15133
+ (isVBind && isStaticArgOf(arg, 'key')) ||
15134
+ // inline before-update hooks need to force block so that it is invoked
15135
+ // before children
15136
+ (isVOn && hasChildren && isStaticArgOf(arg, 'vue:before-update'))) {
15137
+ shouldUseBlock = true;
15138
+ }
15139
+ if (isVBind && isStaticArgOf(arg, 'ref') && context.scopes.vFor > 0) {
15140
+ properties.push(createObjectProperty(createSimpleExpression('ref_for', true), createSimpleExpression('true')));
15141
+ }
15142
15142
  // special case for v-bind and v-on with no argument
15143
15143
  if (!arg && (isVBind || isVOn)) {
15144
15144
  hasDynamicKeys = true;
@@ -15189,14 +15189,13 @@ function buildProps(node, context, props = node.props, ssr = false) {
15189
15189
  else {
15190
15190
  // no built-in transform, this is a user custom directive.
15191
15191
  runtimeDirectives.push(prop);
15192
+ // custom dirs may use beforeUpdate so they need to force blocks
15193
+ // to ensure before-update gets called before children update
15194
+ if (hasChildren) {
15195
+ shouldUseBlock = true;
15196
+ }
15192
15197
  }
15193
15198
  }
15194
- if (prop.type === 6 /* ATTRIBUTE */ &&
15195
- prop.name === 'ref' &&
15196
- context.scopes.vFor > 0 &&
15197
- checkCompatEnabled$1("COMPILER_V_FOR_REF" /* COMPILER_V_FOR_REF */, context, prop.loc)) {
15198
- properties.push(createObjectProperty(createSimpleExpression('refInFor', true), createSimpleExpression('true', false)));
15199
- }
15200
15199
  }
15201
15200
  let propsExpression = undefined;
15202
15201
  // has v-bind="object" or v-on="object", wrap with mergeProps
@@ -15233,7 +15232,8 @@ function buildProps(node, context, props = node.props, ssr = false) {
15233
15232
  patchFlag |= 32 /* HYDRATE_EVENTS */;
15234
15233
  }
15235
15234
  }
15236
- if ((patchFlag === 0 || patchFlag === 32 /* HYDRATE_EVENTS */) &&
15235
+ if (!shouldUseBlock &&
15236
+ (patchFlag === 0 || patchFlag === 32 /* HYDRATE_EVENTS */) &&
15237
15237
  (hasRef || hasVnodeHook || runtimeDirectives.length > 0)) {
15238
15238
  patchFlag |= 512 /* NEED_PATCH */;
15239
15239
  }
@@ -15300,7 +15300,8 @@ function buildProps(node, context, props = node.props, ssr = false) {
15300
15300
  props: propsExpression,
15301
15301
  directives: runtimeDirectives,
15302
15302
  patchFlag,
15303
- dynamicPropNames
15303
+ dynamicPropNames,
15304
+ shouldUseBlock
15304
15305
  };
15305
15306
  }
15306
15307
  // Dedupe props in an object literal.
@@ -15395,21 +15396,6 @@ function stringifyDynamicPropNames(props) {
15395
15396
  }
15396
15397
  function isComponentTag(tag) {
15397
15398
  return tag === 'component' || tag === 'Component';
15398
- }
15399
- function processInlineRef(context, raw) {
15400
- const body = [createSimpleExpression(`_refs['${raw}'] = _value`)];
15401
- const { bindingMetadata, helperString } = context;
15402
- const type = bindingMetadata[raw];
15403
- if (type === "setup-ref" /* SETUP_REF */) {
15404
- body.push(createSimpleExpression(`${raw}.value = _value`));
15405
- }
15406
- else if (type === "setup-maybe-ref" /* SETUP_MAYBE_REF */) {
15407
- body.push(createSimpleExpression(`${helperString(IS_REF)}(${raw}) && (${raw}.value = _value)`));
15408
- }
15409
- else if (type === "setup-let" /* SETUP_LET */) {
15410
- body.push(createSimpleExpression(`${helperString(IS_REF)}(${raw}) ? ${raw}.value = _value : ${raw} = _value`));
15411
- }
15412
- return body;
15413
15399
  }
15414
15400
 
15415
15401
  const transformSlotOutlet = (node, context) => {
@@ -15457,7 +15443,7 @@ function processSlotOutlet(node, context) {
15457
15443
  }
15458
15444
  }
15459
15445
  else {
15460
- if (p.name === 'bind' && isBindKey(p.arg, 'name')) {
15446
+ if (p.name === 'bind' && isStaticArgOf(p.arg, 'name')) {
15461
15447
  if (p.exp)
15462
15448
  slotName = p.exp;
15463
15449
  }
@@ -15491,7 +15477,11 @@ const transformOn = (dir, node, context, augmentor) => {
15491
15477
  let eventName;
15492
15478
  if (arg.type === 4 /* SIMPLE_EXPRESSION */) {
15493
15479
  if (arg.isStatic) {
15494
- const rawName = arg.content;
15480
+ let rawName = arg.content;
15481
+ // TODO deprecate @vnodeXXX usage
15482
+ if (rawName.startsWith('vue:')) {
15483
+ rawName = `vnode-${rawName.slice(4)}`;
15484
+ }
15495
15485
  // for all event listeners, auto convert it to camelCase. See issue #2249
15496
15486
  eventName = createSimpleExpression(toHandlerKey(camelize(rawName)), true, arg.loc);
15497
15487
  }
@@ -18823,6 +18813,11 @@ const transformShow = (dir, node, context) => {
18823
18813
  /**
18824
18814
  * This module is Node-only.
18825
18815
  */
18816
+ /**
18817
+ * Regex for replacing placeholders for embedded constant variables
18818
+ * (e.g. import URL string constants generated by compiler-sfc)
18819
+ */
18820
+ const expReplaceRE = /__VUE_EXP_START__(.*?)__VUE_EXP_END__/g;
18826
18821
  /**
18827
18822
  * Turn eligible hoisted static trees into stringified static nodes, e.g.
18828
18823
  *
@@ -18859,7 +18854,7 @@ const stringifyStatic = (children, context, parent) => {
18859
18854
  ec >= 5 /* ELEMENT_WITH_BINDING_COUNT */) {
18860
18855
  // combine all currently eligible nodes into a single static vnode call
18861
18856
  const staticCall = createCallExpression(context.helper(CREATE_STATIC), [
18862
- JSON.stringify(currentChunk.map(node => stringifyNode(node, context)).join('')),
18857
+ JSON.stringify(currentChunk.map(node => stringifyNode(node, context)).join('')).replace(expReplaceRE, `" + $1 + "`),
18863
18858
  // the 2nd argument indicates the number of DOM nodes this static vnode
18864
18859
  // will insert / hydrate
18865
18860
  String(currentChunk.length)
@@ -18927,7 +18922,7 @@ const replaceHoist = (node, replacement, context) => {
18927
18922
  const isNonStringifiable = /*#__PURE__*/ makeMap(`caption,thead,tr,th,tbody,td,tfoot,colgroup,col`);
18928
18923
  /**
18929
18924
  * for a hoisted node, analyze it and return:
18930
- * - false: bailed (contains runtime constant)
18925
+ * - false: bailed (contains non-stringifiable props or runtime constant)
18931
18926
  * - [nc, ec] where
18932
18927
  * - nc is the number of nodes inside
18933
18928
  * - ec is the number of element with bindings inside
@@ -18965,6 +18960,11 @@ function analyzeNode(node) {
18965
18960
  (p.arg.isStatic && !isStringifiableAttr(p.arg.content, node.ns)))) {
18966
18961
  return bail();
18967
18962
  }
18963
+ if (p.exp &&
18964
+ (p.exp.type === 8 /* COMPOUND_EXPRESSION */ ||
18965
+ p.exp.constType < 3 /* CAN_STRINGIFY */)) {
18966
+ return bail();
18967
+ }
18968
18968
  }
18969
18969
  }
18970
18970
  for (let i = 0; i < node.children.length; i++) {
@@ -19020,8 +19020,15 @@ function stringifyElement(node, context) {
19020
19020
  }
19021
19021
  }
19022
19022
  else if (p.type === 7 /* DIRECTIVE */ && p.name === 'bind') {
19023
+ const exp = p.exp;
19024
+ if (exp.content[0] === '_') {
19025
+ // internally generated string constant references
19026
+ // e.g. imported URL strings via compiler-sfc transformAssetUrl plugin
19027
+ res += ` ${p.arg.content}="__VUE_EXP_START__${exp.content}__VUE_EXP_END__"`;
19028
+ continue;
19029
+ }
19023
19030
  // constant v-bind, e.g. :foo="1"
19024
- let evaluated = evaluateConstant(p.exp);
19031
+ let evaluated = evaluateConstant(exp);
19025
19032
  if (evaluated != null) {
19026
19033
  const arg = p.arg && p.arg.content;
19027
19034
  if (arg === 'class') {