@vue/compat 3.2.38 → 3.2.40

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.
@@ -38,6 +38,13 @@ const isGloballyWhitelisted = /*#__PURE__*/ makeMap(GLOBALS_WHITE_LISTED);
38
38
  */
39
39
  const specialBooleanAttrs = `itemscope,allowfullscreen,formnovalidate,ismap,nomodule,novalidate,readonly`;
40
40
  const isSpecialBooleanAttr = /*#__PURE__*/ makeMap(specialBooleanAttrs);
41
+ /**
42
+ * The full list is needed during SSR to produce the correct initial markup.
43
+ */
44
+ const isBooleanAttr = /*#__PURE__*/ makeMap(specialBooleanAttrs +
45
+ `,async,autofocus,autoplay,controls,default,defer,disabled,hidden,` +
46
+ `loop,open,required,reversed,scoped,seamless,` +
47
+ `checked,muted,multiple,selected`);
41
48
  /**
42
49
  * Boolean attributes should be included if the value is truthy or ''.
43
50
  * e.g. `<select multiple>` compiles to `{ multiple: '' }`
@@ -1819,7 +1826,9 @@ function queuePostFlushCb(cb) {
1819
1826
  }
1820
1827
  queueFlush();
1821
1828
  }
1822
- function flushPreFlushCbs(seen, i = flushIndex) {
1829
+ function flushPreFlushCbs(seen,
1830
+ // if currently flushing, skip the current job itself
1831
+ i = isFlushing ? flushIndex + 1 : 0) {
1823
1832
  for (; i < queue.length; i++) {
1824
1833
  const cb = queue[i];
1825
1834
  if (cb && cb.pre) {
@@ -3975,7 +3984,7 @@ function injectHook(type, hook, target = currentInstance, prepend = false) {
3975
3984
  const createHook = (lifecycle) => (hook, target = currentInstance) =>
3976
3985
  // post-create lifecycle registrations are noops during SSR (except for serverPrefetch)
3977
3986
  (!isInSSRComponentSetup || lifecycle === "sp" /* LifecycleHooks.SERVER_PREFETCH */) &&
3978
- injectHook(lifecycle, hook, target);
3987
+ injectHook(lifecycle, (...args) => hook(...args), target);
3979
3988
  const onBeforeMount = createHook("bm" /* LifecycleHooks.BEFORE_MOUNT */);
3980
3989
  const onMounted = createHook("m" /* LifecycleHooks.MOUNTED */);
3981
3990
  const onBeforeUpdate = createHook("bu" /* LifecycleHooks.BEFORE_UPDATE */);
@@ -4507,7 +4516,10 @@ function createSlots(slots, dynamicSlots) {
4507
4516
  slots[slot.name] = slot.key
4508
4517
  ? (...args) => {
4509
4518
  const res = slot.fn(...args);
4510
- res.key = slot.key;
4519
+ // attach branch key so each conditional branch is considered a
4520
+ // different fragment
4521
+ if (res)
4522
+ res.key = slot.key;
4511
4523
  return res;
4512
4524
  }
4513
4525
  : slot.fn;
@@ -5872,7 +5884,7 @@ function createCompatVue(createApp, createSingletonApp) {
5872
5884
  return vm;
5873
5885
  }
5874
5886
  }
5875
- Vue.version = `2.6.14-compat:${"3.2.38"}`;
5887
+ Vue.version = `2.6.14-compat:${"3.2.40"}`;
5876
5888
  Vue.config = singletonApp.config;
5877
5889
  Vue.use = (p, ...options) => {
5878
5890
  if (p && isFunction(p.install)) {
@@ -6473,7 +6485,7 @@ function createHydrationFunctions(rendererInternals) {
6473
6485
  const isFragmentStart = isComment(node) && node.data === '[';
6474
6486
  const onMismatch = () => handleMismatch(node, vnode, parentComponent, parentSuspense, slotScopeIds, isFragmentStart);
6475
6487
  const { type, ref, shapeFlag, patchFlag } = vnode;
6476
- const domType = node.nodeType;
6488
+ let domType = node.nodeType;
6477
6489
  vnode.el = node;
6478
6490
  if (patchFlag === -2 /* PatchFlags.BAIL */) {
6479
6491
  optimized = false;
@@ -6510,10 +6522,12 @@ function createHydrationFunctions(rendererInternals) {
6510
6522
  }
6511
6523
  break;
6512
6524
  case Static:
6513
- if (domType !== 1 /* DOMNodeTypes.ELEMENT */ && domType !== 3 /* DOMNodeTypes.TEXT */) {
6514
- nextNode = onMismatch();
6525
+ if (isFragmentStart) {
6526
+ // entire template is static but SSRed as a fragment
6527
+ node = nextSibling(node);
6528
+ domType = node.nodeType;
6515
6529
  }
6516
- else {
6530
+ if (domType === 1 /* DOMNodeTypes.ELEMENT */ || domType === 3 /* DOMNodeTypes.TEXT */) {
6517
6531
  // determine anchor, adopt content
6518
6532
  nextNode = node;
6519
6533
  // if the static vnode has its content stripped during build,
@@ -6530,7 +6544,10 @@ function createHydrationFunctions(rendererInternals) {
6530
6544
  }
6531
6545
  nextNode = nextSibling(nextNode);
6532
6546
  }
6533
- return nextNode;
6547
+ return isFragmentStart ? nextSibling(nextNode) : nextNode;
6548
+ }
6549
+ else {
6550
+ onMismatch();
6534
6551
  }
6535
6552
  break;
6536
6553
  case Fragment:
@@ -6792,7 +6809,7 @@ function createHydrationRenderer(options) {
6792
6809
  function baseCreateRenderer(options, createHydrationFns) {
6793
6810
  const target = getGlobalThis();
6794
6811
  target.__VUE__ = true;
6795
- const { insert: hostInsert, remove: hostRemove, patchProp: hostPatchProp, createElement: hostCreateElement, createText: hostCreateText, createComment: hostCreateComment, setText: hostSetText, setElementText: hostSetElementText, parentNode: hostParentNode, nextSibling: hostNextSibling, setScopeId: hostSetScopeId = NOOP, cloneNode: hostCloneNode, insertStaticContent: hostInsertStaticContent } = options;
6812
+ const { insert: hostInsert, remove: hostRemove, patchProp: hostPatchProp, createElement: hostCreateElement, createText: hostCreateText, createComment: hostCreateComment, setText: hostSetText, setElementText: hostSetElementText, parentNode: hostParentNode, nextSibling: hostNextSibling, setScopeId: hostSetScopeId = NOOP, insertStaticContent: hostInsertStaticContent } = options;
6796
6813
  // Note: functions inside this closure should use `const xxx = () => {}`
6797
6814
  // style in order to prevent being inlined by minifiers.
6798
6815
  const patch = (n1, n2, container, anchor = null, parentComponent = null, parentSuspense = null, isSVG = false, slotScopeIds = null, optimized = !!n2.dynamicChildren) => {
@@ -6898,55 +6915,44 @@ function baseCreateRenderer(options, createHydrationFns) {
6898
6915
  const mountElement = (vnode, container, anchor, parentComponent, parentSuspense, isSVG, slotScopeIds, optimized) => {
6899
6916
  let el;
6900
6917
  let vnodeHook;
6901
- const { type, props, shapeFlag, transition, patchFlag, dirs } = vnode;
6902
- if (vnode.el &&
6903
- hostCloneNode !== undefined &&
6904
- patchFlag === -1 /* PatchFlags.HOISTED */) {
6905
- // If a vnode has non-null el, it means it's being reused.
6906
- // Only static vnodes can be reused, so its mounted DOM nodes should be
6907
- // exactly the same, and we can simply do a clone here.
6908
- // only do this in production since cloned trees cannot be HMR updated.
6909
- el = vnode.el = hostCloneNode(vnode.el);
6918
+ const { type, props, shapeFlag, transition, dirs } = vnode;
6919
+ el = vnode.el = hostCreateElement(vnode.type, isSVG, props && props.is, props);
6920
+ // mount children first, since some props may rely on child content
6921
+ // being already rendered, e.g. `<select value>`
6922
+ if (shapeFlag & 8 /* ShapeFlags.TEXT_CHILDREN */) {
6923
+ hostSetElementText(el, vnode.children);
6910
6924
  }
6911
- else {
6912
- el = vnode.el = hostCreateElement(vnode.type, isSVG, props && props.is, props);
6913
- // mount children first, since some props may rely on child content
6914
- // being already rendered, e.g. `<select value>`
6915
- if (shapeFlag & 8 /* ShapeFlags.TEXT_CHILDREN */) {
6916
- hostSetElementText(el, vnode.children);
6917
- }
6918
- else if (shapeFlag & 16 /* ShapeFlags.ARRAY_CHILDREN */) {
6919
- mountChildren(vnode.children, el, null, parentComponent, parentSuspense, isSVG && type !== 'foreignObject', slotScopeIds, optimized);
6920
- }
6921
- if (dirs) {
6922
- invokeDirectiveHook(vnode, null, parentComponent, 'created');
6923
- }
6924
- // props
6925
- if (props) {
6926
- for (const key in props) {
6927
- if (key !== 'value' && !isReservedProp(key)) {
6928
- hostPatchProp(el, key, null, props[key], isSVG, vnode.children, parentComponent, parentSuspense, unmountChildren);
6929
- }
6930
- }
6931
- /**
6932
- * Special case for setting value on DOM elements:
6933
- * - it can be order-sensitive (e.g. should be set *after* min/max, #2325, #4024)
6934
- * - it needs to be forced (#1471)
6935
- * #2353 proposes adding another renderer option to configure this, but
6936
- * the properties affects are so finite it is worth special casing it
6937
- * here to reduce the complexity. (Special casing it also should not
6938
- * affect non-DOM renderers)
6939
- */
6940
- if ('value' in props) {
6941
- hostPatchProp(el, 'value', null, props.value);
6942
- }
6943
- if ((vnodeHook = props.onVnodeBeforeMount)) {
6944
- invokeVNodeHook(vnodeHook, parentComponent, vnode);
6945
- }
6946
- }
6947
- // scopeId
6948
- setScopeId(el, vnode, vnode.scopeId, slotScopeIds, parentComponent);
6925
+ else if (shapeFlag & 16 /* ShapeFlags.ARRAY_CHILDREN */) {
6926
+ mountChildren(vnode.children, el, null, parentComponent, parentSuspense, isSVG && type !== 'foreignObject', slotScopeIds, optimized);
6927
+ }
6928
+ if (dirs) {
6929
+ invokeDirectiveHook(vnode, null, parentComponent, 'created');
6949
6930
  }
6931
+ // props
6932
+ if (props) {
6933
+ for (const key in props) {
6934
+ if (key !== 'value' && !isReservedProp(key)) {
6935
+ hostPatchProp(el, key, null, props[key], isSVG, vnode.children, parentComponent, parentSuspense, unmountChildren);
6936
+ }
6937
+ }
6938
+ /**
6939
+ * Special case for setting value on DOM elements:
6940
+ * - it can be order-sensitive (e.g. should be set *after* min/max, #2325, #4024)
6941
+ * - it needs to be forced (#1471)
6942
+ * #2353 proposes adding another renderer option to configure this, but
6943
+ * the properties affects are so finite it is worth special casing it
6944
+ * here to reduce the complexity. (Special casing it also should not
6945
+ * affect non-DOM renderers)
6946
+ */
6947
+ if ('value' in props) {
6948
+ hostPatchProp(el, 'value', null, props.value);
6949
+ }
6950
+ if ((vnodeHook = props.onVnodeBeforeMount)) {
6951
+ invokeVNodeHook(vnodeHook, parentComponent, vnode);
6952
+ }
6953
+ }
6954
+ // scopeId
6955
+ setScopeId(el, vnode, vnode.scopeId, slotScopeIds, parentComponent);
6950
6956
  if (dirs) {
6951
6957
  invokeDirectiveHook(vnode, null, parentComponent, 'beforeMount');
6952
6958
  }
@@ -7108,6 +7114,13 @@ function baseCreateRenderer(options, createHydrationFns) {
7108
7114
  };
7109
7115
  const patchProps = (el, vnode, oldProps, newProps, parentComponent, parentSuspense, isSVG) => {
7110
7116
  if (oldProps !== newProps) {
7117
+ if (oldProps !== EMPTY_OBJ) {
7118
+ for (const key in oldProps) {
7119
+ if (!isReservedProp(key) && !(key in newProps)) {
7120
+ hostPatchProp(el, key, oldProps[key], null, isSVG, vnode.children, parentComponent, parentSuspense, unmountChildren);
7121
+ }
7122
+ }
7123
+ }
7111
7124
  for (const key in newProps) {
7112
7125
  // empty string is not valid prop
7113
7126
  if (isReservedProp(key))
@@ -7119,13 +7132,6 @@ function baseCreateRenderer(options, createHydrationFns) {
7119
7132
  hostPatchProp(el, key, prev, next, isSVG, vnode.children, parentComponent, parentSuspense, unmountChildren);
7120
7133
  }
7121
7134
  }
7122
- if (oldProps !== EMPTY_OBJ) {
7123
- for (const key in oldProps) {
7124
- if (!isReservedProp(key) && !(key in newProps)) {
7125
- hostPatchProp(el, key, oldProps[key], null, isSVG, vnode.children, parentComponent, parentSuspense, unmountChildren);
7126
- }
7127
- }
7128
- }
7129
7135
  if ('value' in newProps) {
7130
7136
  hostPatchProp(el, 'value', oldProps.value, newProps.value);
7131
7137
  }
@@ -8561,7 +8567,10 @@ function normalizeVNode(child) {
8561
8567
  }
8562
8568
  // optimized normalization for template-compiled render fns
8563
8569
  function cloneIfMounted(child) {
8564
- return child.el === null || child.memo ? child : cloneVNode(child);
8570
+ return (child.el === null && child.patchFlag !== -1 /* PatchFlags.HOISTED */) ||
8571
+ child.memo
8572
+ ? child
8573
+ : cloneVNode(child);
8565
8574
  }
8566
8575
  function normalizeChildren(vnode, children) {
8567
8576
  let type = 0;
@@ -8859,7 +8868,8 @@ function finishComponentSetup(instance, isSSR, skipOptions) {
8859
8868
  if (!isSSR && compile && !Component.render) {
8860
8869
  const template = (instance.vnode.props &&
8861
8870
  instance.vnode.props['inline-template']) ||
8862
- Component.template;
8871
+ Component.template ||
8872
+ resolveMergedOptions(instance).template;
8863
8873
  if (template) {
8864
8874
  const { isCustomElement, compilerOptions } = instance.appContext.config;
8865
8875
  const { delimiters, compilerOptions: componentCompilerOptions } = Component;
@@ -9176,7 +9186,7 @@ function isMemoSame(cached, memo) {
9176
9186
  }
9177
9187
 
9178
9188
  // Core API ------------------------------------------------------------------
9179
- const version = "3.2.38";
9189
+ const version = "3.2.40";
9180
9190
  const _ssrUtils = {
9181
9191
  createComponentInstance,
9182
9192
  setupComponent,
@@ -9242,22 +9252,6 @@ const nodeOps = {
9242
9252
  setScopeId(el, id) {
9243
9253
  el.setAttribute(id, '');
9244
9254
  },
9245
- cloneNode(el) {
9246
- const cloned = el.cloneNode(true);
9247
- // #3072
9248
- // - in `patchDOMProp`, we store the actual value in the `el._value` property.
9249
- // - normally, elements using `:value` bindings will not be hoisted, but if
9250
- // the bound value is a constant, e.g. `:value="true"` - they do get
9251
- // hoisted.
9252
- // - in production, hoisted nodes are cloned when subsequent inserts, but
9253
- // cloneNode() does not copy the custom property we attached.
9254
- // - This may need to account for other custom DOM properties we attach to
9255
- // elements in addition to `_value` in the future.
9256
- if (`_value` in el) {
9257
- cloned._value = el._value;
9258
- }
9259
- return cloned;
9260
- },
9261
9255
  // __UNSAFE__
9262
9256
  // Reason: innerHTML.
9263
9257
  // Static content here can only come from compiled templates.
@@ -9428,14 +9422,14 @@ const isEnumeratedAttr = /*#__PURE__*/ makeMap('contenteditable,draggable,spellc
9428
9422
  ;
9429
9423
  function compatCoerceAttr(el, key, value, instance = null) {
9430
9424
  if (isEnumeratedAttr(key)) {
9431
- const v2CocercedValue = value === null
9425
+ const v2CoercedValue = value === null
9432
9426
  ? 'false'
9433
9427
  : typeof value !== 'boolean' && value !== undefined
9434
9428
  ? 'true'
9435
9429
  : null;
9436
- if (v2CocercedValue &&
9437
- compatUtils.softAssertCompatEnabled("ATTR_ENUMERATED_COERCION" /* DeprecationTypes.ATTR_ENUMERATED_COERCION */, instance, key, value, v2CocercedValue)) {
9438
- el.setAttribute(key, v2CocercedValue);
9430
+ if (v2CoercedValue &&
9431
+ compatUtils.softAssertCompatEnabled("ATTR_ENUMERATED_COERCION" /* DeprecationTypes.ATTR_ENUMERATED_COERCION */, instance, key, value, v2CoercedValue)) {
9432
+ el.setAttribute(key, v2CoercedValue);
9439
9433
  return true;
9440
9434
  }
9441
9435
  }
@@ -9496,7 +9490,6 @@ prevChildren, parentComponent, parentSuspense, unmountChildren) {
9496
9490
  }
9497
9491
  else if (type === 'number') {
9498
9492
  // e.g. <img :width="null">
9499
- // the value of some IDL attr must be greater than 0, e.g. input.size = 0 -> error
9500
9493
  value = 0;
9501
9494
  needRemove = true;
9502
9495
  }
@@ -11784,34 +11777,42 @@ function parseChildren(context, mode, ancestors) {
11784
11777
  const shouldCondense = context.options.whitespace !== 'preserve';
11785
11778
  for (let i = 0; i < nodes.length; i++) {
11786
11779
  const node = nodes[i];
11787
- if (!context.inPre && node.type === 2 /* NodeTypes.TEXT */) {
11788
- if (!/[^\t\r\n\f ]/.test(node.content)) {
11789
- const prev = nodes[i - 1];
11790
- const next = nodes[i + 1];
11791
- // Remove if:
11792
- // - the whitespace is the first or last node, or:
11793
- // - (condense mode) the whitespace is adjacent to a comment, or:
11794
- // - (condense mode) the whitespace is between two elements AND contains newline
11795
- if (!prev ||
11796
- !next ||
11797
- (shouldCondense &&
11798
- (prev.type === 3 /* NodeTypes.COMMENT */ ||
11799
- next.type === 3 /* NodeTypes.COMMENT */ ||
11800
- (prev.type === 1 /* NodeTypes.ELEMENT */ &&
11801
- next.type === 1 /* NodeTypes.ELEMENT */ &&
11802
- /[\r\n]/.test(node.content))))) {
11803
- removedWhitespace = true;
11804
- nodes[i] = null;
11780
+ if (node.type === 2 /* NodeTypes.TEXT */) {
11781
+ if (!context.inPre) {
11782
+ if (!/[^\t\r\n\f ]/.test(node.content)) {
11783
+ const prev = nodes[i - 1];
11784
+ const next = nodes[i + 1];
11785
+ // Remove if:
11786
+ // - the whitespace is the first or last node, or:
11787
+ // - (condense mode) the whitespace is adjacent to a comment, or:
11788
+ // - (condense mode) the whitespace is between two elements AND contains newline
11789
+ if (!prev ||
11790
+ !next ||
11791
+ (shouldCondense &&
11792
+ (prev.type === 3 /* NodeTypes.COMMENT */ ||
11793
+ next.type === 3 /* NodeTypes.COMMENT */ ||
11794
+ (prev.type === 1 /* NodeTypes.ELEMENT */ &&
11795
+ next.type === 1 /* NodeTypes.ELEMENT */ &&
11796
+ /[\r\n]/.test(node.content))))) {
11797
+ removedWhitespace = true;
11798
+ nodes[i] = null;
11799
+ }
11800
+ else {
11801
+ // Otherwise, the whitespace is condensed into a single space
11802
+ node.content = ' ';
11803
+ }
11805
11804
  }
11806
- else {
11807
- // Otherwise, the whitespace is condensed into a single space
11808
- node.content = ' ';
11805
+ else if (shouldCondense) {
11806
+ // in condense mode, consecutive whitespaces in text are condensed
11807
+ // down to a single space.
11808
+ node.content = node.content.replace(/[\t\r\n\f ]+/g, ' ');
11809
11809
  }
11810
11810
  }
11811
- else if (shouldCondense) {
11812
- // in condense mode, consecutive whitespaces in text are condensed
11813
- // down to a single space.
11814
- node.content = node.content.replace(/[\t\r\n\f ]+/g, ' ');
11811
+ else {
11812
+ // #6410 normalize windows newlines in <pre>:
11813
+ // in SSR, browsers normalize server-rendered \r\n into a single \n
11814
+ // in the DOM
11815
+ node.content = node.content.replace(/\r\n/g, '\n');
11815
11816
  }
11816
11817
  }
11817
11818
  // Remove comment nodes if desired by configuration.
@@ -12476,11 +12477,6 @@ function walk$1(node, context, doNotHoistNode = false) {
12476
12477
  }
12477
12478
  }
12478
12479
  }
12479
- else if (child.type === 12 /* NodeTypes.TEXT_CALL */ &&
12480
- getConstantType(child.content, context) >= 2 /* ConstantTypes.CAN_HOIST */) {
12481
- child.codegenNode = context.hoist(child.codegenNode);
12482
- hoistedCount++;
12483
- }
12484
12480
  // walk further
12485
12481
  if (child.type === 1 /* NodeTypes.ELEMENT */) {
12486
12482
  const isComponent = child.tagType === 1 /* ElementTypes.COMPONENT */;
@@ -15286,6 +15282,14 @@ function buildProps(node, context, props = node.props, isComponent, isDynamicCom
15286
15282
  let hasDynamicKeys = false;
15287
15283
  let hasVnodeHook = false;
15288
15284
  const dynamicPropNames = [];
15285
+ const pushMergeArg = (arg) => {
15286
+ if (properties.length) {
15287
+ mergeArgs.push(createObjectExpression(dedupeProperties(properties), elementLoc));
15288
+ properties = [];
15289
+ }
15290
+ if (arg)
15291
+ mergeArgs.push(arg);
15292
+ };
15289
15293
  const analyzePatchFlag = ({ key, value }) => {
15290
15294
  if (isStaticExp(key)) {
15291
15295
  const name = key.content;
@@ -15407,11 +15411,9 @@ function buildProps(node, context, props = node.props, isComponent, isDynamicCom
15407
15411
  if (!arg && (isVBind || isVOn)) {
15408
15412
  hasDynamicKeys = true;
15409
15413
  if (exp) {
15410
- if (properties.length) {
15411
- mergeArgs.push(createObjectExpression(dedupeProperties(properties), elementLoc));
15412
- properties = [];
15413
- }
15414
15414
  if (isVBind) {
15415
+ // have to merge early for compat build check
15416
+ pushMergeArg();
15415
15417
  {
15416
15418
  if (isCompatEnabled$1("COMPILER_V_BIND_OBJECT_ORDER" /* CompilerDeprecationTypes.COMPILER_V_BIND_OBJECT_ORDER */, context)) {
15417
15419
  mergeArgs.unshift(exp);
@@ -15422,7 +15424,7 @@ function buildProps(node, context, props = node.props, isComponent, isDynamicCom
15422
15424
  }
15423
15425
  else {
15424
15426
  // v-on="obj" -> toHandlers(obj)
15425
- mergeArgs.push({
15427
+ pushMergeArg({
15426
15428
  type: 14 /* NodeTypes.JS_CALL_EXPRESSION */,
15427
15429
  loc,
15428
15430
  callee: context.helper(TO_HANDLERS),
@@ -15442,7 +15444,12 @@ function buildProps(node, context, props = node.props, isComponent, isDynamicCom
15442
15444
  // has built-in directive transform.
15443
15445
  const { props, needRuntime } = directiveTransform(prop, node, context);
15444
15446
  !ssr && props.forEach(analyzePatchFlag);
15445
- properties.push(...props);
15447
+ if (isVOn && arg && !isStaticExp(arg)) {
15448
+ pushMergeArg(createObjectExpression(props, elementLoc));
15449
+ }
15450
+ else {
15451
+ properties.push(...props);
15452
+ }
15446
15453
  if (needRuntime) {
15447
15454
  runtimeDirectives.push(prop);
15448
15455
  if (isSymbol(needRuntime)) {
@@ -15464,9 +15471,8 @@ function buildProps(node, context, props = node.props, isComponent, isDynamicCom
15464
15471
  let propsExpression = undefined;
15465
15472
  // has v-bind="object" or v-on="object", wrap with mergeProps
15466
15473
  if (mergeArgs.length) {
15467
- if (properties.length) {
15468
- mergeArgs.push(createObjectExpression(dedupeProperties(properties), elementLoc));
15469
- }
15474
+ // close up any not-yet-merged props
15475
+ pushMergeArg();
15470
15476
  if (mergeArgs.length > 1) {
15471
15477
  propsExpression = createCallExpression(context.helper(MERGE_PROPS), mergeArgs, elementLoc);
15472
15478
  }
@@ -19300,6 +19306,11 @@ function stringifyElement(node, context) {
19300
19306
  res += ` ${p.arg.content}="__VUE_EXP_START__${exp.content}__VUE_EXP_END__"`;
19301
19307
  continue;
19302
19308
  }
19309
+ // #6568
19310
+ if (isBooleanAttr(p.arg.content) &&
19311
+ exp.content === 'false') {
19312
+ continue;
19313
+ }
19303
19314
  // constant v-bind, e.g. :foo="1"
19304
19315
  let evaluated = evaluateConstant(exp);
19305
19316
  if (evaluated != null) {