diff --git a/.eslintrc.cjs b/.eslintrc.cjs index 04ecf049ca9..4296d0f39b6 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -1,3 +1,5 @@ +/* eslint-disable no-restricted-globals */ + const DOMGlobals = ['window', 'document'] const NodeGlobals = ['module', 'require'] @@ -9,12 +11,6 @@ module.exports = { plugins: ['jest'], rules: { 'no-debugger': 'error', - 'no-unused-vars': [ - 'error', - // we are only using this rule to check for unused arguments since TS - // catches unused variables but not args. - { varsIgnorePattern: '.*', args: 'none' } - ], // most of the codebase are expected to be env agnostic 'no-restricted-globals': ['error', ...DOMGlobals, ...NodeGlobals], @@ -72,6 +68,14 @@ module.exports = { 'no-restricted-syntax': 'off' } }, + // JavaScript files + { + files: ['*.js', '*.cjs'], + rules: { + // We only do `no-unused-vars` checks for js files, TS files are checked by TypeScript itself. + 'no-unused-vars': ['error', { vars: 'all', args: 'none' }] + } + }, // Node scripts { files: ['scripts/**', '*.{js,ts}', 'packages/**/index.js'], diff --git a/.github/workflows/canary.yml b/.github/workflows/canary.yml index e2f411c8e09..61265c2d0e6 100644 --- a/.github/workflows/canary.yml +++ b/.github/workflows/canary.yml @@ -17,10 +17,10 @@ jobs: - name: Install pnpm uses: pnpm/action-setup@v2 - - name: Set node version to 18 + - name: Install Node.js uses: actions/setup-node@v3 with: - node-version: 18 + node-version-file: '.node-version' registry-url: 'https://registry.npmjs.org' cache: 'pnpm' diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8fd0389f41c..db874b1240e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,10 +22,10 @@ jobs: - name: Install pnpm uses: pnpm/action-setup@v2 - - name: Set node version to 18 + - name: Install Node.js uses: actions/setup-node@v3 with: - node-version: 18 + node-version-file: '.node-version' cache: 'pnpm' - run: pnpm install @@ -44,10 +44,10 @@ jobs: - name: Install pnpm uses: pnpm/action-setup@v2 - - name: Set node version to 18 + - name: Install Node.js uses: actions/setup-node@v3 with: - node-version: 18 + node-version-file: '.node-version' cache: 'pnpm' - run: pnpm install @@ -73,10 +73,10 @@ jobs: - name: Install pnpm uses: pnpm/action-setup@v2 - - name: Set node version to 18 + - name: Install Node.js uses: actions/setup-node@v3 with: - node-version: 18 + node-version-file: '.node-version' cache: 'pnpm' - run: pnpm install @@ -96,10 +96,10 @@ jobs: - name: Install pnpm uses: pnpm/action-setup@v2 - - name: Set node version to 18 + - name: Install Node.js uses: actions/setup-node@v3 with: - node-version: 18 + node-version-file: '.node-version' cache: 'pnpm' - run: pnpm install diff --git a/.github/workflows/size-data.yml b/.github/workflows/size-data.yml index 8068b8645b6..83141e242f8 100644 --- a/.github/workflows/size-data.yml +++ b/.github/workflows/size-data.yml @@ -24,10 +24,10 @@ jobs: - name: Install pnpm uses: pnpm/action-setup@v2 - - name: Set node version to LTS + - name: Install Node.js uses: actions/setup-node@v3 with: - node-version: lts/* + node-version-file: '.node-version' cache: pnpm - name: Install dependencies diff --git a/.github/workflows/size-report.yml b/.github/workflows/size-report.yml index 8acf464ae37..cdfce9a979f 100644 --- a/.github/workflows/size-report.yml +++ b/.github/workflows/size-report.yml @@ -26,10 +26,10 @@ jobs: - name: Install pnpm uses: pnpm/action-setup@v2 - - name: Set node version to LTS + - name: Install Node.js uses: actions/setup-node@v3 with: - node-version: lts/* + node-version-file: '.node-version' cache: pnpm - name: Install dependencies diff --git a/.node-version b/.node-version new file mode 100644 index 00000000000..209e3ef4b62 --- /dev/null +++ b/.node-version @@ -0,0 +1 @@ +20 diff --git a/CHANGELOG.md b/CHANGELOG.md index dd2d4775424..12be7dc8a3a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,30 @@ +## [3.3.6](https://github.com/vuejs/core/compare/v3.3.5...v3.3.6) (2023-10-20) + + +### Bug Fixes + +* **compiler-sfc:** model name conflict ([#8798](https://github.com/vuejs/core/issues/8798)) ([df81da8](https://github.com/vuejs/core/commit/df81da8be97c8a1366563c7e3e01076ef02eb8f7)) +* **compiler-sfc:** support asset paths containing spaces ([#8752](https://github.com/vuejs/core/issues/8752)) ([36c99a9](https://github.com/vuejs/core/commit/36c99a9c6bb6bc306be054c3c8a85ff8ce50605a)) +* **compiler-ssr:** fix missing scopeId on server-rendered TransitionGroup ([#7557](https://github.com/vuejs/core/issues/7557)) ([61c1357](https://github.com/vuejs/core/commit/61c135742795aa5e3189a79c7dec6afa21bbc8d9)), closes [#7554](https://github.com/vuejs/core/issues/7554) +* **compiler-ssr:** fix ssr compile error for select with non-option children ([#9442](https://github.com/vuejs/core/issues/9442)) ([cdb2e72](https://github.com/vuejs/core/commit/cdb2e725e7ea297f1f4180fb04889a3b757bc84e)), closes [#9440](https://github.com/vuejs/core/issues/9440) +* **runtime-core:** delete stale slots which are present but undefined ([#6484](https://github.com/vuejs/core/issues/6484)) ([75b8722](https://github.com/vuejs/core/commit/75b872213574cb37e2c9e8a15f65613f867ca9a6)), closes [#9109](https://github.com/vuejs/core/issues/9109) +* **runtime-core:** fix error when using cssvars with disabled teleport ([#7341](https://github.com/vuejs/core/issues/7341)) ([8f0472c](https://github.com/vuejs/core/commit/8f0472c9abedb337dc256143b69d8ab8759dbf5c)), closes [#7342](https://github.com/vuejs/core/issues/7342) +* **teleport:** ensure descendent component would be unmounted correctly ([#6529](https://github.com/vuejs/core/issues/6529)) ([4162311](https://github.com/vuejs/core/commit/4162311efdb0db5ca458542e1604b19efa2fae0e)), closes [#6347](https://github.com/vuejs/core/issues/6347) +* **types:** support contenteditable="plaintext-only" ([#8796](https://github.com/vuejs/core/issues/8796)) ([26ca89e](https://github.com/vuejs/core/commit/26ca89e5cf734fbef81e182050d2a215ec8a437b)) + + +### Performance Improvements + +* replace Map/Set with WeakMap/WeakSet ([#8549](https://github.com/vuejs/core/issues/8549)) ([712f96d](https://github.com/vuejs/core/commit/712f96d6ac4d3d984732cba448cb84624daba850)) + + + ## [3.3.5](https://github.com/vuejs/core/compare/v3.3.4...v3.3.5) (2023-10-20) ### Bug Fixes -* add isGloballyWhitelisted back, but deprecated ([#8556](https://github.com/vuejs/core/issues/8556)) ([63dfe8e](https://github.com/vuejs/core/commit/63dfe8eab499979bcc2f7829e82464e13899c895)), closes [/github.com/vuejs/core/issues/8416#issuecomment-1566583260](https://github.com//github.com/vuejs/core/issues/8416/issues/issuecomment-1566583260) +* add isGloballyWhitelisted back, but deprecated ([#8556](https://github.com/vuejs/core/issues/8556)) ([63dfe8e](https://github.com/vuejs/core/commit/63dfe8eab499979bcc2f7829e82464e13899c895)), closes [#8416](https://github.com/vuejs/core/issues/8416) * **build:** disable useDefineForClassFields in esbuild ([#9252](https://github.com/vuejs/core/issues/9252)) ([6d14fa8](https://github.com/vuejs/core/commit/6d14fa88e85d4c9e264be394ddb37a54ca6738a8)) * **compat:** return value of vue compat set() ([#9377](https://github.com/vuejs/core/issues/9377)) ([e3c2d69](https://github.com/vuejs/core/commit/e3c2d699f694d9500ddee78571172a24f0e3b17a)) * **compiler-sfc:** don't hoist props and emit ([#8535](https://github.com/vuejs/core/issues/8535)) ([24db951](https://github.com/vuejs/core/commit/24db9516d8b4857182ec1a3af86cb7346691679b)), closes [#7805](https://github.com/vuejs/core/issues/7805) [#7812](https://github.com/vuejs/core/issues/7812) diff --git a/package.json b/package.json index d28f5a77c45..d903294ab1e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "private": true, - "version": "3.3.5", + "version": "3.3.6", "packageManager": "pnpm@8.9.2", "type": "module", "scripts": { diff --git a/packages/compiler-core/package.json b/packages/compiler-core/package.json index 160b0335079..f885e2046e1 100644 --- a/packages/compiler-core/package.json +++ b/packages/compiler-core/package.json @@ -1,6 +1,6 @@ { "name": "@vue/compiler-core", - "version": "3.3.5", + "version": "3.3.6", "description": "@vue/compiler-core", "main": "index.js", "module": "dist/compiler-core.esm-bundler.js", @@ -33,7 +33,7 @@ "homepage": "https://github.com/vuejs/core/tree/main/packages/compiler-core#readme", "dependencies": { "@babel/parser": "^7.23.0", - "@vue/shared": "3.3.5", + "@vue/shared": "3.3.6", "estree-walker": "^2.0.2", "source-map-js": "^1.0.2" }, diff --git a/packages/compiler-core/src/transform.ts b/packages/compiler-core/src/transform.ts index 4d9e8c6ed49..d26c11bba20 100644 --- a/packages/compiler-core/src/transform.ts +++ b/packages/compiler-core/src/transform.ts @@ -117,7 +117,7 @@ export interface TransformContext removeIdentifiers(exp: ExpressionNode | string): void hoist(exp: string | JSChildNode | ArrayExpression): SimpleExpressionNode cache(exp: T, isVNode?: boolean): CacheExpression | T - constantCache: Map + constantCache: WeakMap // 2.x Compat only filters?: Set @@ -181,7 +181,7 @@ export function createTransformContext( directives: new Set(), hoists: [], imports: [], - constantCache: new Map(), + constantCache: new WeakMap(), temps: 0, cached: 0, identifiers: Object.create(null), diff --git a/packages/compiler-dom/package.json b/packages/compiler-dom/package.json index db4c1f5af1d..8bde209e292 100644 --- a/packages/compiler-dom/package.json +++ b/packages/compiler-dom/package.json @@ -1,6 +1,6 @@ { "name": "@vue/compiler-dom", - "version": "3.3.5", + "version": "3.3.6", "description": "@vue/compiler-dom", "main": "index.js", "module": "dist/compiler-dom.esm-bundler.js", @@ -37,7 +37,7 @@ }, "homepage": "https://github.com/vuejs/core/tree/main/packages/compiler-dom#readme", "dependencies": { - "@vue/shared": "3.3.5", - "@vue/compiler-core": "3.3.5" + "@vue/shared": "3.3.6", + "@vue/compiler-core": "3.3.6" } } diff --git a/packages/compiler-sfc/__tests__/compileScript/__snapshots__/defineModel.spec.ts.snap b/packages/compiler-sfc/__tests__/compileScript/__snapshots__/defineModel.spec.ts.snap index fdfd3710efc..297ee62724c 100644 --- a/packages/compiler-sfc/__tests__/compileScript/__snapshots__/defineModel.spec.ts.snap +++ b/packages/compiler-sfc/__tests__/compileScript/__snapshots__/defineModel.spec.ts.snap @@ -7,15 +7,17 @@ export default { props: { \\"modelValue\\": { required: true }, \\"count\\": {}, + \\"toString\\": { type: Function }, }, - emits: [\\"update:modelValue\\", \\"update:count\\"], + emits: [\\"update:modelValue\\", \\"update:count\\", \\"update:toString\\"], setup(__props, { expose: __expose }) { __expose(); const modelValue = _useModel(__props, \\"modelValue\\") const c = _useModel(__props, \\"count\\") + const toString = _useModel(__props, \\"toString\\") -return { modelValue, c } +return { modelValue, c, toString } } }" diff --git a/packages/compiler-sfc/__tests__/compileScript/defineModel.spec.ts b/packages/compiler-sfc/__tests__/compileScript/defineModel.spec.ts index 61a9adcbe0d..10fab947c13 100644 --- a/packages/compiler-sfc/__tests__/compileScript/defineModel.spec.ts +++ b/packages/compiler-sfc/__tests__/compileScript/defineModel.spec.ts @@ -8,6 +8,7 @@ describe('defineModel()', () => { `, { defineModel: true } @@ -16,18 +17,22 @@ describe('defineModel()', () => { expect(content).toMatch('props: {') expect(content).toMatch('"modelValue": { required: true },') expect(content).toMatch('"count": {},') - expect(content).toMatch('emits: ["update:modelValue", "update:count"],') + expect(content).toMatch('"toString": { type: Function },') + expect(content).toMatch( + 'emits: ["update:modelValue", "update:count", "update:toString"],' + ) expect(content).toMatch( `const modelValue = _useModel(__props, "modelValue")` ) expect(content).toMatch(`const c = _useModel(__props, "count")`) - expect(content).toMatch(`return { modelValue, c }`) + expect(content).toMatch(`return { modelValue, c, toString }`) expect(content).not.toMatch('defineModel') expect(bindings).toStrictEqual({ modelValue: BindingTypes.SETUP_REF, count: BindingTypes.PROPS, - c: BindingTypes.SETUP_REF + c: BindingTypes.SETUP_REF, + toString: BindingTypes.SETUP_REF }) }) diff --git a/packages/compiler-sfc/__tests__/templateTransformAssetUrl.spec.ts b/packages/compiler-sfc/__tests__/templateTransformAssetUrl.spec.ts index f267e73ede0..44c13e47ea2 100644 --- a/packages/compiler-sfc/__tests__/templateTransformAssetUrl.spec.ts +++ b/packages/compiler-sfc/__tests__/templateTransformAssetUrl.spec.ts @@ -166,4 +166,34 @@ describe('compiler sfc: transform asset url', () => { expect(code).toMatch(`_createStaticVNode`) expect(code).toMatchSnapshot() }) + + test('transform with stringify with space in absolute filename', () => { + const { code } = compileWithAssetUrls( + `
`, + { + includeAbsolute: true + }, + { + hoistStatic: true, + transformHoist: stringifyStatic + } + ) + expect(code).toMatch(`_createElementVNode`) + expect(code).toContain(`import _imports_0 from '/foo bar.png'`) + }) + + test('transform with stringify with space in relative filename', () => { + const { code } = compileWithAssetUrls( + `
`, + { + includeAbsolute: true + }, + { + hoistStatic: true, + transformHoist: stringifyStatic + } + ) + expect(code).toMatch(`_createElementVNode`) + expect(code).toContain(`import _imports_0 from './foo bar.png'`) + }) }) diff --git a/packages/compiler-sfc/package.json b/packages/compiler-sfc/package.json index 69749c8eb3e..6a1fc8bba3a 100644 --- a/packages/compiler-sfc/package.json +++ b/packages/compiler-sfc/package.json @@ -1,6 +1,6 @@ { "name": "@vue/compiler-sfc", - "version": "3.3.5", + "version": "3.3.6", "description": "@vue/compiler-sfc", "main": "dist/compiler-sfc.cjs.js", "module": "dist/compiler-sfc.esm-browser.js", @@ -33,11 +33,11 @@ "homepage": "https://github.com/vuejs/core/tree/main/packages/compiler-sfc#readme", "dependencies": { "@babel/parser": "^7.23.0", - "@vue/compiler-core": "3.3.5", - "@vue/compiler-dom": "3.3.5", - "@vue/compiler-ssr": "3.3.5", - "@vue/reactivity-transform": "3.3.5", - "@vue/shared": "3.3.5", + "@vue/compiler-core": "3.3.6", + "@vue/compiler-dom": "3.3.6", + "@vue/compiler-ssr": "3.3.6", + "@vue/reactivity-transform": "3.3.6", + "@vue/shared": "3.3.6", "estree-walker": "^2.0.2", "magic-string": "^0.30.5", "postcss": "^8.4.31", @@ -45,7 +45,6 @@ }, "devDependencies": { "@babel/types": "^7.23.0", - "@types/estree": "^0.0.52", "@vue/consolidate": "^0.17.3", "hash-sum": "^2.0.0", "lru-cache": "^10.0.1", diff --git a/packages/compiler-sfc/src/script/context.ts b/packages/compiler-sfc/src/script/context.ts index 5fe09d28a42..692eab3ab9e 100644 --- a/packages/compiler-sfc/src/script/context.ts +++ b/packages/compiler-sfc/src/script/context.ts @@ -53,7 +53,7 @@ export class ScriptCompileContext { emitDecl: Node | undefined // defineModel - modelDecls: Record = {} + modelDecls: Record = Object.create(null) // defineOptions optionsRuntimeDecl: Node | undefined diff --git a/packages/compiler-sfc/src/template/transformAssetUrl.ts b/packages/compiler-sfc/src/template/transformAssetUrl.ts index 32bf33bcea1..4267d4ea352 100644 --- a/packages/compiler-sfc/src/template/transformAssetUrl.ts +++ b/packages/compiler-sfc/src/template/transformAssetUrl.ts @@ -168,7 +168,13 @@ function getImportsExpressionExp( loc, ConstantTypes.CAN_STRINGIFY ) - context.imports.push({ exp, path }) + + // We need to ensure the path is not encoded (to %2F), + // so we decode it back in case it is encoded + context.imports.push({ + exp, + path: decodeURIComponent(path) + }) } if (!hash) { diff --git a/packages/compiler-ssr/__tests__/ssrScopeId.spec.ts b/packages/compiler-ssr/__tests__/ssrScopeId.spec.ts index 3445a84fda9..1be6a2c180c 100644 --- a/packages/compiler-ssr/__tests__/ssrScopeId.spec.ts +++ b/packages/compiler-ssr/__tests__/ssrScopeId.spec.ts @@ -124,4 +124,48 @@ describe('ssr: scopeId', () => { }" `) }) + + // #7554 + test('scopeId is correctly transform to scope attribute of transition-group ', () => { + expect( + compile( + `hello`, + { + scopeId, + mode: 'module' + } + ).code + ).toMatchInlineSnapshot(` + "import { mergeProps as _mergeProps } from \\"vue\\" + import { ssrRenderAttrs as _ssrRenderAttrs } from \\"vue/server-renderer\\" + + export function ssrRender(_ctx, _push, _parent, _attrs) { + _push(\`hello\`) + }" + `) + + // with dynamic tag + expect( + compile( + `hello`, + { + scopeId, + mode: 'module' + } + ).code + ).toMatchInlineSnapshot(` + "import { mergeProps as _mergeProps } from \\"vue\\" + import { ssrRenderAttrs as _ssrRenderAttrs } from \\"vue/server-renderer\\" + + export function ssrRender(_ctx, _push, _parent, _attrs) { + _push(\`<\${ + _ctx.someTag + }\${ + _ssrRenderAttrs(_mergeProps({ class: \\"red\\" }, _attrs)) + } data-v-xxxxxxx>hello\`) + }" + `) + }) }) diff --git a/packages/compiler-ssr/__tests__/ssrVModel.spec.ts b/packages/compiler-ssr/__tests__/ssrVModel.spec.ts index 5bccbcb788c..f28c38d4026 100644 --- a/packages/compiler-ssr/__tests__/ssrVModel.spec.ts +++ b/packages/compiler-ssr/__tests__/ssrVModel.spec.ts @@ -69,6 +69,57 @@ describe('ssr: v-model', () => { }>\`) }" `) + + expect( + compileWithWrapper(``) + .code + ).toMatchInlineSnapshot(` + "const { ssrRenderSlot: _ssrRenderSlot, ssrRenderAttrs: _ssrRenderAttrs } = require(\\"vue/server-renderer\\") + + return function ssrRender(_ctx, _push, _parent, _attrs) { + _push(\`\`) + }" + `) + + expect( + compileWithWrapper(` + `).code + ).toMatchInlineSnapshot(` + "const { ssrIncludeBooleanAttr: _ssrIncludeBooleanAttr, ssrLooseContain: _ssrLooseContain, ssrLooseEqual: _ssrLooseEqual, ssrRenderAttrs: _ssrRenderAttrs } = require(\\"vue/server-renderer\\") + + return function ssrRender(_ctx, _push, _parent, _attrs) { + _push(\`\`) + }" + `) + + expect( + compileWithWrapper(` + `).code + ).toMatchInlineSnapshot(` + "const { ssrRenderSlot: _ssrRenderSlot, ssrRenderAttrs: _ssrRenderAttrs } = require(\\"vue/server-renderer\\") + + return function ssrRender(_ctx, _push, _parent, _attrs) { + _push(\`\`) + }" + `) }) test('', () => { diff --git a/packages/compiler-ssr/package.json b/packages/compiler-ssr/package.json index 66d69523ed7..dc4933349f0 100644 --- a/packages/compiler-ssr/package.json +++ b/packages/compiler-ssr/package.json @@ -1,6 +1,6 @@ { "name": "@vue/compiler-ssr", - "version": "3.3.5", + "version": "3.3.6", "description": "@vue/compiler-ssr", "main": "dist/compiler-ssr.cjs.js", "types": "dist/compiler-ssr.d.ts", @@ -28,7 +28,7 @@ }, "homepage": "https://github.com/vuejs/core/tree/main/packages/compiler-ssr#readme", "dependencies": { - "@vue/shared": "3.3.5", - "@vue/compiler-dom": "3.3.5" + "@vue/shared": "3.3.6", + "@vue/compiler-dom": "3.3.6" } } diff --git a/packages/compiler-ssr/src/transforms/ssrTransformTransitionGroup.ts b/packages/compiler-ssr/src/transforms/ssrTransformTransitionGroup.ts index 00b0d9dd45a..b0f96e4dd6c 100644 --- a/packages/compiler-ssr/src/transforms/ssrTransformTransitionGroup.ts +++ b/packages/compiler-ssr/src/transforms/ssrTransformTransitionGroup.ts @@ -18,6 +18,7 @@ const wipMap = new WeakMap() interface WIPEntry { tag: AttributeNode | DirectiveNode propsExp: string | JSChildNode | null + scopeId: string | null } // phase 1: build props @@ -45,7 +46,8 @@ export function ssrTransformTransitionGroup( } wipMap.set(node, { tag, - propsExp + propsExp, + scopeId: context.scopeId || null }) } } @@ -58,7 +60,7 @@ export function ssrProcessTransitionGroup( ) { const entry = wipMap.get(node) if (entry) { - const { tag, propsExp } = entry + const { tag, propsExp, scopeId } = entry if (tag.type === NodeTypes.DIRECTIVE) { // dynamic :tag context.pushStringPart(`<`) @@ -66,6 +68,9 @@ export function ssrProcessTransitionGroup( if (propsExp) { context.pushStringPart(propsExp) } + if (scopeId) { + context.pushStringPart(` ${scopeId}`) + } context.pushStringPart(`>`) processChildren( @@ -89,6 +94,9 @@ export function ssrProcessTransitionGroup( if (propsExp) { context.pushStringPart(propsExp) } + if (scopeId) { + context.pushStringPart(` ${scopeId}`) + } context.pushStringPart(`>`) processChildren(node, context, false, true) context.pushStringPart(``) diff --git a/packages/compiler-ssr/src/transforms/ssrVModel.ts b/packages/compiler-ssr/src/transforms/ssrVModel.ts index bd587edcb9c..0c4bd177875 100644 --- a/packages/compiler-ssr/src/transforms/ssrVModel.ts +++ b/packages/compiler-ssr/src/transforms/ssrVModel.ts @@ -38,6 +38,38 @@ export const ssrTransformModel: DirectiveTransform = (dir, node, context) => { } } + function processOption(plainNode: PlainElementNode) { + if (plainNode.tag === 'option') { + if (plainNode.props.findIndex(p => p.name === 'selected') === -1) { + const value = findValueBinding(plainNode) + plainNode.ssrCodegenNode!.elements.push( + createConditionalExpression( + createCallExpression(context.helper(SSR_INCLUDE_BOOLEAN_ATTR), [ + createConditionalExpression( + createCallExpression(`Array.isArray`, [model]), + createCallExpression(context.helper(SSR_LOOSE_CONTAIN), [ + model, + value + ]), + createCallExpression(context.helper(SSR_LOOSE_EQUAL), [ + model, + value + ]) + ) + ]), + createSimpleExpression(' selected', true), + createSimpleExpression('', true), + false /* no newline */ + ) + ) + } + } else if (plainNode.tag === 'optgroup') { + plainNode.children.forEach(option => + processOption(option as PlainElementNode) + ) + } + } + if (node.tagType === ElementTypes.ELEMENT) { const res: DirectiveTransformResult = { props: [] } const defaultProps = [ @@ -130,32 +162,9 @@ export const ssrTransformModel: DirectiveTransform = (dir, node, context) => { checkDuplicatedValue() node.children = [createInterpolation(model, model.loc)] } else if (node.tag === 'select') { - node.children.forEach(option => { - if (option.type === NodeTypes.ELEMENT) { - const plainNode = option as PlainElementNode - if (plainNode.props.findIndex(p => p.name === 'selected') === -1) { - const value = findValueBinding(plainNode) - plainNode.ssrCodegenNode!.elements.push( - createConditionalExpression( - createCallExpression(context.helper(SSR_INCLUDE_BOOLEAN_ATTR), [ - createConditionalExpression( - createCallExpression(`Array.isArray`, [model]), - createCallExpression(context.helper(SSR_LOOSE_CONTAIN), [ - model, - value - ]), - createCallExpression(context.helper(SSR_LOOSE_EQUAL), [ - model, - value - ]) - ) - ]), - createSimpleExpression(' selected', true), - createSimpleExpression('', true), - false /* no newline */ - ) - ) - } + node.children.forEach(child => { + if (child.type === NodeTypes.ELEMENT) { + processOption(child as PlainElementNode) } }) } else { diff --git a/packages/dts-test/package.json b/packages/dts-test/package.json index a6933d2dca7..da8424e254c 100644 --- a/packages/dts-test/package.json +++ b/packages/dts-test/package.json @@ -4,5 +4,5 @@ "dependencies": { "vue": "workspace:*" }, - "version": "3.3.5" + "version": "3.3.6" } diff --git a/packages/reactivity-transform/package.json b/packages/reactivity-transform/package.json index ef884997ad0..887fedabc6e 100644 --- a/packages/reactivity-transform/package.json +++ b/packages/reactivity-transform/package.json @@ -1,6 +1,6 @@ { "name": "@vue/reactivity-transform", - "version": "3.3.5", + "version": "3.3.6", "description": "@vue/reactivity-transform", "main": "dist/reactivity-transform.cjs.js", "files": [ @@ -29,8 +29,8 @@ "homepage": "https://github.com/vuejs/core/tree/dev/packages/reactivity-transform#readme", "dependencies": { "@babel/parser": "^7.23.0", - "@vue/compiler-core": "3.3.5", - "@vue/shared": "3.3.5", + "@vue/compiler-core": "3.3.6", + "@vue/shared": "3.3.6", "estree-walker": "^2.0.2", "magic-string": "^0.30.5" }, diff --git a/packages/reactivity/package.json b/packages/reactivity/package.json index 5438a3debd8..ac49b4ec7d2 100644 --- a/packages/reactivity/package.json +++ b/packages/reactivity/package.json @@ -1,6 +1,6 @@ { "name": "@vue/reactivity", - "version": "3.3.5", + "version": "3.3.6", "description": "@vue/reactivity", "main": "index.js", "module": "dist/reactivity.esm-bundler.js", @@ -36,6 +36,6 @@ }, "homepage": "https://github.com/vuejs/core/tree/main/packages/reactivity#readme", "dependencies": { - "@vue/shared": "3.3.5" + "@vue/shared": "3.3.6" } } diff --git a/packages/runtime-core/__tests__/componentSlots.spec.ts b/packages/runtime-core/__tests__/componentSlots.spec.ts index f08f1910cd4..708fb20c423 100644 --- a/packages/runtime-core/__tests__/componentSlots.spec.ts +++ b/packages/runtime-core/__tests__/componentSlots.spec.ts @@ -134,9 +134,11 @@ describe('component: slots', () => { } const oldSlots = { - header: 'header' + header: 'header', + footer: undefined } const newSlots = { + header: undefined, footer: 'footer' } diff --git a/packages/runtime-core/__tests__/components/Teleport.spec.ts b/packages/runtime-core/__tests__/components/Teleport.spec.ts index 7371f53f7b6..c0dbd4cae9c 100644 --- a/packages/runtime-core/__tests__/components/Teleport.spec.ts +++ b/packages/runtime-core/__tests__/components/Teleport.spec.ts @@ -172,6 +172,31 @@ describe('renderer: teleport', () => { expect(serializeInner(target)).toBe('') }) + // #6347 + test('descendent component should be unmounted when teleport is disabled and unmounted', () => { + const root = nodeOps.createElement('div') + + const CompWithHook = { + render() { + return [h('p'), h('p')] + }, + beforeUnmount: vi.fn(), + unmounted: vi.fn() + } + + render( + h(() => [h(Teleport, { to: null, disabled: true }, h(CompWithHook))]), + root + ) + expect(CompWithHook.beforeUnmount).toBeCalledTimes(0) + expect(CompWithHook.unmounted).toBeCalledTimes(0) + + render(null, root) + + expect(CompWithHook.beforeUnmount).toBeCalledTimes(1) + expect(CompWithHook.unmounted).toBeCalledTimes(1) + }) + test('multiple teleport with same target', () => { const target = nodeOps.createElement('div') const root = nodeOps.createElement('div') diff --git a/packages/runtime-core/package.json b/packages/runtime-core/package.json index 946420ebf5a..9d2c04d757f 100644 --- a/packages/runtime-core/package.json +++ b/packages/runtime-core/package.json @@ -1,6 +1,6 @@ { "name": "@vue/runtime-core", - "version": "3.3.5", + "version": "3.3.6", "description": "@vue/runtime-core", "main": "index.js", "module": "dist/runtime-core.esm-bundler.js", @@ -32,7 +32,7 @@ }, "homepage": "https://github.com/vuejs/core/tree/main/packages/runtime-core#readme", "dependencies": { - "@vue/shared": "3.3.5", - "@vue/reactivity": "3.3.5" + "@vue/shared": "3.3.6", + "@vue/reactivity": "3.3.6" } } diff --git a/packages/runtime-core/src/apiCreateApp.ts b/packages/runtime-core/src/apiCreateApp.ts index c5ac9d68a52..8e4ab1f3aa0 100644 --- a/packages/runtime-core/src/apiCreateApp.ts +++ b/packages/runtime-core/src/apiCreateApp.ts @@ -227,7 +227,7 @@ export function createAppAPI( }) } - const installedPlugins = new Set() + const installedPlugins = new WeakSet() let isMounted = false diff --git a/packages/runtime-core/src/compat/componentAsync.ts b/packages/runtime-core/src/compat/componentAsync.ts index 0a0dee72b63..5b2ac22c233 100644 --- a/packages/runtime-core/src/compat/componentAsync.ts +++ b/packages/runtime-core/src/compat/componentAsync.ts @@ -18,7 +18,10 @@ type LegacyAsyncComponent = ( reject?: (reason?: any) => void ) => LegacyAsyncReturnValue | undefined -const normalizedAsyncComponentMap = new Map() +const normalizedAsyncComponentMap = new WeakMap< + LegacyAsyncComponent, + Component +>() export function convertLegacyAsyncComponent(comp: LegacyAsyncComponent) { if (normalizedAsyncComponentMap.has(comp)) { diff --git a/packages/runtime-core/src/compat/componentFunctional.ts b/packages/runtime-core/src/compat/componentFunctional.ts index 1b1146bbab9..90d24e1ba73 100644 --- a/packages/runtime-core/src/compat/componentFunctional.ts +++ b/packages/runtime-core/src/compat/componentFunctional.ts @@ -8,11 +8,10 @@ import { InternalSlots } from '../componentSlots' import { getCompatListeners } from './instanceListeners' import { compatH } from './renderFn' -const normalizedFunctionalComponentMap = new Map< +const normalizedFunctionalComponentMap = new WeakMap< ComponentOptions, FunctionalComponent >() - export const legacySlotProxyHandlers: ProxyHandler = { get(target, key: string) { const slot = target[key] diff --git a/packages/runtime-core/src/componentSlots.ts b/packages/runtime-core/src/componentSlots.ts index afc5f03933b..980ee799186 100644 --- a/packages/runtime-core/src/componentSlots.ts +++ b/packages/runtime-core/src/componentSlots.ts @@ -234,7 +234,7 @@ export const updateSlots = ( // delete stale slots if (needDeletionCheck) { for (const key in slots) { - if (!isInternalKey(key) && !(key in deletionComparisonTarget)) { + if (!isInternalKey(key) && deletionComparisonTarget[key] == null) { delete slots[key] } } diff --git a/packages/runtime-core/src/components/Teleport.ts b/packages/runtime-core/src/components/Teleport.ts index 19ccbc5de27..cbb77c53516 100644 --- a/packages/runtime-core/src/components/Teleport.ts +++ b/packages/runtime-core/src/components/Teleport.ts @@ -239,7 +239,7 @@ export const TeleportImpl = { parentSuspense: SuspenseBoundary | null, optimized: boolean, { um: unmount, o: { remove: hostRemove } }: RendererInternals, - doRemove: Boolean + doRemove: boolean ) { const { shapeFlag, children, anchor, targetAnchor, target, props } = vnode @@ -247,20 +247,19 @@ export const TeleportImpl = { hostRemove(targetAnchor!) } - // an unmounted teleport should always remove its children if not disabled - if (doRemove || !isTeleportDisabled(props)) { - hostRemove(anchor!) - if (shapeFlag & ShapeFlags.ARRAY_CHILDREN) { - for (let i = 0; i < (children as VNode[]).length; i++) { - const child = (children as VNode[])[i] - unmount( - child, - parentComponent, - parentSuspense, - true, - !!child.dynamicChildren - ) - } + // an unmounted teleport should always unmount its children whether it's disabled or not + doRemove && hostRemove(anchor!) + if (shapeFlag & ShapeFlags.ARRAY_CHILDREN) { + const shouldRemove = doRemove || !isTeleportDisabled(props) + for (let i = 0; i < (children as VNode[]).length; i++) { + const child = (children as VNode[])[i] + unmount( + child, + parentComponent, + parentSuspense, + shouldRemove, + !!child.dynamicChildren + ) } } }, @@ -414,7 +413,7 @@ function updateCssVars(vnode: VNode) { const ctx = vnode.ctx if (ctx && ctx.ut) { let node = (vnode.children as VNode[])[0].el! - while (node !== vnode.targetAnchor) { + while (node && node !== vnode.targetAnchor) { if (node.nodeType === 1) node.setAttribute('data-v-owner', ctx.uid) node = node.nextSibling } diff --git a/packages/runtime-dom/__tests__/helpers/useCssVars.spec.ts b/packages/runtime-dom/__tests__/helpers/useCssVars.spec.ts index 7d24ec0f434..5792a0107b1 100644 --- a/packages/runtime-dom/__tests__/helpers/useCssVars.spec.ts +++ b/packages/runtime-dom/__tests__/helpers/useCssVars.spec.ts @@ -275,4 +275,22 @@ describe('useCssVars', () => { expect((c as HTMLElement).style.getPropertyValue(`--color`)).toBe('red') } }) + + test('with teleport(disabled)', async () => { + document.body.innerHTML = '' + const state = reactive({ color: 'red' }) + const root = document.createElement('div') + const target = document.body + + const App = { + setup() { + useCssVars(() => state) + return () => [h(Teleport, { to: target, disabled: true }, [h('div')])] + } + } + + expect(() => render(h(App), root)).not.toThrow(TypeError) + await nextTick() + expect(target.children.length).toBe(0) + }) }) diff --git a/packages/runtime-dom/package.json b/packages/runtime-dom/package.json index 3de508580aa..2de47ff45f6 100644 --- a/packages/runtime-dom/package.json +++ b/packages/runtime-dom/package.json @@ -1,6 +1,6 @@ { "name": "@vue/runtime-dom", - "version": "3.3.5", + "version": "3.3.6", "description": "@vue/runtime-dom", "main": "index.js", "module": "dist/runtime-dom.esm-bundler.js", @@ -35,8 +35,8 @@ }, "homepage": "https://github.com/vuejs/core/tree/main/packages/runtime-dom#readme", "dependencies": { - "@vue/shared": "3.3.5", - "@vue/runtime-core": "3.3.5", + "@vue/shared": "3.3.6", + "@vue/runtime-core": "3.3.6", "csstype": "^3.1.2" } } diff --git a/packages/runtime-dom/src/jsx.ts b/packages/runtime-dom/src/jsx.ts index d3c0332c7c3..03b84f9e020 100644 --- a/packages/runtime-dom/src/jsx.ts +++ b/packages/runtime-dom/src/jsx.ts @@ -244,7 +244,7 @@ export interface HTMLAttributes extends AriaAttributes, EventHandlers { // Standard HTML Attributes accesskey?: string - contenteditable?: Booleanish | 'inherit' + contenteditable?: Booleanish | 'inherit' | 'plaintext-only' contextmenu?: string dir?: string draggable?: Booleanish diff --git a/packages/runtime-test/package.json b/packages/runtime-test/package.json index fec3ca51d40..80084a36342 100644 --- a/packages/runtime-test/package.json +++ b/packages/runtime-test/package.json @@ -1,6 +1,6 @@ { "name": "@vue/runtime-test", - "version": "3.3.5", + "version": "3.3.6", "description": "@vue/runtime-test", "private": true, "main": "index.js", @@ -25,7 +25,7 @@ }, "homepage": "https://github.com/vuejs/core/tree/main/packages/runtime-test#readme", "dependencies": { - "@vue/shared": "3.3.5", - "@vue/runtime-core": "3.3.5" + "@vue/shared": "3.3.6", + "@vue/runtime-core": "3.3.6" } } diff --git a/packages/server-renderer/package.json b/packages/server-renderer/package.json index ffc8a16f17c..66256838e60 100644 --- a/packages/server-renderer/package.json +++ b/packages/server-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@vue/server-renderer", - "version": "3.3.5", + "version": "3.3.6", "description": "@vue/server-renderer", "main": "index.js", "module": "dist/server-renderer.esm-bundler.js", @@ -32,10 +32,10 @@ }, "homepage": "https://github.com/vuejs/core/tree/main/packages/server-renderer#readme", "peerDependencies": { - "vue": "3.3.5" + "vue": "3.3.6" }, "dependencies": { - "@vue/shared": "3.3.5", - "@vue/compiler-ssr": "3.3.5" + "@vue/shared": "3.3.6", + "@vue/compiler-ssr": "3.3.6" } } diff --git a/packages/sfc-playground/package.json b/packages/sfc-playground/package.json index 22a6ef82b54..2c538bbeaac 100644 --- a/packages/sfc-playground/package.json +++ b/packages/sfc-playground/package.json @@ -1,6 +1,6 @@ { "name": "@vue/sfc-playground", - "version": "3.3.5", + "version": "3.3.6", "type": "module", "private": true, "scripts": { diff --git a/packages/sfc-playground/vite.config.ts b/packages/sfc-playground/vite.config.ts index df5441cb0f6..0a5bfa6af0a 100644 --- a/packages/sfc-playground/vite.config.ts +++ b/packages/sfc-playground/vite.config.ts @@ -4,7 +4,7 @@ import { defineConfig, Plugin } from 'vite' import vue from '@vitejs/plugin-vue' import { execaSync } from 'execa' -const commit = execaSync('git', ['rev-parse', 'HEAD']).stdout.slice(0, 7) +const commit = execaSync('git', ['rev-parse', '--short=7', 'HEAD']).stdout export default defineConfig({ plugins: [ diff --git a/packages/shared/package.json b/packages/shared/package.json index ba2567286b0..4b20b2c4c75 100644 --- a/packages/shared/package.json +++ b/packages/shared/package.json @@ -1,6 +1,6 @@ { "name": "@vue/shared", - "version": "3.3.5", + "version": "3.3.6", "description": "internal utils shared across @vue packages", "main": "index.js", "module": "dist/shared.esm-bundler.js", diff --git a/packages/template-explorer/package.json b/packages/template-explorer/package.json index b2fcf90182d..870f635834e 100644 --- a/packages/template-explorer/package.json +++ b/packages/template-explorer/package.json @@ -1,6 +1,6 @@ { "name": "@vue/template-explorer", - "version": "3.3.5", + "version": "3.3.6", "private": true, "buildOptions": { "formats": [ diff --git a/packages/template-explorer/src/index.ts b/packages/template-explorer/src/index.ts index bace011ed89..9faeb0a59f6 100644 --- a/packages/template-explorer/src/index.ts +++ b/packages/template-explorer/src/index.ts @@ -76,8 +76,8 @@ window.init = () => { const compileFn = ssrMode.value ? ssrCompile : compile const start = performance.now() const { code, ast, map } = compileFn(source, { - filename: 'ExampleTemplate.vue', ...compilerOptions, + filename: 'ExampleTemplate.vue', sourceMap: true, onError: err => { errors.push(err) diff --git a/packages/vue-compat/package.json b/packages/vue-compat/package.json index e6f9bfcfa7e..c3126afec55 100644 --- a/packages/vue-compat/package.json +++ b/packages/vue-compat/package.json @@ -1,6 +1,6 @@ { "name": "@vue/compat", - "version": "3.3.5", + "version": "3.3.6", "description": "Vue 3 compatibility build for Vue 2", "main": "index.js", "module": "dist/vue.runtime.esm-bundler.js", @@ -43,6 +43,6 @@ "source-map-js": "^1.0.2" }, "peerDependencies": { - "vue": "3.3.5" + "vue": "3.3.6" } } diff --git a/packages/vue/package.json b/packages/vue/package.json index 3edd19aadfa..627cfc73518 100644 --- a/packages/vue/package.json +++ b/packages/vue/package.json @@ -1,6 +1,6 @@ { "name": "vue", - "version": "3.3.5", + "version": "3.3.6", "description": "The progressive JavaScript framework for building modern web UI.", "main": "index.js", "module": "dist/vue.runtime.esm-bundler.js", @@ -96,11 +96,11 @@ }, "homepage": "https://github.com/vuejs/core/tree/main/packages/vue#readme", "dependencies": { - "@vue/shared": "3.3.5", - "@vue/compiler-dom": "3.3.5", - "@vue/runtime-dom": "3.3.5", - "@vue/compiler-sfc": "3.3.5", - "@vue/server-renderer": "3.3.5" + "@vue/shared": "3.3.6", + "@vue/compiler-dom": "3.3.6", + "@vue/runtime-dom": "3.3.6", + "@vue/compiler-sfc": "3.3.6", + "@vue/server-renderer": "3.3.6" }, "peerDependencies": { "typescript": "*" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4402fa9341e..026d799f036 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -162,7 +162,7 @@ importers: specifier: ^7.23.0 version: 7.23.0 '@vue/shared': - specifier: 3.3.5 + specifier: 3.3.6 version: link:../shared estree-walker: specifier: ^2.0.2 @@ -178,10 +178,10 @@ importers: packages/compiler-dom: dependencies: '@vue/compiler-core': - specifier: 3.3.5 + specifier: 3.3.6 version: link:../compiler-core '@vue/shared': - specifier: 3.3.5 + specifier: 3.3.6 version: link:../shared packages/compiler-sfc: @@ -190,19 +190,19 @@ importers: specifier: ^7.23.0 version: 7.23.0 '@vue/compiler-core': - specifier: 3.3.5 + specifier: 3.3.6 version: link:../compiler-core '@vue/compiler-dom': - specifier: 3.3.5 + specifier: 3.3.6 version: link:../compiler-dom '@vue/compiler-ssr': - specifier: 3.3.5 + specifier: 3.3.6 version: link:../compiler-ssr '@vue/reactivity-transform': - specifier: 3.3.5 + specifier: 3.3.6 version: link:../reactivity-transform '@vue/shared': - specifier: 3.3.5 + specifier: 3.3.6 version: link:../shared estree-walker: specifier: ^2.0.2 @@ -220,9 +220,6 @@ importers: '@babel/types': specifier: ^7.23.0 version: 7.23.0 - '@types/estree': - specifier: ^0.0.52 - version: 0.0.52 '@vue/consolidate': specifier: ^0.17.3 version: 0.17.3 @@ -254,10 +251,10 @@ importers: packages/compiler-ssr: dependencies: '@vue/compiler-dom': - specifier: 3.3.5 + specifier: 3.3.6 version: link:../compiler-dom '@vue/shared': - specifier: 3.3.5 + specifier: 3.3.6 version: link:../shared packages/dts-test: @@ -269,7 +266,7 @@ importers: packages/reactivity: dependencies: '@vue/shared': - specifier: 3.3.5 + specifier: 3.3.6 version: link:../shared packages/reactivity-transform: @@ -278,10 +275,10 @@ importers: specifier: ^7.23.0 version: 7.23.0 '@vue/compiler-core': - specifier: 3.3.5 + specifier: 3.3.6 version: link:../compiler-core '@vue/shared': - specifier: 3.3.5 + specifier: 3.3.6 version: link:../shared estree-walker: specifier: ^2.0.2 @@ -300,19 +297,19 @@ importers: packages/runtime-core: dependencies: '@vue/reactivity': - specifier: 3.3.5 + specifier: 3.3.6 version: link:../reactivity '@vue/shared': - specifier: 3.3.5 + specifier: 3.3.6 version: link:../shared packages/runtime-dom: dependencies: '@vue/runtime-core': - specifier: 3.3.5 + specifier: 3.3.6 version: link:../runtime-core '@vue/shared': - specifier: 3.3.5 + specifier: 3.3.6 version: link:../shared csstype: specifier: ^3.1.2 @@ -321,22 +318,22 @@ importers: packages/runtime-test: dependencies: '@vue/runtime-core': - specifier: 3.3.5 + specifier: 3.3.6 version: link:../runtime-core '@vue/shared': - specifier: 3.3.5 + specifier: 3.3.6 version: link:../shared packages/server-renderer: dependencies: '@vue/compiler-ssr': - specifier: 3.3.5 + specifier: 3.3.6 version: link:../compiler-ssr '@vue/shared': - specifier: 3.3.5 + specifier: 3.3.6 version: link:../shared vue: - specifier: 3.3.5 + specifier: 3.3.6 version: link:../vue packages/sfc-playground: @@ -375,19 +372,19 @@ importers: packages/vue: dependencies: '@vue/compiler-dom': - specifier: 3.3.5 + specifier: 3.3.6 version: link:../compiler-dom '@vue/compiler-sfc': - specifier: 3.3.5 + specifier: 3.3.6 version: link:../compiler-sfc '@vue/runtime-dom': - specifier: 3.3.5 + specifier: 3.3.6 version: link:../runtime-dom '@vue/server-renderer': - specifier: 3.3.5 + specifier: 3.3.6 version: link:../server-renderer '@vue/shared': - specifier: 3.3.5 + specifier: 3.3.6 version: link:../shared typescript: specifier: '*' @@ -405,7 +402,7 @@ importers: specifier: ^1.0.2 version: 1.0.2 vue: - specifier: 3.3.5 + specifier: 3.3.6 version: link:../vue packages: diff --git a/scripts/build.js b/scripts/build.js index 77f711ce87f..0cd011025ec 100644 --- a/scripts/build.js +++ b/scripts/build.js @@ -40,7 +40,7 @@ const sourceMap = args.sourcemap || args.s const isRelease = args.release const buildAllMatching = args.all || args.a const writeSize = args.size -const commit = execaSync('git', ['rev-parse', 'HEAD']).stdout.slice(0, 7) +const commit = execaSync('git', ['rev-parse', '--short=7', 'HEAD']).stdout const sizeDir = path.resolve('temp/size') pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy