diff --git a/AGENTS.md b/AGENTS.md index d59fdf1dd1..380a4a99c7 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -168,6 +168,10 @@ Changelogs must describe **user-facing changes**. Avoid internal noise. ## Extra guidance (short additions) +### Scopes (for Conventional Commits) + +Git conventional commit scopes live in [SCOPES.md](./SCOPES.md). Use it to pick the right scope when committing. + ### Environment - Recommended Node version: >=24.x. Use a node version manager (nvm, fnm) or Corepack to pin a runtime that matches the root `package.json` `engines.node` requirement. @@ -209,4 +213,4 @@ If a single package is failing types, run a targeted build for that package (e.g ### Troubleshooting notes - If CI fails with dependency or lockfile errors, run `pnpm reset` locally and re-run the build. -- For flaky Playwright tests, reproduce locally with `pnpm test:e2e:open` (UI mode) or rerun with `--trace on` and inspect via `pnpm test:e2e:report`. +- For flaky Playwright tests, reproduce locally with `pnpm test:e2e:open` (UI mode) or rerun with `--trace on` and inspect via `pnpm test:e2e:report` diff --git a/CHANGELOG.md b/CHANGELOG.md index 5a0994c60d..dae39afd31 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,563 @@ # Releases +## v3.23.6 + +### @tiptap/extension-drag-handle + +#### Patch Changes + +- 937ff2e: **DragHandle**: Added `dragImageProperties` option to limit which CSS properties are cloned for the drag image. By default all ~300+ computed styles are copied; setting this to a subset (e.g. `['color', 'background-color', 'font-size']`) reduces the cost when dragging selections with complex nodes. +- Updated dependencies [937ff2e] + - @tiptap/core@3.23.6 + - @tiptap/extension-collaboration@3.23.6 + - @tiptap/extension-node-range@3.23.6 + - @tiptap/pm@3.23.6 + +### @tiptap/core + +#### Patch Changes + +- 937ff2e: Fix deleteSelection to properly handle inline nodes with `text*` content. The selection is now expanded to include the entire inline node boundaries when deleting, preventing incorrect collapse of inline text nodes. +- @tiptap/pm@3.23.6 + +### @tiptap/extensions + +#### Patch Changes + +- 937ff2e: **Placeholder**: Replaced full-document `doc.descendants()` traversal with a cursor-resolved fast path for the default config and viewport-limited scanning for the non-default config, significantly reducing decoration overhead on large documents. +- Updated dependencies [937ff2e] + - @tiptap/core@3.23.6 + - @tiptap/pm@3.23.6 + +### @tiptap/extension-drag-handle-react + +#### Patch Changes + +- Updated dependencies [937ff2e] + - @tiptap/extension-drag-handle@3.23.6 + - @tiptap/react@3.23.6 + - @tiptap/pm@3.23.6 + +### @tiptap/extension-drag-handle-vue-2 + +#### Patch Changes + +- Updated dependencies [937ff2e] + - @tiptap/extension-drag-handle@3.23.6 + - @tiptap/vue-2@3.23.6 + - @tiptap/pm@3.23.6 + +### @tiptap/extension-drag-handle-vue-3 + +#### Patch Changes + +- Updated dependencies [937ff2e] + - @tiptap/extension-drag-handle@3.23.6 + - @tiptap/vue-3@3.23.6 + - @tiptap/pm@3.23.6 + +### @tiptap/extension-audio + +#### Patch Changes + +- Updated dependencies [937ff2e] + - @tiptap/core@3.23.6 + +### @tiptap/extension-blockquote + +#### Patch Changes + +- Updated dependencies [937ff2e] + - @tiptap/core@3.23.6 + +### @tiptap/extension-bold + +#### Patch Changes + +- Updated dependencies [937ff2e] + - @tiptap/core@3.23.6 + +### @tiptap/extension-bubble-menu + +#### Patch Changes + +- Updated dependencies [937ff2e] + - @tiptap/core@3.23.6 + - @tiptap/pm@3.23.6 + +### @tiptap/extension-code + +#### Patch Changes + +- Updated dependencies [937ff2e] + - @tiptap/core@3.23.6 + +### @tiptap/extension-code-block + +#### Patch Changes + +- Updated dependencies [937ff2e] + - @tiptap/core@3.23.6 + - @tiptap/pm@3.23.6 + +### @tiptap/extension-code-block-lowlight + +#### Patch Changes + +- Updated dependencies [937ff2e] + - @tiptap/core@3.23.6 + - @tiptap/extension-code-block@3.23.6 + - @tiptap/pm@3.23.6 + +### @tiptap/extension-collaboration + +#### Patch Changes + +- Updated dependencies [937ff2e] + - @tiptap/core@3.23.6 + - @tiptap/pm@3.23.6 + +### @tiptap/extension-collaboration-caret + +#### Patch Changes + +- Updated dependencies [937ff2e] + - @tiptap/core@3.23.6 + - @tiptap/pm@3.23.6 + +### @tiptap/extension-details + +#### Patch Changes + +- Updated dependencies [937ff2e] + - @tiptap/core@3.23.6 + - @tiptap/extension-text-style@3.23.6 + - @tiptap/pm@3.23.6 + +### @tiptap/extension-document + +#### Patch Changes + +- Updated dependencies [937ff2e] + - @tiptap/core@3.23.6 + +### @tiptap/extension-emoji + +#### Patch Changes + +- Updated dependencies [937ff2e] + - @tiptap/core@3.23.6 + - @tiptap/suggestion@3.23.6 + - @tiptap/pm@3.23.6 + +### @tiptap/extension-file-handler + +#### Patch Changes + +- Updated dependencies [937ff2e] + - @tiptap/core@3.23.6 + - @tiptap/extension-text-style@3.23.6 + - @tiptap/pm@3.23.6 + +### @tiptap/extension-floating-menu + +#### Patch Changes + +- Updated dependencies [937ff2e] + - @tiptap/core@3.23.6 + - @tiptap/pm@3.23.6 + +### @tiptap/extension-hard-break + +#### Patch Changes + +- Updated dependencies [937ff2e] + - @tiptap/core@3.23.6 + +### @tiptap/extension-heading + +#### Patch Changes + +- Updated dependencies [937ff2e] + - @tiptap/core@3.23.6 + +### @tiptap/extension-highlight + +#### Patch Changes + +- Updated dependencies [937ff2e] + - @tiptap/core@3.23.6 + +### @tiptap/extension-horizontal-rule + +#### Patch Changes + +- Updated dependencies [937ff2e] + - @tiptap/core@3.23.6 + - @tiptap/pm@3.23.6 + +### @tiptap/extension-image + +#### Patch Changes + +- Updated dependencies [937ff2e] + - @tiptap/core@3.23.6 + +### @tiptap/extension-invisible-characters + +#### Patch Changes + +- Updated dependencies [937ff2e] + - @tiptap/core@3.23.6 + - @tiptap/extension-text-style@3.23.6 + - @tiptap/pm@3.23.6 + +### @tiptap/extension-italic + +#### Patch Changes + +- Updated dependencies [937ff2e] + - @tiptap/core@3.23.6 + +### @tiptap/extension-link + +#### Patch Changes + +- Updated dependencies [937ff2e] + - @tiptap/core@3.23.6 + - @tiptap/pm@3.23.6 + +### @tiptap/extension-list + +#### Patch Changes + +- Updated dependencies [937ff2e] + - @tiptap/core@3.23.6 + - @tiptap/pm@3.23.6 + +### @tiptap/extension-mathematics + +#### Patch Changes + +- Updated dependencies [937ff2e] + - @tiptap/core@3.23.6 + - @tiptap/pm@3.23.6 + +### @tiptap/extension-mention + +#### Patch Changes + +- Updated dependencies [937ff2e] + - @tiptap/core@3.23.6 + - @tiptap/suggestion@3.23.6 + - @tiptap/pm@3.23.6 + +### @tiptap/extension-node-range + +#### Patch Changes + +- Updated dependencies [937ff2e] + - @tiptap/core@3.23.6 + - @tiptap/pm@3.23.6 + +### @tiptap/extension-paragraph + +#### Patch Changes + +- Updated dependencies [937ff2e] + - @tiptap/core@3.23.6 + +### @tiptap/extension-strike + +#### Patch Changes + +- Updated dependencies [937ff2e] + - @tiptap/core@3.23.6 + +### @tiptap/extension-subscript + +#### Patch Changes + +- Updated dependencies [937ff2e] + - @tiptap/core@3.23.6 + - @tiptap/pm@3.23.6 + +### @tiptap/extension-superscript + +#### Patch Changes + +- Updated dependencies [937ff2e] + - @tiptap/core@3.23.6 + - @tiptap/pm@3.23.6 + +### @tiptap/extension-table + +#### Patch Changes + +- Updated dependencies [937ff2e] + - @tiptap/core@3.23.6 + - @tiptap/pm@3.23.6 + +### @tiptap/extension-table-of-contents + +#### Patch Changes + +- Updated dependencies [937ff2e] + - @tiptap/core@3.23.6 + - @tiptap/pm@3.23.6 + +### @tiptap/extension-text + +#### Patch Changes + +- Updated dependencies [937ff2e] + - @tiptap/core@3.23.6 + +### @tiptap/extension-text-align + +#### Patch Changes + +- Updated dependencies [937ff2e] + - @tiptap/core@3.23.6 + +### @tiptap/extension-text-style + +#### Patch Changes + +- Updated dependencies [937ff2e] + - @tiptap/core@3.23.6 + +### @tiptap/extension-twitch + +#### Patch Changes + +- Updated dependencies [937ff2e] + - @tiptap/core@3.23.6 + +### @tiptap/extension-typography + +#### Patch Changes + +- Updated dependencies [937ff2e] + - @tiptap/core@3.23.6 + +### @tiptap/extension-underline + +#### Patch Changes + +- Updated dependencies [937ff2e] + - @tiptap/core@3.23.6 + +### @tiptap/extension-unique-id + +#### Patch Changes + +- Updated dependencies [937ff2e] + - @tiptap/core@3.23.6 + - @tiptap/pm@3.23.6 + +### @tiptap/extension-youtube + +#### Patch Changes + +- Updated dependencies [937ff2e] + - @tiptap/core@3.23.6 + +### @tiptap/html + +#### Patch Changes + +- Updated dependencies [937ff2e] + - @tiptap/core@3.23.6 + - @tiptap/pm@3.23.6 + +### @tiptap/markdown + +#### Patch Changes + +- Updated dependencies [937ff2e] + - @tiptap/core@3.23.6 + - @tiptap/pm@3.23.6 + +### @tiptap/react + +#### Patch Changes + +- Updated dependencies [937ff2e] + - @tiptap/core@3.23.6 + - @tiptap/pm@3.23.6 + +### @tiptap/static-renderer + +#### Patch Changes + +- Updated dependencies [937ff2e] + - @tiptap/core@3.23.6 + - @tiptap/pm@3.23.6 + +### @tiptap/suggestion + +#### Patch Changes + +- Updated dependencies [937ff2e] + - @tiptap/core@3.23.6 + - @tiptap/pm@3.23.6 + +### @tiptap/vue-2 + +#### Patch Changes + +- Updated dependencies [937ff2e] + - @tiptap/core@3.23.6 + - @tiptap/pm@3.23.6 + +### @tiptap/vue-3 + +#### Patch Changes + +- Updated dependencies [937ff2e] + - @tiptap/core@3.23.6 + - @tiptap/pm@3.23.6 + +### @tiptap/extension-character-count + +#### Patch Changes + +- Updated dependencies [937ff2e] + - @tiptap/extensions@3.23.6 + +### @tiptap/extension-dropcursor + +#### Patch Changes + +- Updated dependencies [937ff2e] + - @tiptap/extensions@3.23.6 + +### @tiptap/extension-focus + +#### Patch Changes + +- Updated dependencies [937ff2e] + - @tiptap/extensions@3.23.6 + +### @tiptap/extension-gapcursor + +#### Patch Changes + +- Updated dependencies [937ff2e] + - @tiptap/extensions@3.23.6 + +### @tiptap/extension-history + +#### Patch Changes + +- Updated dependencies [937ff2e] + - @tiptap/extensions@3.23.6 + +### @tiptap/extension-placeholder + +#### Patch Changes + +- Updated dependencies [937ff2e] + - @tiptap/extensions@3.23.6 + +### @tiptap/extension-list-item + +#### Patch Changes + +- @tiptap/extension-list@3.23.6 + +### @tiptap/extension-list-keymap + +#### Patch Changes + +- @tiptap/extension-list@3.23.6 + +### @tiptap/extension-task-item + +#### Patch Changes + +- @tiptap/extension-list@3.23.6 + +### @tiptap/extension-task-list + +#### Patch Changes + +- @tiptap/extension-list@3.23.6 + +### @tiptap/extension-bullet-list + +#### Patch Changes + +- @tiptap/extension-list@3.23.6 + +### @tiptap/extension-ordered-list + +#### Patch Changes + +- @tiptap/extension-list@3.23.6 + +### @tiptap/extension-table-cell + +#### Patch Changes + +- @tiptap/extension-table@3.23.6 + +### @tiptap/extension-table-header + +#### Patch Changes + +- @tiptap/extension-table@3.23.6 + +### @tiptap/extension-table-row + +#### Patch Changes + +- @tiptap/extension-table@3.23.6 + +### @tiptap/extension-color + +#### Patch Changes + +- @tiptap/extension-text-style@3.23.6 + +### @tiptap/extension-font-family + +#### Patch Changes + +- @tiptap/extension-text-style@3.23.6 + +### @tiptap/starter-kit + +#### Patch Changes + +- Updated dependencies [937ff2e] +- Updated dependencies [937ff2e] + - @tiptap/core@3.23.6 + - @tiptap/extensions@3.23.6 + - @tiptap/extension-blockquote@3.23.6 + - @tiptap/extension-bold@3.23.6 + - @tiptap/extension-code@3.23.6 + - @tiptap/extension-code-block@3.23.6 + - @tiptap/extension-document@3.23.6 + - @tiptap/extension-hard-break@3.23.6 + - @tiptap/extension-heading@3.23.6 + - @tiptap/extension-horizontal-rule@3.23.6 + - @tiptap/extension-italic@3.23.6 + - @tiptap/extension-link@3.23.6 + - @tiptap/extension-list@3.23.6 + - @tiptap/extension-paragraph@3.23.6 + - @tiptap/extension-strike@3.23.6 + - @tiptap/extension-text@3.23.6 + - @tiptap/extension-underline@3.23.6 + - @tiptap/extension-dropcursor@3.23.6 + - @tiptap/extension-gapcursor@3.23.6 + - @tiptap/extension-list-item@3.23.6 + - @tiptap/extension-list-keymap@3.23.6 + - @tiptap/extension-bullet-list@3.23.6 + - @tiptap/extension-ordered-list@3.23.6 + - @tiptap/pm@3.23.6 + ## v3.23.5 ### @tiptap/markdown diff --git a/SCOPES.md b/SCOPES.md new file mode 100644 index 0000000000..e95d8eb3a1 --- /dev/null +++ b/SCOPES.md @@ -0,0 +1,75 @@ +# Scopes + +## Primary scopes (monorepo packages) + +### Core, framework bindings, and shared utilities +- core +- extensions +- html +- markdown +- pm +- react +- server-ai-toolkit +- starter-kit +- static-renderer +- suggestion +- vue-2 +- vue-3 + +### Extensions +- extension-audio +- extension-blockquote +- extension-bold +- extension-bubble-menu +- extension-bullet-list +- extension-code +- extension-code-block +- extension-code-block-lowlight +- extension-collaboration +- extension-collaboration-caret +- extension-color +- extension-details +- extension-document +- extension-drag-handle +- extension-drag-handle-react +- extension-drag-handle-vue-2 +- extension-drag-handle-vue-3 +- extension-emoji +- extension-file-handler +- extension-floating-menu +- extension-font-family +- extension-hard-break +- extension-heading +- extension-highlight +- extension-horizontal-rule +- extension-image +- extension-invisible-characters +- extension-italic +- extension-link +- extension-list +- extension-mathematics +- extension-mention +- extension-node-range +- extension-ordered-list +- extension-paragraph +- extension-strike +- extension-subscript +- extension-superscript +- extension-table +- extension-table-of-contents +- extension-text +- extension-text-align +- extension-text-style +- extension-twitch +- extension-typography +- extension-underline +- extension-unique-id +- extension-youtube + +## Additional scopes +- demos +- tests +- ci +- config +- docs +- changeset diff --git a/packages-deprecated/extension-character-count/CHANGELOG.md b/packages-deprecated/extension-character-count/CHANGELOG.md index 7f62e84e17..f3e8b4b666 100644 --- a/packages-deprecated/extension-character-count/CHANGELOG.md +++ b/packages-deprecated/extension-character-count/CHANGELOG.md @@ -1,5 +1,12 @@ # Change Log +## 3.23.6 + +### Patch Changes + +- Updated dependencies [937ff2e] + - @tiptap/extensions@3.23.6 + ## 3.23.5 ### Patch Changes diff --git a/packages-deprecated/extension-character-count/package.json b/packages-deprecated/extension-character-count/package.json index 6f0bffd972..fc76a741fc 100644 --- a/packages-deprecated/extension-character-count/package.json +++ b/packages-deprecated/extension-character-count/package.json @@ -1,7 +1,7 @@ { "name": "@tiptap/extension-character-count", "description": "font family extension for tiptap", - "version": "3.23.5", + "version": "3.23.6", "homepage": "https://tiptap.dev", "keywords": [ "tiptap", diff --git a/packages-deprecated/extension-dropcursor/CHANGELOG.md b/packages-deprecated/extension-dropcursor/CHANGELOG.md index dee9999c48..89f19fe0e3 100644 --- a/packages-deprecated/extension-dropcursor/CHANGELOG.md +++ b/packages-deprecated/extension-dropcursor/CHANGELOG.md @@ -1,5 +1,12 @@ # Change Log +## 3.23.6 + +### Patch Changes + +- Updated dependencies [937ff2e] + - @tiptap/extensions@3.23.6 + ## 3.23.5 ### Patch Changes diff --git a/packages-deprecated/extension-dropcursor/package.json b/packages-deprecated/extension-dropcursor/package.json index 38eb27d7b0..e8786f9380 100644 --- a/packages-deprecated/extension-dropcursor/package.json +++ b/packages-deprecated/extension-dropcursor/package.json @@ -1,7 +1,7 @@ { "name": "@tiptap/extension-dropcursor", "description": "dropcursor extension for tiptap", - "version": "3.23.5", + "version": "3.23.6", "homepage": "https://tiptap.dev", "keywords": [ "tiptap", diff --git a/packages-deprecated/extension-focus/CHANGELOG.md b/packages-deprecated/extension-focus/CHANGELOG.md index 8a5dba31b8..4d3b06d940 100644 --- a/packages-deprecated/extension-focus/CHANGELOG.md +++ b/packages-deprecated/extension-focus/CHANGELOG.md @@ -1,5 +1,12 @@ # Change Log +## 3.23.6 + +### Patch Changes + +- Updated dependencies [937ff2e] + - @tiptap/extensions@3.23.6 + ## 3.23.5 ### Patch Changes diff --git a/packages-deprecated/extension-focus/package.json b/packages-deprecated/extension-focus/package.json index 7562097dbf..f8b2e0f190 100644 --- a/packages-deprecated/extension-focus/package.json +++ b/packages-deprecated/extension-focus/package.json @@ -1,7 +1,7 @@ { "name": "@tiptap/extension-focus", "description": "focus extension for tiptap", - "version": "3.23.5", + "version": "3.23.6", "homepage": "https://tiptap.dev", "keywords": [ "tiptap", diff --git a/packages-deprecated/extension-gapcursor/CHANGELOG.md b/packages-deprecated/extension-gapcursor/CHANGELOG.md index d7221aa11a..c88e030ac8 100644 --- a/packages-deprecated/extension-gapcursor/CHANGELOG.md +++ b/packages-deprecated/extension-gapcursor/CHANGELOG.md @@ -1,5 +1,12 @@ # Change Log +## 3.23.6 + +### Patch Changes + +- Updated dependencies [937ff2e] + - @tiptap/extensions@3.23.6 + ## 3.23.5 ### Patch Changes diff --git a/packages-deprecated/extension-gapcursor/package.json b/packages-deprecated/extension-gapcursor/package.json index e752dd9f65..bf2ae91589 100644 --- a/packages-deprecated/extension-gapcursor/package.json +++ b/packages-deprecated/extension-gapcursor/package.json @@ -1,7 +1,7 @@ { "name": "@tiptap/extension-gapcursor", "description": "gapcursor extension for tiptap", - "version": "3.23.5", + "version": "3.23.6", "homepage": "https://tiptap.dev", "keywords": [ "tiptap", diff --git a/packages-deprecated/extension-history/CHANGELOG.md b/packages-deprecated/extension-history/CHANGELOG.md index 1f733988b4..5b3cf85a18 100644 --- a/packages-deprecated/extension-history/CHANGELOG.md +++ b/packages-deprecated/extension-history/CHANGELOG.md @@ -1,5 +1,12 @@ # Change Log +## 3.23.6 + +### Patch Changes + +- Updated dependencies [937ff2e] + - @tiptap/extensions@3.23.6 + ## 3.23.5 ### Patch Changes diff --git a/packages-deprecated/extension-history/package.json b/packages-deprecated/extension-history/package.json index 984227e9e8..87fc07078e 100644 --- a/packages-deprecated/extension-history/package.json +++ b/packages-deprecated/extension-history/package.json @@ -1,7 +1,7 @@ { "name": "@tiptap/extension-history", "description": "history extension for tiptap", - "version": "3.23.5", + "version": "3.23.6", "homepage": "https://tiptap.dev", "keywords": [ "tiptap", diff --git a/packages-deprecated/extension-list-item/CHANGELOG.md b/packages-deprecated/extension-list-item/CHANGELOG.md index ff14e49876..382204f8f2 100644 --- a/packages-deprecated/extension-list-item/CHANGELOG.md +++ b/packages-deprecated/extension-list-item/CHANGELOG.md @@ -1,5 +1,11 @@ # Change Log +## 3.23.6 + +### Patch Changes + +- @tiptap/extension-list@3.23.6 + ## 3.23.5 ### Patch Changes diff --git a/packages-deprecated/extension-list-item/package.json b/packages-deprecated/extension-list-item/package.json index 2e42f51925..d6aa8c2b6c 100644 --- a/packages-deprecated/extension-list-item/package.json +++ b/packages-deprecated/extension-list-item/package.json @@ -1,7 +1,7 @@ { "name": "@tiptap/extension-list-item", "description": "list item extension for tiptap", - "version": "3.23.5", + "version": "3.23.6", "homepage": "https://tiptap.dev", "keywords": [ "tiptap", diff --git a/packages-deprecated/extension-list-keymap/CHANGELOG.md b/packages-deprecated/extension-list-keymap/CHANGELOG.md index 7155f376e2..37a495ebe0 100644 --- a/packages-deprecated/extension-list-keymap/CHANGELOG.md +++ b/packages-deprecated/extension-list-keymap/CHANGELOG.md @@ -1,5 +1,11 @@ # Change Log +## 3.23.6 + +### Patch Changes + +- @tiptap/extension-list@3.23.6 + ## 3.23.5 ### Patch Changes diff --git a/packages-deprecated/extension-list-keymap/package.json b/packages-deprecated/extension-list-keymap/package.json index bac879b3fb..b3b4f7e0c8 100644 --- a/packages-deprecated/extension-list-keymap/package.json +++ b/packages-deprecated/extension-list-keymap/package.json @@ -1,7 +1,7 @@ { "name": "@tiptap/extension-list-keymap", "description": "list keymap extension for tiptap", - "version": "3.23.5", + "version": "3.23.6", "homepage": "https://tiptap.dev", "keywords": [ "tiptap", diff --git a/packages-deprecated/extension-placeholder/CHANGELOG.md b/packages-deprecated/extension-placeholder/CHANGELOG.md index 5a11817513..9a4fa010ef 100644 --- a/packages-deprecated/extension-placeholder/CHANGELOG.md +++ b/packages-deprecated/extension-placeholder/CHANGELOG.md @@ -1,5 +1,12 @@ # Change Log +## 3.23.6 + +### Patch Changes + +- Updated dependencies [937ff2e] + - @tiptap/extensions@3.23.6 + ## 3.23.5 ### Patch Changes diff --git a/packages-deprecated/extension-placeholder/package.json b/packages-deprecated/extension-placeholder/package.json index 43b9cfb451..d390cdb12b 100644 --- a/packages-deprecated/extension-placeholder/package.json +++ b/packages-deprecated/extension-placeholder/package.json @@ -1,7 +1,7 @@ { "name": "@tiptap/extension-placeholder", "description": "placeholder extension for tiptap", - "version": "3.23.5", + "version": "3.23.6", "homepage": "https://tiptap.dev", "keywords": [ "tiptap", diff --git a/packages-deprecated/extension-table-cell/CHANGELOG.md b/packages-deprecated/extension-table-cell/CHANGELOG.md index 1de5cea974..29297c019f 100644 --- a/packages-deprecated/extension-table-cell/CHANGELOG.md +++ b/packages-deprecated/extension-table-cell/CHANGELOG.md @@ -1,5 +1,11 @@ # Change Log +## 3.23.6 + +### Patch Changes + +- @tiptap/extension-table@3.23.6 + ## 3.23.5 ### Patch Changes diff --git a/packages-deprecated/extension-table-cell/package.json b/packages-deprecated/extension-table-cell/package.json index 4ca742a0bd..83dd598ed3 100644 --- a/packages-deprecated/extension-table-cell/package.json +++ b/packages-deprecated/extension-table-cell/package.json @@ -1,7 +1,7 @@ { "name": "@tiptap/extension-table-cell", "description": "table cell extension for tiptap", - "version": "3.23.5", + "version": "3.23.6", "homepage": "https://tiptap.dev", "keywords": [ "tiptap", diff --git a/packages-deprecated/extension-table-header/CHANGELOG.md b/packages-deprecated/extension-table-header/CHANGELOG.md index 0cb07cee83..3bb80ac436 100644 --- a/packages-deprecated/extension-table-header/CHANGELOG.md +++ b/packages-deprecated/extension-table-header/CHANGELOG.md @@ -1,5 +1,11 @@ # Change Log +## 3.23.6 + +### Patch Changes + +- @tiptap/extension-table@3.23.6 + ## 3.23.5 ### Patch Changes diff --git a/packages-deprecated/extension-table-header/package.json b/packages-deprecated/extension-table-header/package.json index 36374bff4d..566688f2a4 100644 --- a/packages-deprecated/extension-table-header/package.json +++ b/packages-deprecated/extension-table-header/package.json @@ -1,7 +1,7 @@ { "name": "@tiptap/extension-table-header", "description": "table cell extension for tiptap", - "version": "3.23.5", + "version": "3.23.6", "homepage": "https://tiptap.dev", "keywords": [ "tiptap", diff --git a/packages-deprecated/extension-table-row/CHANGELOG.md b/packages-deprecated/extension-table-row/CHANGELOG.md index 9e5591aab8..02bf820cd9 100644 --- a/packages-deprecated/extension-table-row/CHANGELOG.md +++ b/packages-deprecated/extension-table-row/CHANGELOG.md @@ -1,5 +1,11 @@ # Change Log +## 3.23.6 + +### Patch Changes + +- @tiptap/extension-table@3.23.6 + ## 3.23.5 ### Patch Changes diff --git a/packages-deprecated/extension-table-row/package.json b/packages-deprecated/extension-table-row/package.json index 93bcd4bb6e..18177d58db 100644 --- a/packages-deprecated/extension-table-row/package.json +++ b/packages-deprecated/extension-table-row/package.json @@ -1,7 +1,7 @@ { "name": "@tiptap/extension-table-row", "description": "table row extension for tiptap", - "version": "3.23.5", + "version": "3.23.6", "homepage": "https://tiptap.dev", "keywords": [ "tiptap", diff --git a/packages-deprecated/extension-task-item/CHANGELOG.md b/packages-deprecated/extension-task-item/CHANGELOG.md index f26b50e8ce..6119ef4b9f 100644 --- a/packages-deprecated/extension-task-item/CHANGELOG.md +++ b/packages-deprecated/extension-task-item/CHANGELOG.md @@ -1,5 +1,11 @@ # Change Log +## 3.23.6 + +### Patch Changes + +- @tiptap/extension-list@3.23.6 + ## 3.23.5 ### Patch Changes diff --git a/packages-deprecated/extension-task-item/package.json b/packages-deprecated/extension-task-item/package.json index 64a65c7eef..608501e9b8 100644 --- a/packages-deprecated/extension-task-item/package.json +++ b/packages-deprecated/extension-task-item/package.json @@ -1,7 +1,7 @@ { "name": "@tiptap/extension-task-item", "description": "task item extension for tiptap", - "version": "3.23.5", + "version": "3.23.6", "homepage": "https://tiptap.dev", "keywords": [ "tiptap", diff --git a/packages-deprecated/extension-task-list/CHANGELOG.md b/packages-deprecated/extension-task-list/CHANGELOG.md index be2dc2a02f..d5e8ad3671 100644 --- a/packages-deprecated/extension-task-list/CHANGELOG.md +++ b/packages-deprecated/extension-task-list/CHANGELOG.md @@ -1,5 +1,11 @@ # Change Log +## 3.23.6 + +### Patch Changes + +- @tiptap/extension-list@3.23.6 + ## 3.23.5 ### Patch Changes diff --git a/packages-deprecated/extension-task-list/package.json b/packages-deprecated/extension-task-list/package.json index 1767417dfa..c0250bb218 100644 --- a/packages-deprecated/extension-task-list/package.json +++ b/packages-deprecated/extension-task-list/package.json @@ -1,7 +1,7 @@ { "name": "@tiptap/extension-task-list", "description": "task list extension for tiptap", - "version": "3.23.5", + "version": "3.23.6", "homepage": "https://tiptap.dev", "keywords": [ "tiptap", diff --git a/packages/core/CHANGELOG.md b/packages/core/CHANGELOG.md index 7bd6b9fd6e..ba289ff40b 100644 --- a/packages/core/CHANGELOG.md +++ b/packages/core/CHANGELOG.md @@ -1,5 +1,12 @@ # Change Log +## 3.23.6 + +### Patch Changes + +- d168376: Fix deleteSelection to properly handle inline nodes with `text*` content. The selection is now expanded to include the entire inline node boundaries when deleting, preventing incorrect collapse of inline text nodes. + - @tiptap/pm@3.23.6 + ## 3.23.5 ### Patch Changes diff --git a/packages/core/__tests__/delete.spec.ts b/packages/core/__tests__/delete.spec.ts index 10c8d528a3..23a7688bc9 100644 --- a/packages/core/__tests__/delete.spec.ts +++ b/packages/core/__tests__/delete.spec.ts @@ -1,6 +1,7 @@ -import { Editor } from '@tiptap/core' +import { Editor, Node } from '@tiptap/core' import Bold from '@tiptap/extension-bold' import Document from '@tiptap/extension-document' +import Paragraph from '@tiptap/extension-paragraph' import Text from '@tiptap/extension-text' import { describe, expect, it, vi } from 'vitest' @@ -8,6 +9,33 @@ const InlineDocument = Document.extend({ content: 'inline*', }) +// Test extension for the bug fix: inline node with text* content and node view +const TestInlineNode = Node.create({ + name: 'testInlineNode', + group: 'inline', + inline: true, + content: 'text*', + renderHTML() { + return ['span', { 'data-test-node': '' }, 0] + }, + parseHTML() { + return [ + { + tag: 'span[data-test-node]', + }, + ] + }, + addNodeView() { + return () => { + const dom = document.createElement('span') + dom.dataset.testNode = 'true' + const contentDOM = document.createElement('span') + dom.appendChild(contentDOM) + return { dom, contentDOM } + } + }, +}) + describe('delete extension', () => { it('should not throw when removing a mark from inline content at position 0', () => { const onDelete = vi.fn() @@ -45,4 +73,87 @@ describe('delete extension', () => { editor.destroy() }) + + it('should return false for empty selection', () => { + const editor = new Editor({ + extensions: [Document, Paragraph, Text], + content: '

hello

', + }) + + // Set cursor at position 1 (empty selection) + editor.commands.setTextSelection({ from: 1, to: 1 }) + + const result = editor.commands.deleteSelection() + expect(result).toBe(false) + + editor.destroy() + }) + + it('should delete selected text', () => { + const editor = new Editor({ + extensions: [Document, Paragraph, Text], + content: '

hello world

', + }) + + // Select "hello " + editor.chain().setTextSelection({ from: 1, to: 7 }).deleteSelection().run() + + expect(editor.getHTML()).toBe('

world

') + editor.destroy() + }) + + it('should delete selection across two paragraphs', () => { + const editor = new Editor({ + extensions: [Document, Paragraph, Text], + content: '

one

two

', + }) + + // Select from end of first paragraph to start of second + editor.chain().setTextSelection({ from: 2, to: 7 }).deleteSelection().run() + + expect(editor.getHTML()).toBe('

owo

') + editor.destroy() + }) + + it('should delete entire inline node with text* when selecting inside it', () => { + const editor = new Editor({ + extensions: [Document, Paragraph, Text, TestInlineNode], + content: '

before test after

', + }) + + // Select inside the inline node (position 9-13 selects "test") + editor.chain().setTextSelection({ from: 9, to: 13 }).deleteSelection().run() + + // The entire node should be deleted + expect(editor.getHTML()).toBe('

before after

') + editor.destroy() + }) + + it('should keep inline node when selecting only half of its text content', () => { + const editor = new Editor({ + extensions: [Document, Paragraph, Text, TestInlineNode], + content: '

before test after

', + }) + + // Select only half of the text inside the inline node (position 9-11 selects "te") + editor.chain().setTextSelection({ from: 9, to: 11 }).deleteSelection().run() + + // The node should remain with remaining text + expect(editor.getHTML()).toBe('

before st after

') + editor.destroy() + }) + + it('should delete selection spanning around entire inline node', () => { + const editor = new Editor({ + extensions: [Document, Paragraph, Text, TestInlineNode], + content: '

before test after

', + }) + + // Select from before the inline node to after it (position 4-17) + editor.chain().setTextSelection({ from: 4, to: 17 }).deleteSelection().run() + + // The entire selection including the inline node should be deleted + expect(editor.getHTML()).toBe('

befter

') + editor.destroy() + }) }) diff --git a/packages/core/package.json b/packages/core/package.json index cd9d70a724..834e07027a 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,7 +1,7 @@ { "name": "@tiptap/core", "description": "headless rich text editor", - "version": "3.23.5", + "version": "3.23.6", "homepage": "https://tiptap.dev", "keywords": [ "tiptap", diff --git a/packages/core/src/commands/deleteSelection.ts b/packages/core/src/commands/deleteSelection.ts index 0c111df95f..81bd77d2f3 100644 --- a/packages/core/src/commands/deleteSelection.ts +++ b/packages/core/src/commands/deleteSelection.ts @@ -1,7 +1,62 @@ -import { deleteSelection as originalDeleteSelection } from '@tiptap/pm/commands' +import type { ResolvedPos, Schema } from '@tiptap/pm/model' import type { RawCommands } from '../types.js' +/** + * Check if a node has text content based on its content specification. + * Returns true if the node's content spec matches text* or text+ patterns. + */ +const hasTextContent = (nodeSpec: { content?: string }): boolean => { + if (!nodeSpec.content) { + return false + } + const textRegex = /^text(\*|\+)/ + return textRegex.test(nodeSpec.content) +} + +/** + * Expand selection position for a specific side (left or right) to handle inline text nodes. + * This function checks if the position is within an inline node with text content and + * expands it to include the entire node boundaries for proper deletion. + * @param $pos - The resolved position to expand + * @param schema - The ProseMirror schema + * @param side - Which side to expand ('left' or 'right') + * @returns The expanded position for deletion + */ +const expandSelectionForSide = ($pos: ResolvedPos, schema: Schema, side: 'left' | 'right'): number => { + if (!$pos.parent.isInline) { + return $pos.pos + } + + if ((side === 'left' && $pos.pos > $pos.start()) || (side === 'right' && $pos.pos < $pos.end())) { + return $pos.pos + } + + const parentContent = schema.nodes[$pos.parent.type.name].spec + if (!hasTextContent(parentContent)) { + return $pos.pos + } + + return side === 'left' ? $pos.start() - 1 : $pos.end() + 1 +} + +/** + * Expand selection range to properly handle deletion of inline text nodes. + * Inline text nodes don't collapse correctly when text inside is deleted, + * so we need to expand the selection to include the entire node. + * See: https://code.haverbeke.berlin/prosemirror/prosemirror/issues/1365 + */ +const expandSelectionForInlineText = ( + $from: ResolvedPos, + $to: ResolvedPos, + schema: Schema, +): { from: number; to: number } => { + const from = expandSelectionForSide($from, schema, 'left') + const to = expandSelectionForSide($to, schema, 'right') + + return { from, to } +} + declare module '@tiptap/core' { interface Commands { deleteSelection: { @@ -17,5 +72,17 @@ declare module '@tiptap/core' { export const deleteSelection: RawCommands['deleteSelection'] = () => ({ state, dispatch }) => { - return originalDeleteSelection(state, dispatch) + const { $from, $to } = state.selection + if (state.selection.empty) { + return false + } + + const { from, to } = expandSelectionForInlineText($from, $to, state.schema) + + if (dispatch) { + state.tr.deleteRange(from, to).scrollIntoView() + dispatch(state.tr) + } + + return true } diff --git a/packages/extension-audio/CHANGELOG.md b/packages/extension-audio/CHANGELOG.md index 46fb19330c..5d00a98433 100644 --- a/packages/extension-audio/CHANGELOG.md +++ b/packages/extension-audio/CHANGELOG.md @@ -1,5 +1,12 @@ # @tiptap/extension-audio +## 3.23.6 + +### Patch Changes + +- Updated dependencies [d168376] + - @tiptap/core@3.23.6 + ## 3.23.5 ### Patch Changes diff --git a/packages/extension-audio/package.json b/packages/extension-audio/package.json index 47f84b9058..7e1a178b1a 100644 --- a/packages/extension-audio/package.json +++ b/packages/extension-audio/package.json @@ -1,7 +1,7 @@ { "name": "@tiptap/extension-audio", "description": "audio extension for tiptap", - "version": "3.23.5", + "version": "3.23.6", "homepage": "https://tiptap.dev", "keywords": [ "tiptap", diff --git a/packages/extension-blockquote/CHANGELOG.md b/packages/extension-blockquote/CHANGELOG.md index cddf974352..f4772d63d8 100644 --- a/packages/extension-blockquote/CHANGELOG.md +++ b/packages/extension-blockquote/CHANGELOG.md @@ -1,5 +1,12 @@ # Change Log +## 3.23.6 + +### Patch Changes + +- Updated dependencies [d168376] + - @tiptap/core@3.23.6 + ## 3.23.5 ### Patch Changes diff --git a/packages/extension-blockquote/package.json b/packages/extension-blockquote/package.json index a6e4bd9cd0..6091fc1de1 100644 --- a/packages/extension-blockquote/package.json +++ b/packages/extension-blockquote/package.json @@ -1,7 +1,7 @@ { "name": "@tiptap/extension-blockquote", "description": "blockquote extension for tiptap", - "version": "3.23.5", + "version": "3.23.6", "homepage": "https://tiptap.dev", "keywords": [ "tiptap", diff --git a/packages/extension-bold/CHANGELOG.md b/packages/extension-bold/CHANGELOG.md index 532954a1f7..fd8b30dce6 100644 --- a/packages/extension-bold/CHANGELOG.md +++ b/packages/extension-bold/CHANGELOG.md @@ -1,5 +1,12 @@ # Change Log +## 3.23.6 + +### Patch Changes + +- Updated dependencies [d168376] + - @tiptap/core@3.23.6 + ## 3.23.5 ### Patch Changes diff --git a/packages/extension-bold/package.json b/packages/extension-bold/package.json index e603071e32..58da540e08 100644 --- a/packages/extension-bold/package.json +++ b/packages/extension-bold/package.json @@ -1,7 +1,7 @@ { "name": "@tiptap/extension-bold", "description": "bold extension for tiptap", - "version": "3.23.5", + "version": "3.23.6", "homepage": "https://tiptap.dev", "keywords": [ "tiptap", diff --git a/packages/extension-bubble-menu/CHANGELOG.md b/packages/extension-bubble-menu/CHANGELOG.md index 88fa24080b..c6377f52ee 100644 --- a/packages/extension-bubble-menu/CHANGELOG.md +++ b/packages/extension-bubble-menu/CHANGELOG.md @@ -1,5 +1,13 @@ # Change Log +## 3.23.6 + +### Patch Changes + +- Updated dependencies [d168376] + - @tiptap/core@3.23.6 + - @tiptap/pm@3.23.6 + ## 3.23.5 ### Patch Changes diff --git a/packages/extension-bubble-menu/package.json b/packages/extension-bubble-menu/package.json index 238f1d496a..a269a33fe4 100644 --- a/packages/extension-bubble-menu/package.json +++ b/packages/extension-bubble-menu/package.json @@ -1,7 +1,7 @@ { "name": "@tiptap/extension-bubble-menu", "description": "bubble-menu extension for tiptap", - "version": "3.23.5", + "version": "3.23.6", "homepage": "https://tiptap.dev", "keywords": [ "tiptap", diff --git a/packages/extension-bullet-list/CHANGELOG.md b/packages/extension-bullet-list/CHANGELOG.md index 5ae6d0e232..0b9f3e16ed 100644 --- a/packages/extension-bullet-list/CHANGELOG.md +++ b/packages/extension-bullet-list/CHANGELOG.md @@ -1,5 +1,11 @@ # Change Log +## 3.23.6 + +### Patch Changes + +- @tiptap/extension-list@3.23.6 + ## 3.23.5 ### Patch Changes diff --git a/packages/extension-bullet-list/package.json b/packages/extension-bullet-list/package.json index 2dfbb0b955..71d2ced254 100644 --- a/packages/extension-bullet-list/package.json +++ b/packages/extension-bullet-list/package.json @@ -1,7 +1,7 @@ { "name": "@tiptap/extension-bullet-list", "description": "bullet list extension for tiptap", - "version": "3.23.5", + "version": "3.23.6", "homepage": "https://tiptap.dev", "keywords": [ "tiptap", diff --git a/packages/extension-code-block-lowlight/CHANGELOG.md b/packages/extension-code-block-lowlight/CHANGELOG.md index 469c232511..5d7bafea3e 100644 --- a/packages/extension-code-block-lowlight/CHANGELOG.md +++ b/packages/extension-code-block-lowlight/CHANGELOG.md @@ -1,5 +1,14 @@ # Change Log +## 3.23.6 + +### Patch Changes + +- Updated dependencies [d168376] + - @tiptap/core@3.23.6 + - @tiptap/extension-code-block@3.23.6 + - @tiptap/pm@3.23.6 + ## 3.23.5 ### Patch Changes diff --git a/packages/extension-code-block-lowlight/package.json b/packages/extension-code-block-lowlight/package.json index b04dbcdbdf..bbbf959f0e 100644 --- a/packages/extension-code-block-lowlight/package.json +++ b/packages/extension-code-block-lowlight/package.json @@ -1,7 +1,7 @@ { "name": "@tiptap/extension-code-block-lowlight", "description": "code block extension for tiptap", - "version": "3.23.5", + "version": "3.23.6", "homepage": "https://tiptap.dev", "keywords": [ "tiptap", diff --git a/packages/extension-code-block/CHANGELOG.md b/packages/extension-code-block/CHANGELOG.md index 835d94b9fe..0a72fcadab 100644 --- a/packages/extension-code-block/CHANGELOG.md +++ b/packages/extension-code-block/CHANGELOG.md @@ -1,5 +1,13 @@ # Change Log +## 3.23.6 + +### Patch Changes + +- Updated dependencies [d168376] + - @tiptap/core@3.23.6 + - @tiptap/pm@3.23.6 + ## 3.23.5 ### Patch Changes diff --git a/packages/extension-code-block/package.json b/packages/extension-code-block/package.json index 61606f149b..2ce871dd5f 100644 --- a/packages/extension-code-block/package.json +++ b/packages/extension-code-block/package.json @@ -1,7 +1,7 @@ { "name": "@tiptap/extension-code-block", "description": "code block extension for tiptap", - "version": "3.23.5", + "version": "3.23.6", "homepage": "https://tiptap.dev", "keywords": [ "tiptap", diff --git a/packages/extension-code/CHANGELOG.md b/packages/extension-code/CHANGELOG.md index d05dfb65a0..ee52d3fdc9 100644 --- a/packages/extension-code/CHANGELOG.md +++ b/packages/extension-code/CHANGELOG.md @@ -1,5 +1,12 @@ # Change Log +## 3.23.6 + +### Patch Changes + +- Updated dependencies [d168376] + - @tiptap/core@3.23.6 + ## 3.23.5 ### Patch Changes diff --git a/packages/extension-code/package.json b/packages/extension-code/package.json index afa3cd6e30..e504a06c68 100644 --- a/packages/extension-code/package.json +++ b/packages/extension-code/package.json @@ -1,7 +1,7 @@ { "name": "@tiptap/extension-code", "description": "code extension for tiptap", - "version": "3.23.5", + "version": "3.23.6", "homepage": "https://tiptap.dev", "keywords": [ "tiptap", diff --git a/packages/extension-collaboration-caret/CHANGELOG.md b/packages/extension-collaboration-caret/CHANGELOG.md index f3806865f7..0b7cb3e437 100644 --- a/packages/extension-collaboration-caret/CHANGELOG.md +++ b/packages/extension-collaboration-caret/CHANGELOG.md @@ -1,5 +1,13 @@ # Change Log +## 3.23.6 + +### Patch Changes + +- Updated dependencies [d168376] + - @tiptap/core@3.23.6 + - @tiptap/pm@3.23.6 + ## 3.23.5 ### Patch Changes diff --git a/packages/extension-collaboration-caret/package.json b/packages/extension-collaboration-caret/package.json index 417e9629f8..f9136ee5f5 100644 --- a/packages/extension-collaboration-caret/package.json +++ b/packages/extension-collaboration-caret/package.json @@ -1,7 +1,7 @@ { "name": "@tiptap/extension-collaboration-caret", "description": "collaboration caret extension for tiptap", - "version": "3.23.5", + "version": "3.23.6", "homepage": "https://tiptap.dev", "keywords": [ "tiptap", diff --git a/packages/extension-collaboration/CHANGELOG.md b/packages/extension-collaboration/CHANGELOG.md index 7b5c4a515a..c82ad6372a 100644 --- a/packages/extension-collaboration/CHANGELOG.md +++ b/packages/extension-collaboration/CHANGELOG.md @@ -1,5 +1,13 @@ # Change Log +## 3.23.6 + +### Patch Changes + +- Updated dependencies [d168376] + - @tiptap/core@3.23.6 + - @tiptap/pm@3.23.6 + ## 3.23.5 ### Patch Changes diff --git a/packages/extension-collaboration/package.json b/packages/extension-collaboration/package.json index 2e1375b26a..f28b016695 100644 --- a/packages/extension-collaboration/package.json +++ b/packages/extension-collaboration/package.json @@ -1,7 +1,7 @@ { "name": "@tiptap/extension-collaboration", "description": "collaboration extension for tiptap", - "version": "3.23.5", + "version": "3.23.6", "homepage": "https://tiptap.dev", "keywords": [ "tiptap", diff --git a/packages/extension-color/CHANGELOG.md b/packages/extension-color/CHANGELOG.md index 471107d3c0..f66ab3c440 100644 --- a/packages/extension-color/CHANGELOG.md +++ b/packages/extension-color/CHANGELOG.md @@ -1,5 +1,11 @@ # Change Log +## 3.23.6 + +### Patch Changes + +- @tiptap/extension-text-style@3.23.6 + ## 3.23.5 ### Patch Changes diff --git a/packages/extension-color/package.json b/packages/extension-color/package.json index 06da66537a..869b3406e4 100644 --- a/packages/extension-color/package.json +++ b/packages/extension-color/package.json @@ -1,7 +1,7 @@ { "name": "@tiptap/extension-color", "description": "text color extension for tiptap", - "version": "3.23.5", + "version": "3.23.6", "homepage": "https://tiptap.dev", "keywords": [ "tiptap", diff --git a/packages/extension-details/CHANGELOG.md b/packages/extension-details/CHANGELOG.md index 236e427754..c819f12e96 100644 --- a/packages/extension-details/CHANGELOG.md +++ b/packages/extension-details/CHANGELOG.md @@ -1,5 +1,14 @@ # @tiptap/extension-details +## 3.23.6 + +### Patch Changes + +- Updated dependencies [d168376] + - @tiptap/core@3.23.6 + - @tiptap/extension-text-style@3.23.6 + - @tiptap/pm@3.23.6 + ## 3.23.5 ### Patch Changes diff --git a/packages/extension-details/package.json b/packages/extension-details/package.json index 851044d0b2..7ff0affb29 100644 --- a/packages/extension-details/package.json +++ b/packages/extension-details/package.json @@ -1,7 +1,7 @@ { "name": "@tiptap/extension-details", "description": "details extension for tiptap", - "version": "3.23.5", + "version": "3.23.6", "homepage": "https://tiptap.dev/api/nodes/details", "keywords": [ "tiptap", diff --git a/packages/extension-document/CHANGELOG.md b/packages/extension-document/CHANGELOG.md index e73b07c1d7..1c7e8fe75a 100644 --- a/packages/extension-document/CHANGELOG.md +++ b/packages/extension-document/CHANGELOG.md @@ -1,5 +1,12 @@ # Change Log +## 3.23.6 + +### Patch Changes + +- Updated dependencies [d168376] + - @tiptap/core@3.23.6 + ## 3.23.5 ### Patch Changes diff --git a/packages/extension-document/package.json b/packages/extension-document/package.json index 83425afccc..202f8c78c3 100644 --- a/packages/extension-document/package.json +++ b/packages/extension-document/package.json @@ -1,7 +1,7 @@ { "name": "@tiptap/extension-document", "description": "document extension for tiptap", - "version": "3.23.5", + "version": "3.23.6", "homepage": "https://tiptap.dev", "keywords": [ "tiptap", diff --git a/packages/extension-drag-handle-react/CHANGELOG.md b/packages/extension-drag-handle-react/CHANGELOG.md index d26a7f1d82..7c2f5049f2 100644 --- a/packages/extension-drag-handle-react/CHANGELOG.md +++ b/packages/extension-drag-handle-react/CHANGELOG.md @@ -1,5 +1,14 @@ # @tiptap/extension-drag-handle-react +## 3.23.6 + +### Patch Changes + +- Updated dependencies [937ff2e] + - @tiptap/extension-drag-handle@3.23.6 + - @tiptap/react@3.23.6 + - @tiptap/pm@3.23.6 + ## 3.23.5 ### Patch Changes diff --git a/packages/extension-drag-handle-react/package.json b/packages/extension-drag-handle-react/package.json index 314e25b495..95a16605ef 100644 --- a/packages/extension-drag-handle-react/package.json +++ b/packages/extension-drag-handle-react/package.json @@ -1,7 +1,7 @@ { "name": "@tiptap/extension-drag-handle-react", "description": "drag handle extension for tiptap with react", - "version": "3.23.5", + "version": "3.23.6", "homepage": "https://tiptap.dev", "keywords": [ "tiptap", diff --git a/packages/extension-drag-handle-vue-2/CHANGELOG.md b/packages/extension-drag-handle-vue-2/CHANGELOG.md index 3b067a5952..7e161bc802 100644 --- a/packages/extension-drag-handle-vue-2/CHANGELOG.md +++ b/packages/extension-drag-handle-vue-2/CHANGELOG.md @@ -1,5 +1,14 @@ # @tiptap/extension-drag-handle-vue-2 +## 3.23.6 + +### Patch Changes + +- Updated dependencies [937ff2e] + - @tiptap/extension-drag-handle@3.23.6 + - @tiptap/vue-2@3.23.6 + - @tiptap/pm@3.23.6 + ## 3.23.5 ### Patch Changes diff --git a/packages/extension-drag-handle-vue-2/package.json b/packages/extension-drag-handle-vue-2/package.json index ab87133edc..904b8012c5 100644 --- a/packages/extension-drag-handle-vue-2/package.json +++ b/packages/extension-drag-handle-vue-2/package.json @@ -1,7 +1,7 @@ { "name": "@tiptap/extension-drag-handle-vue-2", "description": "drag handle extension for tiptap with vue 2", - "version": "3.23.5", + "version": "3.23.6", "homepage": "https://tiptap.dev", "keywords": [ "tiptap", diff --git a/packages/extension-drag-handle-vue-3/CHANGELOG.md b/packages/extension-drag-handle-vue-3/CHANGELOG.md index 61e5cfa4f2..955ee98d06 100644 --- a/packages/extension-drag-handle-vue-3/CHANGELOG.md +++ b/packages/extension-drag-handle-vue-3/CHANGELOG.md @@ -1,5 +1,14 @@ # @tiptap/extension-drag-handle-vue-3 +## 3.23.6 + +### Patch Changes + +- Updated dependencies [937ff2e] + - @tiptap/extension-drag-handle@3.23.6 + - @tiptap/vue-3@3.23.6 + - @tiptap/pm@3.23.6 + ## 3.23.5 ### Patch Changes diff --git a/packages/extension-drag-handle-vue-3/package.json b/packages/extension-drag-handle-vue-3/package.json index 165a355147..c7124eb872 100644 --- a/packages/extension-drag-handle-vue-3/package.json +++ b/packages/extension-drag-handle-vue-3/package.json @@ -1,7 +1,7 @@ { "name": "@tiptap/extension-drag-handle-vue-3", "description": "drag handle extension for tiptap with vue 3", - "version": "3.23.5", + "version": "3.23.6", "homepage": "https://tiptap.dev", "keywords": [ "tiptap", diff --git a/packages/extension-drag-handle/CHANGELOG.md b/packages/extension-drag-handle/CHANGELOG.md index 8d30c2fb2d..43831fc548 100644 --- a/packages/extension-drag-handle/CHANGELOG.md +++ b/packages/extension-drag-handle/CHANGELOG.md @@ -1,5 +1,16 @@ # @tiptap/extension-drag-handle +## 3.23.6 + +### Patch Changes + +- 937ff2e: **DragHandle**: Added `dragImageProperties` option to limit which CSS properties are cloned for the drag image. By default all ~300+ computed styles are copied; setting this to a subset (e.g. `['color', 'background-color', 'font-size']`) reduces the cost when dragging selections with complex nodes. +- Updated dependencies [d168376] + - @tiptap/core@3.23.6 + - @tiptap/extension-collaboration@3.23.6 + - @tiptap/extension-node-range@3.23.6 + - @tiptap/pm@3.23.6 + ## 3.23.5 ### Patch Changes diff --git a/packages/extension-drag-handle/__tests__/cloneElement.spec.ts b/packages/extension-drag-handle/__tests__/cloneElement.spec.ts index 53f0b7619d..6431cd50d7 100644 --- a/packages/extension-drag-handle/__tests__/cloneElement.spec.ts +++ b/packages/extension-drag-handle/__tests__/cloneElement.spec.ts @@ -7,41 +7,119 @@ describe('cloneElement', () => { vi.restoreAllMocks() }) - it('copies computed styles to the clone', () => { - const element = document.createElement('p') - const child = document.createElement('span') - - element.appendChild(child) - - vi.spyOn(window, 'getComputedStyle').mockImplementation((node: Element) => { - const styles = node === element ? ['margin-top', 'color'] : ['font-weight'] - - return { - length: styles.length, - 0: styles[0], - 1: styles[1], - getPropertyValue: (property: string) => { - if (property === 'margin-top') { - return '24px' - } - - if (property === 'color') { - return 'rgb(1, 2, 3)' - } - - if (property === 'font-weight') { - return '700' - } - - return '' - }, - } as unknown as CSSStyleDeclaration + describe('without properties filter', () => { + it('copies computed styles to the clone', () => { + const element = document.createElement('p') + const child = document.createElement('span') + + element.appendChild(child) + + vi.spyOn(window, 'getComputedStyle').mockImplementation((node: Element) => { + const styles = node === element ? ['margin-top', 'color'] : ['font-weight'] + + return { + length: styles.length, + 0: styles[0], + 1: styles[1], + getPropertyValue: (property: string) => { + if (property === 'margin-top') { + return '24px' + } + + if (property === 'color') { + return 'rgb(1, 2, 3)' + } + + if (property === 'font-weight') { + return '700' + } + + return '' + }, + } as unknown as CSSStyleDeclaration + }) + + const clone = cloneElement(element) + + expect(clone.style.cssText).toContain('margin-top: 24px;') + expect(clone.style.cssText).toContain('color: rgb(1, 2, 3);') + expect((clone.firstElementChild as HTMLElement).style.cssText).toContain('font-weight: 700;') }) + }) + + describe('with properties filter', () => { + it('copies only the listed properties to the clone', () => { + const element = document.createElement('p') + const child = document.createElement('span') + + element.appendChild(child) + + vi.spyOn(window, 'getComputedStyle').mockImplementation(() => { + return { + length: 6, + 0: 'margin-top', + 1: 'color', + 2: 'font-weight', + 3: 'background-color', + 4: 'opacity', + 5: 'font-size', + getPropertyValue: (property: string) => { + if (property === 'margin-top') { + return '24px' + } + + if (property === 'color') { + return 'rgb(1, 2, 3)' + } - const clone = cloneElement(element) + if (property === 'font-weight') { + return '700' + } - expect(clone.style.cssText).toContain('margin-top: 24px;') - expect(clone.style.cssText).toContain('color: rgb(1, 2, 3);') - expect((clone.firstElementChild as HTMLElement).style.cssText).toContain('font-weight: 700;') + if (property === 'background-color') { + return 'rgb(255, 0, 0)' + } + + if (property === 'opacity') { + return '0.5' + } + + if (property === 'font-size') { + return '16px' + } + + return '' + }, + } as unknown as CSSStyleDeclaration + }) + + const clone = cloneElement(element, ['margin-top', 'color']) + + // Listed properties should be present + expect(clone.style.cssText).toContain('margin-top: 24px;') + expect(clone.style.cssText).toContain('color: rgb(1, 2, 3);') + + // Non-listed properties should not be present + expect(clone.style.cssText).not.toContain('font-weight') + expect(clone.style.cssText).not.toContain('background-color') + expect(clone.style.cssText).not.toContain('opacity') + expect(clone.style.cssText).not.toContain('font-size') + }) + + it('returns an empty cssText when the properties list is empty', () => { + const element = document.createElement('p') + + vi.spyOn(window, 'getComputedStyle').mockImplementation(() => { + return { + length: 1, + 0: 'color', + getPropertyValue: () => 'red', + } as unknown as CSSStyleDeclaration + }) + + const clone = cloneElement(element, []) + + expect(clone.style.cssText).toBe('') + }) }) }) diff --git a/packages/extension-drag-handle/package.json b/packages/extension-drag-handle/package.json index b00935a10b..3ed3fcdda6 100644 --- a/packages/extension-drag-handle/package.json +++ b/packages/extension-drag-handle/package.json @@ -1,7 +1,7 @@ { "name": "@tiptap/extension-drag-handle", "description": "drag handle extension for tiptap", - "version": "3.23.5", + "version": "3.23.6", "homepage": "https://tiptap.dev/docs/editor/extensions/functionality/drag-handle", "keywords": [ "tiptap", diff --git a/packages/extension-drag-handle/src/drag-handle-plugin.ts b/packages/extension-drag-handle/src/drag-handle-plugin.ts index 24f491aa3f..889a19bb7e 100644 --- a/packages/extension-drag-handle/src/drag-handle-plugin.ts +++ b/packages/extension-drag-handle/src/drag-handle-plugin.ts @@ -66,6 +66,7 @@ export interface DragHandlePluginProps { computePositionConfig?: ComputePositionConfig getReferencedVirtualElement?: () => VirtualElement | null nestedOptions: NormalizedNestedOptions + dragImageProperties?: string[] } export const dragHandlePluginDefaultKey = new PluginKey('dragHandle') @@ -80,6 +81,7 @@ export const DragHandlePlugin = ({ onElementDragStart, onElementDragEnd, nestedOptions, + dragImageProperties, }: DragHandlePluginProps) => { const wrapper = document.createElement('div') let locked = false @@ -132,7 +134,7 @@ export const DragHandlePlugin = ({ // Push this to the end of the event cue // Fixes bug where incorrect drag pos is returned if drag handle has position: absolute // Pass the current node context to avoid recalculation issues during drag start - dragHandler(e, editor, nestedOptions, { node: currentNode, pos: currentNodePos }) + dragHandler(e, editor, nestedOptions, { node: currentNode, pos: currentNodePos }, dragImageProperties) if (element) { element.dataset.dragging = 'true' diff --git a/packages/extension-drag-handle/src/drag-handle.ts b/packages/extension-drag-handle/src/drag-handle.ts index 12d2fe8bdd..6709a8b089 100644 --- a/packages/extension-drag-handle/src/drag-handle.ts +++ b/packages/extension-drag-handle/src/drag-handle.ts @@ -97,6 +97,21 @@ export interface DragHandleOptions { * }) */ nested?: boolean | NestedOptions + /** + * Limit the drag image clone to a subset of CSS properties instead of + * copying all computed styles. When set, only the listed properties + * are read from `getComputedStyle` and applied to the drag image clone. + * + * Useful for improving drag performance on selections containing complex + * or deeply nested nodes. + * + * @example + * // Only copy visual appearance, skip layout properties + * DragHandle.configure({ + * dragImageProperties: ['color', 'background-color', 'font-size', 'font-family'], + * }) + */ + dragImageProperties?: string[] } declare module '@tiptap/core' { @@ -138,6 +153,7 @@ export const DragHandle = Extension.create({ onElementDragStart: undefined, onElementDragEnd: undefined, nested: false, + dragImageProperties: undefined, } }, @@ -178,6 +194,7 @@ export const DragHandle = Extension.create({ onElementDragStart: this.options.onElementDragStart, onElementDragEnd: this.options.onElementDragEnd, nestedOptions, + dragImageProperties: this.options.dragImageProperties, }).plugin, ] }, diff --git a/packages/extension-drag-handle/src/helpers/cloneElement.ts b/packages/extension-drag-handle/src/helpers/cloneElement.ts index d01a61a768..0892649e82 100644 --- a/packages/extension-drag-handle/src/helpers/cloneElement.ts +++ b/packages/extension-drag-handle/src/helpers/cloneElement.ts @@ -1,7 +1,15 @@ -function getCSSText(element: Element) { - let value = '' +function getCSSText(element: Element, properties?: string[]) { const style = getComputedStyle(element) + if (properties) { + return properties + .filter(p => p.trim().length > 0) + .map(p => `${p}:${style.getPropertyValue(p)};`) + .join('') + } + + let value = '' + for (let i = 0; i < style.length; i += 1) { value += `${style[i]}:${style.getPropertyValue(style[i])};` } @@ -9,13 +17,13 @@ function getCSSText(element: Element) { return value } -export function cloneElement(node: HTMLElement) { +export function cloneElement(node: HTMLElement, properties?: string[]) { const clonedNode = node.cloneNode(true) as HTMLElement const sourceElements = [node, ...Array.from(node.getElementsByTagName('*'))] as HTMLElement[] const targetElements = [clonedNode, ...Array.from(clonedNode.getElementsByTagName('*'))] as HTMLElement[] sourceElements.forEach((sourceElement, index) => { - targetElements[index].style.cssText = getCSSText(sourceElement) + targetElements[index].style.cssText = getCSSText(sourceElement, properties) }) return clonedNode diff --git a/packages/extension-drag-handle/src/helpers/dragHandler.ts b/packages/extension-drag-handle/src/helpers/dragHandler.ts index d2ca3f88eb..81d70ec40f 100644 --- a/packages/extension-drag-handle/src/helpers/dragHandler.ts +++ b/packages/extension-drag-handle/src/helpers/dragHandler.ts @@ -68,6 +68,7 @@ export function dragHandler( editor: Editor, nestedOptions?: NormalizedNestedOptions, dragContext?: DragContext, + dragImageProperties?: string[], ) { const { view } = editor @@ -126,7 +127,7 @@ export function dragHandler( return } - const clonedElement = cloneElement(element) + const clonedElement = cloneElement(element, dragImageProperties) clonedElement.style.margin = '0' diff --git a/packages/extension-emoji/CHANGELOG.md b/packages/extension-emoji/CHANGELOG.md index dc5d48b8e2..a802d9cc47 100644 --- a/packages/extension-emoji/CHANGELOG.md +++ b/packages/extension-emoji/CHANGELOG.md @@ -1,5 +1,14 @@ # @tiptap/extension-emoji +## 3.23.6 + +### Patch Changes + +- Updated dependencies [d168376] + - @tiptap/core@3.23.6 + - @tiptap/suggestion@3.23.6 + - @tiptap/pm@3.23.6 + ## 3.23.5 ### Patch Changes diff --git a/packages/extension-emoji/package.json b/packages/extension-emoji/package.json index 002eb5fafa..208d5595f8 100644 --- a/packages/extension-emoji/package.json +++ b/packages/extension-emoji/package.json @@ -1,7 +1,7 @@ { "name": "@tiptap/extension-emoji", "description": "emoji extension for tiptap", - "version": "3.23.5", + "version": "3.23.6", "homepage": "https://tiptap.dev/api/nodes/emoji", "keywords": [ "tiptap", diff --git a/packages/extension-file-handler/CHANGELOG.md b/packages/extension-file-handler/CHANGELOG.md index 1eca9da46b..f14035837e 100644 --- a/packages/extension-file-handler/CHANGELOG.md +++ b/packages/extension-file-handler/CHANGELOG.md @@ -1,5 +1,14 @@ # @tiptap/extension-file-handler +## 3.23.6 + +### Patch Changes + +- Updated dependencies [d168376] + - @tiptap/core@3.23.6 + - @tiptap/extension-text-style@3.23.6 + - @tiptap/pm@3.23.6 + ## 3.23.5 ### Patch Changes diff --git a/packages/extension-file-handler/package.json b/packages/extension-file-handler/package.json index 3754e14fb4..d4d66a7b7f 100644 --- a/packages/extension-file-handler/package.json +++ b/packages/extension-file-handler/package.json @@ -1,7 +1,7 @@ { "name": "@tiptap/extension-file-handler", "description": "file handler extension for tiptap", - "version": "3.23.5", + "version": "3.23.6", "homepage": "https://tiptap.dev/docs/editor/extensions/functionality/filehandler", "keywords": [ "tiptap", diff --git a/packages/extension-floating-menu/CHANGELOG.md b/packages/extension-floating-menu/CHANGELOG.md index aae81e3b83..e5752255cd 100644 --- a/packages/extension-floating-menu/CHANGELOG.md +++ b/packages/extension-floating-menu/CHANGELOG.md @@ -1,5 +1,13 @@ # Change Log +## 3.23.6 + +### Patch Changes + +- Updated dependencies [d168376] + - @tiptap/core@3.23.6 + - @tiptap/pm@3.23.6 + ## 3.23.5 ### Patch Changes diff --git a/packages/extension-floating-menu/package.json b/packages/extension-floating-menu/package.json index 213ec83139..22807de099 100644 --- a/packages/extension-floating-menu/package.json +++ b/packages/extension-floating-menu/package.json @@ -1,7 +1,7 @@ { "name": "@tiptap/extension-floating-menu", "description": "floating-menu extension for tiptap", - "version": "3.23.5", + "version": "3.23.6", "homepage": "https://tiptap.dev", "keywords": [ "tiptap", diff --git a/packages/extension-font-family/CHANGELOG.md b/packages/extension-font-family/CHANGELOG.md index 6dd13ba72e..e54a094934 100644 --- a/packages/extension-font-family/CHANGELOG.md +++ b/packages/extension-font-family/CHANGELOG.md @@ -1,5 +1,11 @@ # Change Log +## 3.23.6 + +### Patch Changes + +- @tiptap/extension-text-style@3.23.6 + ## 3.23.5 ### Patch Changes diff --git a/packages/extension-font-family/package.json b/packages/extension-font-family/package.json index 2cc3e02560..f2460296e9 100644 --- a/packages/extension-font-family/package.json +++ b/packages/extension-font-family/package.json @@ -1,7 +1,7 @@ { "name": "@tiptap/extension-font-family", "description": "font family extension for tiptap", - "version": "3.23.5", + "version": "3.23.6", "homepage": "https://tiptap.dev", "keywords": [ "tiptap", diff --git a/packages/extension-hard-break/CHANGELOG.md b/packages/extension-hard-break/CHANGELOG.md index e436961bb0..abd9f78e41 100644 --- a/packages/extension-hard-break/CHANGELOG.md +++ b/packages/extension-hard-break/CHANGELOG.md @@ -1,5 +1,12 @@ # Change Log +## 3.23.6 + +### Patch Changes + +- Updated dependencies [d168376] + - @tiptap/core@3.23.6 + ## 3.23.5 ### Patch Changes diff --git a/packages/extension-hard-break/package.json b/packages/extension-hard-break/package.json index 18799451b0..9646a6a9d2 100644 --- a/packages/extension-hard-break/package.json +++ b/packages/extension-hard-break/package.json @@ -1,7 +1,7 @@ { "name": "@tiptap/extension-hard-break", "description": "hard break extension for tiptap", - "version": "3.23.5", + "version": "3.23.6", "homepage": "https://tiptap.dev", "keywords": [ "tiptap", diff --git a/packages/extension-heading/CHANGELOG.md b/packages/extension-heading/CHANGELOG.md index 6c1457349b..08ea370abe 100644 --- a/packages/extension-heading/CHANGELOG.md +++ b/packages/extension-heading/CHANGELOG.md @@ -1,5 +1,12 @@ # Change Log +## 3.23.6 + +### Patch Changes + +- Updated dependencies [d168376] + - @tiptap/core@3.23.6 + ## 3.23.5 ### Patch Changes diff --git a/packages/extension-heading/package.json b/packages/extension-heading/package.json index 2d796d4ec1..3e0c00910c 100644 --- a/packages/extension-heading/package.json +++ b/packages/extension-heading/package.json @@ -1,7 +1,7 @@ { "name": "@tiptap/extension-heading", "description": "heading extension for tiptap", - "version": "3.23.5", + "version": "3.23.6", "homepage": "https://tiptap.dev", "keywords": [ "tiptap", diff --git a/packages/extension-highlight/CHANGELOG.md b/packages/extension-highlight/CHANGELOG.md index ab3ff2694c..86fcdb9320 100644 --- a/packages/extension-highlight/CHANGELOG.md +++ b/packages/extension-highlight/CHANGELOG.md @@ -1,5 +1,12 @@ # Change Log +## 3.23.6 + +### Patch Changes + +- Updated dependencies [d168376] + - @tiptap/core@3.23.6 + ## 3.23.5 ### Patch Changes diff --git a/packages/extension-highlight/package.json b/packages/extension-highlight/package.json index c0a137872e..f017c2c56e 100644 --- a/packages/extension-highlight/package.json +++ b/packages/extension-highlight/package.json @@ -1,7 +1,7 @@ { "name": "@tiptap/extension-highlight", "description": "highlight extension for tiptap", - "version": "3.23.5", + "version": "3.23.6", "homepage": "https://tiptap.dev", "keywords": [ "tiptap", diff --git a/packages/extension-horizontal-rule/CHANGELOG.md b/packages/extension-horizontal-rule/CHANGELOG.md index a334e5bbde..13dc35c1a8 100644 --- a/packages/extension-horizontal-rule/CHANGELOG.md +++ b/packages/extension-horizontal-rule/CHANGELOG.md @@ -1,5 +1,13 @@ # Change Log +## 3.23.6 + +### Patch Changes + +- Updated dependencies [d168376] + - @tiptap/core@3.23.6 + - @tiptap/pm@3.23.6 + ## 3.23.5 ### Patch Changes diff --git a/packages/extension-horizontal-rule/package.json b/packages/extension-horizontal-rule/package.json index 99e83c07b7..a8da9b0891 100644 --- a/packages/extension-horizontal-rule/package.json +++ b/packages/extension-horizontal-rule/package.json @@ -1,7 +1,7 @@ { "name": "@tiptap/extension-horizontal-rule", "description": "horizontal rule extension for tiptap", - "version": "3.23.5", + "version": "3.23.6", "homepage": "https://tiptap.dev", "keywords": [ "tiptap", diff --git a/packages/extension-image/CHANGELOG.md b/packages/extension-image/CHANGELOG.md index b883ce6d0c..047f27720e 100644 --- a/packages/extension-image/CHANGELOG.md +++ b/packages/extension-image/CHANGELOG.md @@ -1,5 +1,12 @@ # Change Log +## 3.23.6 + +### Patch Changes + +- Updated dependencies [d168376] + - @tiptap/core@3.23.6 + ## 3.23.5 ### Patch Changes diff --git a/packages/extension-image/package.json b/packages/extension-image/package.json index 9a7d0051d6..5b9877ed53 100644 --- a/packages/extension-image/package.json +++ b/packages/extension-image/package.json @@ -1,7 +1,7 @@ { "name": "@tiptap/extension-image", "description": "image extension for tiptap", - "version": "3.23.5", + "version": "3.23.6", "homepage": "https://tiptap.dev", "keywords": [ "tiptap", diff --git a/packages/extension-invisible-characters/CHANGELOG.md b/packages/extension-invisible-characters/CHANGELOG.md index 7be73aa8ab..a85cab794e 100644 --- a/packages/extension-invisible-characters/CHANGELOG.md +++ b/packages/extension-invisible-characters/CHANGELOG.md @@ -1,5 +1,14 @@ # @tiptap/extension-invisible-characters +## 3.23.6 + +### Patch Changes + +- Updated dependencies [d168376] + - @tiptap/core@3.23.6 + - @tiptap/extension-text-style@3.23.6 + - @tiptap/pm@3.23.6 + ## 3.23.5 ### Patch Changes diff --git a/packages/extension-invisible-characters/package.json b/packages/extension-invisible-characters/package.json index ae245a6049..3829af8bf0 100644 --- a/packages/extension-invisible-characters/package.json +++ b/packages/extension-invisible-characters/package.json @@ -1,7 +1,7 @@ { "name": "@tiptap/extension-invisible-characters", "description": "invisible characters extension for tiptap", - "version": "3.23.5", + "version": "3.23.6", "homepage": "https://tiptap.dev/docs/editor/extensions/functionality/invisiblecharacters", "keywords": [ "tiptap", diff --git a/packages/extension-italic/CHANGELOG.md b/packages/extension-italic/CHANGELOG.md index e406112665..05384e0c55 100644 --- a/packages/extension-italic/CHANGELOG.md +++ b/packages/extension-italic/CHANGELOG.md @@ -1,5 +1,12 @@ # Change Log +## 3.23.6 + +### Patch Changes + +- Updated dependencies [d168376] + - @tiptap/core@3.23.6 + ## 3.23.5 ### Patch Changes diff --git a/packages/extension-italic/package.json b/packages/extension-italic/package.json index c5f52be53f..43d19bf199 100644 --- a/packages/extension-italic/package.json +++ b/packages/extension-italic/package.json @@ -1,7 +1,7 @@ { "name": "@tiptap/extension-italic", "description": "italic extension for tiptap", - "version": "3.23.5", + "version": "3.23.6", "homepage": "https://tiptap.dev", "keywords": [ "tiptap", diff --git a/packages/extension-link/CHANGELOG.md b/packages/extension-link/CHANGELOG.md index 702467b28d..2f7cd9c4b9 100644 --- a/packages/extension-link/CHANGELOG.md +++ b/packages/extension-link/CHANGELOG.md @@ -1,5 +1,13 @@ # Change Log +## 3.23.6 + +### Patch Changes + +- Updated dependencies [d168376] + - @tiptap/core@3.23.6 + - @tiptap/pm@3.23.6 + ## 3.23.5 ### Patch Changes diff --git a/packages/extension-link/package.json b/packages/extension-link/package.json index a3ed9fd887..8dc0d09ba7 100644 --- a/packages/extension-link/package.json +++ b/packages/extension-link/package.json @@ -1,7 +1,7 @@ { "name": "@tiptap/extension-link", "description": "link extension for tiptap", - "version": "3.23.5", + "version": "3.23.6", "homepage": "https://tiptap.dev", "keywords": [ "tiptap", diff --git a/packages/extension-list/CHANGELOG.md b/packages/extension-list/CHANGELOG.md index e002ccecc5..cd15ed29e8 100644 --- a/packages/extension-list/CHANGELOG.md +++ b/packages/extension-list/CHANGELOG.md @@ -1,5 +1,13 @@ # Change Log +## 3.23.6 + +### Patch Changes + +- Updated dependencies [d168376] + - @tiptap/core@3.23.6 + - @tiptap/pm@3.23.6 + ## 3.23.5 ### Patch Changes diff --git a/packages/extension-list/package.json b/packages/extension-list/package.json index ca5af5c62b..462ce34c85 100644 --- a/packages/extension-list/package.json +++ b/packages/extension-list/package.json @@ -1,7 +1,7 @@ { "name": "@tiptap/extension-list", "description": "List extension for tiptap", - "version": "3.23.5", + "version": "3.23.6", "homepage": "https://tiptap.dev", "keywords": [ "tiptap", diff --git a/packages/extension-mathematics/CHANGELOG.md b/packages/extension-mathematics/CHANGELOG.md index 5f51a776e5..fdc7a0c3b9 100644 --- a/packages/extension-mathematics/CHANGELOG.md +++ b/packages/extension-mathematics/CHANGELOG.md @@ -1,5 +1,13 @@ # @tiptap/extension-mathematics +## 3.23.6 + +### Patch Changes + +- Updated dependencies [d168376] + - @tiptap/core@3.23.6 + - @tiptap/pm@3.23.6 + ## 3.23.5 ### Patch Changes diff --git a/packages/extension-mathematics/package.json b/packages/extension-mathematics/package.json index 07fe5dc51a..a2bbac00f0 100644 --- a/packages/extension-mathematics/package.json +++ b/packages/extension-mathematics/package.json @@ -1,7 +1,7 @@ { "name": "@tiptap/extension-mathematics", "description": "latex math extension for tiptap", - "version": "3.23.5", + "version": "3.23.6", "homepage": "https://tiptap.dev/api/extensions/mathematics", "keywords": [ "tiptap", diff --git a/packages/extension-mention/CHANGELOG.md b/packages/extension-mention/CHANGELOG.md index e1f1369696..ffd5d66712 100644 --- a/packages/extension-mention/CHANGELOG.md +++ b/packages/extension-mention/CHANGELOG.md @@ -1,5 +1,14 @@ # Change Log +## 3.23.6 + +### Patch Changes + +- Updated dependencies [d168376] + - @tiptap/core@3.23.6 + - @tiptap/suggestion@3.23.6 + - @tiptap/pm@3.23.6 + ## 3.23.5 ### Patch Changes diff --git a/packages/extension-mention/package.json b/packages/extension-mention/package.json index 9267ab9791..58e0e7c4f7 100644 --- a/packages/extension-mention/package.json +++ b/packages/extension-mention/package.json @@ -1,7 +1,7 @@ { "name": "@tiptap/extension-mention", "description": "mention extension for tiptap", - "version": "3.23.5", + "version": "3.23.6", "homepage": "https://tiptap.dev", "keywords": [ "tiptap", diff --git a/packages/extension-node-range/CHANGELOG.md b/packages/extension-node-range/CHANGELOG.md index 9c673c2948..6a3a2d93fb 100644 --- a/packages/extension-node-range/CHANGELOG.md +++ b/packages/extension-node-range/CHANGELOG.md @@ -1,5 +1,13 @@ # @tiptap/extension-node-range +## 3.23.6 + +### Patch Changes + +- Updated dependencies [d168376] + - @tiptap/core@3.23.6 + - @tiptap/pm@3.23.6 + ## 3.23.5 ### Patch Changes diff --git a/packages/extension-node-range/package.json b/packages/extension-node-range/package.json index f0adda3ca0..fdba848d79 100644 --- a/packages/extension-node-range/package.json +++ b/packages/extension-node-range/package.json @@ -1,7 +1,7 @@ { "name": "@tiptap/extension-node-range", "description": "node range extension for tiptap", - "version": "3.23.5", + "version": "3.23.6", "homepage": "https://tiptap.dev", "keywords": [ "tiptap", diff --git a/packages/extension-ordered-list/CHANGELOG.md b/packages/extension-ordered-list/CHANGELOG.md index c7f17738d5..4777b2a98b 100644 --- a/packages/extension-ordered-list/CHANGELOG.md +++ b/packages/extension-ordered-list/CHANGELOG.md @@ -1,5 +1,11 @@ # Change Log +## 3.23.6 + +### Patch Changes + +- @tiptap/extension-list@3.23.6 + ## 3.23.5 ### Patch Changes diff --git a/packages/extension-ordered-list/package.json b/packages/extension-ordered-list/package.json index 9980a6ea1d..8284c3f051 100644 --- a/packages/extension-ordered-list/package.json +++ b/packages/extension-ordered-list/package.json @@ -1,7 +1,7 @@ { "name": "@tiptap/extension-ordered-list", "description": "ordered list extension for tiptap", - "version": "3.23.5", + "version": "3.23.6", "homepage": "https://tiptap.dev", "keywords": [ "tiptap", diff --git a/packages/extension-paragraph/CHANGELOG.md b/packages/extension-paragraph/CHANGELOG.md index 1e4b3f6098..038d86855e 100644 --- a/packages/extension-paragraph/CHANGELOG.md +++ b/packages/extension-paragraph/CHANGELOG.md @@ -1,5 +1,12 @@ # Change Log +## 3.23.6 + +### Patch Changes + +- Updated dependencies [d168376] + - @tiptap/core@3.23.6 + ## 3.23.5 ### Patch Changes diff --git a/packages/extension-paragraph/package.json b/packages/extension-paragraph/package.json index 897306c82f..6ba2493cc4 100644 --- a/packages/extension-paragraph/package.json +++ b/packages/extension-paragraph/package.json @@ -1,7 +1,7 @@ { "name": "@tiptap/extension-paragraph", "description": "paragraph extension for tiptap", - "version": "3.23.5", + "version": "3.23.6", "homepage": "https://tiptap.dev", "keywords": [ "tiptap", diff --git a/packages/extension-strike/CHANGELOG.md b/packages/extension-strike/CHANGELOG.md index a908481ae6..0bcf488f74 100644 --- a/packages/extension-strike/CHANGELOG.md +++ b/packages/extension-strike/CHANGELOG.md @@ -1,5 +1,12 @@ # Change Log +## 3.23.6 + +### Patch Changes + +- Updated dependencies [d168376] + - @tiptap/core@3.23.6 + ## 3.23.5 ### Patch Changes diff --git a/packages/extension-strike/package.json b/packages/extension-strike/package.json index cc002e549b..ff3e89c318 100644 --- a/packages/extension-strike/package.json +++ b/packages/extension-strike/package.json @@ -1,7 +1,7 @@ { "name": "@tiptap/extension-strike", "description": "strike extension for tiptap", - "version": "3.23.5", + "version": "3.23.6", "homepage": "https://tiptap.dev", "keywords": [ "tiptap", diff --git a/packages/extension-subscript/CHANGELOG.md b/packages/extension-subscript/CHANGELOG.md index 319e5bc386..1028f43de5 100644 --- a/packages/extension-subscript/CHANGELOG.md +++ b/packages/extension-subscript/CHANGELOG.md @@ -1,5 +1,13 @@ # Change Log +## 3.23.6 + +### Patch Changes + +- Updated dependencies [d168376] + - @tiptap/core@3.23.6 + - @tiptap/pm@3.23.6 + ## 3.23.5 ### Patch Changes diff --git a/packages/extension-subscript/package.json b/packages/extension-subscript/package.json index a26607859d..9c6da9a78e 100644 --- a/packages/extension-subscript/package.json +++ b/packages/extension-subscript/package.json @@ -1,7 +1,7 @@ { "name": "@tiptap/extension-subscript", "description": "subscript extension for tiptap", - "version": "3.23.5", + "version": "3.23.6", "homepage": "https://tiptap.dev", "keywords": [ "tiptap", diff --git a/packages/extension-superscript/CHANGELOG.md b/packages/extension-superscript/CHANGELOG.md index 562daab7c5..7d9ff2fba3 100644 --- a/packages/extension-superscript/CHANGELOG.md +++ b/packages/extension-superscript/CHANGELOG.md @@ -1,5 +1,13 @@ # Change Log +## 3.23.6 + +### Patch Changes + +- Updated dependencies [d168376] + - @tiptap/core@3.23.6 + - @tiptap/pm@3.23.6 + ## 3.23.5 ### Patch Changes diff --git a/packages/extension-superscript/package.json b/packages/extension-superscript/package.json index fa2a5293ad..e9d456aab1 100644 --- a/packages/extension-superscript/package.json +++ b/packages/extension-superscript/package.json @@ -1,7 +1,7 @@ { "name": "@tiptap/extension-superscript", "description": "superscript extension for tiptap", - "version": "3.23.5", + "version": "3.23.6", "homepage": "https://tiptap.dev", "keywords": [ "tiptap", diff --git a/packages/extension-table-of-contents/CHANGELOG.md b/packages/extension-table-of-contents/CHANGELOG.md index 8bdb05fc80..252ccf876c 100644 --- a/packages/extension-table-of-contents/CHANGELOG.md +++ b/packages/extension-table-of-contents/CHANGELOG.md @@ -1,5 +1,13 @@ # @tiptap/extension-table-of-contents +## 3.23.6 + +### Patch Changes + +- Updated dependencies [d168376] + - @tiptap/core@3.23.6 + - @tiptap/pm@3.23.6 + ## 3.23.5 ### Patch Changes diff --git a/packages/extension-table-of-contents/package.json b/packages/extension-table-of-contents/package.json index 5ba2aff79f..90587cedd4 100644 --- a/packages/extension-table-of-contents/package.json +++ b/packages/extension-table-of-contents/package.json @@ -1,7 +1,7 @@ { "name": "@tiptap/extension-table-of-contents", "description": "table of contents extension for Tiptap", - "version": "3.23.5", + "version": "3.23.6", "homepage": "https://tiptap.dev/docs/editor/extensions/functionality/table-of-contents", "keywords": [ "tiptap", diff --git a/packages/extension-table/CHANGELOG.md b/packages/extension-table/CHANGELOG.md index 1da77ffa18..f9654faed0 100644 --- a/packages/extension-table/CHANGELOG.md +++ b/packages/extension-table/CHANGELOG.md @@ -1,5 +1,13 @@ # Change Log +## 3.23.6 + +### Patch Changes + +- Updated dependencies [d168376] + - @tiptap/core@3.23.6 + - @tiptap/pm@3.23.6 + ## 3.23.5 ### Patch Changes diff --git a/packages/extension-table/package.json b/packages/extension-table/package.json index 8e0f71a548..229ec8ff46 100644 --- a/packages/extension-table/package.json +++ b/packages/extension-table/package.json @@ -1,7 +1,7 @@ { "name": "@tiptap/extension-table", "description": "table extension for tiptap", - "version": "3.23.5", + "version": "3.23.6", "homepage": "https://tiptap.dev", "keywords": [ "tiptap", diff --git a/packages/extension-text-align/CHANGELOG.md b/packages/extension-text-align/CHANGELOG.md index 59bee50666..9001fa3246 100644 --- a/packages/extension-text-align/CHANGELOG.md +++ b/packages/extension-text-align/CHANGELOG.md @@ -1,5 +1,12 @@ # Change Log +## 3.23.6 + +### Patch Changes + +- Updated dependencies [d168376] + - @tiptap/core@3.23.6 + ## 3.23.5 ### Patch Changes diff --git a/packages/extension-text-align/package.json b/packages/extension-text-align/package.json index f674d8bd40..fcfcdb5080 100644 --- a/packages/extension-text-align/package.json +++ b/packages/extension-text-align/package.json @@ -1,7 +1,7 @@ { "name": "@tiptap/extension-text-align", "description": "text align extension for tiptap", - "version": "3.23.5", + "version": "3.23.6", "homepage": "https://tiptap.dev", "keywords": [ "tiptap", diff --git a/packages/extension-text-style/CHANGELOG.md b/packages/extension-text-style/CHANGELOG.md index 50dae94ead..5cd43a3109 100644 --- a/packages/extension-text-style/CHANGELOG.md +++ b/packages/extension-text-style/CHANGELOG.md @@ -1,5 +1,12 @@ # Change Log +## 3.23.6 + +### Patch Changes + +- Updated dependencies [d168376] + - @tiptap/core@3.23.6 + ## 3.23.5 ### Patch Changes diff --git a/packages/extension-text-style/package.json b/packages/extension-text-style/package.json index bbb200ba8b..95c24c5d95 100644 --- a/packages/extension-text-style/package.json +++ b/packages/extension-text-style/package.json @@ -1,7 +1,7 @@ { "name": "@tiptap/extension-text-style", "description": "text style extension for tiptap", - "version": "3.23.5", + "version": "3.23.6", "homepage": "https://tiptap.dev", "keywords": [ "tiptap", diff --git a/packages/extension-text/CHANGELOG.md b/packages/extension-text/CHANGELOG.md index cd1f91287c..38242ff328 100644 --- a/packages/extension-text/CHANGELOG.md +++ b/packages/extension-text/CHANGELOG.md @@ -1,5 +1,12 @@ # Change Log +## 3.23.6 + +### Patch Changes + +- Updated dependencies [d168376] + - @tiptap/core@3.23.6 + ## 3.23.5 ### Patch Changes diff --git a/packages/extension-text/package.json b/packages/extension-text/package.json index 350033c6b2..04cedec24b 100644 --- a/packages/extension-text/package.json +++ b/packages/extension-text/package.json @@ -1,7 +1,7 @@ { "name": "@tiptap/extension-text", "description": "text extension for tiptap", - "version": "3.23.5", + "version": "3.23.6", "homepage": "https://tiptap.dev", "keywords": [ "tiptap", diff --git a/packages/extension-twitch/CHANGELOG.md b/packages/extension-twitch/CHANGELOG.md index 153a882f05..11e20d3784 100644 --- a/packages/extension-twitch/CHANGELOG.md +++ b/packages/extension-twitch/CHANGELOG.md @@ -1,5 +1,12 @@ # @tiptap/extension-twitch +## 3.23.6 + +### Patch Changes + +- Updated dependencies [d168376] + - @tiptap/core@3.23.6 + ## 3.23.5 ### Patch Changes diff --git a/packages/extension-twitch/package.json b/packages/extension-twitch/package.json index b53f59c030..3bdb823051 100644 --- a/packages/extension-twitch/package.json +++ b/packages/extension-twitch/package.json @@ -1,7 +1,7 @@ { "name": "@tiptap/extension-twitch", "description": "a twitch embed extension for tiptap", - "version": "3.23.5", + "version": "3.23.6", "homepage": "https://tiptap.dev", "keywords": [ "tiptap", diff --git a/packages/extension-typography/CHANGELOG.md b/packages/extension-typography/CHANGELOG.md index 8f64405158..c7a21824fc 100644 --- a/packages/extension-typography/CHANGELOG.md +++ b/packages/extension-typography/CHANGELOG.md @@ -1,5 +1,12 @@ # Change Log +## 3.23.6 + +### Patch Changes + +- Updated dependencies [d168376] + - @tiptap/core@3.23.6 + ## 3.23.5 ### Patch Changes diff --git a/packages/extension-typography/package.json b/packages/extension-typography/package.json index e2cd855e6a..51b018e770 100644 --- a/packages/extension-typography/package.json +++ b/packages/extension-typography/package.json @@ -1,7 +1,7 @@ { "name": "@tiptap/extension-typography", "description": "typography extension for tiptap", - "version": "3.23.5", + "version": "3.23.6", "homepage": "https://tiptap.dev", "keywords": [ "tiptap", diff --git a/packages/extension-underline/CHANGELOG.md b/packages/extension-underline/CHANGELOG.md index 352719ed72..6536c93a94 100644 --- a/packages/extension-underline/CHANGELOG.md +++ b/packages/extension-underline/CHANGELOG.md @@ -1,5 +1,12 @@ # Change Log +## 3.23.6 + +### Patch Changes + +- Updated dependencies [d168376] + - @tiptap/core@3.23.6 + ## 3.23.5 ### Patch Changes diff --git a/packages/extension-underline/package.json b/packages/extension-underline/package.json index be3511473d..725104bd88 100644 --- a/packages/extension-underline/package.json +++ b/packages/extension-underline/package.json @@ -1,7 +1,7 @@ { "name": "@tiptap/extension-underline", "description": "underline extension for tiptap", - "version": "3.23.5", + "version": "3.23.6", "homepage": "https://tiptap.dev", "keywords": [ "tiptap", diff --git a/packages/extension-unique-id/CHANGELOG.md b/packages/extension-unique-id/CHANGELOG.md index b0dabb584b..7b96229060 100644 --- a/packages/extension-unique-id/CHANGELOG.md +++ b/packages/extension-unique-id/CHANGELOG.md @@ -1,5 +1,13 @@ # @tiptap/extension-unique-id +## 3.23.6 + +### Patch Changes + +- Updated dependencies [d168376] + - @tiptap/core@3.23.6 + - @tiptap/pm@3.23.6 + ## 3.23.5 ### Patch Changes diff --git a/packages/extension-unique-id/package.json b/packages/extension-unique-id/package.json index 182c0992eb..e6fddd06d2 100644 --- a/packages/extension-unique-id/package.json +++ b/packages/extension-unique-id/package.json @@ -1,7 +1,7 @@ { "name": "@tiptap/extension-unique-id", "description": "unique id extension for tiptap", - "version": "3.23.5", + "version": "3.23.6", "homepage": "https://tiptap.dev/api/extensions/unique-id", "keywords": [ "tiptap", diff --git a/packages/extension-youtube/CHANGELOG.md b/packages/extension-youtube/CHANGELOG.md index 629dcff77a..75a804c1d7 100644 --- a/packages/extension-youtube/CHANGELOG.md +++ b/packages/extension-youtube/CHANGELOG.md @@ -1,5 +1,12 @@ # Change Log +## 3.23.6 + +### Patch Changes + +- Updated dependencies [d168376] + - @tiptap/core@3.23.6 + ## 3.23.5 ### Patch Changes diff --git a/packages/extension-youtube/package.json b/packages/extension-youtube/package.json index ce0a53812f..ac75a15766 100644 --- a/packages/extension-youtube/package.json +++ b/packages/extension-youtube/package.json @@ -1,7 +1,7 @@ { "name": "@tiptap/extension-youtube", "description": "a youtube embed extension for tiptap", - "version": "3.23.5", + "version": "3.23.6", "homepage": "https://tiptap.dev", "keywords": [ "tiptap", diff --git a/packages/extensions/CHANGELOG.md b/packages/extensions/CHANGELOG.md index db10b3a348..4bdd0e0a34 100644 --- a/packages/extensions/CHANGELOG.md +++ b/packages/extensions/CHANGELOG.md @@ -1,5 +1,14 @@ # Change Log +## 3.23.6 + +### Patch Changes + +- 937ff2e: **Placeholder**: Replaced full-document `doc.descendants()` traversal with a cursor-resolved fast path for the default config and viewport-limited scanning for the non-default config, significantly reducing decoration overhead on large documents. +- Updated dependencies [d168376] + - @tiptap/core@3.23.6 + - @tiptap/pm@3.23.6 + ## 3.23.5 ### Patch Changes diff --git a/packages/extensions/__tests__/placeholder.spec.ts b/packages/extensions/__tests__/placeholder.spec.ts index 8beeda3b33..2a6cac0e3f 100644 --- a/packages/extensions/__tests__/placeholder.spec.ts +++ b/packages/extensions/__tests__/placeholder.spec.ts @@ -7,7 +7,10 @@ import TaskItem from '@tiptap/extension-task-item' import TaskList from '@tiptap/extension-task-list' import Text from '@tiptap/extension-text' import { type PlaceholderOptions, Placeholder, preparePlaceholderAttribute } from '@tiptap/extensions' -import { afterEach, describe, expect, it } from 'vitest' +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' + +import { findScrollParent } from '../src/placeholder/utils/findScrollParent.js' +import { throttle } from '../src/placeholder/utils/throttle.js' describe('extension-placeholder', () => { let editor: Editor | null = null @@ -186,3 +189,335 @@ describe('extension-placeholder with includeChildren and wrapper nodes', () => { expect(paragraph.hasAttribute('data-placeholder')).toBe(false) }) }) + +describe('extension-placeholder: fast path (default config)', () => { + let editor: Editor | null = null + + afterEach(() => { + if (editor) { + editor.destroy() + editor = null + } + }) + + it('shows placeholder in the current empty paragraph via the fast path', () => { + editor = new Editor({ + extensions: [ + Document, + Paragraph, + Text, + Placeholder.configure({ + placeholder: 'Type something...', + showOnlyCurrent: true, + includeChildren: false, + }), + ], + content: '

', + }) + + const paragraph = editor!.view.dom.querySelector('p') as HTMLElement + expect(paragraph.getAttribute('data-placeholder')).toBe('Type something...') + expect(paragraph.classList.contains('is-empty')).toBe(true) + }) + + it('hides placeholder when the cursor is in a non-empty paragraph', () => { + editor = new Editor({ + extensions: [ + Document, + Paragraph, + Text, + Placeholder.configure({ + placeholder: 'Type something...', + showOnlyCurrent: true, + includeChildren: false, + }), + ], + content: '

Hello

', + }) + + const paragraph = editor!.view.dom.querySelector('p') as HTMLElement + expect(paragraph.hasAttribute('data-placeholder')).toBe(false) + expect(paragraph.classList.contains('is-empty')).toBe(false) + }) + + it('shows placeholder only for the current empty node when multiple paragraphs exist', () => { + editor = new Editor({ + extensions: [ + Document, + Paragraph, + Text, + Placeholder.configure({ + placeholder: 'Write here...', + showOnlyCurrent: true, + includeChildren: false, + }), + ], + content: '

', + }) + + // Cursor is in the first paragraph by default (start of doc) + const paragraphs = editor!.view.dom.querySelectorAll('p') + // Only the first paragraph (where the cursor is) should have a placeholder + expect(paragraphs[0].getAttribute('data-placeholder')).toBe('Write here...') + // The second paragraph should not have a placeholder since showOnlyCurrent is true + expect(paragraphs[1].hasAttribute('data-placeholder')).toBe(false) + }) + + it('removes placeholder when user types into the empty paragraph', () => { + editor = new Editor({ + extensions: [ + Document, + Paragraph, + Text, + Placeholder.configure({ + placeholder: 'Type something...', + showOnlyCurrent: true, + includeChildren: false, + }), + ], + content: '

', + }) + + const paragraph = editor!.view.dom.querySelector('p') as HTMLElement + expect(paragraph.getAttribute('data-placeholder')).toBe('Type something...') + + // Insert text into the paragraph + editor!.commands.insertContent('Hello') + expect(paragraph.hasAttribute('data-placeholder')).toBe(false) + expect(paragraph.classList.contains('is-empty')).toBe(false) + }) +}) + +describe('extension-placeholder: slow path (showOnlyCurrent: false)', () => { + let editor: Editor | null = null + + afterEach(() => { + if (editor) { + editor.destroy() + editor = null + } + }) + + it('shows placeholder on all empty textblocks when showOnlyCurrent is false', () => { + editor = new Editor({ + extensions: [ + Document, + Paragraph, + Text, + Placeholder.configure({ + placeholder: 'Fill me in...', + showOnlyCurrent: false, + includeChildren: false, + }), + ], + content: '

Content

', + }) + + const paragraphs = editor!.view.dom.querySelectorAll('p') + // First paragraph (empty) should have placeholder + expect(paragraphs[0].getAttribute('data-placeholder')).toBe('Fill me in...') + // Second paragraph (has content) should not + expect(paragraphs[1].hasAttribute('data-placeholder')).toBe(false) + // Third paragraph (empty) should have placeholder + expect(paragraphs[2].getAttribute('data-placeholder')).toBe('Fill me in...') + }) +}) + +describe('extension-placeholder — empty editor class', () => { + let editor: Editor | null = null + + afterEach(() => { + if (editor) { + editor.destroy() + editor = null + } + }) + + it('adds is-editor-empty class when the entire document is empty', () => { + editor = new Editor({ + extensions: [Document, Paragraph, Text, Placeholder], + content: '

', + }) + + const paragraph = editor!.view.dom.querySelector('p') as HTMLElement + expect(paragraph.classList.contains('is-editor-empty')).toBe(true) + }) + + it('removes is-editor-empty class when content is added', () => { + editor = new Editor({ + extensions: [Document, Paragraph, Text, Placeholder], + content: '

', + }) + + const paragraph = editor!.view.dom.querySelector('p') as HTMLElement + expect(paragraph.classList.contains('is-editor-empty')).toBe(true) + + editor!.commands.insertContent('Hello') + expect(paragraph.classList.contains('is-editor-empty')).toBe(false) + }) + + it('uses custom emptyEditorClass option', () => { + editor = new Editor({ + extensions: [ + Document, + Paragraph, + Text, + Placeholder.configure({ + emptyEditorClass: 'my-empty-editor', + emptyNodeClass: 'my-empty-node', + }), + ], + content: '

', + }) + + const paragraph = editor!.view.dom.querySelector('p') as HTMLElement + expect(paragraph.classList.contains('my-empty-editor')).toBe(true) + expect(paragraph.classList.contains('my-empty-node')).toBe(true) + }) +}) + +describe('placeholder utility: findScrollParent', () => { + let container: HTMLElement + + beforeEach(() => { + container = document.createElement('div') + document.body.appendChild(container) + }) + + afterEach(() => { + document.body.removeChild(container) + }) + + it('returns the window when no scroll parent exists', () => { + const el = document.createElement('span') + container.appendChild(el) + expect(findScrollParent(el)).toBe(window) + }) + + it('finds a scrollable parent element with overflow: auto', () => { + const scrollable = document.createElement('div') + scrollable.style.overflow = 'auto' + const child = document.createElement('span') + scrollable.appendChild(child) + container.appendChild(scrollable) + + expect(findScrollParent(child)).toBe(scrollable) + }) + + it('finds a scrollable parent element with overflow: scroll', () => { + const scrollable = document.createElement('div') + scrollable.style.overflow = 'scroll' + const child = document.createElement('span') + scrollable.appendChild(child) + container.appendChild(scrollable) + + expect(findScrollParent(child)).toBe(scrollable) + }) + + it('does not return elements with overflow: hidden or overflow: clip', () => { + const hidden = document.createElement('div') + hidden.style.overflow = 'hidden' + const clip = document.createElement('div') + clip.style.overflow = 'clip' + const child = document.createElement('span') + hidden.appendChild(clip) + clip.appendChild(child) + container.appendChild(hidden) + + expect(findScrollParent(child)).toBe(window) + }) + + it('finds the nearest scrollable ancestor', () => { + const outer = document.createElement('div') + outer.style.overflow = 'scroll' + const middle = document.createElement('div') + middle.style.overflow = 'hidden' + const child = document.createElement('span') + middle.appendChild(child) + outer.appendChild(middle) + container.appendChild(outer) + + // Should find `outer`, not stop at `middle` (which is hidden, not scrollable) + expect(findScrollParent(child)).toBe(outer) + }) +}) + +describe('placeholder utility: throttle', () => { + it('calls the function immediately on the first invocation (leading-edge)', () => { + let called = false + const { call } = throttle(() => { + called = true + }, 250) + call() + expect(called).toBe(true) + }) + + it('ignores subsequent calls within the delay window', () => { + let count = 0 + const { call } = throttle(() => { + count += 1 + }, 250) + + call() + call() + call() + // Leading-edge fires immediately, subsequent calls within the delay are blocked + expect(count).toBe(1) + }) + + it('allows a call after the delay has elapsed', () => { + vi.useFakeTimers() + let count = 0 + const { call } = throttle(() => { + count += 1 + }, 250) + + call() + expect(count).toBe(1) + + vi.advanceTimersByTime(250) + call() + expect(count).toBe(2) + vi.useRealTimers() + }) + + it('resets the timer on each call within the window', () => { + vi.useFakeTimers() + let count = 0 + const { call } = throttle(() => { + count += 1 + }, 250) + + call() // fires immediately + expect(count).toBe(1) + + vi.advanceTimersByTime(100) + call() // ignored (within 250ms window) + vi.advanceTimersByTime(100) + call() // ignored + vi.advanceTimersByTime(100) + // 300ms elapsed total, but the window extends 250ms from the last call + expect(count).toBe(1) + + vi.advanceTimersByTime(150) + call() // 250ms has passed since last call + expect(count).toBe(2) + vi.useRealTimers() + }) + + it('cancel() clears the timer and allows immediate re-call', () => { + vi.useFakeTimers() + let count = 0 + const { call, cancel } = throttle(() => { + count += 1 + }, 250) + + call() // fires, starts timer + expect(count).toBe(1) + + cancel() // clears timer + call() // fires again because timer was cancelled + expect(count).toBe(2) + vi.useRealTimers() + }) +}) diff --git a/packages/extensions/package.json b/packages/extensions/package.json index e8e9b22d33..a3c20888d3 100644 --- a/packages/extensions/package.json +++ b/packages/extensions/package.json @@ -1,7 +1,7 @@ { "name": "@tiptap/extensions", "description": "various extensions for tiptap", - "version": "3.23.5", + "version": "3.23.6", "homepage": "https://tiptap.dev", "keywords": [ "tiptap", diff --git a/packages/extensions/src/placeholder/index.ts b/packages/extensions/src/placeholder/index.ts index d2ea7291a7..70f8306c46 100644 --- a/packages/extensions/src/placeholder/index.ts +++ b/packages/extensions/src/placeholder/index.ts @@ -1 +1,2 @@ export * from './placeholder.js' +export * from './types.js' diff --git a/packages/extensions/src/placeholder/placeholder.ts b/packages/extensions/src/placeholder/placeholder.ts index 3c8c483e88..232a6bd604 100644 --- a/packages/extensions/src/placeholder/placeholder.ts +++ b/packages/extensions/src/placeholder/placeholder.ts @@ -1,8 +1,13 @@ -import type { Editor } from '@tiptap/core' import { Extension, isNodeEmpty } from '@tiptap/core' -import type { Node as ProsemirrorNode } from '@tiptap/pm/model' import { Plugin, PluginKey } from '@tiptap/pm/state' -import { Decoration, DecorationSet } from '@tiptap/pm/view' +import type { Decoration } from '@tiptap/pm/view' +import { DecorationSet } from '@tiptap/pm/view' + +import type { PlaceholderOptions } from './types.js' +import { createPlaceholderDecoration } from './utils/createPlaceholderDecoration.js' +import { findScrollParent } from './utils/findScrollParent.js' +import { getViewportBoundaryPositions } from './utils/getViewportBoundaryPositions.js' +import { throttle } from './utils/throttle.js' /** * The default data attribute label @@ -31,63 +36,7 @@ export function preparePlaceholderAttribute(attr: string): string { ) } -export interface PlaceholderOptions { - /** - * **The class name for the empty editor** - * @default 'is-editor-empty' - */ - emptyEditorClass: string - - /** - * **The class name for empty nodes** - * @default 'is-empty' - */ - emptyNodeClass: string - - /** - * **The data-attribute used for the placeholder label** - * Will be prepended with `data-` and converted to kebab-case and cleaned of special characters. - * @default 'placeholder' - */ - dataAttribute: string - - /** - * **The placeholder content** - * - * You can use a function to return a dynamic placeholder or a string. - * @default 'Write something …' - */ - placeholder: - | ((PlaceholderProps: { editor: Editor; node: ProsemirrorNode; pos: number; hasAnchor: boolean }) => string) - | string - - /** - * **Checks if the placeholder should be only shown when the editor is editable.** - * - * If true, the placeholder will only be shown when the editor is editable. - * If false, the placeholder will always be shown. - * @default true - */ - showOnlyWhenEditable: boolean - - /** - * **Checks if the placeholder should be only shown when the current node is empty.** - * - * If true, the placeholder will only be shown when the current node is empty. - * If false, the placeholder will be shown when any node is empty. - * @default true - */ - showOnlyCurrent: boolean - - /** - * **Controls if the placeholder should be shown for all descendents.** - * - * If true, the placeholder will be shown for all descendents. - * If false, the placeholder will only be shown for the current node. - * @default false - */ - includeChildren: boolean -} +export const PLUGIN_KEY = new PluginKey('tiptap__placeholder') /** * This extension allows you to add a placeholder to your editor. @@ -116,52 +65,157 @@ export const Placeholder = Extension.create({ return [ new Plugin({ - key: new PluginKey('placeholder'), + state: { + init() { + return { + // null means "no viewport info yet" — decoration callback falls + // back to full document scan until the scroll handler fires. + topPos: null as number | null, + bottomPos: null as number | null, + } + }, + apply(tr, prev) { + const meta = tr.getMeta(PLUGIN_KEY) as { positions?: { top: number; bottom: number } } | undefined + + if (meta?.positions) { + return { + topPos: meta.positions.top, + bottomPos: meta.positions.bottom, + } + } + + if (!tr.docChanged) { + return prev + } + + // Preserve last known viewport positions across transactions. + // Without this, every keystroke resets back to a full document + // scan, defeating the viewport optimisation. + // Only map when we have actual positions — null means "no viewport + // info yet" and should stay null to fall back to full doc scan. + return { + topPos: prev.topPos !== null ? tr.mapping.map(prev.topPos) : null, + bottomPos: prev.bottomPos !== null ? tr.mapping.map(prev.bottomPos) : null, + } + }, + }, + key: PLUGIN_KEY, + view(view) { + const scrollContainer = findScrollParent(view.dom) + + const computeAndDispatch = () => { + const positions = getViewportBoundaryPositions({ + view, + doc: view.state.doc, + scrollContainer, + }) + + const prev = PLUGIN_KEY.getState(view.state) + if (prev.topPos === positions.top && prev.bottomPos === positions.bottom) { + return + } + + const tr = view.state.tr + .setMeta(PLUGIN_KEY, { positions }) + // Flag this transaction so the update() method can detect + // it and avoid re-entrant computation. + .setMeta('tiptap__viewportUpdate', true) + view.dispatch(tr) + } + + const { call: throttledUpdate, cancel: cancelThrottle } = throttle(computeAndDispatch, 250) + const scrollParent = scrollContainer + + scrollParent.addEventListener('scroll', throttledUpdate, { passive: true }) + + // Fire once to populate initial viewport (bypass throttle) + computeAndDispatch() + + return { + update(_, prevState) { + // Skip re-entry: the dispatch inside computeAndDispatch would + // trigger this update again, but the doc didn't change so the + // size guard catches that. The meta flag is an extra safeguard. + if (view.state.doc.content.size !== prevState.doc.content.size) { + computeAndDispatch() + } + }, + destroy: () => { + cancelThrottle() + scrollParent.removeEventListener('scroll', throttledUpdate) + }, + } + }, props: { decorations: ({ doc, selection }) => { const active = this.editor.isEditable || !this.options.showOnlyWhenEditable - const { anchor } = selection - const decorations: Decoration[] = [] if (!active) { return null } + const { anchor } = selection + const decorations: Decoration[] = [] const isEmptyDoc = this.editor.isEmpty - doc.descendants((node, pos) => { - const hasAnchor = anchor >= pos && anchor <= pos + node.nodeSize - const isEmpty = !node.isLeaf && isNodeEmpty(node) - - if (!node.type.isTextblock) { - return this.options.includeChildren + const useResolvedPath = this.options.showOnlyCurrent && !this.options.includeChildren + + if (useResolvedPath) { + const resolved = doc.resolve(anchor) + + if (resolved.depth > 0) { + const node = resolved.node(1) + const nodeStart = resolved.before(1) + + if (node.type.isTextblock && isNodeEmpty(node)) { + const hasAnchor = anchor >= nodeStart && anchor <= nodeStart + node.nodeSize + const decoration = createPlaceholderDecoration({ + node, + dataAttribute, + hasAnchor, + placeholder: this.options.placeholder, + classes: { + emptyEditor: this.options.emptyEditorClass, + emptyNode: this.options.emptyNodeClass, + }, + editor: this.editor, + isEmptyDoc, + pos: resolved.before(1), + }) + + decorations.push(decoration) + } } + } else { + const pluginState = PLUGIN_KEY.getState(this.editor.state) + const from = pluginState.topPos ?? 0 + const to = pluginState.bottomPos ?? doc.content.size - if ((hasAnchor || !this.options.showOnlyCurrent) && isEmpty) { - const classes = [this.options.emptyNodeClass] + doc.nodesBetween(from, to, (node, pos) => { + const hasAnchor = anchor >= pos && anchor <= pos + node.nodeSize + const isEmpty = !node.isLeaf && isNodeEmpty(node) - if (isEmptyDoc) { - classes.push(this.options.emptyEditorClass) + if (!node.type.isTextblock) { + return this.options.includeChildren } - const decoration = Decoration.node(pos, pos + node.nodeSize, { - class: classes.join(' '), - [dataAttribute]: - typeof this.options.placeholder === 'function' - ? this.options.placeholder({ - editor: this.editor, - node, - pos, - hasAnchor, - }) - : this.options.placeholder, - }) - - decorations.push(decoration) - } + if ((hasAnchor || !this.options.showOnlyCurrent) && isEmpty) { + const decoration = createPlaceholderDecoration({ + classes: { emptyEditor: this.options.emptyEditorClass, emptyNode: this.options.emptyNodeClass }, + editor: this.editor, + isEmptyDoc, + dataAttribute, + hasAnchor, + placeholder: this.options.placeholder, + node, + pos, + }) + decorations.push(decoration) + } - return this.options.includeChildren - }) + return this.options.includeChildren + }) + } return DecorationSet.create(doc, decorations) }, diff --git a/packages/extensions/src/placeholder/types.ts b/packages/extensions/src/placeholder/types.ts new file mode 100644 index 0000000000..5e9f631f13 --- /dev/null +++ b/packages/extensions/src/placeholder/types.ts @@ -0,0 +1,60 @@ +import type { Editor } from '@tiptap/core' +import type { Node as ProsemirrorNode } from '@tiptap/pm/model' + +export interface PlaceholderOptions { + /** + * **The class name for the empty editor** + * @default 'is-editor-empty' + */ + emptyEditorClass: string + + /** + * **The class name for empty nodes** + * @default 'is-empty' + */ + emptyNodeClass: string + + /** + * **The data-attribute used for the placeholder label** + * Will be prepended with `data-` and converted to kebab-case and cleaned of special characters. + * @default 'placeholder' + */ + dataAttribute: string + + /** + * **The placeholder content** + * + * You can use a function to return a dynamic placeholder or a string. + * @default 'Write something …' + */ + placeholder: + | ((PlaceholderProps: { editor: Editor; node: ProsemirrorNode; pos: number; hasAnchor: boolean }) => string) + | string + + /** + * **Checks if the placeholder should be only shown when the editor is editable.** + * + * If true, the placeholder will only be shown when the editor is editable. + * If false, the placeholder will always be shown. + * @default true + */ + showOnlyWhenEditable: boolean + + /** + * **Checks if the placeholder should be only shown when the current node is empty.** + * + * If true, the placeholder will only be shown when the current node is empty. + * If false, the placeholder will be shown when any node is empty. + * @default true + */ + showOnlyCurrent: boolean + + /** + * **Controls if the placeholder should be shown for all descendants.** + * + * If true, the placeholder will be shown for all descendants. + * If false, the placeholder will only be shown for the current node. + * @default false + */ + includeChildren: boolean +} diff --git a/packages/extensions/src/placeholder/utils/createPlaceholderDecoration.ts b/packages/extensions/src/placeholder/utils/createPlaceholderDecoration.ts new file mode 100644 index 0000000000..b2ee275c83 --- /dev/null +++ b/packages/extensions/src/placeholder/utils/createPlaceholderDecoration.ts @@ -0,0 +1,61 @@ +import type { Editor } from '@tiptap/core' +import type { Node } from '@tiptap/pm/model' +import { Decoration } from '@tiptap/pm/view' + +import type { PlaceholderOptions } from '../types.js' + +/** + * Creates a ProseMirror node decoration that applies a placeholder + * CSS class and data attribute to an empty node. + * @param options.editor - The editor instance + * @param options.pos - The position of the node in the document + * @param options.node - The ProseMirror node + * @param options.isEmptyDoc - Whether the entire document is empty + * @param options.hasAnchor - Whether the selection anchor is within the node + * @param options.dataAttribute - The data attribute name (e.g. `data-placeholder`) + * @param options.classes - CSS classes for empty nodes and the empty editor + * @param options.placeholder - The placeholder text or a function that returns it + * @returns A ProseMirror node decoration with placeholder classes and data attribute + */ +export function createPlaceholderDecoration(options: { + editor: Editor + pos: number + node: Node + isEmptyDoc: boolean + hasAnchor: boolean + dataAttribute: string + classes: { + emptyEditor: PlaceholderOptions['emptyEditorClass'] + emptyNode: PlaceholderOptions['emptyNodeClass'] + } + placeholder: PlaceholderOptions['placeholder'] +}) { + const { + editor, + placeholder, + dataAttribute, + pos, + node, + isEmptyDoc, + hasAnchor, + classes: { emptyNode, emptyEditor }, + } = options + const classes = [emptyNode] + + if (isEmptyDoc) { + classes.push(emptyEditor) + } + + return Decoration.node(pos, pos + node.nodeSize, { + class: classes.join(' '), + [dataAttribute]: + typeof placeholder === 'function' + ? placeholder({ + editor, + node, + pos, + hasAnchor, + }) + : placeholder, + }) +} diff --git a/packages/extensions/src/placeholder/utils/findScrollParent.ts b/packages/extensions/src/placeholder/utils/findScrollParent.ts new file mode 100644 index 0000000000..cc547d5b62 --- /dev/null +++ b/packages/extensions/src/placeholder/utils/findScrollParent.ts @@ -0,0 +1,38 @@ +/** + * Checks if an element is scrollable by testing its overflow properties. + * Elements with `overflow: hidden` or `overflow: clip` are intentionally + * excluded — they clip content but don't emit scroll events. + */ +function isScrollable(el: HTMLElement): boolean { + const style = getComputedStyle(el) + const overflow = `${style.overflow} ${style.overflowY} ${style.overflowX}` + + return /auto|scroll|overlay/.test(overflow) +} + +export function findScrollParent(element: HTMLElement): HTMLElement | Window { + let el: HTMLElement | null = element + + while (el) { + if (isScrollable(el)) { + return el + } + + // Check if we hit a Shadow DOM boundary. If so, jump to the shadow host + // and continue traversing the light DOM. + const parent = el.parentElement + if (!parent) { + const root = el.getRootNode() + if (root instanceof ShadowRoot) { + el = root.host as HTMLElement + continue + } + + return window + } + + el = parent + } + + return window +} diff --git a/packages/extensions/src/placeholder/utils/getViewportBoundaryPositions.ts b/packages/extensions/src/placeholder/utils/getViewportBoundaryPositions.ts new file mode 100644 index 0000000000..6a8fdfece0 --- /dev/null +++ b/packages/extensions/src/placeholder/utils/getViewportBoundaryPositions.ts @@ -0,0 +1,45 @@ +import type { Node } from '@tiptap/pm/model' +import type { EditorView } from '@tiptap/pm/view' + +function getContainerRect(container: HTMLElement | Window): { top: number; bottom: number } { + if (container === window) { + return { top: 0, bottom: window.innerHeight } + } + + return (container as HTMLElement).getBoundingClientRect() +} + +export function getViewportBoundaryPositions({ + doc, + view, + scrollContainer, +}: { + doc: Node + view: EditorView + scrollContainer?: HTMLElement | Window +}) { + const editorRect = view.dom.getBoundingClientRect() + const containerRect = scrollContainer ? getContainerRect(scrollContainer) : { top: 0, bottom: window.innerHeight } + + const visibleTop = Math.max(editorRect.top, containerRect.top) + const visibleBottom = Math.min(editorRect.bottom, containerRect.bottom) + + if (visibleTop >= visibleBottom) { + // Editor is not visible — fall back to full document range + return { top: 0, bottom: doc.content.size } + } + + // Pick the x-coordinate based on text direction. In LTR the content + // starts at the left edge; in RTL it starts at the right edge. + // Clamp to ensure the coordinate stays inside the editor bounds. + const isRTL = getComputedStyle(view.dom).direction === 'rtl' + const x = isRTL ? Math.max(editorRect.right - 2, editorRect.left + 2) : editorRect.left + 2 + + const topPos = view.posAtCoords({ left: x, top: visibleTop + 2 }) + const bottomPos = view.posAtCoords({ left: x, top: visibleBottom - 2 }) + + return { + top: topPos ? topPos.pos : 0, + bottom: bottomPos ? bottomPos.pos : doc.content.size, + } +} diff --git a/packages/extensions/src/placeholder/utils/throttle.ts b/packages/extensions/src/placeholder/utils/throttle.ts new file mode 100644 index 0000000000..fab2e19cd7 --- /dev/null +++ b/packages/extensions/src/placeholder/utils/throttle.ts @@ -0,0 +1,25 @@ +export function throttle void>(fn: T, delay: number): { call: T; cancel: () => void } { + let timer: ReturnType | null = null + + const call = ((...args: any[]) => { + if (timer) { + return + } + + // Leading-edge: fire immediately, then prevent subsequent calls + // until the timer fires and resets. + fn(...args) + timer = setTimeout(() => { + timer = null + }, delay) + }) as T + + const cancel = () => { + if (timer) { + clearTimeout(timer) + timer = null + } + } + + return { call, cancel } +} diff --git a/packages/html/CHANGELOG.md b/packages/html/CHANGELOG.md index b535f1b72d..652039e387 100644 --- a/packages/html/CHANGELOG.md +++ b/packages/html/CHANGELOG.md @@ -1,5 +1,13 @@ # Change Log +## 3.23.6 + +### Patch Changes + +- Updated dependencies [d168376] + - @tiptap/core@3.23.6 + - @tiptap/pm@3.23.6 + ## 3.23.5 ### Patch Changes diff --git a/packages/html/package.json b/packages/html/package.json index d297723b51..d106cfade7 100644 --- a/packages/html/package.json +++ b/packages/html/package.json @@ -1,7 +1,7 @@ { "name": "@tiptap/html", "description": "utility package to render tiptap JSON as HTML", - "version": "3.23.5", + "version": "3.23.6", "homepage": "https://tiptap.dev", "keywords": [ "tiptap", diff --git a/packages/markdown/CHANGELOG.md b/packages/markdown/CHANGELOG.md index fd9d5258c2..561dfc4ba3 100644 --- a/packages/markdown/CHANGELOG.md +++ b/packages/markdown/CHANGELOG.md @@ -1,5 +1,13 @@ # @tiptap/markdown +## 3.23.6 + +### Patch Changes + +- Updated dependencies [d168376] + - @tiptap/core@3.23.6 + - @tiptap/pm@3.23.6 + ## 3.23.5 ### Patch Changes diff --git a/packages/markdown/package.json b/packages/markdown/package.json index 2b9c969de3..a4b71df542 100644 --- a/packages/markdown/package.json +++ b/packages/markdown/package.json @@ -1,7 +1,7 @@ { "name": "@tiptap/markdown", "description": "markdown parser and serializer for tiptap", - "version": "3.23.5", + "version": "3.23.6", "homepage": "https://tiptap.dev", "keywords": [ "tiptap", diff --git a/packages/pm/CHANGELOG.md b/packages/pm/CHANGELOG.md index 4be9cb81d5..3247759f08 100644 --- a/packages/pm/CHANGELOG.md +++ b/packages/pm/CHANGELOG.md @@ -1,5 +1,7 @@ # Change Log +## 3.23.6 + ## 3.23.5 ## 3.23.4 diff --git a/packages/pm/package.json b/packages/pm/package.json index 4940ecd726..ac935a5435 100644 --- a/packages/pm/package.json +++ b/packages/pm/package.json @@ -1,7 +1,7 @@ { "name": "@tiptap/pm", "description": "prosemirror wrapper package for tiptap", - "version": "3.23.5", + "version": "3.23.6", "homepage": "https://tiptap.dev", "keywords": [ "tiptap", diff --git a/packages/react/CHANGELOG.md b/packages/react/CHANGELOG.md index 2b57e28fa8..e6bf2663d1 100644 --- a/packages/react/CHANGELOG.md +++ b/packages/react/CHANGELOG.md @@ -1,5 +1,13 @@ # Change Log +## 3.23.6 + +### Patch Changes + +- Updated dependencies [d168376] + - @tiptap/core@3.23.6 + - @tiptap/pm@3.23.6 + ## 3.23.5 ### Patch Changes diff --git a/packages/react/package.json b/packages/react/package.json index a27f7a6c91..9667a41fd3 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -1,7 +1,7 @@ { "name": "@tiptap/react", "description": "React components for tiptap", - "version": "3.23.5", + "version": "3.23.6", "homepage": "https://tiptap.dev", "keywords": [ "tiptap", diff --git a/packages/starter-kit/CHANGELOG.md b/packages/starter-kit/CHANGELOG.md index 1c8d71af51..bbca91c870 100644 --- a/packages/starter-kit/CHANGELOG.md +++ b/packages/starter-kit/CHANGELOG.md @@ -1,5 +1,36 @@ # Change Log +## 3.23.6 + +### Patch Changes + +- Updated dependencies [d168376] +- Updated dependencies [937ff2e] + - @tiptap/core@3.23.6 + - @tiptap/extensions@3.23.6 + - @tiptap/extension-blockquote@3.23.6 + - @tiptap/extension-bold@3.23.6 + - @tiptap/extension-code@3.23.6 + - @tiptap/extension-code-block@3.23.6 + - @tiptap/extension-document@3.23.6 + - @tiptap/extension-hard-break@3.23.6 + - @tiptap/extension-heading@3.23.6 + - @tiptap/extension-horizontal-rule@3.23.6 + - @tiptap/extension-italic@3.23.6 + - @tiptap/extension-link@3.23.6 + - @tiptap/extension-list@3.23.6 + - @tiptap/extension-paragraph@3.23.6 + - @tiptap/extension-strike@3.23.6 + - @tiptap/extension-text@3.23.6 + - @tiptap/extension-underline@3.23.6 + - @tiptap/extension-dropcursor@3.23.6 + - @tiptap/extension-gapcursor@3.23.6 + - @tiptap/extension-list-item@3.23.6 + - @tiptap/extension-list-keymap@3.23.6 + - @tiptap/extension-bullet-list@3.23.6 + - @tiptap/extension-ordered-list@3.23.6 + - @tiptap/pm@3.23.6 + ## 3.23.5 ### Patch Changes diff --git a/packages/starter-kit/package.json b/packages/starter-kit/package.json index 34feae7ddd..3d8a2a4cad 100644 --- a/packages/starter-kit/package.json +++ b/packages/starter-kit/package.json @@ -1,7 +1,7 @@ { "name": "@tiptap/starter-kit", "description": "starter kit for tiptap", - "version": "3.23.5", + "version": "3.23.6", "homepage": "https://tiptap.dev", "keywords": [ "tiptap", diff --git a/packages/static-renderer/CHANGELOG.md b/packages/static-renderer/CHANGELOG.md index a08329afc2..886ffba73f 100644 --- a/packages/static-renderer/CHANGELOG.md +++ b/packages/static-renderer/CHANGELOG.md @@ -1,5 +1,13 @@ # Change Log +## 3.23.6 + +### Patch Changes + +- Updated dependencies [d168376] + - @tiptap/core@3.23.6 + - @tiptap/pm@3.23.6 + ## 3.23.5 ### Patch Changes diff --git a/packages/static-renderer/package.json b/packages/static-renderer/package.json index a02c20418a..a61b6cba4f 100644 --- a/packages/static-renderer/package.json +++ b/packages/static-renderer/package.json @@ -1,7 +1,7 @@ { "name": "@tiptap/static-renderer", "description": "statically render Tiptap JSON", - "version": "3.23.5", + "version": "3.23.6", "homepage": "https://tiptap.dev", "keywords": [ "tiptap", diff --git a/packages/suggestion/CHANGELOG.md b/packages/suggestion/CHANGELOG.md index 442801f181..6e86bf7b0e 100644 --- a/packages/suggestion/CHANGELOG.md +++ b/packages/suggestion/CHANGELOG.md @@ -1,5 +1,13 @@ # Change Log +## 3.23.6 + +### Patch Changes + +- Updated dependencies [d168376] + - @tiptap/core@3.23.6 + - @tiptap/pm@3.23.6 + ## 3.23.5 ### Patch Changes diff --git a/packages/suggestion/package.json b/packages/suggestion/package.json index 6bbeb6ea52..fa859559f8 100644 --- a/packages/suggestion/package.json +++ b/packages/suggestion/package.json @@ -1,7 +1,7 @@ { "name": "@tiptap/suggestion", "description": "suggestion plugin for tiptap", - "version": "3.23.5", + "version": "3.23.6", "homepage": "https://tiptap.dev", "keywords": [ "tiptap", diff --git a/packages/vue-2/CHANGELOG.md b/packages/vue-2/CHANGELOG.md index d2785e2f31..fd73016036 100644 --- a/packages/vue-2/CHANGELOG.md +++ b/packages/vue-2/CHANGELOG.md @@ -1,5 +1,13 @@ # Change Log +## 3.23.6 + +### Patch Changes + +- Updated dependencies [d168376] + - @tiptap/core@3.23.6 + - @tiptap/pm@3.23.6 + ## 3.23.5 ### Patch Changes diff --git a/packages/vue-2/package.json b/packages/vue-2/package.json index 08a6ca8754..a269de8783 100644 --- a/packages/vue-2/package.json +++ b/packages/vue-2/package.json @@ -1,7 +1,7 @@ { "name": "@tiptap/vue-2", "description": "Vue components for tiptap", - "version": "3.23.5", + "version": "3.23.6", "homepage": "https://tiptap.dev", "keywords": [ "tiptap", diff --git a/packages/vue-3/CHANGELOG.md b/packages/vue-3/CHANGELOG.md index 60f8efabca..f91a74f18c 100644 --- a/packages/vue-3/CHANGELOG.md +++ b/packages/vue-3/CHANGELOG.md @@ -1,5 +1,13 @@ # Change Log +## 3.23.6 + +### Patch Changes + +- Updated dependencies [d168376] + - @tiptap/core@3.23.6 + - @tiptap/pm@3.23.6 + ## 3.23.5 ### Patch Changes diff --git a/packages/vue-3/package.json b/packages/vue-3/package.json index d5de2b5e3b..cf4078de83 100644 --- a/packages/vue-3/package.json +++ b/packages/vue-3/package.json @@ -1,7 +1,7 @@ { "name": "@tiptap/vue-3", "description": "Vue components for tiptap", - "version": "3.23.5", + "version": "3.23.6", "homepage": "https://tiptap.dev", "keywords": [ "tiptap",