Skip to content

Commit

Permalink
Merge branch 'main' into feat/return-cleanup-function
Browse files Browse the repository at this point in the history
# Conflicts:
#	packages/reactivity/__tests__/watch.spec.ts
  • Loading branch information
Mini-ghost committed Sep 19, 2024
2 parents 9b33b49 + e075dfa commit c118104
Show file tree
Hide file tree
Showing 63 changed files with 1,326 additions and 657 deletions.
32 changes: 32 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,35 @@
## [3.5.6](https://github.com/vuejs/core/compare/v3.5.5...v3.5.6) (2024-09-16)


### Bug Fixes

* **compile-dom:** should be able to stringify mathML ([#11891](https://github.com/vuejs/core/issues/11891)) ([85c138c](https://github.com/vuejs/core/commit/85c138ced108268f7656b568dfd3036a1e0aae34))
* **compiler-sfc:** preserve old behavior when using withDefaults with desutructure ([8492c3c](https://github.com/vuejs/core/commit/8492c3c49a922363d6c77ef192c133a8fbce6514)), closes [#11930](https://github.com/vuejs/core/issues/11930)
* **reactivity:** avoid exponential perf cost and reduce call stack depth for deeply chained computeds ([#11944](https://github.com/vuejs/core/issues/11944)) ([c74bb8c](https://github.com/vuejs/core/commit/c74bb8c2dd9e82aaabb0a2a2b368e900929b513b)), closes [#11928](https://github.com/vuejs/core/issues/11928)
* **reactivity:** rely on dirty check only when computed has deps ([#11931](https://github.com/vuejs/core/issues/11931)) ([aa5dafd](https://github.com/vuejs/core/commit/aa5dafd2b55d42d6a29316a3bc91aea85c676a0b)), closes [#11929](https://github.com/vuejs/core/issues/11929)
* **watch:** `once` option should be ignored by watchEffect ([#11884](https://github.com/vuejs/core/issues/11884)) ([49fa673](https://github.com/vuejs/core/commit/49fa673493d93b77ddba2165ab6545bae84fd1ae))
* **watch:** unwatch should be callable during SSR ([#11925](https://github.com/vuejs/core/issues/11925)) ([2d6adf7](https://github.com/vuejs/core/commit/2d6adf78a047eed091db277ffbd9df0822fb0bdd)), closes [#11924](https://github.com/vuejs/core/issues/11924)



## [3.5.5](https://github.com/vuejs/core/compare/v3.5.4...v3.5.5) (2024-09-13)


### Bug Fixes

* **compiler-core:** fix handling of delimiterOpen in VPre ([#11915](https://github.com/vuejs/core/issues/11915)) ([706d4ac](https://github.com/vuejs/core/commit/706d4ac1d0210b2d9134b3228280187fe02fc971)), closes [#11913](https://github.com/vuejs/core/issues/11913)
* **compiler-dom:** fix stringify static edge for partially eligible chunks in cached parent ([1d99d61](https://github.com/vuejs/core/commit/1d99d61c1bd77f9ea6743f6214a82add8346a121)), closes [#11879](https://github.com/vuejs/core/issues/11879) [#11890](https://github.com/vuejs/core/issues/11890)
* **compiler-dom:** should ignore leading newline in <textarea> per spec ([3c4bf76](https://github.com/vuejs/core/commit/3c4bf7627649ec1e3220f8c4e4163c20d2afb367))
* **compiler-sfc:** nested css supports atrule and comment ([#11899](https://github.com/vuejs/core/issues/11899)) ([0e7bc71](https://github.com/vuejs/core/commit/0e7bc717e6640644f062957ec5031506f0dab215)), closes [#11896](https://github.com/vuejs/core/issues/11896)
* **custom-element:** handle nested customElement mount w/ shadowRoot false ([#11861](https://github.com/vuejs/core/issues/11861)) ([f2d8019](https://github.com/vuejs/core/commit/f2d801918841e7673ff3f048d0d895592a2f7e23)), closes [#11851](https://github.com/vuejs/core/issues/11851) [#11871](https://github.com/vuejs/core/issues/11871)
* **hmr:** reload async child wrapped in Suspense + KeepAlive ([#11907](https://github.com/vuejs/core/issues/11907)) ([10a2c60](https://github.com/vuejs/core/commit/10a2c6053bd30d160d0214bb3566f540187e6874)), closes [#11868](https://github.com/vuejs/core/issues/11868)
* **hydration:** fix mismatch of leading newline in `<textarea>` and `<pre>` ([a5f3c2e](https://github.com/vuejs/core/commit/a5f3c2eb4d2e7fae93ff93ce865b269f01cc825e)), closes [#11873](https://github.com/vuejs/core/issues/11873) [#11874](https://github.com/vuejs/core/issues/11874)
* **reactivity:** properly clean up deps, fix memory leak ([8ea5d6d](https://github.com/vuejs/core/commit/8ea5d6d6981ab7febda0be43c3c92b18869c3a2a)), closes [#11901](https://github.com/vuejs/core/issues/11901)
* **runtime-core:** properly update async component nested in KeepAlive ([#11917](https://github.com/vuejs/core/issues/11917)) ([7fe6c79](https://github.com/vuejs/core/commit/7fe6c795a1fc7ddcea5ad91a56141561192373ac)), closes [#11916](https://github.com/vuejs/core/issues/11916)
* **TransitionGroup:** not warn unkeyed text children with whitespece preserve ([#11888](https://github.com/vuejs/core/issues/11888)) ([7571f20](https://github.com/vuejs/core/commit/7571f20bc3d1854377a146f41d211e05bb68cd47)), closes [#11885](https://github.com/vuejs/core/issues/11885)



## [3.5.4](https://github.com/vuejs/core/compare/v3.5.3...v3.5.4) (2024-09-10)


Expand Down
24 changes: 12 additions & 12 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"private": true,
"version": "3.5.4",
"version": "3.5.6",
"packageManager": "[email protected]",
"type": "module",
"scripts": {
Expand All @@ -17,11 +17,11 @@
"format": "prettier --write --cache .",
"format-check": "prettier --check --cache .",
"test": "vitest",
"test-unit": "vitest -c vitest.unit.config.ts",
"test-e2e": "node scripts/build.js vue -f global -d && vitest -c vitest.e2e.config.ts",
"test-unit": "vitest --project unit",
"test-e2e": "node scripts/build.js vue -f global -d && vitest --project e2e",
"test-dts": "run-s build-dts test-dts-only",
"test-dts-only": "tsc -p packages-private/dts-built-test/tsconfig.json && tsc -p ./packages-private/dts-test/tsconfig.test.json",
"test-coverage": "vitest run -c vitest.unit.config.ts --coverage",
"test-coverage": "vitest run --project unit --coverage",
"test-bench": "vitest bench",
"release": "node scripts/release.js",
"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s",
Expand Down Expand Up @@ -66,19 +66,19 @@
"@rollup/plugin-json": "^6.1.0",
"@rollup/plugin-node-resolve": "^15.2.3",
"@rollup/plugin-replace": "5.0.4",
"@swc/core": "^1.7.24",
"@swc/core": "^1.7.26",
"@types/hash-sum": "^1.0.2",
"@types/node": "^20.16.5",
"@types/semver": "^7.5.8",
"@types/serve-handler": "^6.1.4",
"@vitest/coverage-v8": "^2.0.5",
"@vitest/coverage-v8": "^2.1.1",
"@vue/consolidate": "1.0.0",
"conventional-changelog-cli": "^5.0.0",
"enquirer": "^2.4.1",
"esbuild": "^0.23.1",
"esbuild-plugin-polyfill-node": "^0.3.0",
"eslint": "^9.9.1",
"eslint-plugin-import-x": "^3.1.0",
"eslint": "^9.10.0",
"eslint-plugin-import-x": "^4.2.1",
"eslint-plugin-vitest": "^0.5.4",
"estree-walker": "catalog:",
"jsdom": "^25.0.0",
Expand All @@ -87,14 +87,14 @@
"magic-string": "^0.30.11",
"markdown-table": "^3.0.3",
"marked": "13.0.3",
"npm-run-all2": "^6.2.2",
"npm-run-all2": "^6.2.3",
"picocolors": "^1.1.0",
"prettier": "^3.3.3",
"pretty-bytes": "^6.1.1",
"pug": "^3.0.3",
"puppeteer": "~23.3.0",
"rimraf": "^6.0.1",
"rollup": "^4.21.2",
"rollup": "^4.21.3",
"rollup-plugin-dts": "^6.1.1",
"rollup-plugin-esbuild": "^6.1.1",
"rollup-plugin-polyfill-node": "^0.13.0",
Expand All @@ -105,9 +105,9 @@
"todomvc-app-css": "^2.4.3",
"tslib": "^2.7.0",
"typescript": "~5.6.2",
"typescript-eslint": "^8.4.0",
"typescript-eslint": "^8.5.0",
"vite": "catalog:",
"vitest": "^2.0.5"
"vitest": "^2.1.1"
},
"pnpm": {
"peerDependencyRules": {
Expand Down
19 changes: 12 additions & 7 deletions packages-private/dts-test/appDirective.test-d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,17 @@ import { expectType } from './utils'

const app = createApp({})

app.directive<HTMLElement, string>('custom', {
mounted(el, binding) {
expectType<HTMLElement>(el)
expectType<string>(binding.value)
app.directive<HTMLElement, string, 'prevent' | 'stop', 'arg1' | 'arg2'>(
'custom',
{
mounted(el, binding) {
expectType<HTMLElement>(el)
expectType<string>(binding.value)
expectType<{ prevent: boolean; stop: boolean }>(binding.modifiers)
expectType<'arg1' | 'arg2'>(binding.arg!)

// @ts-expect-error not any
expectType<number>(binding.value)
// @ts-expect-error not any
expectType<number>(binding.value)
},
},
})
)
8 changes: 8 additions & 0 deletions packages-private/global.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/// <reference types="vite/client" />

// Global compile-time constants
declare var __COMMIT__: string

declare module 'file-saver' {
export function saveAs(blob: any, name: any): void
}
2 changes: 1 addition & 1 deletion packages-private/sfc-playground/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"vite": "catalog:"
},
"dependencies": {
"@vue/repl": "^4.4.0",
"@vue/repl": "^4.4.2",
"file-saver": "^2.0.5",
"jszip": "^3.10.1",
"vue": "workspace:*"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@
},
"devDependencies": {
"@vitejs/plugin-vue": "^5.1.3",
"vite": "^5.4.3"
"vite": "^5.4.5"
}
}
2 changes: 1 addition & 1 deletion packages-private/template-explorer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@
},
"dependencies": {
"monaco-editor": "^0.51.0",
"source-map-js": "^1.2.0"
"source-map-js": "^1.2.1"
}
}
16 changes: 16 additions & 0 deletions packages/compiler-core/__tests__/parse.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2019,6 +2019,21 @@ describe('compiler: parse', () => {
children: [{ type: NodeTypes.TEXT, content: `{{ number ` }],
},
])

const ast3 = baseParse(`<div v-pre><textarea>{{ foo </textarea></div>`, {
parseMode: 'html',
})
expect((ast3.children[0] as ElementNode).children).toMatchObject([
{
type: NodeTypes.ELEMENT,
children: [
{
type: NodeTypes.TEXT,
content: `{{ foo `,
},
],
},
])
})

test('self-closing v-pre', () => {
Expand Down Expand Up @@ -2354,6 +2369,7 @@ describe('compiler: parse', () => {
test('should remove leading newline character immediately following the pre element start tag', () => {
const ast = parse(`<pre>\n foo bar </pre>`, {
isPreTag: tag => tag === 'pre',
isIgnoreNewlineTag: tag => tag === 'pre',
})
expect(ast.children).toHaveLength(1)
const preElement = ast.children[0] as ElementNode
Expand Down
2 changes: 1 addition & 1 deletion packages/compiler-core/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@vue/compiler-core",
"version": "3.5.4",
"version": "3.5.6",
"description": "@vue/compiler-core",
"main": "index.js",
"module": "dist/compiler-core.esm-bundler.js",
Expand Down
5 changes: 5 additions & 0 deletions packages/compiler-core/src/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ export interface ParserOptions
* e.g. elements that should preserve whitespace inside, e.g. `<pre>`
*/
isPreTag?: (tag: string) => boolean
/**
* Elements that should ignore the first newline token per parinsg spec
* e.g. `<textarea>` and `<pre>`
*/
isIgnoreNewlineTag?: (tag: string) => boolean
/**
* Platform-specific built-in components e.g. `<Transition>`
*/
Expand Down
23 changes: 13 additions & 10 deletions packages/compiler-core/src/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ export const defaultParserOptions: MergedParserOptions = {
getNamespace: () => Namespaces.HTML,
isVoidTag: NO,
isPreTag: NO,
isIgnoreNewlineTag: NO,
isCustomElement: NO,
onError: defaultOnError,
onWarn: defaultOnWarn,
Expand Down Expand Up @@ -633,7 +634,7 @@ function onCloseTag(el: ElementNode, end: number, isImplied = false) {
}

// refine element type
const { tag, ns } = el
const { tag, ns, children } = el
if (!inVPre) {
if (tag === 'slot') {
el.tagType = ElementTypes.SLOT
Expand All @@ -646,8 +647,18 @@ function onCloseTag(el: ElementNode, end: number, isImplied = false) {

// whitespace management
if (!tokenizer.inRCDATA) {
el.children = condenseWhitespace(el.children, el.tag)
el.children = condenseWhitespace(children, tag)
}

if (ns === Namespaces.HTML && currentOptions.isIgnoreNewlineTag(tag)) {
// remove leading newline for <textarea> and <pre> per html spec
// https://html.spec.whatwg.org/multipage/parsing.html#parsing-main-inbody
const first = children[0]
if (first && first.type === NodeTypes.TEXT) {
first.content = first.content.replace(/^\r?\n/, '')
}
}

if (ns === Namespaces.HTML && currentOptions.isPreTag(tag)) {
inPre--
}
Expand Down Expand Up @@ -869,14 +880,6 @@ function condenseWhitespace(
}
}
}
if (inPre && tag && currentOptions.isPreTag(tag)) {
// remove leading newline per html spec
// https://html.spec.whatwg.org/multipage/grouping-content.html#the-pre-element
const first = nodes[0]
if (first && first.type === NodeTypes.TEXT) {
first.content = first.content.replace(/^\r?\n/, '')
}
}
return removedWhitespace ? nodes.filter(Boolean) : nodes
}

Expand Down
2 changes: 1 addition & 1 deletion packages/compiler-core/src/tokenizer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -438,7 +438,7 @@ export default class Tokenizer {
// We have to parse entities in <title> and <textarea> tags.
if (!__BROWSER__ && c === CharCodes.Amp) {
this.startEntity()
} else if (c === this.delimiterOpen[0]) {
} else if (!this.inVPre && c === this.delimiterOpen[0]) {
// We also need to handle interpolation
this.state = State.InterpolationOpen
this.delimiterIndex = 0
Expand Down
16 changes: 16 additions & 0 deletions packages/compiler-dom/__tests__/parse.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,22 @@ describe('DOM parser', () => {
})
})

test('<textarea> should remove leading newline', () => {
const ast = parse('<textarea>\nhello</textarea>', parserOptions)
const element = ast.children[0] as ElementNode
const text = element.children[0] as TextNode
expect(element.children.length).toBe(1)
expect(text).toStrictEqual({
type: NodeTypes.TEXT,
content: 'hello',
loc: {
start: { offset: 10, line: 1, column: 11 },
end: { offset: 16, line: 2, column: 6 },
source: '\nhello',
},
})
})

test('should not treat Uppercase component as special tag', () => {
const ast = parse(
'<TextArea>some<div>text</div>and<!--comment--></TextArea>',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`stringify static html > eligible content (elements > 20) + non-eligible content 1`] = `
"const { createElementVNode: _createElementVNode, createStaticVNode: _createStaticVNode, openBlock: _openBlock, createElementBlock: _createElementBlock } = Vue
return function render(_ctx, _cache) {
return (_openBlock(), _createElementBlock("div", null, _cache[0] || (_cache[0] = [
_createStaticVNode("<span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span>", 20),
_createElementVNode("div", { key: "1" }, "1", -1 /* HOISTED */),
_createStaticVNode("<span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span>", 20)
])))
}"
`;

exports[`stringify static html > escape 1`] = `
"const { toDisplayString: _toDisplayString, normalizeClass: _normalizeClass, createElementVNode: _createElementVNode, createStaticVNode: _createStaticVNode, openBlock: _openBlock, createElementBlock: _createElementBlock } = Vue
Expand Down
32 changes: 32 additions & 0 deletions packages/compiler-dom/__tests__/transforms/stringifyStatic.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,24 @@ describe('stringify static html', () => {
])
})

test('should stringify mathML', () => {
const math = `<math xmlns="http://www.w3.org/1998/Math/MathML">`
const repeated = `<ms>1</ms>`
const { ast } = compileWithStringify(
`<div>${math}${repeat(
repeated,
StringifyThresholds.NODE_COUNT,
)}</math></div>`,
)

expect(ast.cached).toMatchObject([
cachedArrayStaticNodeMatcher(
`${math}${repeat(repeated, StringifyThresholds.NODE_COUNT)}</math>`,
1,
),
])
})

// #5439
test('stringify v-html', () => {
const { code } = compileWithStringify(`
Expand Down Expand Up @@ -451,4 +469,18 @@ describe('stringify static html', () => {
expect(ast.cached).toMatchObject([cachedArrayBailedMatcher()])
expect(code).toMatchSnapshot()
})

test('eligible content (elements > 20) + non-eligible content', () => {
const { code } = compileWithStringify(
`<div>${repeat(
`<span/>`,
StringifyThresholds.NODE_COUNT,
)}<div key="1">1</div>${repeat(
`<span/>`,
StringifyThresholds.NODE_COUNT,
)}</div>`,
)

expect(code).toMatchSnapshot()
})
})
2 changes: 1 addition & 1 deletion packages/compiler-dom/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@vue/compiler-dom",
"version": "3.5.4",
"version": "3.5.6",
"description": "@vue/compiler-dom",
"main": "index.js",
"module": "dist/compiler-dom.esm-bundler.js",
Expand Down
1 change: 1 addition & 0 deletions packages/compiler-dom/src/parserOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export const parserOptions: ParserOptions = {
isVoidTag,
isNativeTag: tag => isHTMLTag(tag) || isSVGTag(tag) || isMathMLTag(tag),
isPreTag: tag => tag === 'pre',
isIgnoreNewlineTag: tag => tag === 'pre' || tag === 'textarea',
decodeEntities: __BROWSER__ ? decodeHtmlBrowser : undefined,

isBuiltInComponent: tag => {
Expand Down
Loading

0 comments on commit c118104

Please sign in to comment.