From: daiwei Date: Tue, 20 Jan 2026 01:58:09 +0000 (+0800) Subject: fix(vapor): refined inline-block nesting check for html abbreviation X-Git-Tag: v3.6.0-beta.4~7 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=92206430286d0b88c7364d14d5a83bbbf0a415ca;p=thirdparty%2Fvuejs%2Fcore.git fix(vapor): refined inline-block nesting check for html abbreviation --- diff --git a/packages/compiler-vapor/__tests__/abbreviation.spec.ts b/packages/compiler-vapor/__tests__/abbreviation.spec.ts index c125424861..130c6202f4 100644 --- a/packages/compiler-vapor/__tests__/abbreviation.spec.ts +++ b/packages/compiler-vapor/__tests__/abbreviation.spec.ts @@ -180,3 +180,54 @@ test('always close tags', () => { '
', ) }) + +test('inline/block ancestor relationships', () => { + // Inline element containing block element with sibling after inline + // The block element must close because inline ancestor needs to close + checkAbbr( + '
text

after

', + '
text

after', + '

text

after

', + ) + + // Same situation but deeper nesting + checkAbbr( + '

text

after
', + '

text

after', + '

text

after
', + ) + + // Inline containing block on rightmost path - can omit + checkAbbr( + '
text
', + '
text', + '
text
', + ) + + // Normal case - no inline/block issue + checkAbbr('

text

', '

text', '

text

') + + // Sibling after parent but no inline/block issue + checkAbbr( + '

text

after
', + '

text

after', + '

text

after
', + ) + + // Multi-level inline nesting with block inside + // Outer span is not rightmost -> Needs close -> Inner block needs close + checkAbbr( + '
text

after

', + '
text

after', + '

text

after

', + ) + + // Mixed nesting: div > span > div > span > div + // The middle div is inside a span that needs closing (because of outer structure) + // Both inner divs need closing because they are inside spans that need closing + checkAbbr( + '
text

after

', + '
text

after', + '

text

after

', + ) +}) diff --git a/packages/compiler-vapor/src/transform.ts b/packages/compiler-vapor/src/transform.ts index c51e89c34d..357ffaf265 100644 --- a/packages/compiler-vapor/src/transform.ts +++ b/packages/compiler-vapor/src/transform.ts @@ -15,7 +15,14 @@ import { getSelfName, isVSlot, } from '@vue/compiler-dom' -import { EMPTY_OBJ, NOOP, extend, isArray, isString } from '@vue/shared' +import { + EMPTY_OBJ, + NOOP, + extend, + isArray, + isInlineTag, + isString, +} from '@vue/shared' import { type BlockIRNode, DynamicFlag, @@ -98,6 +105,9 @@ export class TransformContext { // whether this node is on the rightmost path of the tree // (all ancestors are also last effective children) isOnRightmostPath: boolean = true + // whether there is an inline ancestor that needs closing + // (i.e. is an inline tag and not on the rightmost path) + hasInlineAncestorNeedingClose: boolean = false private globalId = 0 private nextIdMap: Map | null = null @@ -228,6 +238,25 @@ export class TransformContext { const isLastEffectiveChild = this.isEffectivelyLastChild(index) const isOnRightmostPath = this.isOnRightmostPath && isLastEffectiveChild + // propagate the inline ancestor status + let hasInlineAncestorNeedingClose = this.hasInlineAncestorNeedingClose + if (this.node.type === NodeTypes.ELEMENT) { + if (this.node.tag === 'template') { + //