diff --git a/.eslintrc.js b/.eslintrc.js index ebea8e4542..18cd55d3a0 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -8,6 +8,15 @@ module.exports = { node: true, }, overrides: [ + { + files: [ + './**/*.ts', + './**/*.tsx', + './**/*.js', + './**/*.jsx', + ], + extends: ['plugin:react-hooks/recommended'], + }, { files: [ './**/*.ts', diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f34ac29061..6b2ef91679 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -103,7 +103,7 @@ jobs: - name: Test ${{ matrix.test-spec.name }} id: cypress - uses: cypress-io/github-action@v6.7.1 + uses: cypress-io/github-action@v6.7.2 with: cache-key: ${{ runner.os }}-node-${{ matrix.node-version }}-${{ hashFiles('**/package-lock.json') }} start: npm run serve @@ -114,7 +114,7 @@ jobs: quiet: true - name: Export screenshots (on failure only) - uses: actions/upload-artifact@v4.3.3 + uses: actions/upload-artifact@v4.3.5 if: failure() with: name: cypress-screenshots @@ -122,7 +122,7 @@ jobs: retention-days: 7 - name: Export screen recordings (on failure only) - uses: actions/upload-artifact@v4.3.3 + uses: actions/upload-artifact@v4.3.5 if: failure() with: name: cypress-videos diff --git a/demos/CHANGELOG.md b/demos/CHANGELOG.md index 64820fea77..dbc2ca3348 100644 --- a/demos/CHANGELOG.md +++ b/demos/CHANGELOG.md @@ -1,5 +1,11 @@ # Change Log +## 2.4.2 + +### Patch Changes + +- d6e56c4: declare lowlight to be a peer dep of extension-code-block-lowlight, update usage to v3 + ## 2.4.1 ### Patch Changes diff --git a/demos/includeDependencies.txt b/demos/includeDependencies.txt index 54929e3c27..20de61e95e 100644 --- a/demos/includeDependencies.txt +++ b/demos/includeDependencies.txt @@ -6,7 +6,6 @@ highlight.js/lib/languages/xml highlight.js/lib/core linkifyjs lowlight -lowlight/lib/core prosemirror-commands prosemirror-dropcursor prosemirror-gapcursor @@ -21,6 +20,7 @@ prosemirror-view react react-dom react-dom/client +use-sync-external-store/shim/with-selector shiki simplify-js tippy.js diff --git a/demos/package.json b/demos/package.json index e9efcdaa3d..5ecad0b4cd 100644 --- a/demos/package.json +++ b/demos/package.json @@ -1,6 +1,6 @@ { "name": "tiptap-demos", - "version": "2.4.1", + "version": "2.4.2", "private": true, "type": "module", "scripts": { @@ -14,13 +14,13 @@ "@lexical/react": "^0.11.1", "d3": "^7.3.0", "fast-glob": "^3.2.11", - "highlight.js": "^11.6.0", + "highlight.js": "^11.10.0", "lexical": "^0.11.1", - "lowlight": "^2.7.0", + "lowlight": "^3.1.0", "remixicon": "^2.5.0", "shiki": "^1.10.3", "simplify-js": "^1.2.4", - "y-prosemirror": "^1.2.9", + "y-prosemirror": "^1.2.11", "y-webrtc": "^10.3.0", "yjs": "^13.6.18" }, diff --git a/demos/setup/vue.ts b/demos/setup/vue.ts index 9b797386c0..aad10cf133 100644 --- a/demos/setup/vue.ts +++ b/demos/setup/vue.ts @@ -14,7 +14,12 @@ export default function init(name: string, source: any) { import(`../src/${demoCategory}/${demoName}/${frameworkName}/index.vue`) .then(module => { - createApp(module.default).mount('#app') + const app = createApp(module.default) + + if (typeof module.configureApp === 'function') { + module.configureApp(app) + } + app.mount('#app') debug() }) } diff --git a/demos/src/Commands/Cut/React/index.jsx b/demos/src/Commands/Cut/React/index.jsx index 66a871ec26..02bea76cd5 100644 --- a/demos/src/Commands/Cut/React/index.jsx +++ b/demos/src/Commands/Cut/React/index.jsx @@ -8,10 +8,6 @@ import StarterKit from '@tiptap/starter-kit' import React, { useCallback } from 'react' const MenuBar = ({ editor }) => { - if (!editor) { - return null - } - const onCutToStart = useCallback(() => { editor.chain().cut({ from: editor.state.selection.$from.pos, to: editor.state.selection.$to.pos }, 1).run() }, [editor]) @@ -20,6 +16,10 @@ const MenuBar = ({ editor }) => { editor.chain().cut({ from: editor.state.selection.$from.pos, to: editor.state.selection.$to.pos }, editor.state.doc.nodeSize - 2).run() }, [editor]) + if (!editor) { + return null + } + return (
diff --git a/demos/src/Examples/CodeBlockLanguage/React/index.jsx b/demos/src/Examples/CodeBlockLanguage/React/index.jsx index cdb1d35de4..a94b423279 100644 --- a/demos/src/Examples/CodeBlockLanguage/React/index.jsx +++ b/demos/src/Examples/CodeBlockLanguage/React/index.jsx @@ -1,7 +1,3 @@ -// load specific languages only -// import { lowlight } from 'lowlight/lib/core' -// import javascript from 'highlight.js/lib/languages/javascript' -// lowlight.registerLanguage('javascript', javascript) import './styles.scss' import CodeBlockLowlight from '@tiptap/extension-code-block-lowlight' @@ -13,16 +9,21 @@ import css from 'highlight.js/lib/languages/css' import js from 'highlight.js/lib/languages/javascript' import ts from 'highlight.js/lib/languages/typescript' import html from 'highlight.js/lib/languages/xml' -// load all highlight.js languages -import { lowlight } from 'lowlight' +// load all languages with "all" or common languages with "common" +import { all, createLowlight } from 'lowlight' import React from 'react' -import CodeBlockComponent from './CodeBlockComponent.jsx' +// eslint-disable-next-line +import CodeBlockComponent from './CodeBlockComponent' -lowlight.registerLanguage('html', html) -lowlight.registerLanguage('css', css) -lowlight.registerLanguage('js', js) -lowlight.registerLanguage('ts', ts) +// create a lowlight instance +const lowlight = createLowlight(all) + +// you can also register individual languages +lowlight.register('html', html) +lowlight.register('css', css) +lowlight.register('js', js) +lowlight.register('ts', ts) const MenuBar = ({ editor }) => { if (!editor) { @@ -56,7 +57,7 @@ export default () => { ], content: `

- That’s a boring paragraph followed by a fenced code block: + That's a boring paragraph followed by a fenced code block:

for (var i=1; i <= 20; i++)
 {
diff --git a/demos/src/Examples/CodeBlockLanguage/Vue/index.vue b/demos/src/Examples/CodeBlockLanguage/Vue/index.vue
index 6a30301cd0..4846fb30c6 100644
--- a/demos/src/Examples/CodeBlockLanguage/Vue/index.vue
+++ b/demos/src/Examples/CodeBlockLanguage/Vue/index.vue
@@ -21,20 +21,19 @@ import css from 'highlight.js/lib/languages/css'
 import js from 'highlight.js/lib/languages/javascript'
 import ts from 'highlight.js/lib/languages/typescript'
 import html from 'highlight.js/lib/languages/xml'
-// load all highlight.js languages
-import { lowlight } from 'lowlight'
+// load all languages with "all" or common languages with "common"
+import { all, createLowlight } from 'lowlight'
 
 import CodeBlockComponent from './CodeBlockComponent.vue'
 
-lowlight.registerLanguage('html', html)
-lowlight.registerLanguage('css', css)
-lowlight.registerLanguage('js', js)
-lowlight.registerLanguage('ts', ts)
+// create a lowlight instance
+const lowlight = createLowlight(all)
 
-// load specific languages only
-// import { lowlight } from 'lowlight/lib/core'
-// import javascript from 'highlight.js/lib/languages/javascript'
-// lowlight.registerLanguage('javascript', javascript)
+// you can also register languages
+lowlight.register('html', html)
+lowlight.register('css', css)
+lowlight.register('js', js)
+lowlight.register('ts', ts)
 
 export default {
   components: {
@@ -63,7 +62,7 @@ export default {
       ],
       content: `
         

- That’s a boring paragraph followed by a fenced code block: + That's a boring paragraph followed by a fenced code block:

for (var i=1; i <= 20; i++)
 {
diff --git a/demos/src/Examples/InteractivityComponentProvideInject/Vue/Component.vue b/demos/src/Examples/InteractivityComponentProvideInject/Vue/Component.vue
new file mode 100644
index 0000000000..c5268e979b
--- /dev/null
+++ b/demos/src/Examples/InteractivityComponentProvideInject/Vue/Component.vue
@@ -0,0 +1,50 @@
+
+
+
+
+
diff --git a/demos/src/Examples/InteractivityComponentProvideInject/Vue/Editor.vue b/demos/src/Examples/InteractivityComponentProvideInject/Vue/Editor.vue
new file mode 100644
index 0000000000..a3c3d0de94
--- /dev/null
+++ b/demos/src/Examples/InteractivityComponentProvideInject/Vue/Editor.vue
@@ -0,0 +1,144 @@
+
+
+
+
+
diff --git a/demos/src/Examples/InteractivityComponentProvideInject/Vue/Extension.js b/demos/src/Examples/InteractivityComponentProvideInject/Vue/Extension.js
new file mode 100644
index 0000000000..9dede7bb0d
--- /dev/null
+++ b/demos/src/Examples/InteractivityComponentProvideInject/Vue/Extension.js
@@ -0,0 +1,36 @@
+import { mergeAttributes, Node } from '@tiptap/core'
+import { VueNodeViewRenderer } from '@tiptap/vue-3'
+
+import Component from './Component.vue'
+
+export default Node.create({
+  name: 'vueComponent',
+
+  group: 'block',
+
+  atom: true,
+
+  addAttributes() {
+    return {
+      count: {
+        default: 0,
+      },
+    }
+  },
+
+  parseHTML() {
+    return [
+      {
+        tag: 'vue-component',
+      },
+    ]
+  },
+
+  renderHTML({ HTMLAttributes }) {
+    return ['vue-component', mergeAttributes(HTMLAttributes)]
+  },
+
+  addNodeView() {
+    return VueNodeViewRenderer(Component)
+  },
+})
diff --git a/demos/src/Examples/InteractivityComponentProvideInject/Vue/ValidateInject.vue b/demos/src/Examples/InteractivityComponentProvideInject/Vue/ValidateInject.vue
new file mode 100644
index 0000000000..557cc1c18f
--- /dev/null
+++ b/demos/src/Examples/InteractivityComponentProvideInject/Vue/ValidateInject.vue
@@ -0,0 +1,20 @@
+
+
+
+
+
diff --git a/demos/src/Examples/InteractivityComponentProvideInject/Vue/index.html b/demos/src/Examples/InteractivityComponentProvideInject/Vue/index.html
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/demos/src/Examples/InteractivityComponentProvideInject/Vue/index.spec.js b/demos/src/Examples/InteractivityComponentProvideInject/Vue/index.spec.js
new file mode 100644
index 0000000000..8beaf0ea00
--- /dev/null
+++ b/demos/src/Examples/InteractivityComponentProvideInject/Vue/index.spec.js
@@ -0,0 +1,29 @@
+context('/src/Examples/InteractivityComponentProvideInject/Vue/', () => {
+  beforeEach(() => {
+    cy.visit('/src/Examples/InteractivityComponentProvideInject/Vue/')
+  })
+
+  it('should have a working tiptap instance', () => {
+    cy.get('.tiptap').then(([{ editor }]) => {
+      // eslint-disable-next-line
+      expect(editor).to.not.be.null
+    })
+  })
+
+  it('should render a custom node', () => {
+    cy.get('.tiptap .vue-component').should('have.length', 1)
+  })
+
+  it('should have global and all injected values', () => {
+    const expectedTexts = [
+      'globalValue',
+      'appValue',
+      'indexValue',
+      'editorValue',
+    ]
+
+    cy.get('.tiptap .vue-component p').each((p, index) => {
+      cy.wrap(p).should('have.text', expectedTexts[index])
+    })
+  })
+})
diff --git a/demos/src/Examples/InteractivityComponentProvideInject/Vue/index.vue b/demos/src/Examples/InteractivityComponentProvideInject/Vue/index.vue
new file mode 100644
index 0000000000..185226b3ee
--- /dev/null
+++ b/demos/src/Examples/InteractivityComponentProvideInject/Vue/index.vue
@@ -0,0 +1,24 @@
+
+
+
diff --git a/demos/src/Examples/Performance/React/index.jsx b/demos/src/Examples/Performance/React/index.jsx
index 4dce96ff95..827ec69910 100644
--- a/demos/src/Examples/Performance/React/index.jsx
+++ b/demos/src/Examples/Performance/React/index.jsx
@@ -62,7 +62,7 @@ function EditorInstance({ shouldOptimizeRendering }) {
   })
 
   return (
-    <>
+    
Number of renders: {countRenderRef.current}
@@ -89,12 +89,13 @@ function EditorInstance({ shouldOptimizeRendering }) { )} - +
) } const EditorControls = () => { const [shouldOptimizeRendering, setShouldOptimizeRendering] = React.useState(true) + const [rendered, setRendered] = React.useState(true) return ( <> @@ -123,8 +124,9 @@ const EditorControls = () => { Render every transaction (default behavior)
+
- + {rendered && } ) } diff --git a/demos/src/Experiments/All/Vue/index.vue b/demos/src/Experiments/All/Vue/index.vue index cdd835a237..5b1e370f7a 100644 --- a/demos/src/Experiments/All/Vue/index.vue +++ b/demos/src/Experiments/All/Vue/index.vue @@ -108,7 +108,9 @@ import TextAlign from '@tiptap/extension-text-align' import TextStyle from '@tiptap/extension-text-style' import Underline from '@tiptap/extension-underline' import { Editor, EditorContent } from '@tiptap/vue-3' -import { lowlight } from 'lowlight' +import { all, createLowlight } from 'lowlight' + +const lowlight = createLowlight(all) export default { components: { @@ -182,14 +184,14 @@ export default {

  • - That’s a bullet list with one … + That's a bullet list with one …
  • … or two list items.

- Isn’t that great? And all of that is editable. But wait, there’s more. Let’s try a code block: + Isn't that great? And all of that is editable. But wait, there's more. Let's try a code block:

for (var i=1; i <= 20; i++)
 {
@@ -203,10 +205,10 @@ export default {
     console.log(i);
 }

- I know, I know, this is impressive. It’s only the tip of the iceberg though. Give it a try and click a little bit around. Don’t forget to check the other examples too. + I know, I know, this is impressive. It's only the tip of the iceberg though. Give it a try and click a little bit around. Don’t forget to check the other examples too.

- Wow, that’s amazing. Good work, boy! 👏 + Wow, that's amazing. Good work, boy! 👏
— Mom
@@ -214,9 +216,9 @@ export default {

first paragraph

second paragraph

Color

-

Oh, for some reason that’s purple.

+

Oh, for some reason that's purple.

Highlight

-

This isn’t highlighted.

+

This isn't highlighted.

But that one is.

And this is highlighted too, but in a different color.

And this one has a data attribute.

diff --git a/demos/src/GuideContent/ReadOnly/React/index.jsx b/demos/src/GuideContent/ReadOnly/React/index.jsx index 657c33382f..095d3540c1 100644 --- a/demos/src/GuideContent/ReadOnly/React/index.jsx +++ b/demos/src/GuideContent/ReadOnly/React/index.jsx @@ -7,6 +7,7 @@ import React, { useEffect, useState } from 'react' export default () => { const [editable, setEditable] = useState(false) const editor = useEditor({ + shouldRerenderOnTransaction: false, editable, content: `

diff --git a/demos/src/Nodes/CodeBlockLowlight/React/index.jsx b/demos/src/Nodes/CodeBlockLowlight/React/index.jsx index 6a5264f0c1..2f131dd350 100644 --- a/demos/src/Nodes/CodeBlockLowlight/React/index.jsx +++ b/demos/src/Nodes/CodeBlockLowlight/React/index.jsx @@ -1,7 +1,3 @@ -// load specific languages only -// import { lowlight } from 'lowlight/lib/core' -// import javascript from 'highlight.js/lib/languages/javascript' -// lowlight.registerLanguage('javascript', javascript) import './styles.scss' import CodeBlockLowlight from '@tiptap/extension-code-block-lowlight' @@ -13,14 +9,29 @@ import css from 'highlight.js/lib/languages/css' import js from 'highlight.js/lib/languages/javascript' import ts from 'highlight.js/lib/languages/typescript' import html from 'highlight.js/lib/languages/xml' -// load all highlight.js languages -import { lowlight } from 'lowlight' +// load all languages with "all" or common languages with "common" +import { all, createLowlight } from 'lowlight' import React from 'react' -lowlight.registerLanguage('html', html) -lowlight.registerLanguage('css', css) -lowlight.registerLanguage('js', js) -lowlight.registerLanguage('ts', ts) +// create a lowlight instance with all languages loaded +const lowlight = createLowlight(all) + +// This is only an example, all supported languages are already loaded above +// but you can also register only specific languages to reduce bundle-size +lowlight.register('html', html) +lowlight.register('css', css) +lowlight.register('js', js) +lowlight.register('ts', ts) + +/** + * Lowlight version 2.x had a different API + * import { lowlight } from 'lowlight' + * + * lowlight.registerLanguage('html', html) + * lowlight.registerLanguage('css', css) + * lowlight.registerLanguage('js', js) + * lowlight.registerLanguage('ts', ts) + */ export default () => { const editor = useEditor({ @@ -34,7 +45,7 @@ export default () => { ], content: `

- That’s a boring paragraph followed by a fenced code block: + That's a boring paragraph followed by a fenced code block:

for (var i=1; i <= 20; i++)
 {
diff --git a/demos/src/Nodes/CodeBlockLowlight/Vue/index.vue b/demos/src/Nodes/CodeBlockLowlight/Vue/index.vue
index dfd6a3defb..5ee047ec5a 100644
--- a/demos/src/Nodes/CodeBlockLowlight/Vue/index.vue
+++ b/demos/src/Nodes/CodeBlockLowlight/Vue/index.vue
@@ -25,13 +25,17 @@ import css from 'highlight.js/lib/languages/css'
 import js from 'highlight.js/lib/languages/javascript'
 import ts from 'highlight.js/lib/languages/typescript'
 import html from 'highlight.js/lib/languages/xml'
-// load all highlight.js languages
-import { lowlight } from 'lowlight'
+// load all languages with "all" or common languages with "common"
+import { all, createLowlight } from 'lowlight'
 
-lowlight.registerLanguage('html', html)
-lowlight.registerLanguage('css', css)
-lowlight.registerLanguage('js', js)
-lowlight.registerLanguage('ts', ts)
+// create a lowlight instance
+const lowlight = createLowlight(all)
+
+// you can also register languages
+lowlight.register('html', html)
+lowlight.register('css', css)
+lowlight.register('js', js)
+lowlight.register('ts', ts)
 
 export default {
   components: {
@@ -56,7 +60,7 @@ export default {
       ],
       content: `
         

- That’s a boring paragraph followed by a fenced code block: + That's a boring paragraph followed by a fenced code block:

for (var i=1; i <= 20; i++)
 {
diff --git a/package-lock.json b/package-lock.json
index 108a13a46d..119ba5ec56 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -35,6 +35,7 @@
         "eslint-plugin-cypress": "^2.15.2",
         "eslint-plugin-html": "^6.2.0",
         "eslint-plugin-import": "^2.29.1",
+        "eslint-plugin-react-hooks": "4.6.2",
         "eslint-plugin-simple-import-sort": "^7.0.0",
         "eslint-plugin-vue": "^9.27.0",
         "husky": "^8.0.3",
@@ -59,13 +60,13 @@
         "@lexical/react": "^0.11.1",
         "d3": "^7.3.0",
         "fast-glob": "^3.2.11",
-        "highlight.js": "^11.6.0",
+        "highlight.js": "^11.10.0",
         "lexical": "^0.11.1",
-        "lowlight": "^2.7.0",
+        "lowlight": "^3.1.0",
         "remixicon": "^2.5.0",
         "shiki": "^1.10.3",
         "simplify-js": "^1.2.4",
-        "y-prosemirror": "^1.2.9",
+        "y-prosemirror": "^1.2.11",
         "y-webrtc": "^10.3.0",
         "yjs": "^13.6.18"
       },
@@ -115,14 +116,6 @@
         "yjs": "^13.6.8"
       }
     },
-    "demos/node_modules/@types/hast": {
-      "version": "3.0.4",
-      "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz",
-      "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==",
-      "dependencies": {
-        "@types/unist": "*"
-      }
-    },
     "demos/node_modules/@vitejs/plugin-vue": {
       "version": "5.0.5",
       "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.0.5.tgz",
@@ -344,6 +337,14 @@
         "node": ">=8"
       }
     },
+    "demos/node_modules/highlight.js": {
+      "version": "11.10.0",
+      "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.10.0.tgz",
+      "integrity": "sha512-SYVnVFswQER+zu1laSya563s+F8VDGt7o35d4utbamowvUNLLMovFqwCLSocpZTz3MgaSRA1IbqRWZv97dtErQ==",
+      "engines": {
+        "node": ">=12.0.0"
+      }
+    },
     "demos/node_modules/hosted-git-info": {
       "version": "4.1.0",
       "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz",
@@ -790,6 +791,29 @@
         }
       }
     },
+    "demos/node_modules/y-prosemirror": {
+      "version": "1.2.11",
+      "resolved": "https://registry.npmjs.org/y-prosemirror/-/y-prosemirror-1.2.11.tgz",
+      "integrity": "sha512-MUGMYyokOb9DpBRHr4Cadob2KheDCKW2LHceAM2yrWp9dfX+3HZZUNEubEPd4zszq4DF2fGCFhE3N66zOTLoxA==",
+      "dependencies": {
+        "lib0": "^0.2.42"
+      },
+      "engines": {
+        "node": ">=16.0.0",
+        "npm": ">=8.0.0"
+      },
+      "funding": {
+        "type": "GitHub Sponsors ❤",
+        "url": "https://github.com/sponsors/dmonad"
+      },
+      "peerDependencies": {
+        "prosemirror-model": "^1.7.1",
+        "prosemirror-state": "^1.2.3",
+        "prosemirror-view": "^1.9.10",
+        "y-protocols": "^1.0.1",
+        "yjs": "^13.5.38"
+      }
+    },
     "demos/node_modules/yallist": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
@@ -5042,14 +5066,6 @@
         "@types/hast": "^3.0.4"
       }
     },
-    "node_modules/@shikijs/core/node_modules/@types/hast": {
-      "version": "3.0.4",
-      "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz",
-      "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==",
-      "dependencies": {
-        "@types/unist": "*"
-      }
-    },
     "node_modules/@sveltejs/vite-plugin-svelte": {
       "version": "2.5.3",
       "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-2.5.3.tgz",
@@ -5400,11 +5416,11 @@
       "dev": true
     },
     "node_modules/@types/hast": {
-      "version": "2.3.10",
-      "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.10.tgz",
-      "integrity": "sha512-McWspRw8xx8J9HurkVBfYj0xKoE25tOFlHGdx4MJ5xORQrMGZNqJhVQWaIbm6Oyla5kYOXtDiopzKRJzEOkwJw==",
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz",
+      "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==",
       "dependencies": {
-        "@types/unist": "^2"
+        "@types/unist": "*"
       }
     },
     "node_modules/@types/json-schema": {
@@ -8304,6 +8320,14 @@
         "node": ">=0.4.0"
       }
     },
+    "node_modules/dequal": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
+      "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==",
+      "engines": {
+        "node": ">=6"
+      }
+    },
     "node_modules/detect-file": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz",
@@ -8322,6 +8346,18 @@
         "node": ">=8"
       }
     },
+    "node_modules/devlop": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz",
+      "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==",
+      "dependencies": {
+        "dequal": "^2.0.0"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm"
+      }
+    },
     "node_modules/didyoumean": {
       "version": "1.2.2",
       "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz",
@@ -8942,6 +8978,18 @@
         "node": ">=0.10.0"
       }
     },
+    "node_modules/eslint-plugin-react-hooks": {
+      "version": "4.6.2",
+      "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.2.tgz",
+      "integrity": "sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=10"
+      },
+      "peerDependencies": {
+        "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0"
+      }
+    },
     "node_modules/eslint-plugin-simple-import-sort": {
       "version": "7.0.0",
       "resolved": "https://registry.npmjs.org/eslint-plugin-simple-import-sort/-/eslint-plugin-simple-import-sort-7.0.0.tgz",
@@ -9567,18 +9615,6 @@
         "reusify": "^1.0.4"
       }
     },
-    "node_modules/fault": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/fault/-/fault-2.0.1.tgz",
-      "integrity": "sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ==",
-      "dependencies": {
-        "format": "^0.2.0"
-      },
-      "funding": {
-        "type": "github",
-        "url": "https://github.com/sponsors/wooorm"
-      }
-    },
     "node_modules/fd-slicer": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
@@ -9841,14 +9877,6 @@
         "node": ">= 0.12"
       }
     },
-    "node_modules/format": {
-      "version": "0.2.2",
-      "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz",
-      "integrity": "sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==",
-      "engines": {
-        "node": ">=0.4.x"
-      }
-    },
     "node_modules/fraction.js": {
       "version": "4.3.7",
       "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz",
@@ -12362,27 +12390,19 @@
       }
     },
     "node_modules/lowlight": {
-      "version": "2.9.0",
-      "resolved": "https://registry.npmjs.org/lowlight/-/lowlight-2.9.0.tgz",
-      "integrity": "sha512-OpcaUTCLmHuVuBcyNckKfH5B0oA4JUavb/M/8n9iAvanJYNQkrVm4pvyX0SUaqkBG4dnWHKt7p50B3ngAG2Rfw==",
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/lowlight/-/lowlight-3.1.0.tgz",
+      "integrity": "sha512-CEbNVoSikAxwDMDPjXlqlFYiZLkDJHwyGu/MfOsJnF3d7f3tds5J3z8s/l9TMXhzfsJCCJEAsD78842mwmg0PQ==",
       "dependencies": {
-        "@types/hast": "^2.0.0",
-        "fault": "^2.0.0",
-        "highlight.js": "~11.8.0"
+        "@types/hast": "^3.0.0",
+        "devlop": "^1.0.0",
+        "highlight.js": "~11.9.0"
       },
       "funding": {
         "type": "github",
         "url": "https://github.com/sponsors/wooorm"
       }
     },
-    "node_modules/lowlight/node_modules/highlight.js": {
-      "version": "11.8.0",
-      "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.8.0.tgz",
-      "integrity": "sha512-MedQhoqVdr0U6SSnWPzfiadUcDHfN/Wzq25AkXiQv9oiOO/sG0S7XkvpFIqWBl9Yq1UYyYOOVORs5UW2XlPyzg==",
-      "engines": {
-        "node": ">=12.0.0"
-      }
-    },
     "node_modules/lru-cache": {
       "version": "5.1.1",
       "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
@@ -17728,29 +17748,6 @@
         "node": ">=12"
       }
     },
-    "node_modules/y-prosemirror": {
-      "version": "1.2.9",
-      "resolved": "https://registry.npmjs.org/y-prosemirror/-/y-prosemirror-1.2.9.tgz",
-      "integrity": "sha512-fThGIVmSqrqnG/ckywEGlHM9ElfILC4TcMZd5zxWPe/i+UuP97TEr4swsopRKG3Y+KHBVt4Y/5NVBC3AAsUoUg==",
-      "dependencies": {
-        "lib0": "^0.2.42"
-      },
-      "engines": {
-        "node": ">=16.0.0",
-        "npm": ">=8.0.0"
-      },
-      "funding": {
-        "type": "GitHub Sponsors ❤",
-        "url": "https://github.com/sponsors/dmonad"
-      },
-      "peerDependencies": {
-        "prosemirror-model": "^1.7.1",
-        "prosemirror-state": "^1.2.3",
-        "prosemirror-view": "^1.9.10",
-        "y-protocols": "^1.0.1",
-        "yjs": "^13.5.38"
-      }
-    },
     "node_modules/y-protocols": {
       "version": "1.0.6",
       "resolved": "https://registry.npmjs.org/y-protocols/-/y-protocols-1.0.6.tgz",
@@ -17902,785 +17899,836 @@
     },
     "packages/core": {
       "name": "@tiptap/core",
-      "version": "2.5.7",
+      "version": "2.5.8",
       "license": "MIT",
       "devDependencies": {
-        "@tiptap/pm": "^2.5.7"
+        "@tiptap/pm": "^2.5.8"
       },
       "funding": {
         "type": "github",
         "url": "https://github.com/sponsors/ueberdosis"
       },
       "peerDependencies": {
-        "@tiptap/pm": "^2.5.7"
+        "@tiptap/pm": "^2.5.8"
       }
     },
     "packages/extension-blockquote": {
       "name": "@tiptap/extension-blockquote",
-      "version": "2.5.7",
+      "version": "2.5.8",
       "license": "MIT",
       "devDependencies": {
-        "@tiptap/core": "^2.5.7"
+        "@tiptap/core": "^2.5.8"
       },
       "funding": {
         "type": "github",
         "url": "https://github.com/sponsors/ueberdosis"
       },
       "peerDependencies": {
-        "@tiptap/core": "^2.5.7"
+        "@tiptap/core": "^2.5.8"
       }
     },
     "packages/extension-bold": {
       "name": "@tiptap/extension-bold",
-      "version": "2.5.7",
+      "version": "2.5.8",
       "license": "MIT",
       "devDependencies": {
-        "@tiptap/core": "^2.5.7"
+        "@tiptap/core": "^2.5.8"
       },
       "funding": {
         "type": "github",
         "url": "https://github.com/sponsors/ueberdosis"
       },
       "peerDependencies": {
-        "@tiptap/core": "^2.5.7"
+        "@tiptap/core": "^2.5.8"
       }
     },
     "packages/extension-bubble-menu": {
       "name": "@tiptap/extension-bubble-menu",
-      "version": "2.5.7",
+      "version": "2.5.8",
       "license": "MIT",
       "dependencies": {
         "tippy.js": "^6.3.7"
       },
       "devDependencies": {
-        "@tiptap/core": "^2.5.7",
-        "@tiptap/pm": "^2.5.7"
+        "@tiptap/core": "^2.5.8",
+        "@tiptap/pm": "^2.5.8"
       },
       "funding": {
         "type": "github",
         "url": "https://github.com/sponsors/ueberdosis"
       },
       "peerDependencies": {
-        "@tiptap/core": "^2.5.7",
-        "@tiptap/pm": "^2.5.7"
+        "@tiptap/core": "^2.5.8",
+        "@tiptap/pm": "^2.5.8"
       }
     },
     "packages/extension-bullet-list": {
       "name": "@tiptap/extension-bullet-list",
-      "version": "2.5.7",
+      "version": "2.5.8",
       "license": "MIT",
       "devDependencies": {
-        "@tiptap/core": "^2.5.7"
+        "@tiptap/core": "^2.5.8"
       },
       "funding": {
         "type": "github",
         "url": "https://github.com/sponsors/ueberdosis"
       },
       "peerDependencies": {
-        "@tiptap/core": "^2.5.7"
+        "@tiptap/core": "^2.5.8"
       }
     },
     "packages/extension-character-count": {
       "name": "@tiptap/extension-character-count",
-      "version": "2.5.7",
+      "version": "2.5.8",
       "license": "MIT",
       "devDependencies": {
-        "@tiptap/core": "^2.5.7",
-        "@tiptap/pm": "^2.5.7"
+        "@tiptap/core": "^2.5.8",
+        "@tiptap/pm": "^2.5.8"
       },
       "funding": {
         "type": "github",
         "url": "https://github.com/sponsors/ueberdosis"
       },
       "peerDependencies": {
-        "@tiptap/core": "^2.5.7",
-        "@tiptap/pm": "^2.5.7"
+        "@tiptap/core": "^2.5.8",
+        "@tiptap/pm": "^2.5.8"
       }
     },
     "packages/extension-code": {
       "name": "@tiptap/extension-code",
-      "version": "2.5.7",
+      "version": "2.5.8",
       "license": "MIT",
       "devDependencies": {
-        "@tiptap/core": "^2.5.7"
+        "@tiptap/core": "^2.5.8"
       },
       "funding": {
         "type": "github",
         "url": "https://github.com/sponsors/ueberdosis"
       },
       "peerDependencies": {
-        "@tiptap/core": "^2.5.7"
+        "@tiptap/core": "^2.5.8"
       }
     },
     "packages/extension-code-block": {
       "name": "@tiptap/extension-code-block",
-      "version": "2.5.7",
+      "version": "2.5.8",
       "license": "MIT",
       "devDependencies": {
-        "@tiptap/core": "^2.5.7",
-        "@tiptap/pm": "^2.5.7"
+        "@tiptap/core": "^2.5.8",
+        "@tiptap/pm": "^2.5.8"
       },
       "funding": {
         "type": "github",
         "url": "https://github.com/sponsors/ueberdosis"
       },
       "peerDependencies": {
-        "@tiptap/core": "^2.5.7",
-        "@tiptap/pm": "^2.5.7"
+        "@tiptap/core": "^2.5.8",
+        "@tiptap/pm": "^2.5.8"
       }
     },
     "packages/extension-code-block-lowlight": {
       "name": "@tiptap/extension-code-block-lowlight",
-      "version": "2.5.7",
+      "version": "2.5.8",
       "license": "MIT",
       "devDependencies": {
-        "@tiptap/core": "^2.5.7",
-        "@tiptap/extension-code-block": "^2.5.7",
-        "@tiptap/pm": "^2.5.7"
+        "@tiptap/core": "^2.5.8",
+        "@tiptap/extension-code-block": "^2.5.8",
+        "@tiptap/pm": "^2.5.8",
+        "lowlight": "^2 || ^3"
       },
       "funding": {
         "type": "github",
         "url": "https://github.com/sponsors/ueberdosis"
       },
       "peerDependencies": {
-        "@tiptap/core": "^2.5.7",
-        "@tiptap/extension-code-block": "^2.5.7",
-        "@tiptap/pm": "^2.5.7"
+        "@tiptap/core": "^2.5.8",
+        "@tiptap/extension-code-block": "^2.5.8",
+        "@tiptap/pm": "^2.5.8",
+        "highlight.js": "^11",
+        "lowlight": "^2 || ^3"
       }
     },
     "packages/extension-collaboration": {
       "name": "@tiptap/extension-collaboration",
-      "version": "2.5.7",
+      "version": "2.5.8",
       "license": "MIT",
       "devDependencies": {
-        "@tiptap/core": "^2.5.7",
-        "@tiptap/pm": "^2.5.7",
-        "y-prosemirror": "^1.2.9"
+        "@tiptap/core": "^2.5.8",
+        "@tiptap/pm": "^2.5.8",
+        "y-prosemirror": "^1.2.11"
       },
       "funding": {
         "type": "github",
         "url": "https://github.com/sponsors/ueberdosis"
       },
       "peerDependencies": {
-        "@tiptap/core": "^2.5.7",
-        "@tiptap/pm": "^2.5.7",
-        "y-prosemirror": "^1.2.6"
+        "@tiptap/core": "^2.5.8",
+        "@tiptap/pm": "^2.5.8",
+        "y-prosemirror": "^1.2.11"
       }
     },
     "packages/extension-collaboration-cursor": {
       "name": "@tiptap/extension-collaboration-cursor",
-      "version": "2.5.7",
+      "version": "2.5.8",
       "license": "MIT",
       "devDependencies": {
-        "@tiptap/core": "^2.5.7",
-        "y-prosemirror": "^1.2.9"
+        "@tiptap/core": "^2.5.8",
+        "y-prosemirror": "^1.2.11"
       },
       "funding": {
         "type": "github",
         "url": "https://github.com/sponsors/ueberdosis"
       },
       "peerDependencies": {
-        "@tiptap/core": "^2.5.7",
-        "y-prosemirror": "^1.2.6"
+        "@tiptap/core": "^2.5.8",
+        "y-prosemirror": "^1.2.11"
+      }
+    },
+    "packages/extension-collaboration-cursor/node_modules/y-prosemirror": {
+      "version": "1.2.11",
+      "resolved": "https://registry.npmjs.org/y-prosemirror/-/y-prosemirror-1.2.11.tgz",
+      "integrity": "sha512-MUGMYyokOb9DpBRHr4Cadob2KheDCKW2LHceAM2yrWp9dfX+3HZZUNEubEPd4zszq4DF2fGCFhE3N66zOTLoxA==",
+      "dev": true,
+      "dependencies": {
+        "lib0": "^0.2.42"
+      },
+      "engines": {
+        "node": ">=16.0.0",
+        "npm": ">=8.0.0"
+      },
+      "funding": {
+        "type": "GitHub Sponsors ❤",
+        "url": "https://github.com/sponsors/dmonad"
+      },
+      "peerDependencies": {
+        "prosemirror-model": "^1.7.1",
+        "prosemirror-state": "^1.2.3",
+        "prosemirror-view": "^1.9.10",
+        "y-protocols": "^1.0.1",
+        "yjs": "^13.5.38"
+      }
+    },
+    "packages/extension-collaboration/node_modules/y-prosemirror": {
+      "version": "1.2.11",
+      "resolved": "https://registry.npmjs.org/y-prosemirror/-/y-prosemirror-1.2.11.tgz",
+      "integrity": "sha512-MUGMYyokOb9DpBRHr4Cadob2KheDCKW2LHceAM2yrWp9dfX+3HZZUNEubEPd4zszq4DF2fGCFhE3N66zOTLoxA==",
+      "dev": true,
+      "dependencies": {
+        "lib0": "^0.2.42"
+      },
+      "engines": {
+        "node": ">=16.0.0",
+        "npm": ">=8.0.0"
+      },
+      "funding": {
+        "type": "GitHub Sponsors ❤",
+        "url": "https://github.com/sponsors/dmonad"
+      },
+      "peerDependencies": {
+        "prosemirror-model": "^1.7.1",
+        "prosemirror-state": "^1.2.3",
+        "prosemirror-view": "^1.9.10",
+        "y-protocols": "^1.0.1",
+        "yjs": "^13.5.38"
       }
     },
     "packages/extension-color": {
       "name": "@tiptap/extension-color",
-      "version": "2.5.7",
+      "version": "2.5.8",
       "license": "MIT",
       "devDependencies": {
-        "@tiptap/core": "^2.5.7",
-        "@tiptap/extension-text-style": "^2.5.7"
+        "@tiptap/core": "^2.5.8",
+        "@tiptap/extension-text-style": "^2.5.8"
       },
       "funding": {
         "type": "github",
         "url": "https://github.com/sponsors/ueberdosis"
       },
       "peerDependencies": {
-        "@tiptap/core": "^2.5.7",
-        "@tiptap/extension-text-style": "^2.5.7"
+        "@tiptap/core": "^2.5.8",
+        "@tiptap/extension-text-style": "^2.5.8"
       }
     },
     "packages/extension-document": {
       "name": "@tiptap/extension-document",
-      "version": "2.5.7",
+      "version": "2.5.8",
       "license": "MIT",
       "devDependencies": {
-        "@tiptap/core": "^2.5.7"
+        "@tiptap/core": "^2.5.8"
       },
       "funding": {
         "type": "github",
         "url": "https://github.com/sponsors/ueberdosis"
       },
       "peerDependencies": {
-        "@tiptap/core": "^2.5.7"
+        "@tiptap/core": "^2.5.8"
       }
     },
     "packages/extension-dropcursor": {
       "name": "@tiptap/extension-dropcursor",
-      "version": "2.5.7",
+      "version": "2.5.8",
       "license": "MIT",
       "devDependencies": {
-        "@tiptap/core": "^2.5.7",
-        "@tiptap/pm": "^2.5.7"
+        "@tiptap/core": "^2.5.8",
+        "@tiptap/pm": "^2.5.8"
       },
       "funding": {
         "type": "github",
         "url": "https://github.com/sponsors/ueberdosis"
       },
       "peerDependencies": {
-        "@tiptap/core": "^2.5.7",
-        "@tiptap/pm": "^2.5.7"
+        "@tiptap/core": "^2.5.8",
+        "@tiptap/pm": "^2.5.8"
       }
     },
     "packages/extension-floating-menu": {
       "name": "@tiptap/extension-floating-menu",
-      "version": "2.5.7",
+      "version": "2.5.8",
       "license": "MIT",
       "dependencies": {
         "tippy.js": "^6.3.7"
       },
       "devDependencies": {
-        "@tiptap/core": "^2.5.7",
-        "@tiptap/pm": "^2.5.7"
+        "@tiptap/core": "^2.5.8",
+        "@tiptap/pm": "^2.5.8"
       },
       "funding": {
         "type": "github",
         "url": "https://github.com/sponsors/ueberdosis"
       },
       "peerDependencies": {
-        "@tiptap/core": "^2.5.7",
-        "@tiptap/pm": "^2.5.7"
+        "@tiptap/core": "^2.5.8",
+        "@tiptap/pm": "^2.5.8"
       }
     },
     "packages/extension-focus": {
       "name": "@tiptap/extension-focus",
-      "version": "2.5.7",
+      "version": "2.5.8",
       "license": "MIT",
       "devDependencies": {
-        "@tiptap/core": "^2.5.7",
-        "@tiptap/pm": "^2.5.7"
+        "@tiptap/core": "^2.5.8",
+        "@tiptap/pm": "^2.5.8"
       },
       "funding": {
         "type": "github",
         "url": "https://github.com/sponsors/ueberdosis"
       },
       "peerDependencies": {
-        "@tiptap/core": "^2.5.7",
-        "@tiptap/pm": "^2.5.7"
+        "@tiptap/core": "^2.5.8",
+        "@tiptap/pm": "^2.5.8"
       }
     },
     "packages/extension-font-family": {
       "name": "@tiptap/extension-font-family",
-      "version": "2.5.7",
+      "version": "2.5.8",
       "license": "MIT",
       "devDependencies": {
-        "@tiptap/core": "^2.5.7",
-        "@tiptap/extension-text-style": "^2.5.7"
+        "@tiptap/core": "^2.5.8",
+        "@tiptap/extension-text-style": "^2.5.8"
       },
       "funding": {
         "type": "github",
         "url": "https://github.com/sponsors/ueberdosis"
       },
       "peerDependencies": {
-        "@tiptap/core": "^2.5.7",
-        "@tiptap/extension-text-style": "^2.5.7"
+        "@tiptap/core": "^2.5.8",
+        "@tiptap/extension-text-style": "^2.5.8"
       }
     },
     "packages/extension-gapcursor": {
       "name": "@tiptap/extension-gapcursor",
-      "version": "2.5.7",
+      "version": "2.5.8",
       "license": "MIT",
       "devDependencies": {
-        "@tiptap/core": "^2.5.7",
-        "@tiptap/pm": "^2.5.7"
+        "@tiptap/core": "^2.5.8",
+        "@tiptap/pm": "^2.5.8"
       },
       "funding": {
         "type": "github",
         "url": "https://github.com/sponsors/ueberdosis"
       },
       "peerDependencies": {
-        "@tiptap/core": "^2.5.7",
-        "@tiptap/pm": "^2.5.7"
+        "@tiptap/core": "^2.5.8",
+        "@tiptap/pm": "^2.5.8"
       }
     },
     "packages/extension-hard-break": {
       "name": "@tiptap/extension-hard-break",
-      "version": "2.5.7",
+      "version": "2.5.8",
       "license": "MIT",
       "devDependencies": {
-        "@tiptap/core": "^2.5.7"
+        "@tiptap/core": "^2.5.8"
       },
       "funding": {
         "type": "github",
         "url": "https://github.com/sponsors/ueberdosis"
       },
       "peerDependencies": {
-        "@tiptap/core": "^2.5.7"
+        "@tiptap/core": "^2.5.8"
       }
     },
     "packages/extension-heading": {
       "name": "@tiptap/extension-heading",
-      "version": "2.5.7",
+      "version": "2.5.8",
       "license": "MIT",
       "devDependencies": {
-        "@tiptap/core": "^2.5.7"
+        "@tiptap/core": "^2.5.8"
       },
       "funding": {
         "type": "github",
         "url": "https://github.com/sponsors/ueberdosis"
       },
       "peerDependencies": {
-        "@tiptap/core": "^2.5.7"
+        "@tiptap/core": "^2.5.8"
       }
     },
     "packages/extension-highlight": {
       "name": "@tiptap/extension-highlight",
-      "version": "2.5.7",
+      "version": "2.5.8",
       "license": "MIT",
       "devDependencies": {
-        "@tiptap/core": "^2.5.7"
+        "@tiptap/core": "^2.5.8"
       },
       "funding": {
         "type": "github",
         "url": "https://github.com/sponsors/ueberdosis"
       },
       "peerDependencies": {
-        "@tiptap/core": "^2.5.7"
+        "@tiptap/core": "^2.5.8"
       }
     },
     "packages/extension-history": {
       "name": "@tiptap/extension-history",
-      "version": "2.5.7",
+      "version": "2.5.8",
       "license": "MIT",
       "devDependencies": {
-        "@tiptap/core": "^2.5.7",
-        "@tiptap/pm": "^2.5.7"
+        "@tiptap/core": "^2.5.8",
+        "@tiptap/pm": "^2.5.8"
       },
       "funding": {
         "type": "github",
         "url": "https://github.com/sponsors/ueberdosis"
       },
       "peerDependencies": {
-        "@tiptap/core": "^2.5.7",
-        "@tiptap/pm": "^2.5.7"
+        "@tiptap/core": "^2.5.8",
+        "@tiptap/pm": "^2.5.8"
       }
     },
     "packages/extension-horizontal-rule": {
       "name": "@tiptap/extension-horizontal-rule",
-      "version": "2.5.7",
+      "version": "2.5.8",
       "license": "MIT",
       "devDependencies": {
-        "@tiptap/core": "^2.5.7",
-        "@tiptap/pm": "^2.5.7"
+        "@tiptap/core": "^2.5.8",
+        "@tiptap/pm": "^2.5.8"
       },
       "funding": {
         "type": "github",
         "url": "https://github.com/sponsors/ueberdosis"
       },
       "peerDependencies": {
-        "@tiptap/core": "^2.5.7",
-        "@tiptap/pm": "^2.5.7"
+        "@tiptap/core": "^2.5.8",
+        "@tiptap/pm": "^2.5.8"
       }
     },
     "packages/extension-image": {
       "name": "@tiptap/extension-image",
-      "version": "2.5.7",
+      "version": "2.5.8",
       "license": "MIT",
       "devDependencies": {
-        "@tiptap/core": "^2.5.7"
+        "@tiptap/core": "^2.5.8"
       },
       "funding": {
         "type": "github",
         "url": "https://github.com/sponsors/ueberdosis"
       },
       "peerDependencies": {
-        "@tiptap/core": "^2.5.7"
+        "@tiptap/core": "^2.5.8"
       }
     },
     "packages/extension-italic": {
       "name": "@tiptap/extension-italic",
-      "version": "2.5.7",
+      "version": "2.5.8",
       "license": "MIT",
       "devDependencies": {
-        "@tiptap/core": "^2.5.7"
+        "@tiptap/core": "^2.5.8"
       },
       "funding": {
         "type": "github",
         "url": "https://github.com/sponsors/ueberdosis"
       },
       "peerDependencies": {
-        "@tiptap/core": "^2.5.7"
+        "@tiptap/core": "^2.5.8"
       }
     },
     "packages/extension-link": {
       "name": "@tiptap/extension-link",
-      "version": "2.5.7",
+      "version": "2.5.8",
       "license": "MIT",
       "dependencies": {
         "linkifyjs": "^4.1.0"
       },
       "devDependencies": {
-        "@tiptap/core": "^2.5.7",
-        "@tiptap/pm": "^2.5.7"
+        "@tiptap/core": "^2.5.8",
+        "@tiptap/pm": "^2.5.8"
       },
       "funding": {
         "type": "github",
         "url": "https://github.com/sponsors/ueberdosis"
       },
       "peerDependencies": {
-        "@tiptap/core": "^2.5.7",
-        "@tiptap/pm": "^2.5.7"
+        "@tiptap/core": "^2.5.8",
+        "@tiptap/pm": "^2.5.8"
       }
     },
     "packages/extension-list-item": {
       "name": "@tiptap/extension-list-item",
-      "version": "2.5.7",
+      "version": "2.5.8",
       "license": "MIT",
       "devDependencies": {
-        "@tiptap/core": "^2.5.7"
+        "@tiptap/core": "^2.5.8"
       },
       "funding": {
         "type": "github",
         "url": "https://github.com/sponsors/ueberdosis"
       },
       "peerDependencies": {
-        "@tiptap/core": "^2.5.7"
+        "@tiptap/core": "^2.5.8"
       }
     },
     "packages/extension-list-keymap": {
       "name": "@tiptap/extension-list-keymap",
-      "version": "2.5.7",
+      "version": "2.5.8",
       "license": "MIT",
       "devDependencies": {
-        "@tiptap/core": "^2.5.7"
+        "@tiptap/core": "^2.5.8"
       },
       "funding": {
         "type": "github",
         "url": "https://github.com/sponsors/ueberdosis"
       },
       "peerDependencies": {
-        "@tiptap/core": "^2.5.7"
+        "@tiptap/core": "^2.5.8"
       }
     },
     "packages/extension-mention": {
       "name": "@tiptap/extension-mention",
-      "version": "2.5.7",
+      "version": "2.5.8",
       "license": "MIT",
       "devDependencies": {
-        "@tiptap/core": "^2.5.7",
-        "@tiptap/pm": "^2.5.7",
-        "@tiptap/suggestion": "^2.5.7"
+        "@tiptap/core": "^2.5.8",
+        "@tiptap/pm": "^2.5.8",
+        "@tiptap/suggestion": "^2.5.8"
       },
       "funding": {
         "type": "github",
         "url": "https://github.com/sponsors/ueberdosis"
       },
       "peerDependencies": {
-        "@tiptap/core": "^2.5.7",
-        "@tiptap/pm": "^2.5.7",
-        "@tiptap/suggestion": "^2.5.7"
+        "@tiptap/core": "^2.5.8",
+        "@tiptap/pm": "^2.5.8",
+        "@tiptap/suggestion": "^2.5.8"
       }
     },
     "packages/extension-ordered-list": {
       "name": "@tiptap/extension-ordered-list",
-      "version": "2.5.7",
+      "version": "2.5.8",
       "license": "MIT",
       "devDependencies": {
-        "@tiptap/core": "^2.5.7"
+        "@tiptap/core": "^2.5.8"
       },
       "funding": {
         "type": "github",
         "url": "https://github.com/sponsors/ueberdosis"
       },
       "peerDependencies": {
-        "@tiptap/core": "^2.5.7"
+        "@tiptap/core": "^2.5.8"
       }
     },
     "packages/extension-paragraph": {
       "name": "@tiptap/extension-paragraph",
-      "version": "2.5.7",
+      "version": "2.5.8",
       "license": "MIT",
       "devDependencies": {
-        "@tiptap/core": "^2.5.7"
+        "@tiptap/core": "^2.5.8"
       },
       "funding": {
         "type": "github",
         "url": "https://github.com/sponsors/ueberdosis"
       },
       "peerDependencies": {
-        "@tiptap/core": "^2.5.7"
+        "@tiptap/core": "^2.5.8"
       }
     },
     "packages/extension-placeholder": {
       "name": "@tiptap/extension-placeholder",
-      "version": "2.5.7",
+      "version": "2.5.8",
       "license": "MIT",
       "devDependencies": {
-        "@tiptap/core": "^2.5.7",
-        "@tiptap/pm": "^2.5.7"
+        "@tiptap/core": "^2.5.8",
+        "@tiptap/pm": "^2.5.8"
       },
       "funding": {
         "type": "github",
         "url": "https://github.com/sponsors/ueberdosis"
       },
       "peerDependencies": {
-        "@tiptap/core": "^2.5.7",
-        "@tiptap/pm": "^2.5.7"
+        "@tiptap/core": "^2.5.8",
+        "@tiptap/pm": "^2.5.8"
       }
     },
     "packages/extension-strike": {
       "name": "@tiptap/extension-strike",
-      "version": "2.5.7",
+      "version": "2.5.8",
       "license": "MIT",
       "devDependencies": {
-        "@tiptap/core": "^2.5.7"
+        "@tiptap/core": "^2.5.8"
       },
       "funding": {
         "type": "github",
         "url": "https://github.com/sponsors/ueberdosis"
       },
       "peerDependencies": {
-        "@tiptap/core": "^2.5.7"
+        "@tiptap/core": "^2.5.8"
       }
     },
     "packages/extension-subscript": {
       "name": "@tiptap/extension-subscript",
-      "version": "2.5.7",
+      "version": "2.5.8",
       "license": "MIT",
       "devDependencies": {
-        "@tiptap/core": "^2.5.7"
+        "@tiptap/core": "^2.5.8"
       },
       "funding": {
         "type": "github",
         "url": "https://github.com/sponsors/ueberdosis"
       },
       "peerDependencies": {
-        "@tiptap/core": "^2.5.7"
+        "@tiptap/core": "^2.5.8"
       }
     },
     "packages/extension-superscript": {
       "name": "@tiptap/extension-superscript",
-      "version": "2.5.7",
+      "version": "2.5.8",
       "license": "MIT",
       "devDependencies": {
-        "@tiptap/core": "^2.5.7"
+        "@tiptap/core": "^2.5.8"
       },
       "funding": {
         "type": "github",
         "url": "https://github.com/sponsors/ueberdosis"
       },
       "peerDependencies": {
-        "@tiptap/core": "^2.5.7"
+        "@tiptap/core": "^2.5.8"
       }
     },
     "packages/extension-table": {
       "name": "@tiptap/extension-table",
-      "version": "2.5.7",
+      "version": "2.5.8",
       "license": "MIT",
       "devDependencies": {
-        "@tiptap/core": "^2.5.7",
-        "@tiptap/pm": "^2.5.7"
+        "@tiptap/core": "^2.5.8",
+        "@tiptap/pm": "^2.5.8"
       },
       "funding": {
         "type": "github",
         "url": "https://github.com/sponsors/ueberdosis"
       },
       "peerDependencies": {
-        "@tiptap/core": "^2.5.7",
-        "@tiptap/pm": "^2.5.7"
+        "@tiptap/core": "^2.5.8",
+        "@tiptap/pm": "^2.5.8"
       }
     },
     "packages/extension-table-cell": {
       "name": "@tiptap/extension-table-cell",
-      "version": "2.5.7",
+      "version": "2.5.8",
       "license": "MIT",
       "devDependencies": {
-        "@tiptap/core": "^2.5.7"
+        "@tiptap/core": "^2.5.8"
       },
       "funding": {
         "type": "github",
         "url": "https://github.com/sponsors/ueberdosis"
       },
       "peerDependencies": {
-        "@tiptap/core": "^2.5.7"
+        "@tiptap/core": "^2.5.8"
       }
     },
     "packages/extension-table-header": {
       "name": "@tiptap/extension-table-header",
-      "version": "2.5.7",
+      "version": "2.5.8",
       "license": "MIT",
       "devDependencies": {
-        "@tiptap/core": "^2.5.7"
+        "@tiptap/core": "^2.5.8"
       },
       "funding": {
         "type": "github",
         "url": "https://github.com/sponsors/ueberdosis"
       },
       "peerDependencies": {
-        "@tiptap/core": "^2.5.7"
+        "@tiptap/core": "^2.5.8"
       }
     },
     "packages/extension-table-row": {
       "name": "@tiptap/extension-table-row",
-      "version": "2.5.7",
+      "version": "2.5.8",
       "license": "MIT",
       "devDependencies": {
-        "@tiptap/core": "^2.5.7"
+        "@tiptap/core": "^2.5.8"
       },
       "funding": {
         "type": "github",
         "url": "https://github.com/sponsors/ueberdosis"
       },
       "peerDependencies": {
-        "@tiptap/core": "^2.5.7"
+        "@tiptap/core": "^2.5.8"
       }
     },
     "packages/extension-task-item": {
       "name": "@tiptap/extension-task-item",
-      "version": "2.5.7",
+      "version": "2.5.8",
       "license": "MIT",
       "devDependencies": {
-        "@tiptap/core": "^2.5.7",
-        "@tiptap/pm": "^2.5.7"
+        "@tiptap/core": "^2.5.8",
+        "@tiptap/pm": "^2.5.8"
       },
       "funding": {
         "type": "github",
         "url": "https://github.com/sponsors/ueberdosis"
       },
       "peerDependencies": {
-        "@tiptap/core": "^2.5.7",
-        "@tiptap/pm": "^2.5.7"
+        "@tiptap/core": "^2.5.8",
+        "@tiptap/pm": "^2.5.8"
       }
     },
     "packages/extension-task-list": {
       "name": "@tiptap/extension-task-list",
-      "version": "2.5.7",
+      "version": "2.5.8",
       "license": "MIT",
       "devDependencies": {
-        "@tiptap/core": "^2.5.7"
+        "@tiptap/core": "^2.5.8"
       },
       "funding": {
         "type": "github",
         "url": "https://github.com/sponsors/ueberdosis"
       },
       "peerDependencies": {
-        "@tiptap/core": "^2.5.7"
+        "@tiptap/core": "^2.5.8"
       }
     },
     "packages/extension-text": {
       "name": "@tiptap/extension-text",
-      "version": "2.5.7",
+      "version": "2.5.8",
       "license": "MIT",
       "devDependencies": {
-        "@tiptap/core": "^2.5.7"
+        "@tiptap/core": "^2.5.8"
       },
       "funding": {
         "type": "github",
         "url": "https://github.com/sponsors/ueberdosis"
       },
       "peerDependencies": {
-        "@tiptap/core": "^2.5.7"
+        "@tiptap/core": "^2.5.8"
       }
     },
     "packages/extension-text-align": {
       "name": "@tiptap/extension-text-align",
-      "version": "2.5.7",
+      "version": "2.5.8",
       "license": "MIT",
       "devDependencies": {
-        "@tiptap/core": "^2.5.7"
+        "@tiptap/core": "^2.5.8"
       },
       "funding": {
         "type": "github",
         "url": "https://github.com/sponsors/ueberdosis"
       },
       "peerDependencies": {
-        "@tiptap/core": "^2.5.7"
+        "@tiptap/core": "^2.5.8"
       }
     },
     "packages/extension-text-style": {
       "name": "@tiptap/extension-text-style",
-      "version": "2.5.7",
+      "version": "2.5.8",
       "license": "MIT",
       "devDependencies": {
-        "@tiptap/core": "^2.5.7"
+        "@tiptap/core": "^2.5.8"
       },
       "funding": {
         "type": "github",
         "url": "https://github.com/sponsors/ueberdosis"
       },
       "peerDependencies": {
-        "@tiptap/core": "^2.5.7"
+        "@tiptap/core": "^2.5.8"
       }
     },
     "packages/extension-typography": {
       "name": "@tiptap/extension-typography",
-      "version": "2.5.7",
+      "version": "2.5.8",
       "license": "MIT",
       "devDependencies": {
-        "@tiptap/core": "^2.5.7"
+        "@tiptap/core": "^2.5.8"
       },
       "funding": {
         "type": "github",
         "url": "https://github.com/sponsors/ueberdosis"
       },
       "peerDependencies": {
-        "@tiptap/core": "^2.5.7"
+        "@tiptap/core": "^2.5.8"
       }
     },
     "packages/extension-underline": {
       "name": "@tiptap/extension-underline",
-      "version": "2.5.7",
+      "version": "2.5.8",
       "license": "MIT",
       "devDependencies": {
-        "@tiptap/core": "^2.5.7"
+        "@tiptap/core": "^2.5.8"
       },
       "funding": {
         "type": "github",
         "url": "https://github.com/sponsors/ueberdosis"
       },
       "peerDependencies": {
-        "@tiptap/core": "^2.5.7"
+        "@tiptap/core": "^2.5.8"
       }
     },
     "packages/extension-youtube": {
       "name": "@tiptap/extension-youtube",
-      "version": "2.5.7",
+      "version": "2.5.8",
       "license": "MIT",
       "devDependencies": {
-        "@tiptap/core": "^2.5.7"
+        "@tiptap/core": "^2.5.8"
       },
       "funding": {
         "type": "github",
         "url": "https://github.com/sponsors/ueberdosis"
       },
       "peerDependencies": {
-        "@tiptap/core": "^2.5.7"
+        "@tiptap/core": "^2.5.8"
       }
     },
     "packages/html": {
       "name": "@tiptap/html",
-      "version": "2.5.7",
+      "version": "2.5.8",
       "license": "MIT",
       "dependencies": {
         "zeed-dom": "^0.10.9"
       },
       "devDependencies": {
-        "@tiptap/core": "^2.5.7",
-        "@tiptap/pm": "^2.5.7"
+        "@tiptap/core": "^2.5.8",
+        "@tiptap/pm": "^2.5.8"
       },
       "funding": {
         "type": "github",
         "url": "https://github.com/sponsors/ueberdosis"
       },
       "peerDependencies": {
-        "@tiptap/core": "^2.5.7",
-        "@tiptap/pm": "^2.5.7"
+        "@tiptap/core": "^2.5.8",
+        "@tiptap/pm": "^2.5.8"
       }
     },
     "packages/pm": {
       "name": "@tiptap/pm",
-      "version": "2.5.7",
+      "version": "2.5.8",
       "license": "MIT",
       "dependencies": {
         "prosemirror-changeset": "^2.2.1",
@@ -18709,17 +18757,17 @@
     },
     "packages/react": {
       "name": "@tiptap/react",
-      "version": "2.5.7",
+      "version": "2.5.8",
       "license": "MIT",
       "dependencies": {
-        "@tiptap/extension-bubble-menu": "^2.5.7",
-        "@tiptap/extension-floating-menu": "^2.5.7",
+        "@tiptap/extension-bubble-menu": "^2.5.8",
+        "@tiptap/extension-floating-menu": "^2.5.8",
         "@types/use-sync-external-store": "^0.0.6",
         "use-sync-external-store": "^1.2.2"
       },
       "devDependencies": {
-        "@tiptap/core": "^2.5.7",
-        "@tiptap/pm": "^2.5.7",
+        "@tiptap/core": "^2.5.8",
+        "@tiptap/pm": "^2.5.8",
         "@types/react": "^18.2.14",
         "@types/react-dom": "^18.2.6",
         "react": "^18.0.0",
@@ -18730,36 +18778,36 @@
         "url": "https://github.com/sponsors/ueberdosis"
       },
       "peerDependencies": {
-        "@tiptap/core": "^2.5.7",
-        "@tiptap/pm": "^2.5.7",
+        "@tiptap/core": "^2.5.8",
+        "@tiptap/pm": "^2.5.8",
         "react": "^17.0.0 || ^18.0.0",
         "react-dom": "^17.0.0 || ^18.0.0"
       }
     },
     "packages/starter-kit": {
       "name": "@tiptap/starter-kit",
-      "version": "2.5.7",
+      "version": "2.5.8",
       "license": "MIT",
       "dependencies": {
-        "@tiptap/core": "^2.5.7",
-        "@tiptap/extension-blockquote": "^2.5.7",
-        "@tiptap/extension-bold": "^2.5.7",
-        "@tiptap/extension-bullet-list": "^2.5.7",
-        "@tiptap/extension-code": "^2.5.7",
-        "@tiptap/extension-code-block": "^2.5.7",
-        "@tiptap/extension-document": "^2.5.7",
-        "@tiptap/extension-dropcursor": "^2.5.7",
-        "@tiptap/extension-gapcursor": "^2.5.7",
-        "@tiptap/extension-hard-break": "^2.5.7",
-        "@tiptap/extension-heading": "^2.5.7",
-        "@tiptap/extension-history": "^2.5.7",
-        "@tiptap/extension-horizontal-rule": "^2.5.7",
-        "@tiptap/extension-italic": "^2.5.7",
-        "@tiptap/extension-list-item": "^2.5.7",
-        "@tiptap/extension-ordered-list": "^2.5.7",
-        "@tiptap/extension-paragraph": "^2.5.7",
-        "@tiptap/extension-strike": "^2.5.7",
-        "@tiptap/extension-text": "^2.5.7"
+        "@tiptap/core": "^2.5.8",
+        "@tiptap/extension-blockquote": "^2.5.8",
+        "@tiptap/extension-bold": "^2.5.8",
+        "@tiptap/extension-bullet-list": "^2.5.8",
+        "@tiptap/extension-code": "^2.5.8",
+        "@tiptap/extension-code-block": "^2.5.8",
+        "@tiptap/extension-document": "^2.5.8",
+        "@tiptap/extension-dropcursor": "^2.5.8",
+        "@tiptap/extension-gapcursor": "^2.5.8",
+        "@tiptap/extension-hard-break": "^2.5.8",
+        "@tiptap/extension-heading": "^2.5.8",
+        "@tiptap/extension-history": "^2.5.8",
+        "@tiptap/extension-horizontal-rule": "^2.5.8",
+        "@tiptap/extension-italic": "^2.5.8",
+        "@tiptap/extension-list-item": "^2.5.8",
+        "@tiptap/extension-ordered-list": "^2.5.8",
+        "@tiptap/extension-paragraph": "^2.5.8",
+        "@tiptap/extension-strike": "^2.5.8",
+        "@tiptap/extension-text": "^2.5.8"
       },
       "funding": {
         "type": "github",
@@ -18768,33 +18816,33 @@
     },
     "packages/suggestion": {
       "name": "@tiptap/suggestion",
-      "version": "2.5.7",
+      "version": "2.5.8",
       "license": "MIT",
       "devDependencies": {
-        "@tiptap/core": "^2.5.7",
-        "@tiptap/pm": "^2.5.7"
+        "@tiptap/core": "^2.5.8",
+        "@tiptap/pm": "^2.5.8"
       },
       "funding": {
         "type": "github",
         "url": "https://github.com/sponsors/ueberdosis"
       },
       "peerDependencies": {
-        "@tiptap/core": "^2.5.7",
-        "@tiptap/pm": "^2.5.7"
+        "@tiptap/core": "^2.5.8",
+        "@tiptap/pm": "^2.5.8"
       }
     },
     "packages/vue-2": {
       "name": "@tiptap/vue-2",
-      "version": "2.5.7",
+      "version": "2.5.8",
       "license": "MIT",
       "dependencies": {
-        "@tiptap/extension-bubble-menu": "^2.5.7",
-        "@tiptap/extension-floating-menu": "^2.5.7",
+        "@tiptap/extension-bubble-menu": "^2.5.8",
+        "@tiptap/extension-floating-menu": "^2.5.8",
         "vue-ts-types": "^1.6.0"
       },
       "devDependencies": {
-        "@tiptap/core": "^2.5.7",
-        "@tiptap/pm": "^2.5.7",
+        "@tiptap/core": "^2.5.8",
+        "@tiptap/pm": "^2.5.8",
         "vue": "^2.6.0"
       },
       "funding": {
@@ -18802,8 +18850,8 @@
         "url": "https://github.com/sponsors/ueberdosis"
       },
       "peerDependencies": {
-        "@tiptap/core": "^2.5.7",
-        "@tiptap/pm": "^2.5.7",
+        "@tiptap/core": "^2.5.8",
+        "@tiptap/pm": "^2.5.8",
         "vue": "^2.6.0"
       }
     },
@@ -18834,15 +18882,15 @@
     },
     "packages/vue-3": {
       "name": "@tiptap/vue-3",
-      "version": "2.5.7",
+      "version": "2.5.8",
       "license": "MIT",
       "dependencies": {
-        "@tiptap/extension-bubble-menu": "^2.5.7",
-        "@tiptap/extension-floating-menu": "^2.5.7"
+        "@tiptap/extension-bubble-menu": "^2.5.8",
+        "@tiptap/extension-floating-menu": "^2.5.8"
       },
       "devDependencies": {
-        "@tiptap/core": "^2.5.7",
-        "@tiptap/pm": "^2.5.7",
+        "@tiptap/core": "^2.5.8",
+        "@tiptap/pm": "^2.5.8",
         "vue": "^3.0.0"
       },
       "funding": {
@@ -18850,11 +18898,13 @@
         "url": "https://github.com/sponsors/ueberdosis"
       },
       "peerDependencies": {
-        "@tiptap/core": "^2.5.7",
-        "@tiptap/pm": "^2.5.7",
+        "@tiptap/core": "^2.5.8",
+        "@tiptap/pm": "^2.5.8",
         "vue": "^3.0.0"
       }
     },
-    "shared/rollup-config": {}
+    "shared/rollup-config": {
+      "name": "@tiptap-shared/rollup-config"
+    }
   }
 }
diff --git a/package.json b/package.json
index cf21df115f..84132d2511 100644
--- a/package.json
+++ b/package.json
@@ -58,6 +58,7 @@
     "eslint-plugin-cypress": "^2.15.2",
     "eslint-plugin-html": "^6.2.0",
     "eslint-plugin-import": "^2.29.1",
+    "eslint-plugin-react-hooks": "4.6.2",
     "eslint-plugin-simple-import-sort": "^7.0.0",
     "eslint-plugin-vue": "^9.27.0",
     "husky": "^8.0.3",
diff --git a/packages/core/CHANGELOG.md b/packages/core/CHANGELOG.md
index 4664505876..754a9f5bc7 100644
--- a/packages/core/CHANGELOG.md
+++ b/packages/core/CHANGELOG.md
@@ -1,5 +1,30 @@
 # Change Log
 
+## 2.5.9
+
+### Patch Changes
+
+- 84ebd51: Fix change criteria for isNodeEmpty to resolve #5415
+- 0ec0af6: fix(core): findDuplicates - use Array.from when converting Set
+- ae0254d: Add `ignoreWhitespace` option to `isNodeEmpty` to ignore any whitespace and hardbreaks in a node to check for emptiness
+- efb27fa: This fixes a discrepency between `getMarksBetween` and `isActive(markName)` where the position used for getMarksBetween was off by one
+  - @tiptap/pm@2.5.9
+
+## 2.5.8
+
+### Patch Changes
+
+- a08bf85: This fixes a bug with inputrules not being able to resolve positions properly
+  - @tiptap/pm@2.5.8
+
+## 2.5.7
+
+### Patch Changes
+
+- b012471: This addresses an issue with `isNodeEmpty` function where it was also comparing node attributes and finding mismatches on actually empty nodes. This helps placeholders find empty content correctly
+- cc3497e: Fixes a bug where if `enableContentCheck` was true, inserting content as JSON nodes would fail. This was because the node that was being created technically had a different schema than the content being inserted, so it would fail to generate the correct content value
+  - @tiptap/pm@2.5.7
+
 ## 2.5.6
 
 ### Patch Changes
diff --git a/packages/core/package.json b/packages/core/package.json
index f08d30db52..b3b0f36089 100644
--- a/packages/core/package.json
+++ b/packages/core/package.json
@@ -1,7 +1,7 @@
 {
   "name": "@tiptap/core",
   "description": "headless rich text editor",
-  "version": "2.5.6",
+  "version": "2.5.9",
   "homepage": "https://tiptap.dev",
   "keywords": [
     "tiptap",
@@ -32,10 +32,10 @@
     "dist"
   ],
   "devDependencies": {
-    "@tiptap/pm": "^2.5.6"
+    "@tiptap/pm": "^2.5.9"
   },
   "peerDependencies": {
-    "@tiptap/pm": "^2.5.6"
+    "@tiptap/pm": "^2.5.9"
   },
   "repository": {
     "type": "git",
diff --git a/packages/core/src/Editor.ts b/packages/core/src/Editor.ts
index 8b621e7f2f..cd04cafc22 100644
--- a/packages/core/src/Editor.ts
+++ b/packages/core/src/Editor.ts
@@ -39,6 +39,7 @@ import { isFunction } from './utilities/isFunction.js'
 
 export * as extensions from './extensions/index.js'
 
+// @ts-ignore
 export interface TiptapEditorHTMLElement extends HTMLElement {
   editor?: Editor
 }
@@ -340,6 +341,7 @@ export class Editor extends EventEmitter {
 
     // Let’s store the editor instance in the DOM element.
     // So we’ll have access to it for tests.
+    // @ts-ignore
     const dom = this.view.dom as TiptapEditorHTMLElement
 
     dom.editor = this
diff --git a/packages/core/src/Extension.ts b/packages/core/src/Extension.ts
index 97200301fa..0bcd9004de 100644
--- a/packages/core/src/Extension.ts
+++ b/packages/core/src/Extension.ts
@@ -457,7 +457,7 @@ export class Extension {
   configure(options: Partial = {}) {
     // return a new instance so we can use the same extension
     // with different calls of `configure`
-    const extension = this.extend({
+    const extension = this.extend({
       ...this.config,
       addOptions: () => {
         return mergeDeep(this.options as Record, options) as Options
diff --git a/packages/core/src/Mark.ts b/packages/core/src/Mark.ts
index f365ce40e8..e731d24652 100644
--- a/packages/core/src/Mark.ts
+++ b/packages/core/src/Mark.ts
@@ -589,7 +589,7 @@ export class Mark {
   configure(options: Partial = {}) {
     // return a new instance so we can use the same extension
     // with different calls of `configure`
-    const extension = this.extend({
+    const extension = this.extend({
       ...this.config,
       addOptions: () => {
         return mergeDeep(this.options as Record, options) as Options
diff --git a/packages/core/src/Node.ts b/packages/core/src/Node.ts
index a79d3a9aa5..ce21411cae 100644
--- a/packages/core/src/Node.ts
+++ b/packages/core/src/Node.ts
@@ -780,7 +780,7 @@ export class Node {
   configure(options: Partial = {}) {
     // return a new instance so we can use the same extension
     // with different calls of `configure`
-    const extension = this.extend({
+    const extension = this.extend({
       ...this.config,
       addOptions: () => {
         return mergeDeep(this.options as Record, options) as Options
diff --git a/packages/core/src/commands/insertContentAt.ts b/packages/core/src/commands/insertContentAt.ts
index 996cd511fd..e02b6f2060 100644
--- a/packages/core/src/commands/insertContentAt.ts
+++ b/packages/core/src/commands/insertContentAt.ts
@@ -81,6 +81,13 @@ export const insertContentAt: RawCommands['insertContentAt'] = (position, value,
         errorOnInvalidContent: options.errorOnInvalidContent ?? editor.options.enableContentCheck,
       })
     } catch (e) {
+      editor.emit('contentError', {
+        editor,
+        error: e as Error,
+        disableCollaboration: () => {
+          console.error('[tiptap error]: Unable to disable collaboration at this point in time')
+        },
+      })
       return false
     }
 
diff --git a/packages/core/src/helpers/createNodeFromContent.ts b/packages/core/src/helpers/createNodeFromContent.ts
index 0d89553d43..7fe83f83ca 100644
--- a/packages/core/src/helpers/createNodeFromContent.ts
+++ b/packages/core/src/helpers/createNodeFromContent.ts
@@ -58,13 +58,14 @@ export function createNodeFromContent(
   }
 
   if (isTextContent) {
-    let schemaToUse = schema
-    let hasInvalidContent = false
-    let invalidContent = ''
 
-    // Only ever check for invalid content if we're supposed to throw an error
+    // Check for invalid content
     if (options.errorOnInvalidContent) {
-      schemaToUse = new Schema({
+      let hasInvalidContent = false
+      let invalidContent = ''
+
+      // A copy of the current schema with a catch-all node at the end
+      const contentCheckSchema = new Schema({
         topNode: schema.spec.topNode,
         marks: schema.spec.marks,
         // Prosemirror's schemas are executed such that: the last to execute, matches last
@@ -88,19 +89,26 @@ export function createNodeFromContent(
           },
         }),
       })
-    }
 
-    const parser = DOMParser.fromSchema(schemaToUse)
+      if (options.slice) {
+        DOMParser.fromSchema(contentCheckSchema).parseSlice(elementFromString(content), options.parseOptions)
+      } else {
+        DOMParser.fromSchema(contentCheckSchema).parse(elementFromString(content), options.parseOptions)
+      }
 
-    const response = options.slice
-      ? parser.parseSlice(elementFromString(content), options.parseOptions).content
-      : parser.parse(elementFromString(content), options.parseOptions)
+      if (options.errorOnInvalidContent && hasInvalidContent) {
+        throw new Error('[tiptap error]: Invalid HTML content', { cause: new Error(`Invalid element found: ${invalidContent}`) })
+      }
+    }
+
+    const parser = DOMParser.fromSchema(schema)
 
-    if (options.errorOnInvalidContent && hasInvalidContent) {
-      throw new Error('[tiptap error]: Invalid HTML content', { cause: new Error(`Invalid element found: ${invalidContent}`) })
+    if (options.slice) {
+      return parser.parseSlice(elementFromString(content), options.parseOptions).content
     }
 
-    return response
+    return parser.parse(elementFromString(content), options.parseOptions)
+
   }
 
   return createNodeFromContent('', schema, options)
diff --git a/packages/core/src/helpers/getMarksBetween.ts b/packages/core/src/helpers/getMarksBetween.ts
index 177b9bbcee..99c85940a0 100644
--- a/packages/core/src/helpers/getMarksBetween.ts
+++ b/packages/core/src/helpers/getMarksBetween.ts
@@ -12,7 +12,7 @@ export function getMarksBetween(from: number, to: number, doc: ProseMirrorNode):
       .resolve(from)
       .marks()
       .forEach(mark => {
-        const $pos = doc.resolve(from - 1)
+        const $pos = doc.resolve(from)
         const range = getMarkRange($pos, mark.type)
 
         if (!range) {
diff --git a/packages/core/src/helpers/getTextContentFromNodes.ts b/packages/core/src/helpers/getTextContentFromNodes.ts
index c1264d27ba..a9a57391fd 100644
--- a/packages/core/src/helpers/getTextContentFromNodes.ts
+++ b/packages/core/src/helpers/getTextContentFromNodes.ts
@@ -24,7 +24,7 @@ export const getTextContentFromNodes = ($from: ResolvedPos, maxMatch = 500) => {
         || node.textContent
         || '%leaf%'
 
-      textBefore += node.isAtom ? chunk : chunk.slice(0, Math.max(0, sliceEndPos - pos))
+      textBefore += node.isAtom && !node.isText ? chunk : chunk.slice(0, Math.max(0, sliceEndPos - pos))
     },
   )
 
diff --git a/packages/core/src/helpers/isNodeEmpty.ts b/packages/core/src/helpers/isNodeEmpty.ts
index a12511add0..8d9a764006 100644
--- a/packages/core/src/helpers/isNodeEmpty.ts
+++ b/packages/core/src/helpers/isNodeEmpty.ts
@@ -1,11 +1,62 @@
 import { Node as ProseMirrorNode } from '@tiptap/pm/model'
 
-export function isNodeEmpty(node: ProseMirrorNode): boolean {
-  const defaultContent = node.type.createAndFill(node.attrs)
+/**
+ * Returns true if the given prosemirror node is empty.
+ */
+export function isNodeEmpty(
+  node: ProseMirrorNode,
+  {
+    checkChildren = true,
+    ignoreWhitespace = false,
+  }: {
+    /**
+     * When true (default), it will also check if all children are empty.
+     */
+    checkChildren?: boolean;
+    /**
+     * When true, it will ignore whitespace when checking for emptiness.
+     */
+    ignoreWhitespace?: boolean;
+  } = {},
+): boolean {
+  if (ignoreWhitespace) {
+    if (node.type.name === 'hardBreak') {
+      // Hard breaks are considered empty
+      return true
+    }
+    if (node.isText) {
+      return /^\s*$/m.test(node.text ?? '')
+    }
+  }
+
+  if (node.isText) {
+    return !node.text
+  }
 
-  if (!defaultContent) {
+  if (node.isAtom || node.isLeaf) {
     return false
   }
 
-  return node.eq(defaultContent)
+  if (node.content.childCount === 0) {
+    return true
+  }
+
+  if (checkChildren) {
+    let isContentEmpty = true
+
+    node.content.forEach(childNode => {
+      if (isContentEmpty === false) {
+        // Exit early for perf
+        return
+      }
+
+      if (!isNodeEmpty(childNode, { ignoreWhitespace, checkChildren })) {
+        isContentEmpty = false
+      }
+    })
+
+    return isContentEmpty
+  }
+
+  return false
 }
diff --git a/packages/core/src/utilities/findDuplicates.ts b/packages/core/src/utilities/findDuplicates.ts
index 8f1f081336..a506e0d345 100644
--- a/packages/core/src/utilities/findDuplicates.ts
+++ b/packages/core/src/utilities/findDuplicates.ts
@@ -1,5 +1,5 @@
 export function findDuplicates(items: any[]): any[] {
   const filtered = items.filter((el, index) => items.indexOf(el) !== index)
 
-  return [...new Set(filtered)]
+  return Array.from(new Set(filtered))
 }
diff --git a/packages/extension-blockquote/CHANGELOG.md b/packages/extension-blockquote/CHANGELOG.md
index 7fd74a7ec7..2c8557ad91 100644
--- a/packages/extension-blockquote/CHANGELOG.md
+++ b/packages/extension-blockquote/CHANGELOG.md
@@ -1,5 +1,30 @@
 # Change Log
 
+## 2.5.9
+
+### Patch Changes
+
+- Updated dependencies [84ebd51]
+- Updated dependencies [0ec0af6]
+- Updated dependencies [ae0254d]
+- Updated dependencies [efb27fa]
+  - @tiptap/core@2.5.9
+
+## 2.5.8
+
+### Patch Changes
+
+- Updated dependencies [a08bf85]
+  - @tiptap/core@2.5.8
+
+## 2.5.7
+
+### Patch Changes
+
+- Updated dependencies [b012471]
+- Updated dependencies [cc3497e]
+  - @tiptap/core@2.5.7
+
 ## 2.5.6
 
 ### Patch Changes
diff --git a/packages/extension-blockquote/package.json b/packages/extension-blockquote/package.json
index a946fbda6f..db2b781893 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": "2.5.6",
+  "version": "2.5.9",
   "homepage": "https://tiptap.dev",
   "keywords": [
     "tiptap",
@@ -29,10 +29,10 @@
     "dist"
   ],
   "devDependencies": {
-    "@tiptap/core": "^2.5.6"
+    "@tiptap/core": "^2.5.9"
   },
   "peerDependencies": {
-    "@tiptap/core": "^2.5.6"
+    "@tiptap/core": "^2.5.9"
   },
   "repository": {
     "type": "git",
diff --git a/packages/extension-bold/CHANGELOG.md b/packages/extension-bold/CHANGELOG.md
index 65aae7bec4..adee1b0d26 100644
--- a/packages/extension-bold/CHANGELOG.md
+++ b/packages/extension-bold/CHANGELOG.md
@@ -1,5 +1,30 @@
 # Change Log
 
+## 2.5.9
+
+### Patch Changes
+
+- Updated dependencies [84ebd51]
+- Updated dependencies [0ec0af6]
+- Updated dependencies [ae0254d]
+- Updated dependencies [efb27fa]
+  - @tiptap/core@2.5.9
+
+## 2.5.8
+
+### Patch Changes
+
+- Updated dependencies [a08bf85]
+  - @tiptap/core@2.5.8
+
+## 2.5.7
+
+### Patch Changes
+
+- Updated dependencies [b012471]
+- Updated dependencies [cc3497e]
+  - @tiptap/core@2.5.7
+
 ## 2.5.6
 
 ### Patch Changes
diff --git a/packages/extension-bold/package.json b/packages/extension-bold/package.json
index ed0d5b7927..70e9bccf09 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": "2.5.6",
+  "version": "2.5.9",
   "homepage": "https://tiptap.dev",
   "keywords": [
     "tiptap",
@@ -29,10 +29,10 @@
     "dist"
   ],
   "devDependencies": {
-    "@tiptap/core": "^2.5.6"
+    "@tiptap/core": "^2.5.9"
   },
   "peerDependencies": {
-    "@tiptap/core": "^2.5.6"
+    "@tiptap/core": "^2.5.9"
   },
   "repository": {
     "type": "git",
diff --git a/packages/extension-bubble-menu/CHANGELOG.md b/packages/extension-bubble-menu/CHANGELOG.md
index a320cf908e..db637572ae 100644
--- a/packages/extension-bubble-menu/CHANGELOG.md
+++ b/packages/extension-bubble-menu/CHANGELOG.md
@@ -1,5 +1,33 @@
 # Change Log
 
+## 2.5.9
+
+### Patch Changes
+
+- Updated dependencies [84ebd51]
+- Updated dependencies [0ec0af6]
+- Updated dependencies [ae0254d]
+- Updated dependencies [efb27fa]
+  - @tiptap/core@2.5.9
+  - @tiptap/pm@2.5.9
+
+## 2.5.8
+
+### Patch Changes
+
+- Updated dependencies [a08bf85]
+  - @tiptap/core@2.5.8
+  - @tiptap/pm@2.5.8
+
+## 2.5.7
+
+### Patch Changes
+
+- Updated dependencies [b012471]
+- Updated dependencies [cc3497e]
+  - @tiptap/core@2.5.7
+  - @tiptap/pm@2.5.7
+
 ## 2.5.6
 
 ### Patch Changes
diff --git a/packages/extension-bubble-menu/package.json b/packages/extension-bubble-menu/package.json
index 1ea77cb17c..4b7590144e 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": "2.5.6",
+  "version": "2.5.9",
   "homepage": "https://tiptap.dev",
   "keywords": [
     "tiptap",
@@ -38,12 +38,12 @@
   },
   "sideEffects": false,
   "devDependencies": {
-    "@tiptap/core": "^2.5.6",
-    "@tiptap/pm": "^2.5.6"
+    "@tiptap/core": "^2.5.9",
+    "@tiptap/pm": "^2.5.9"
   },
   "peerDependencies": {
-    "@tiptap/core": "^2.5.6",
-    "@tiptap/pm": "^2.5.6"
+    "@tiptap/core": "^2.5.9",
+    "@tiptap/pm": "^2.5.9"
   },
   "scripts": {
     "clean": "rm -rf dist",
diff --git a/packages/extension-bullet-list/CHANGELOG.md b/packages/extension-bullet-list/CHANGELOG.md
index 14315eb4fb..1fd11f2d96 100644
--- a/packages/extension-bullet-list/CHANGELOG.md
+++ b/packages/extension-bullet-list/CHANGELOG.md
@@ -1,5 +1,30 @@
 # Change Log
 
+## 2.5.9
+
+### Patch Changes
+
+- Updated dependencies [84ebd51]
+- Updated dependencies [0ec0af6]
+- Updated dependencies [ae0254d]
+- Updated dependencies [efb27fa]
+  - @tiptap/core@2.5.9
+
+## 2.5.8
+
+### Patch Changes
+
+- Updated dependencies [a08bf85]
+  - @tiptap/core@2.5.8
+
+## 2.5.7
+
+### Patch Changes
+
+- Updated dependencies [b012471]
+- Updated dependencies [cc3497e]
+  - @tiptap/core@2.5.7
+
 ## 2.5.6
 
 ### Patch Changes
diff --git a/packages/extension-bullet-list/package.json b/packages/extension-bullet-list/package.json
index 3a759c3ddd..40bd282b81 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": "2.5.6",
+  "version": "2.5.9",
   "homepage": "https://tiptap.dev",
   "keywords": [
     "tiptap",
@@ -29,10 +29,10 @@
     "dist"
   ],
   "devDependencies": {
-    "@tiptap/core": "^2.5.6"
+    "@tiptap/core": "^2.5.9"
   },
   "peerDependencies": {
-    "@tiptap/core": "^2.5.6"
+    "@tiptap/core": "^2.5.9"
   },
   "repository": {
     "type": "git",
diff --git a/packages/extension-character-count/CHANGELOG.md b/packages/extension-character-count/CHANGELOG.md
index 42ef74e9df..dfd50baa71 100644
--- a/packages/extension-character-count/CHANGELOG.md
+++ b/packages/extension-character-count/CHANGELOG.md
@@ -1,5 +1,33 @@
 # Change Log
 
+## 2.5.9
+
+### Patch Changes
+
+- Updated dependencies [84ebd51]
+- Updated dependencies [0ec0af6]
+- Updated dependencies [ae0254d]
+- Updated dependencies [efb27fa]
+  - @tiptap/core@2.5.9
+  - @tiptap/pm@2.5.9
+
+## 2.5.8
+
+### Patch Changes
+
+- Updated dependencies [a08bf85]
+  - @tiptap/core@2.5.8
+  - @tiptap/pm@2.5.8
+
+## 2.5.7
+
+### Patch Changes
+
+- Updated dependencies [b012471]
+- Updated dependencies [cc3497e]
+  - @tiptap/core@2.5.7
+  - @tiptap/pm@2.5.7
+
 ## 2.5.6
 
 ### Patch Changes
diff --git a/packages/extension-character-count/package.json b/packages/extension-character-count/package.json
index 75013e545c..750b711be3 100644
--- a/packages/extension-character-count/package.json
+++ b/packages/extension-character-count/package.json
@@ -1,7 +1,7 @@
 {
   "name": "@tiptap/extension-character-count",
   "description": "font family extension for tiptap",
-  "version": "2.5.6",
+  "version": "2.5.9",
   "homepage": "https://tiptap.dev",
   "keywords": [
     "tiptap",
@@ -29,12 +29,12 @@
     "dist"
   ],
   "devDependencies": {
-    "@tiptap/core": "^2.5.6",
-    "@tiptap/pm": "^2.5.6"
+    "@tiptap/core": "^2.5.9",
+    "@tiptap/pm": "^2.5.9"
   },
   "peerDependencies": {
-    "@tiptap/core": "^2.5.6",
-    "@tiptap/pm": "^2.5.6"
+    "@tiptap/core": "^2.5.9",
+    "@tiptap/pm": "^2.5.9"
   },
   "repository": {
     "type": "git",
diff --git a/packages/extension-code-block-lowlight/CHANGELOG.md b/packages/extension-code-block-lowlight/CHANGELOG.md
index 1420de82b5..f0826dcf92 100644
--- a/packages/extension-code-block-lowlight/CHANGELOG.md
+++ b/packages/extension-code-block-lowlight/CHANGELOG.md
@@ -1,5 +1,39 @@
 # Change Log
 
+## 2.5.9
+
+### Patch Changes
+
+- d6e56c4: declare lowlight to be a peer dep of extension-code-block-lowlight, update usage to v3
+- 4b215f7: `defaultLanguage` on Code Block Lowlight was not being respected properly, to address this we added `defaultLanguage` as an option to the code-block extension.
+- Updated dependencies [84ebd51]
+- Updated dependencies [0ec0af6]
+- Updated dependencies [4b215f7]
+- Updated dependencies [ae0254d]
+- Updated dependencies [efb27fa]
+  - @tiptap/core@2.5.9
+  - @tiptap/extension-code-block@2.5.9
+  - @tiptap/pm@2.5.9
+
+## 2.5.8
+
+### Patch Changes
+
+- Updated dependencies [a08bf85]
+  - @tiptap/core@2.5.8
+  - @tiptap/extension-code-block@2.5.8
+  - @tiptap/pm@2.5.8
+
+## 2.5.7
+
+### Patch Changes
+
+- Updated dependencies [b012471]
+- Updated dependencies [cc3497e]
+  - @tiptap/core@2.5.7
+  - @tiptap/extension-code-block@2.5.7
+  - @tiptap/pm@2.5.7
+
 ## 2.5.6
 
 ### Patch Changes
diff --git a/packages/extension-code-block-lowlight/package.json b/packages/extension-code-block-lowlight/package.json
index 02acad8566..4ddb57e010 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": "2.5.6",
+  "version": "2.5.9",
   "homepage": "https://tiptap.dev",
   "keywords": [
     "tiptap",
@@ -29,14 +29,17 @@
     "dist"
   ],
   "devDependencies": {
-    "@tiptap/core": "^2.5.6",
-    "@tiptap/extension-code-block": "^2.5.6",
-    "@tiptap/pm": "^2.5.6"
+    "@tiptap/core": "^2.5.9",
+    "@tiptap/extension-code-block": "^2.5.9",
+    "@tiptap/pm": "^2.5.9",
+    "lowlight": "^2 || ^3"
   },
   "peerDependencies": {
-    "@tiptap/core": "^2.5.6",
-    "@tiptap/extension-code-block": "^2.5.6",
-    "@tiptap/pm": "^2.5.6"
+    "@tiptap/core": "^2.5.9",
+    "@tiptap/extension-code-block": "^2.5.9",
+    "@tiptap/pm": "^2.5.9",
+    "lowlight": "^2 || ^3",
+    "highlight.js": "^11"
   },
   "repository": {
     "type": "git",
diff --git a/packages/extension-code-block-lowlight/src/code-block-lowlight.ts b/packages/extension-code-block-lowlight/src/code-block-lowlight.ts
index c1eb4dcbfb..3b952e3298 100644
--- a/packages/extension-code-block-lowlight/src/code-block-lowlight.ts
+++ b/packages/extension-code-block-lowlight/src/code-block-lowlight.ts
@@ -7,13 +7,6 @@ export interface CodeBlockLowlightOptions extends CodeBlockOptions {
    * The lowlight instance.
    */
   lowlight: any,
-
-  /**
-   * The default language.
-   * @default null
-   * @example 'javascript'
-   */
-  defaultLanguage: string | null | undefined,
 }
 
 /**
@@ -25,7 +18,6 @@ export const CodeBlockLowlight = CodeBlock.extend({
     return {
       ...this.parent?.(),
       lowlight: {},
-      defaultLanguage: null,
     }
   },
 
diff --git a/packages/extension-code-block/CHANGELOG.md b/packages/extension-code-block/CHANGELOG.md
index 831d57f22b..0ca36dbd75 100644
--- a/packages/extension-code-block/CHANGELOG.md
+++ b/packages/extension-code-block/CHANGELOG.md
@@ -1,5 +1,34 @@
 # Change Log
 
+## 2.5.9
+
+### Patch Changes
+
+- 4b215f7: `defaultLanguage` on Code Block Lowlight was not being respected properly, to address this we added `defaultLanguage` as an option to the code-block extension.
+- Updated dependencies [84ebd51]
+- Updated dependencies [0ec0af6]
+- Updated dependencies [ae0254d]
+- Updated dependencies [efb27fa]
+  - @tiptap/core@2.5.9
+  - @tiptap/pm@2.5.9
+
+## 2.5.8
+
+### Patch Changes
+
+- Updated dependencies [a08bf85]
+  - @tiptap/core@2.5.8
+  - @tiptap/pm@2.5.8
+
+## 2.5.7
+
+### Patch Changes
+
+- Updated dependencies [b012471]
+- Updated dependencies [cc3497e]
+  - @tiptap/core@2.5.7
+  - @tiptap/pm@2.5.7
+
 ## 2.5.6
 
 ### Patch Changes
diff --git a/packages/extension-code-block/package.json b/packages/extension-code-block/package.json
index 3ed46e8a7e..13e1957e88 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": "2.5.6",
+  "version": "2.5.9",
   "homepage": "https://tiptap.dev",
   "keywords": [
     "tiptap",
@@ -29,12 +29,12 @@
     "dist"
   ],
   "devDependencies": {
-    "@tiptap/core": "^2.5.6",
-    "@tiptap/pm": "^2.5.6"
+    "@tiptap/core": "^2.5.9",
+    "@tiptap/pm": "^2.5.9"
   },
   "peerDependencies": {
-    "@tiptap/core": "^2.5.6",
-    "@tiptap/pm": "^2.5.6"
+    "@tiptap/core": "^2.5.9",
+    "@tiptap/pm": "^2.5.9"
   },
   "repository": {
     "type": "git",
diff --git a/packages/extension-code-block/src/code-block.ts b/packages/extension-code-block/src/code-block.ts
index 8d6b22d4c9..122e476b40 100644
--- a/packages/extension-code-block/src/code-block.ts
+++ b/packages/extension-code-block/src/code-block.ts
@@ -22,6 +22,12 @@ export interface CodeBlockOptions {
    * @default true
    */
   exitOnArrowDown: boolean
+  /**
+   * The default language.
+   * @default null
+   * @example 'js'
+   */
+  defaultLanguage: string | null | undefined
   /**
    * Custom HTML attributes that should be added to the rendered HTML tag.
    * @default {}
@@ -71,6 +77,7 @@ export const CodeBlock = Node.create({
       languageClassPrefix: 'language-',
       exitOnTripleEnter: true,
       exitOnArrowDown: true,
+      defaultLanguage: null,
       HTMLAttributes: {},
     }
   },
@@ -88,7 +95,7 @@ export const CodeBlock = Node.create({
   addAttributes() {
     return {
       language: {
-        default: null,
+        default: this.options.defaultLanguage,
         parseHTML: element => {
           const { languageClassPrefix } = this.options
           const classNames = [...(element.firstElementChild?.classList || [])]
diff --git a/packages/extension-code/CHANGELOG.md b/packages/extension-code/CHANGELOG.md
index 3b17ce2765..478f236e50 100644
--- a/packages/extension-code/CHANGELOG.md
+++ b/packages/extension-code/CHANGELOG.md
@@ -1,5 +1,30 @@
 # Change Log
 
+## 2.5.9
+
+### Patch Changes
+
+- Updated dependencies [84ebd51]
+- Updated dependencies [0ec0af6]
+- Updated dependencies [ae0254d]
+- Updated dependencies [efb27fa]
+  - @tiptap/core@2.5.9
+
+## 2.5.8
+
+### Patch Changes
+
+- Updated dependencies [a08bf85]
+  - @tiptap/core@2.5.8
+
+## 2.5.7
+
+### Patch Changes
+
+- Updated dependencies [b012471]
+- Updated dependencies [cc3497e]
+  - @tiptap/core@2.5.7
+
 ## 2.5.6
 
 ### Patch Changes
diff --git a/packages/extension-code/package.json b/packages/extension-code/package.json
index b118fb03b2..64dde6db88 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": "2.5.6",
+  "version": "2.5.9",
   "homepage": "https://tiptap.dev",
   "keywords": [
     "tiptap",
@@ -29,10 +29,10 @@
     "dist"
   ],
   "devDependencies": {
-    "@tiptap/core": "^2.5.6"
+    "@tiptap/core": "^2.5.9"
   },
   "peerDependencies": {
-    "@tiptap/core": "^2.5.6"
+    "@tiptap/core": "^2.5.9"
   },
   "repository": {
     "type": "git",
diff --git a/packages/extension-collaboration-cursor/CHANGELOG.md b/packages/extension-collaboration-cursor/CHANGELOG.md
index 5f9ed3c83c..8403570003 100644
--- a/packages/extension-collaboration-cursor/CHANGELOG.md
+++ b/packages/extension-collaboration-cursor/CHANGELOG.md
@@ -1,5 +1,31 @@
 # Change Log
 
+## 2.5.9
+
+### Patch Changes
+
+- 174aefe: This updates y-prosemirror to a version that no longer has syncing problems and extension collaboration now respects the onFirstRender option
+- Updated dependencies [84ebd51]
+- Updated dependencies [0ec0af6]
+- Updated dependencies [ae0254d]
+- Updated dependencies [efb27fa]
+  - @tiptap/core@2.5.9
+
+## 2.5.8
+
+### Patch Changes
+
+- Updated dependencies [a08bf85]
+  - @tiptap/core@2.5.8
+
+## 2.5.7
+
+### Patch Changes
+
+- Updated dependencies [b012471]
+- Updated dependencies [cc3497e]
+  - @tiptap/core@2.5.7
+
 ## 2.5.6
 
 ### Patch Changes
diff --git a/packages/extension-collaboration-cursor/package.json b/packages/extension-collaboration-cursor/package.json
index af35ffd249..e4e7a0b99c 100644
--- a/packages/extension-collaboration-cursor/package.json
+++ b/packages/extension-collaboration-cursor/package.json
@@ -1,7 +1,7 @@
 {
   "name": "@tiptap/extension-collaboration-cursor",
   "description": "collaboration cursor extension for tiptap",
-  "version": "2.5.6",
+  "version": "2.5.9",
   "homepage": "https://tiptap.dev",
   "keywords": [
     "tiptap",
@@ -29,12 +29,12 @@
     "dist"
   ],
   "devDependencies": {
-    "@tiptap/core": "^2.5.6",
-    "y-prosemirror": "^1.2.9"
+    "@tiptap/core": "^2.5.9",
+    "y-prosemirror": "^1.2.11"
   },
   "peerDependencies": {
-    "@tiptap/core": "^2.5.6",
-    "y-prosemirror": "^1.2.6"
+    "@tiptap/core": "^2.5.9",
+    "y-prosemirror": "^1.2.11"
   },
   "repository": {
     "type": "git",
diff --git a/packages/extension-collaboration-cursor/src/collaboration-cursor.ts b/packages/extension-collaboration-cursor/src/collaboration-cursor.ts
index ed17ad06f1..3c14708edc 100644
--- a/packages/extension-collaboration-cursor/src/collaboration-cursor.ts
+++ b/packages/extension-collaboration-cursor/src/collaboration-cursor.ts
@@ -127,6 +127,9 @@ export const CollaborationCursor = Extension.create({
     }
 
     const ySyncPluginOptions: YSyncOpts = {
-      ...(this.options.ySyncOptions ? { ...this.options.ySyncOptions } : {}),
-      ...(this.options.onFirstRender ? { ...this.options.onFirstRender } : {}),
+      ...this.options.ySyncOptions,
+      onFirstRender: this.options.onFirstRender,
     }
 
     const ySyncPluginInstance = ySyncPlugin(fragment, ySyncPluginOptions)
diff --git a/packages/extension-color/CHANGELOG.md b/packages/extension-color/CHANGELOG.md
index 0237e68b56..a166686875 100644
--- a/packages/extension-color/CHANGELOG.md
+++ b/packages/extension-color/CHANGELOG.md
@@ -1,5 +1,33 @@
 # Change Log
 
+## 2.5.9
+
+### Patch Changes
+
+- Updated dependencies [84ebd51]
+- Updated dependencies [0ec0af6]
+- Updated dependencies [ae0254d]
+- Updated dependencies [efb27fa]
+  - @tiptap/core@2.5.9
+  - @tiptap/extension-text-style@2.5.9
+
+## 2.5.8
+
+### Patch Changes
+
+- Updated dependencies [a08bf85]
+  - @tiptap/core@2.5.8
+  - @tiptap/extension-text-style@2.5.8
+
+## 2.5.7
+
+### Patch Changes
+
+- Updated dependencies [b012471]
+- Updated dependencies [cc3497e]
+  - @tiptap/core@2.5.7
+  - @tiptap/extension-text-style@2.5.7
+
 ## 2.5.6
 
 ### Patch Changes
diff --git a/packages/extension-color/package.json b/packages/extension-color/package.json
index e30209f76e..332dbc5412 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": "2.5.6",
+  "version": "2.5.9",
   "homepage": "https://tiptap.dev",
   "keywords": [
     "tiptap",
@@ -29,12 +29,12 @@
     "dist"
   ],
   "devDependencies": {
-    "@tiptap/core": "^2.5.6",
-    "@tiptap/extension-text-style": "^2.5.6"
+    "@tiptap/core": "^2.5.9",
+    "@tiptap/extension-text-style": "^2.5.9"
   },
   "peerDependencies": {
-    "@tiptap/core": "^2.5.6",
-    "@tiptap/extension-text-style": "^2.5.6"
+    "@tiptap/core": "^2.5.9",
+    "@tiptap/extension-text-style": "^2.5.9"
   },
   "repository": {
     "type": "git",
diff --git a/packages/extension-document/CHANGELOG.md b/packages/extension-document/CHANGELOG.md
index fd9b0b3ee2..1018bbaf53 100644
--- a/packages/extension-document/CHANGELOG.md
+++ b/packages/extension-document/CHANGELOG.md
@@ -1,5 +1,30 @@
 # Change Log
 
+## 2.5.9
+
+### Patch Changes
+
+- Updated dependencies [84ebd51]
+- Updated dependencies [0ec0af6]
+- Updated dependencies [ae0254d]
+- Updated dependencies [efb27fa]
+  - @tiptap/core@2.5.9
+
+## 2.5.8
+
+### Patch Changes
+
+- Updated dependencies [a08bf85]
+  - @tiptap/core@2.5.8
+
+## 2.5.7
+
+### Patch Changes
+
+- Updated dependencies [b012471]
+- Updated dependencies [cc3497e]
+  - @tiptap/core@2.5.7
+
 ## 2.5.6
 
 ### Patch Changes
diff --git a/packages/extension-document/package.json b/packages/extension-document/package.json
index 2e25e543e1..454f931b5c 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": "2.5.6",
+  "version": "2.5.9",
   "homepage": "https://tiptap.dev",
   "keywords": [
     "tiptap",
@@ -29,10 +29,10 @@
     "dist"
   ],
   "devDependencies": {
-    "@tiptap/core": "^2.5.6"
+    "@tiptap/core": "^2.5.9"
   },
   "peerDependencies": {
-    "@tiptap/core": "^2.5.6"
+    "@tiptap/core": "^2.5.9"
   },
   "repository": {
     "type": "git",
diff --git a/packages/extension-dropcursor/CHANGELOG.md b/packages/extension-dropcursor/CHANGELOG.md
index 063b429cb5..f61ecb5707 100644
--- a/packages/extension-dropcursor/CHANGELOG.md
+++ b/packages/extension-dropcursor/CHANGELOG.md
@@ -1,5 +1,33 @@
 # Change Log
 
+## 2.5.9
+
+### Patch Changes
+
+- Updated dependencies [84ebd51]
+- Updated dependencies [0ec0af6]
+- Updated dependencies [ae0254d]
+- Updated dependencies [efb27fa]
+  - @tiptap/core@2.5.9
+  - @tiptap/pm@2.5.9
+
+## 2.5.8
+
+### Patch Changes
+
+- Updated dependencies [a08bf85]
+  - @tiptap/core@2.5.8
+  - @tiptap/pm@2.5.8
+
+## 2.5.7
+
+### Patch Changes
+
+- Updated dependencies [b012471]
+- Updated dependencies [cc3497e]
+  - @tiptap/core@2.5.7
+  - @tiptap/pm@2.5.7
+
 ## 2.5.6
 
 ### Patch Changes
diff --git a/packages/extension-dropcursor/package.json b/packages/extension-dropcursor/package.json
index 687627b6a2..3446fda508 100644
--- a/packages/extension-dropcursor/package.json
+++ b/packages/extension-dropcursor/package.json
@@ -1,7 +1,7 @@
 {
   "name": "@tiptap/extension-dropcursor",
   "description": "dropcursor extension for tiptap",
-  "version": "2.5.6",
+  "version": "2.5.9",
   "homepage": "https://tiptap.dev",
   "keywords": [
     "tiptap",
@@ -29,12 +29,12 @@
     "dist"
   ],
   "devDependencies": {
-    "@tiptap/core": "^2.5.6",
-    "@tiptap/pm": "^2.5.6"
+    "@tiptap/core": "^2.5.9",
+    "@tiptap/pm": "^2.5.9"
   },
   "peerDependencies": {
-    "@tiptap/core": "^2.5.6",
-    "@tiptap/pm": "^2.5.6"
+    "@tiptap/core": "^2.5.9",
+    "@tiptap/pm": "^2.5.9"
   },
   "repository": {
     "type": "git",
diff --git a/packages/extension-floating-menu/CHANGELOG.md b/packages/extension-floating-menu/CHANGELOG.md
index dab0c07a12..12295e9088 100644
--- a/packages/extension-floating-menu/CHANGELOG.md
+++ b/packages/extension-floating-menu/CHANGELOG.md
@@ -1,5 +1,33 @@
 # Change Log
 
+## 2.5.9
+
+### Patch Changes
+
+- Updated dependencies [84ebd51]
+- Updated dependencies [0ec0af6]
+- Updated dependencies [ae0254d]
+- Updated dependencies [efb27fa]
+  - @tiptap/core@2.5.9
+  - @tiptap/pm@2.5.9
+
+## 2.5.8
+
+### Patch Changes
+
+- Updated dependencies [a08bf85]
+  - @tiptap/core@2.5.8
+  - @tiptap/pm@2.5.8
+
+## 2.5.7
+
+### Patch Changes
+
+- Updated dependencies [b012471]
+- Updated dependencies [cc3497e]
+  - @tiptap/core@2.5.7
+  - @tiptap/pm@2.5.7
+
 ## 2.5.6
 
 ### Patch Changes
diff --git a/packages/extension-floating-menu/package.json b/packages/extension-floating-menu/package.json
index 6fdb649bce..e1e61a7ff9 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": "2.5.6",
+  "version": "2.5.9",
   "homepage": "https://tiptap.dev",
   "keywords": [
     "tiptap",
@@ -29,12 +29,12 @@
     "dist"
   ],
   "devDependencies": {
-    "@tiptap/core": "^2.5.6",
-    "@tiptap/pm": "^2.5.6"
+    "@tiptap/core": "^2.5.9",
+    "@tiptap/pm": "^2.5.9"
   },
   "peerDependencies": {
-    "@tiptap/core": "^2.5.6",
-    "@tiptap/pm": "^2.5.6"
+    "@tiptap/core": "^2.5.9",
+    "@tiptap/pm": "^2.5.9"
   },
   "dependencies": {
     "tippy.js": "^6.3.7"
diff --git a/packages/extension-focus/CHANGELOG.md b/packages/extension-focus/CHANGELOG.md
index 73f6a7dce9..aaf3a11c8a 100644
--- a/packages/extension-focus/CHANGELOG.md
+++ b/packages/extension-focus/CHANGELOG.md
@@ -1,5 +1,33 @@
 # Change Log
 
+## 2.5.9
+
+### Patch Changes
+
+- Updated dependencies [84ebd51]
+- Updated dependencies [0ec0af6]
+- Updated dependencies [ae0254d]
+- Updated dependencies [efb27fa]
+  - @tiptap/core@2.5.9
+  - @tiptap/pm@2.5.9
+
+## 2.5.8
+
+### Patch Changes
+
+- Updated dependencies [a08bf85]
+  - @tiptap/core@2.5.8
+  - @tiptap/pm@2.5.8
+
+## 2.5.7
+
+### Patch Changes
+
+- Updated dependencies [b012471]
+- Updated dependencies [cc3497e]
+  - @tiptap/core@2.5.7
+  - @tiptap/pm@2.5.7
+
 ## 2.5.6
 
 ### Patch Changes
diff --git a/packages/extension-focus/package.json b/packages/extension-focus/package.json
index 2e0a428ad0..5411f8812a 100644
--- a/packages/extension-focus/package.json
+++ b/packages/extension-focus/package.json
@@ -1,7 +1,7 @@
 {
   "name": "@tiptap/extension-focus",
   "description": "focus extension for tiptap",
-  "version": "2.5.6",
+  "version": "2.5.9",
   "homepage": "https://tiptap.dev",
   "keywords": [
     "tiptap",
@@ -29,12 +29,12 @@
     "dist"
   ],
   "devDependencies": {
-    "@tiptap/core": "^2.5.6",
-    "@tiptap/pm": "^2.5.6"
+    "@tiptap/core": "^2.5.9",
+    "@tiptap/pm": "^2.5.9"
   },
   "peerDependencies": {
-    "@tiptap/core": "^2.5.6",
-    "@tiptap/pm": "^2.5.6"
+    "@tiptap/core": "^2.5.9",
+    "@tiptap/pm": "^2.5.9"
   },
   "repository": {
     "type": "git",
diff --git a/packages/extension-font-family/CHANGELOG.md b/packages/extension-font-family/CHANGELOG.md
index fbd809105c..1f0ccadfb2 100644
--- a/packages/extension-font-family/CHANGELOG.md
+++ b/packages/extension-font-family/CHANGELOG.md
@@ -1,5 +1,33 @@
 # Change Log
 
+## 2.5.9
+
+### Patch Changes
+
+- Updated dependencies [84ebd51]
+- Updated dependencies [0ec0af6]
+- Updated dependencies [ae0254d]
+- Updated dependencies [efb27fa]
+  - @tiptap/core@2.5.9
+  - @tiptap/extension-text-style@2.5.9
+
+## 2.5.8
+
+### Patch Changes
+
+- Updated dependencies [a08bf85]
+  - @tiptap/core@2.5.8
+  - @tiptap/extension-text-style@2.5.8
+
+## 2.5.7
+
+### Patch Changes
+
+- Updated dependencies [b012471]
+- Updated dependencies [cc3497e]
+  - @tiptap/core@2.5.7
+  - @tiptap/extension-text-style@2.5.7
+
 ## 2.5.6
 
 ### Patch Changes
diff --git a/packages/extension-font-family/package.json b/packages/extension-font-family/package.json
index f3aee64dc5..991f1f666e 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": "2.5.6",
+  "version": "2.5.9",
   "homepage": "https://tiptap.dev",
   "keywords": [
     "tiptap",
@@ -29,12 +29,12 @@
     "dist"
   ],
   "devDependencies": {
-    "@tiptap/core": "^2.5.6",
-    "@tiptap/extension-text-style": "^2.5.6"
+    "@tiptap/core": "^2.5.9",
+    "@tiptap/extension-text-style": "^2.5.9"
   },
   "peerDependencies": {
-    "@tiptap/core": "^2.5.6",
-    "@tiptap/extension-text-style": "^2.5.6"
+    "@tiptap/core": "^2.5.9",
+    "@tiptap/extension-text-style": "^2.5.9"
   },
   "repository": {
     "type": "git",
diff --git a/packages/extension-gapcursor/CHANGELOG.md b/packages/extension-gapcursor/CHANGELOG.md
index a6d1c20b5a..e384f170eb 100644
--- a/packages/extension-gapcursor/CHANGELOG.md
+++ b/packages/extension-gapcursor/CHANGELOG.md
@@ -1,5 +1,33 @@
 # Change Log
 
+## 2.5.9
+
+### Patch Changes
+
+- Updated dependencies [84ebd51]
+- Updated dependencies [0ec0af6]
+- Updated dependencies [ae0254d]
+- Updated dependencies [efb27fa]
+  - @tiptap/core@2.5.9
+  - @tiptap/pm@2.5.9
+
+## 2.5.8
+
+### Patch Changes
+
+- Updated dependencies [a08bf85]
+  - @tiptap/core@2.5.8
+  - @tiptap/pm@2.5.8
+
+## 2.5.7
+
+### Patch Changes
+
+- Updated dependencies [b012471]
+- Updated dependencies [cc3497e]
+  - @tiptap/core@2.5.7
+  - @tiptap/pm@2.5.7
+
 ## 2.5.6
 
 ### Patch Changes
diff --git a/packages/extension-gapcursor/package.json b/packages/extension-gapcursor/package.json
index 2c6419fa22..efaeded49d 100644
--- a/packages/extension-gapcursor/package.json
+++ b/packages/extension-gapcursor/package.json
@@ -1,7 +1,7 @@
 {
   "name": "@tiptap/extension-gapcursor",
   "description": "gapcursor extension for tiptap",
-  "version": "2.5.6",
+  "version": "2.5.9",
   "homepage": "https://tiptap.dev",
   "keywords": [
     "tiptap",
@@ -29,12 +29,12 @@
     "dist"
   ],
   "devDependencies": {
-    "@tiptap/core": "^2.5.6",
-    "@tiptap/pm": "^2.5.6"
+    "@tiptap/core": "^2.5.9",
+    "@tiptap/pm": "^2.5.9"
   },
   "peerDependencies": {
-    "@tiptap/core": "^2.5.6",
-    "@tiptap/pm": "^2.5.6"
+    "@tiptap/core": "^2.5.9",
+    "@tiptap/pm": "^2.5.9"
   },
   "repository": {
     "type": "git",
diff --git a/packages/extension-hard-break/CHANGELOG.md b/packages/extension-hard-break/CHANGELOG.md
index 13a6ae737c..c2d3d8563b 100644
--- a/packages/extension-hard-break/CHANGELOG.md
+++ b/packages/extension-hard-break/CHANGELOG.md
@@ -1,5 +1,30 @@
 # Change Log
 
+## 2.5.9
+
+### Patch Changes
+
+- Updated dependencies [84ebd51]
+- Updated dependencies [0ec0af6]
+- Updated dependencies [ae0254d]
+- Updated dependencies [efb27fa]
+  - @tiptap/core@2.5.9
+
+## 2.5.8
+
+### Patch Changes
+
+- Updated dependencies [a08bf85]
+  - @tiptap/core@2.5.8
+
+## 2.5.7
+
+### Patch Changes
+
+- Updated dependencies [b012471]
+- Updated dependencies [cc3497e]
+  - @tiptap/core@2.5.7
+
 ## 2.5.6
 
 ### Patch Changes
diff --git a/packages/extension-hard-break/package.json b/packages/extension-hard-break/package.json
index 0ff84451c2..d139dfe06a 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": "2.5.6",
+  "version": "2.5.9",
   "homepage": "https://tiptap.dev",
   "keywords": [
     "tiptap",
@@ -29,10 +29,10 @@
     "dist"
   ],
   "devDependencies": {
-    "@tiptap/core": "^2.5.6"
+    "@tiptap/core": "^2.5.9"
   },
   "peerDependencies": {
-    "@tiptap/core": "^2.5.6"
+    "@tiptap/core": "^2.5.9"
   },
   "repository": {
     "type": "git",
diff --git a/packages/extension-heading/CHANGELOG.md b/packages/extension-heading/CHANGELOG.md
index 6c32907da5..7847c42250 100644
--- a/packages/extension-heading/CHANGELOG.md
+++ b/packages/extension-heading/CHANGELOG.md
@@ -1,5 +1,30 @@
 # Change Log
 
+## 2.5.9
+
+### Patch Changes
+
+- Updated dependencies [84ebd51]
+- Updated dependencies [0ec0af6]
+- Updated dependencies [ae0254d]
+- Updated dependencies [efb27fa]
+  - @tiptap/core@2.5.9
+
+## 2.5.8
+
+### Patch Changes
+
+- Updated dependencies [a08bf85]
+  - @tiptap/core@2.5.8
+
+## 2.5.7
+
+### Patch Changes
+
+- Updated dependencies [b012471]
+- Updated dependencies [cc3497e]
+  - @tiptap/core@2.5.7
+
 ## 2.5.6
 
 ### Patch Changes
diff --git a/packages/extension-heading/package.json b/packages/extension-heading/package.json
index ea9d79d126..d46b275f2a 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": "2.5.6",
+  "version": "2.5.9",
   "homepage": "https://tiptap.dev",
   "keywords": [
     "tiptap",
@@ -29,10 +29,10 @@
     "dist"
   ],
   "devDependencies": {
-    "@tiptap/core": "^2.5.6"
+    "@tiptap/core": "^2.5.9"
   },
   "peerDependencies": {
-    "@tiptap/core": "^2.5.6"
+    "@tiptap/core": "^2.5.9"
   },
   "repository": {
     "type": "git",
diff --git a/packages/extension-highlight/CHANGELOG.md b/packages/extension-highlight/CHANGELOG.md
index 1af9e407f4..778d9fcaff 100644
--- a/packages/extension-highlight/CHANGELOG.md
+++ b/packages/extension-highlight/CHANGELOG.md
@@ -1,5 +1,30 @@
 # Change Log
 
+## 2.5.9
+
+### Patch Changes
+
+- Updated dependencies [84ebd51]
+- Updated dependencies [0ec0af6]
+- Updated dependencies [ae0254d]
+- Updated dependencies [efb27fa]
+  - @tiptap/core@2.5.9
+
+## 2.5.8
+
+### Patch Changes
+
+- Updated dependencies [a08bf85]
+  - @tiptap/core@2.5.8
+
+## 2.5.7
+
+### Patch Changes
+
+- Updated dependencies [b012471]
+- Updated dependencies [cc3497e]
+  - @tiptap/core@2.5.7
+
 ## 2.5.6
 
 ### Patch Changes
diff --git a/packages/extension-highlight/package.json b/packages/extension-highlight/package.json
index 0b3e80181c..4dc6f7f125 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": "2.5.6",
+  "version": "2.5.9",
   "homepage": "https://tiptap.dev",
   "keywords": [
     "tiptap",
@@ -29,10 +29,10 @@
     "dist"
   ],
   "devDependencies": {
-    "@tiptap/core": "^2.5.6"
+    "@tiptap/core": "^2.5.9"
   },
   "peerDependencies": {
-    "@tiptap/core": "^2.5.6"
+    "@tiptap/core": "^2.5.9"
   },
   "repository": {
     "type": "git",
diff --git a/packages/extension-history/CHANGELOG.md b/packages/extension-history/CHANGELOG.md
index 0ec22dc754..ca5869628a 100644
--- a/packages/extension-history/CHANGELOG.md
+++ b/packages/extension-history/CHANGELOG.md
@@ -1,5 +1,33 @@
 # Change Log
 
+## 2.5.9
+
+### Patch Changes
+
+- Updated dependencies [84ebd51]
+- Updated dependencies [0ec0af6]
+- Updated dependencies [ae0254d]
+- Updated dependencies [efb27fa]
+  - @tiptap/core@2.5.9
+  - @tiptap/pm@2.5.9
+
+## 2.5.8
+
+### Patch Changes
+
+- Updated dependencies [a08bf85]
+  - @tiptap/core@2.5.8
+  - @tiptap/pm@2.5.8
+
+## 2.5.7
+
+### Patch Changes
+
+- Updated dependencies [b012471]
+- Updated dependencies [cc3497e]
+  - @tiptap/core@2.5.7
+  - @tiptap/pm@2.5.7
+
 ## 2.5.6
 
 ### Patch Changes
diff --git a/packages/extension-history/package.json b/packages/extension-history/package.json
index 747ce6e4ea..e3965f6fbe 100644
--- a/packages/extension-history/package.json
+++ b/packages/extension-history/package.json
@@ -1,7 +1,7 @@
 {
   "name": "@tiptap/extension-history",
   "description": "history extension for tiptap",
-  "version": "2.5.6",
+  "version": "2.5.9",
   "homepage": "https://tiptap.dev",
   "keywords": [
     "tiptap",
@@ -29,12 +29,12 @@
     "dist"
   ],
   "devDependencies": {
-    "@tiptap/core": "^2.5.6",
-    "@tiptap/pm": "^2.5.6"
+    "@tiptap/core": "^2.5.9",
+    "@tiptap/pm": "^2.5.9"
   },
   "peerDependencies": {
-    "@tiptap/core": "^2.5.6",
-    "@tiptap/pm": "^2.5.6"
+    "@tiptap/core": "^2.5.9",
+    "@tiptap/pm": "^2.5.9"
   },
   "repository": {
     "type": "git",
diff --git a/packages/extension-horizontal-rule/CHANGELOG.md b/packages/extension-horizontal-rule/CHANGELOG.md
index a212cbdc98..6bb2ce9eec 100644
--- a/packages/extension-horizontal-rule/CHANGELOG.md
+++ b/packages/extension-horizontal-rule/CHANGELOG.md
@@ -1,5 +1,33 @@
 # Change Log
 
+## 2.5.9
+
+### Patch Changes
+
+- Updated dependencies [84ebd51]
+- Updated dependencies [0ec0af6]
+- Updated dependencies [ae0254d]
+- Updated dependencies [efb27fa]
+  - @tiptap/core@2.5.9
+  - @tiptap/pm@2.5.9
+
+## 2.5.8
+
+### Patch Changes
+
+- Updated dependencies [a08bf85]
+  - @tiptap/core@2.5.8
+  - @tiptap/pm@2.5.8
+
+## 2.5.7
+
+### Patch Changes
+
+- Updated dependencies [b012471]
+- Updated dependencies [cc3497e]
+  - @tiptap/core@2.5.7
+  - @tiptap/pm@2.5.7
+
 ## 2.5.6
 
 ### Patch Changes
diff --git a/packages/extension-horizontal-rule/package.json b/packages/extension-horizontal-rule/package.json
index b36fb8b121..874907468d 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": "2.5.6",
+  "version": "2.5.9",
   "homepage": "https://tiptap.dev",
   "keywords": [
     "tiptap",
@@ -29,12 +29,12 @@
     "dist"
   ],
   "devDependencies": {
-    "@tiptap/core": "^2.5.6",
-    "@tiptap/pm": "^2.5.6"
+    "@tiptap/core": "^2.5.9",
+    "@tiptap/pm": "^2.5.9"
   },
   "peerDependencies": {
-    "@tiptap/core": "^2.5.6",
-    "@tiptap/pm": "^2.5.6"
+    "@tiptap/core": "^2.5.9",
+    "@tiptap/pm": "^2.5.9"
   },
   "repository": {
     "type": "git",
diff --git a/packages/extension-image/CHANGELOG.md b/packages/extension-image/CHANGELOG.md
index 07eb07ea42..225f552911 100644
--- a/packages/extension-image/CHANGELOG.md
+++ b/packages/extension-image/CHANGELOG.md
@@ -1,5 +1,30 @@
 # Change Log
 
+## 2.5.9
+
+### Patch Changes
+
+- Updated dependencies [84ebd51]
+- Updated dependencies [0ec0af6]
+- Updated dependencies [ae0254d]
+- Updated dependencies [efb27fa]
+  - @tiptap/core@2.5.9
+
+## 2.5.8
+
+### Patch Changes
+
+- Updated dependencies [a08bf85]
+  - @tiptap/core@2.5.8
+
+## 2.5.7
+
+### Patch Changes
+
+- Updated dependencies [b012471]
+- Updated dependencies [cc3497e]
+  - @tiptap/core@2.5.7
+
 ## 2.5.6
 
 ### Patch Changes
diff --git a/packages/extension-image/package.json b/packages/extension-image/package.json
index c828f0c71f..7ba2fc2796 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": "2.5.6",
+  "version": "2.5.9",
   "homepage": "https://tiptap.dev",
   "keywords": [
     "tiptap",
@@ -29,10 +29,10 @@
     "dist"
   ],
   "devDependencies": {
-    "@tiptap/core": "^2.5.6"
+    "@tiptap/core": "^2.5.9"
   },
   "peerDependencies": {
-    "@tiptap/core": "^2.5.6"
+    "@tiptap/core": "^2.5.9"
   },
   "repository": {
     "type": "git",
diff --git a/packages/extension-italic/CHANGELOG.md b/packages/extension-italic/CHANGELOG.md
index 26d69bc2f0..cea723e70d 100644
--- a/packages/extension-italic/CHANGELOG.md
+++ b/packages/extension-italic/CHANGELOG.md
@@ -1,5 +1,30 @@
 # Change Log
 
+## 2.5.9
+
+### Patch Changes
+
+- Updated dependencies [84ebd51]
+- Updated dependencies [0ec0af6]
+- Updated dependencies [ae0254d]
+- Updated dependencies [efb27fa]
+  - @tiptap/core@2.5.9
+
+## 2.5.8
+
+### Patch Changes
+
+- Updated dependencies [a08bf85]
+  - @tiptap/core@2.5.8
+
+## 2.5.7
+
+### Patch Changes
+
+- Updated dependencies [b012471]
+- Updated dependencies [cc3497e]
+  - @tiptap/core@2.5.7
+
 ## 2.5.6
 
 ### Patch Changes
diff --git a/packages/extension-italic/package.json b/packages/extension-italic/package.json
index 4742c30452..e5083adb0c 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": "2.5.6",
+  "version": "2.5.9",
   "homepage": "https://tiptap.dev",
   "keywords": [
     "tiptap",
@@ -29,10 +29,10 @@
     "dist"
   ],
   "devDependencies": {
-    "@tiptap/core": "^2.5.6"
+    "@tiptap/core": "^2.5.9"
   },
   "peerDependencies": {
-    "@tiptap/core": "^2.5.6"
+    "@tiptap/core": "^2.5.9"
   },
   "repository": {
     "type": "git",
diff --git a/packages/extension-link/CHANGELOG.md b/packages/extension-link/CHANGELOG.md
index 851cd49c29..06f5b628f3 100644
--- a/packages/extension-link/CHANGELOG.md
+++ b/packages/extension-link/CHANGELOG.md
@@ -1,5 +1,33 @@
 # Change Log
 
+## 2.5.9
+
+### Patch Changes
+
+- Updated dependencies [84ebd51]
+- Updated dependencies [0ec0af6]
+- Updated dependencies [ae0254d]
+- Updated dependencies [efb27fa]
+  - @tiptap/core@2.5.9
+  - @tiptap/pm@2.5.9
+
+## 2.5.8
+
+### Patch Changes
+
+- Updated dependencies [a08bf85]
+  - @tiptap/core@2.5.8
+  - @tiptap/pm@2.5.8
+
+## 2.5.7
+
+### Patch Changes
+
+- Updated dependencies [b012471]
+- Updated dependencies [cc3497e]
+  - @tiptap/core@2.5.7
+  - @tiptap/pm@2.5.7
+
 ## 2.5.6
 
 ### Patch Changes
diff --git a/packages/extension-link/package.json b/packages/extension-link/package.json
index 4b56843e80..dcd5aab6e9 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": "2.5.6",
+  "version": "2.5.9",
   "homepage": "https://tiptap.dev",
   "keywords": [
     "tiptap",
@@ -32,12 +32,12 @@
     "linkifyjs": "^4.1.0"
   },
   "devDependencies": {
-    "@tiptap/core": "^2.5.6",
-    "@tiptap/pm": "^2.5.6"
+    "@tiptap/core": "^2.5.9",
+    "@tiptap/pm": "^2.5.9"
   },
   "peerDependencies": {
-    "@tiptap/core": "^2.5.6",
-    "@tiptap/pm": "^2.5.6"
+    "@tiptap/core": "^2.5.9",
+    "@tiptap/pm": "^2.5.9"
   },
   "repository": {
     "type": "git",
diff --git a/packages/extension-list-item/CHANGELOG.md b/packages/extension-list-item/CHANGELOG.md
index ac89f44019..80507e8a37 100644
--- a/packages/extension-list-item/CHANGELOG.md
+++ b/packages/extension-list-item/CHANGELOG.md
@@ -1,5 +1,30 @@
 # Change Log
 
+## 2.5.9
+
+### Patch Changes
+
+- Updated dependencies [84ebd51]
+- Updated dependencies [0ec0af6]
+- Updated dependencies [ae0254d]
+- Updated dependencies [efb27fa]
+  - @tiptap/core@2.5.9
+
+## 2.5.8
+
+### Patch Changes
+
+- Updated dependencies [a08bf85]
+  - @tiptap/core@2.5.8
+
+## 2.5.7
+
+### Patch Changes
+
+- Updated dependencies [b012471]
+- Updated dependencies [cc3497e]
+  - @tiptap/core@2.5.7
+
 ## 2.5.6
 
 ### Patch Changes
diff --git a/packages/extension-list-item/package.json b/packages/extension-list-item/package.json
index 8d1e6cd09d..e084fdf465 100644
--- a/packages/extension-list-item/package.json
+++ b/packages/extension-list-item/package.json
@@ -1,7 +1,7 @@
 {
   "name": "@tiptap/extension-list-item",
   "description": "list item extension for tiptap",
-  "version": "2.5.6",
+  "version": "2.5.9",
   "homepage": "https://tiptap.dev",
   "keywords": [
     "tiptap",
@@ -29,10 +29,10 @@
     "dist"
   ],
   "devDependencies": {
-    "@tiptap/core": "^2.5.6"
+    "@tiptap/core": "^2.5.9"
   },
   "peerDependencies": {
-    "@tiptap/core": "^2.5.6"
+    "@tiptap/core": "^2.5.9"
   },
   "repository": {
     "type": "git",
diff --git a/packages/extension-list-keymap/CHANGELOG.md b/packages/extension-list-keymap/CHANGELOG.md
index a21376d76c..c13cd69d98 100644
--- a/packages/extension-list-keymap/CHANGELOG.md
+++ b/packages/extension-list-keymap/CHANGELOG.md
@@ -1,5 +1,30 @@
 # Change Log
 
+## 2.5.9
+
+### Patch Changes
+
+- Updated dependencies [84ebd51]
+- Updated dependencies [0ec0af6]
+- Updated dependencies [ae0254d]
+- Updated dependencies [efb27fa]
+  - @tiptap/core@2.5.9
+
+## 2.5.8
+
+### Patch Changes
+
+- Updated dependencies [a08bf85]
+  - @tiptap/core@2.5.8
+
+## 2.5.7
+
+### Patch Changes
+
+- Updated dependencies [b012471]
+- Updated dependencies [cc3497e]
+  - @tiptap/core@2.5.7
+
 ## 2.5.6
 
 ### Patch Changes
diff --git a/packages/extension-list-keymap/package.json b/packages/extension-list-keymap/package.json
index b438042d40..752ae0d144 100644
--- a/packages/extension-list-keymap/package.json
+++ b/packages/extension-list-keymap/package.json
@@ -1,7 +1,7 @@
 {
   "name": "@tiptap/extension-list-keymap",
   "description": "list keymap extension for tiptap",
-  "version": "2.5.6",
+  "version": "2.5.9",
   "homepage": "https://tiptap.dev",
   "keywords": [
     "tiptap",
@@ -29,10 +29,10 @@
     "dist"
   ],
   "devDependencies": {
-    "@tiptap/core": "^2.5.6"
+    "@tiptap/core": "^2.5.9"
   },
   "peerDependencies": {
-    "@tiptap/core": "^2.5.6"
+    "@tiptap/core": "^2.5.9"
   },
   "repository": {
     "type": "git",
diff --git a/packages/extension-mention/CHANGELOG.md b/packages/extension-mention/CHANGELOG.md
index de80e11f12..70d3500822 100644
--- a/packages/extension-mention/CHANGELOG.md
+++ b/packages/extension-mention/CHANGELOG.md
@@ -1,5 +1,36 @@
 # Change Log
 
+## 2.5.9
+
+### Patch Changes
+
+- Updated dependencies [84ebd51]
+- Updated dependencies [0ec0af6]
+- Updated dependencies [ae0254d]
+- Updated dependencies [efb27fa]
+  - @tiptap/core@2.5.9
+  - @tiptap/pm@2.5.9
+  - @tiptap/suggestion@2.5.9
+
+## 2.5.8
+
+### Patch Changes
+
+- Updated dependencies [a08bf85]
+  - @tiptap/core@2.5.8
+  - @tiptap/pm@2.5.8
+  - @tiptap/suggestion@2.5.8
+
+## 2.5.7
+
+### Patch Changes
+
+- Updated dependencies [b012471]
+- Updated dependencies [cc3497e]
+  - @tiptap/core@2.5.7
+  - @tiptap/pm@2.5.7
+  - @tiptap/suggestion@2.5.7
+
 ## 2.5.6
 
 ### Patch Changes
diff --git a/packages/extension-mention/package.json b/packages/extension-mention/package.json
index 4123beab2a..7bd17ccbf1 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": "2.5.6",
+  "version": "2.5.9",
   "homepage": "https://tiptap.dev",
   "keywords": [
     "tiptap",
@@ -29,14 +29,14 @@
     "dist"
   ],
   "devDependencies": {
-    "@tiptap/core": "^2.5.6",
-    "@tiptap/pm": "^2.5.6",
-    "@tiptap/suggestion": "^2.5.6"
+    "@tiptap/core": "^2.5.9",
+    "@tiptap/pm": "^2.5.9",
+    "@tiptap/suggestion": "^2.5.9"
   },
   "peerDependencies": {
-    "@tiptap/core": "^2.5.6",
-    "@tiptap/pm": "^2.5.6",
-    "@tiptap/suggestion": "^2.5.6"
+    "@tiptap/core": "^2.5.9",
+    "@tiptap/pm": "^2.5.9",
+    "@tiptap/suggestion": "^2.5.9"
   },
   "repository": {
     "type": "git",
diff --git a/packages/extension-ordered-list/CHANGELOG.md b/packages/extension-ordered-list/CHANGELOG.md
index c6e425605f..0cd7cc0d73 100644
--- a/packages/extension-ordered-list/CHANGELOG.md
+++ b/packages/extension-ordered-list/CHANGELOG.md
@@ -1,5 +1,30 @@
 # Change Log
 
+## 2.5.9
+
+### Patch Changes
+
+- Updated dependencies [84ebd51]
+- Updated dependencies [0ec0af6]
+- Updated dependencies [ae0254d]
+- Updated dependencies [efb27fa]
+  - @tiptap/core@2.5.9
+
+## 2.5.8
+
+### Patch Changes
+
+- Updated dependencies [a08bf85]
+  - @tiptap/core@2.5.8
+
+## 2.5.7
+
+### Patch Changes
+
+- Updated dependencies [b012471]
+- Updated dependencies [cc3497e]
+  - @tiptap/core@2.5.7
+
 ## 2.5.6
 
 ### Patch Changes
diff --git a/packages/extension-ordered-list/package.json b/packages/extension-ordered-list/package.json
index 579ba51d75..a61c9761f4 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": "2.5.6",
+  "version": "2.5.9",
   "homepage": "https://tiptap.dev",
   "keywords": [
     "tiptap",
@@ -29,10 +29,10 @@
     "dist"
   ],
   "devDependencies": {
-    "@tiptap/core": "^2.5.6"
+    "@tiptap/core": "^2.5.9"
   },
   "peerDependencies": {
-    "@tiptap/core": "^2.5.6"
+    "@tiptap/core": "^2.5.9"
   },
   "repository": {
     "type": "git",
diff --git a/packages/extension-paragraph/CHANGELOG.md b/packages/extension-paragraph/CHANGELOG.md
index c589a14acd..524ecd339b 100644
--- a/packages/extension-paragraph/CHANGELOG.md
+++ b/packages/extension-paragraph/CHANGELOG.md
@@ -1,5 +1,30 @@
 # Change Log
 
+## 2.5.9
+
+### Patch Changes
+
+- Updated dependencies [84ebd51]
+- Updated dependencies [0ec0af6]
+- Updated dependencies [ae0254d]
+- Updated dependencies [efb27fa]
+  - @tiptap/core@2.5.9
+
+## 2.5.8
+
+### Patch Changes
+
+- Updated dependencies [a08bf85]
+  - @tiptap/core@2.5.8
+
+## 2.5.7
+
+### Patch Changes
+
+- Updated dependencies [b012471]
+- Updated dependencies [cc3497e]
+  - @tiptap/core@2.5.7
+
 ## 2.5.6
 
 ### Patch Changes
diff --git a/packages/extension-paragraph/package.json b/packages/extension-paragraph/package.json
index eee64001ca..bfbf45f340 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": "2.5.6",
+  "version": "2.5.9",
   "homepage": "https://tiptap.dev",
   "keywords": [
     "tiptap",
@@ -29,10 +29,10 @@
     "dist"
   ],
   "devDependencies": {
-    "@tiptap/core": "^2.5.6"
+    "@tiptap/core": "^2.5.9"
   },
   "peerDependencies": {
-    "@tiptap/core": "^2.5.6"
+    "@tiptap/core": "^2.5.9"
   },
   "repository": {
     "type": "git",
diff --git a/packages/extension-placeholder/CHANGELOG.md b/packages/extension-placeholder/CHANGELOG.md
index 98bd672943..40f89124da 100644
--- a/packages/extension-placeholder/CHANGELOG.md
+++ b/packages/extension-placeholder/CHANGELOG.md
@@ -1,5 +1,35 @@
 # Change Log
 
+## 2.5.9
+
+### Patch Changes
+
+- c1ff1b0: add back `considerAsAny` type but mark it deprecated
+- Updated dependencies [84ebd51]
+- Updated dependencies [0ec0af6]
+- Updated dependencies [ae0254d]
+- Updated dependencies [efb27fa]
+  - @tiptap/core@2.5.9
+  - @tiptap/pm@2.5.9
+
+## 2.5.8
+
+### Patch Changes
+
+- Updated dependencies [a08bf85]
+  - @tiptap/core@2.5.8
+  - @tiptap/pm@2.5.8
+
+## 2.5.7
+
+### Patch Changes
+
+- b012471: This addresses an issue with `isNodeEmpty` function where it was also comparing node attributes and finding mismatches on actually empty nodes. This helps placeholders find empty content correctly
+- Updated dependencies [b012471]
+- Updated dependencies [cc3497e]
+  - @tiptap/core@2.5.7
+  - @tiptap/pm@2.5.7
+
 ## 2.5.6
 
 ### Patch Changes
diff --git a/packages/extension-placeholder/package.json b/packages/extension-placeholder/package.json
index 73a741f8df..14dba9cfd9 100644
--- a/packages/extension-placeholder/package.json
+++ b/packages/extension-placeholder/package.json
@@ -1,7 +1,7 @@
 {
   "name": "@tiptap/extension-placeholder",
   "description": "placeholder extension for tiptap",
-  "version": "2.5.6",
+  "version": "2.5.9",
   "homepage": "https://tiptap.dev",
   "keywords": [
     "tiptap",
@@ -29,12 +29,12 @@
     "dist"
   ],
   "devDependencies": {
-    "@tiptap/core": "^2.5.6",
-    "@tiptap/pm": "^2.5.6"
+    "@tiptap/core": "^2.5.9",
+    "@tiptap/pm": "^2.5.9"
   },
   "peerDependencies": {
-    "@tiptap/core": "^2.5.6",
-    "@tiptap/pm": "^2.5.6"
+    "@tiptap/core": "^2.5.9",
+    "@tiptap/pm": "^2.5.9"
   },
   "repository": {
     "type": "git",
diff --git a/packages/extension-placeholder/src/placeholder.ts b/packages/extension-placeholder/src/placeholder.ts
index ad0fb86384..08427a257c 100644
--- a/packages/extension-placeholder/src/placeholder.ts
+++ b/packages/extension-placeholder/src/placeholder.ts
@@ -31,6 +31,12 @@ export interface PlaceholderOptions {
       }) => string)
     | string
 
+  /**
+   * See https://github.com/ueberdosis/tiptap/pull/5278 for more information.
+   * @deprecated This option is no longer respected and this type will be removed in the next major version.
+   */
+  considerAnyAsEmpty?: boolean
+
   /**
    * **Checks if the placeholder should be only shown when the editor is editable.**
    *
diff --git a/packages/extension-strike/CHANGELOG.md b/packages/extension-strike/CHANGELOG.md
index 0a5e914dfc..b7f2117ce4 100644
--- a/packages/extension-strike/CHANGELOG.md
+++ b/packages/extension-strike/CHANGELOG.md
@@ -1,5 +1,30 @@
 # Change Log
 
+## 2.5.9
+
+### Patch Changes
+
+- Updated dependencies [84ebd51]
+- Updated dependencies [0ec0af6]
+- Updated dependencies [ae0254d]
+- Updated dependencies [efb27fa]
+  - @tiptap/core@2.5.9
+
+## 2.5.8
+
+### Patch Changes
+
+- Updated dependencies [a08bf85]
+  - @tiptap/core@2.5.8
+
+## 2.5.7
+
+### Patch Changes
+
+- Updated dependencies [b012471]
+- Updated dependencies [cc3497e]
+  - @tiptap/core@2.5.7
+
 ## 2.5.6
 
 ### Patch Changes
diff --git a/packages/extension-strike/package.json b/packages/extension-strike/package.json
index 7e4d05966c..05f0ab21cc 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": "2.5.6",
+  "version": "2.5.9",
   "homepage": "https://tiptap.dev",
   "keywords": [
     "tiptap",
@@ -29,10 +29,10 @@
     "dist"
   ],
   "devDependencies": {
-    "@tiptap/core": "^2.5.6"
+    "@tiptap/core": "^2.5.9"
   },
   "peerDependencies": {
-    "@tiptap/core": "^2.5.6"
+    "@tiptap/core": "^2.5.9"
   },
   "repository": {
     "type": "git",
diff --git a/packages/extension-subscript/CHANGELOG.md b/packages/extension-subscript/CHANGELOG.md
index 8ebaf6c088..8c4235abf3 100644
--- a/packages/extension-subscript/CHANGELOG.md
+++ b/packages/extension-subscript/CHANGELOG.md
@@ -1,5 +1,30 @@
 # Change Log
 
+## 2.5.9
+
+### Patch Changes
+
+- Updated dependencies [84ebd51]
+- Updated dependencies [0ec0af6]
+- Updated dependencies [ae0254d]
+- Updated dependencies [efb27fa]
+  - @tiptap/core@2.5.9
+
+## 2.5.8
+
+### Patch Changes
+
+- Updated dependencies [a08bf85]
+  - @tiptap/core@2.5.8
+
+## 2.5.7
+
+### Patch Changes
+
+- Updated dependencies [b012471]
+- Updated dependencies [cc3497e]
+  - @tiptap/core@2.5.7
+
 ## 2.5.6
 
 ### Patch Changes
diff --git a/packages/extension-subscript/package.json b/packages/extension-subscript/package.json
index 59215fadd7..aa76a2f3d8 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": "2.5.6",
+  "version": "2.5.9",
   "homepage": "https://tiptap.dev",
   "keywords": [
     "tiptap",
@@ -29,10 +29,10 @@
     "dist"
   ],
   "devDependencies": {
-    "@tiptap/core": "^2.5.6"
+    "@tiptap/core": "^2.5.9"
   },
   "peerDependencies": {
-    "@tiptap/core": "^2.5.6"
+    "@tiptap/core": "^2.5.9"
   },
   "repository": {
     "type": "git",
diff --git a/packages/extension-superscript/CHANGELOG.md b/packages/extension-superscript/CHANGELOG.md
index 848eeb6998..8f467e3c22 100644
--- a/packages/extension-superscript/CHANGELOG.md
+++ b/packages/extension-superscript/CHANGELOG.md
@@ -1,5 +1,30 @@
 # Change Log
 
+## 2.5.9
+
+### Patch Changes
+
+- Updated dependencies [84ebd51]
+- Updated dependencies [0ec0af6]
+- Updated dependencies [ae0254d]
+- Updated dependencies [efb27fa]
+  - @tiptap/core@2.5.9
+
+## 2.5.8
+
+### Patch Changes
+
+- Updated dependencies [a08bf85]
+  - @tiptap/core@2.5.8
+
+## 2.5.7
+
+### Patch Changes
+
+- Updated dependencies [b012471]
+- Updated dependencies [cc3497e]
+  - @tiptap/core@2.5.7
+
 ## 2.5.6
 
 ### Patch Changes
diff --git a/packages/extension-superscript/package.json b/packages/extension-superscript/package.json
index f2dfea67de..3b96de1b20 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": "2.5.6",
+  "version": "2.5.9",
   "homepage": "https://tiptap.dev",
   "keywords": [
     "tiptap",
@@ -29,10 +29,10 @@
     "dist"
   ],
   "devDependencies": {
-    "@tiptap/core": "^2.5.6"
+    "@tiptap/core": "^2.5.9"
   },
   "peerDependencies": {
-    "@tiptap/core": "^2.5.6"
+    "@tiptap/core": "^2.5.9"
   },
   "repository": {
     "type": "git",
diff --git a/packages/extension-table-cell/CHANGELOG.md b/packages/extension-table-cell/CHANGELOG.md
index a254d7326a..05320ef424 100644
--- a/packages/extension-table-cell/CHANGELOG.md
+++ b/packages/extension-table-cell/CHANGELOG.md
@@ -1,5 +1,30 @@
 # Change Log
 
+## 2.5.9
+
+### Patch Changes
+
+- Updated dependencies [84ebd51]
+- Updated dependencies [0ec0af6]
+- Updated dependencies [ae0254d]
+- Updated dependencies [efb27fa]
+  - @tiptap/core@2.5.9
+
+## 2.5.8
+
+### Patch Changes
+
+- Updated dependencies [a08bf85]
+  - @tiptap/core@2.5.8
+
+## 2.5.7
+
+### Patch Changes
+
+- Updated dependencies [b012471]
+- Updated dependencies [cc3497e]
+  - @tiptap/core@2.5.7
+
 ## 2.5.6
 
 ### Patch Changes
diff --git a/packages/extension-table-cell/package.json b/packages/extension-table-cell/package.json
index abb0d5b1c9..0ac19733bd 100644
--- a/packages/extension-table-cell/package.json
+++ b/packages/extension-table-cell/package.json
@@ -1,7 +1,7 @@
 {
   "name": "@tiptap/extension-table-cell",
   "description": "table cell extension for tiptap",
-  "version": "2.5.6",
+  "version": "2.5.9",
   "homepage": "https://tiptap.dev",
   "keywords": [
     "tiptap",
@@ -29,10 +29,10 @@
     "dist"
   ],
   "devDependencies": {
-    "@tiptap/core": "^2.5.6"
+    "@tiptap/core": "^2.5.9"
   },
   "peerDependencies": {
-    "@tiptap/core": "^2.5.6"
+    "@tiptap/core": "^2.5.9"
   },
   "repository": {
     "type": "git",
diff --git a/packages/extension-table-header/CHANGELOG.md b/packages/extension-table-header/CHANGELOG.md
index 805174c96d..3ab1f2c724 100644
--- a/packages/extension-table-header/CHANGELOG.md
+++ b/packages/extension-table-header/CHANGELOG.md
@@ -1,5 +1,30 @@
 # Change Log
 
+## 2.5.9
+
+### Patch Changes
+
+- Updated dependencies [84ebd51]
+- Updated dependencies [0ec0af6]
+- Updated dependencies [ae0254d]
+- Updated dependencies [efb27fa]
+  - @tiptap/core@2.5.9
+
+## 2.5.8
+
+### Patch Changes
+
+- Updated dependencies [a08bf85]
+  - @tiptap/core@2.5.8
+
+## 2.5.7
+
+### Patch Changes
+
+- Updated dependencies [b012471]
+- Updated dependencies [cc3497e]
+  - @tiptap/core@2.5.7
+
 ## 2.5.6
 
 ### Patch Changes
diff --git a/packages/extension-table-header/package.json b/packages/extension-table-header/package.json
index 734806c379..a0afa8ae5f 100644
--- a/packages/extension-table-header/package.json
+++ b/packages/extension-table-header/package.json
@@ -1,7 +1,7 @@
 {
   "name": "@tiptap/extension-table-header",
   "description": "table cell extension for tiptap",
-  "version": "2.5.6",
+  "version": "2.5.9",
   "homepage": "https://tiptap.dev",
   "keywords": [
     "tiptap",
@@ -29,10 +29,10 @@
     "dist"
   ],
   "devDependencies": {
-    "@tiptap/core": "^2.5.6"
+    "@tiptap/core": "^2.5.9"
   },
   "peerDependencies": {
-    "@tiptap/core": "^2.5.6"
+    "@tiptap/core": "^2.5.9"
   },
   "repository": {
     "type": "git",
diff --git a/packages/extension-table-row/CHANGELOG.md b/packages/extension-table-row/CHANGELOG.md
index db1741a7c3..b3a912d3b2 100644
--- a/packages/extension-table-row/CHANGELOG.md
+++ b/packages/extension-table-row/CHANGELOG.md
@@ -1,5 +1,30 @@
 # Change Log
 
+## 2.5.9
+
+### Patch Changes
+
+- Updated dependencies [84ebd51]
+- Updated dependencies [0ec0af6]
+- Updated dependencies [ae0254d]
+- Updated dependencies [efb27fa]
+  - @tiptap/core@2.5.9
+
+## 2.5.8
+
+### Patch Changes
+
+- Updated dependencies [a08bf85]
+  - @tiptap/core@2.5.8
+
+## 2.5.7
+
+### Patch Changes
+
+- Updated dependencies [b012471]
+- Updated dependencies [cc3497e]
+  - @tiptap/core@2.5.7
+
 ## 2.5.6
 
 ### Patch Changes
diff --git a/packages/extension-table-row/package.json b/packages/extension-table-row/package.json
index 9259b4bfb5..0f80056f75 100644
--- a/packages/extension-table-row/package.json
+++ b/packages/extension-table-row/package.json
@@ -1,7 +1,7 @@
 {
   "name": "@tiptap/extension-table-row",
   "description": "table row extension for tiptap",
-  "version": "2.5.6",
+  "version": "2.5.9",
   "homepage": "https://tiptap.dev",
   "keywords": [
     "tiptap",
@@ -29,10 +29,10 @@
     "dist"
   ],
   "devDependencies": {
-    "@tiptap/core": "^2.5.6"
+    "@tiptap/core": "^2.5.9"
   },
   "peerDependencies": {
-    "@tiptap/core": "^2.5.6"
+    "@tiptap/core": "^2.5.9"
   },
   "repository": {
     "type": "git",
diff --git a/packages/extension-table/CHANGELOG.md b/packages/extension-table/CHANGELOG.md
index dc3a6aea93..6e681f0776 100644
--- a/packages/extension-table/CHANGELOG.md
+++ b/packages/extension-table/CHANGELOG.md
@@ -1,5 +1,33 @@
 # Change Log
 
+## 2.5.9
+
+### Patch Changes
+
+- Updated dependencies [84ebd51]
+- Updated dependencies [0ec0af6]
+- Updated dependencies [ae0254d]
+- Updated dependencies [efb27fa]
+  - @tiptap/core@2.5.9
+  - @tiptap/pm@2.5.9
+
+## 2.5.8
+
+### Patch Changes
+
+- Updated dependencies [a08bf85]
+  - @tiptap/core@2.5.8
+  - @tiptap/pm@2.5.8
+
+## 2.5.7
+
+### Patch Changes
+
+- Updated dependencies [b012471]
+- Updated dependencies [cc3497e]
+  - @tiptap/core@2.5.7
+  - @tiptap/pm@2.5.7
+
 ## 2.5.6
 
 ### Patch Changes
diff --git a/packages/extension-table/package.json b/packages/extension-table/package.json
index e6834f6b56..6955456ac8 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": "2.5.6",
+  "version": "2.5.9",
   "homepage": "https://tiptap.dev",
   "keywords": [
     "tiptap",
@@ -29,12 +29,12 @@
     "dist"
   ],
   "devDependencies": {
-    "@tiptap/core": "^2.5.6",
-    "@tiptap/pm": "^2.5.6"
+    "@tiptap/core": "^2.5.9",
+    "@tiptap/pm": "^2.5.9"
   },
   "peerDependencies": {
-    "@tiptap/core": "^2.5.6",
-    "@tiptap/pm": "^2.5.6"
+    "@tiptap/core": "^2.5.9",
+    "@tiptap/pm": "^2.5.9"
   },
   "repository": {
     "type": "git",
diff --git a/packages/extension-table/src/table.ts b/packages/extension-table/src/table.ts
index 5a6fa4fb81..5edd03a414 100644
--- a/packages/extension-table/src/table.ts
+++ b/packages/extension-table/src/table.ts
@@ -1,7 +1,7 @@
 import {
   callOrReturn, getExtensionField, mergeAttributes, Node, ParentConfig,
 } from '@tiptap/core'
-import { DOMOutputSpec } from '@tiptap/pm/model'
+import { DOMOutputSpec, Node as ProseMirrorNode } from '@tiptap/pm/model'
 import { TextSelection } from '@tiptap/pm/state'
 import {
   addColumnAfter,
@@ -22,7 +22,7 @@ import {
   toggleHeader,
   toggleHeaderCell,
 } from '@tiptap/pm/tables'
-import { NodeView } from '@tiptap/pm/view'
+import { EditorView, NodeView } from '@tiptap/pm/view'
 
 import { TableView } from './TableView.js'
 import { createColGroup } from './utilities/createColGroup.js'
@@ -62,7 +62,7 @@ export interface TableOptions {
    * The node view to render the table.
    * @default TableView
    */
-  View: NodeView
+  View: (new (node: ProseMirrorNode, cellMinWidth: number, view: EditorView) => NodeView) | null
 
   /**
    * Enables the resizing of the last column.
@@ -98,7 +98,7 @@ declare module '@tiptap/core' {
        * Add a column before the current column
        * @returns True if the command was successful, otherwise false
        * @example editor.commands.addColumnBefore()
-      */
+       */
       addColumnBefore: () => ReturnType
 
       /**
@@ -234,11 +234,11 @@ declare module '@tiptap/core' {
     tableRole?:
       | string
       | ((this: {
-          name: string
-          options: Options
-          storage: Storage
-          parent: ParentConfig>['tableRole']
-        }) => string)
+      name: string
+      options: Options
+      storage: Storage
+      parent: ParentConfig>['tableRole']
+    }) => string)
   }
 }
 
@@ -431,10 +431,7 @@ export const Table = Node.create({
           columnResizing({
             handleWidth: this.options.handleWidth,
             cellMinWidth: this.options.cellMinWidth,
-            // @ts-ignore (incorrect type)
             View: this.options.View,
-            // TODO: PR for @types/prosemirror-tables
-            // @ts-ignore (incorrect type)
             lastColumnResizable: this.options.lastColumnResizable,
           }),
         ]
diff --git a/packages/extension-task-item/CHANGELOG.md b/packages/extension-task-item/CHANGELOG.md
index d169269447..572ffe2412 100644
--- a/packages/extension-task-item/CHANGELOG.md
+++ b/packages/extension-task-item/CHANGELOG.md
@@ -1,5 +1,34 @@
 # Change Log
 
+## 2.5.9
+
+### Patch Changes
+
+- 6543f05: allow task items to be parsed when only having `
  • ({ parseHTML: element => { const dataChecked = element.getAttribute('data-checked') - return dataChecked == null || dataChecked === 'true' + return dataChecked === '' || dataChecked === 'true' }, renderHTML: attributes => ({ 'data-checked': attributes.checked, diff --git a/packages/extension-task-list/CHANGELOG.md b/packages/extension-task-list/CHANGELOG.md index 0b34006ef8..a0dc089fe8 100644 --- a/packages/extension-task-list/CHANGELOG.md +++ b/packages/extension-task-list/CHANGELOG.md @@ -1,5 +1,30 @@ # Change Log +## 2.5.9 + +### Patch Changes + +- Updated dependencies [84ebd51] +- Updated dependencies [0ec0af6] +- Updated dependencies [ae0254d] +- Updated dependencies [efb27fa] + - @tiptap/core@2.5.9 + +## 2.5.8 + +### Patch Changes + +- Updated dependencies [a08bf85] + - @tiptap/core@2.5.8 + +## 2.5.7 + +### Patch Changes + +- Updated dependencies [b012471] +- Updated dependencies [cc3497e] + - @tiptap/core@2.5.7 + ## 2.5.6 ### Patch Changes diff --git a/packages/extension-task-list/package.json b/packages/extension-task-list/package.json index bb463ca201..c643b28868 100644 --- a/packages/extension-task-list/package.json +++ b/packages/extension-task-list/package.json @@ -1,7 +1,7 @@ { "name": "@tiptap/extension-task-list", "description": "task list extension for tiptap", - "version": "2.5.6", + "version": "2.5.9", "homepage": "https://tiptap.dev", "keywords": [ "tiptap", @@ -29,10 +29,10 @@ "dist" ], "devDependencies": { - "@tiptap/core": "^2.5.6" + "@tiptap/core": "^2.5.9" }, "peerDependencies": { - "@tiptap/core": "^2.5.6" + "@tiptap/core": "^2.5.9" }, "repository": { "type": "git", diff --git a/packages/extension-text-align/CHANGELOG.md b/packages/extension-text-align/CHANGELOG.md index 66628c1279..3b41de58bb 100644 --- a/packages/extension-text-align/CHANGELOG.md +++ b/packages/extension-text-align/CHANGELOG.md @@ -1,5 +1,30 @@ # Change Log +## 2.5.9 + +### Patch Changes + +- Updated dependencies [84ebd51] +- Updated dependencies [0ec0af6] +- Updated dependencies [ae0254d] +- Updated dependencies [efb27fa] + - @tiptap/core@2.5.9 + +## 2.5.8 + +### Patch Changes + +- Updated dependencies [a08bf85] + - @tiptap/core@2.5.8 + +## 2.5.7 + +### Patch Changes + +- Updated dependencies [b012471] +- Updated dependencies [cc3497e] + - @tiptap/core@2.5.7 + ## 2.5.6 ### Patch Changes diff --git a/packages/extension-text-align/package.json b/packages/extension-text-align/package.json index 9855d2655f..f0f158ebea 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": "2.5.6", + "version": "2.5.9", "homepage": "https://tiptap.dev", "keywords": [ "tiptap", @@ -29,10 +29,10 @@ "dist" ], "devDependencies": { - "@tiptap/core": "^2.5.6" + "@tiptap/core": "^2.5.9" }, "peerDependencies": { - "@tiptap/core": "^2.5.6" + "@tiptap/core": "^2.5.9" }, "repository": { "type": "git", diff --git a/packages/extension-text-style/CHANGELOG.md b/packages/extension-text-style/CHANGELOG.md index a355131916..4ca4c60fd2 100644 --- a/packages/extension-text-style/CHANGELOG.md +++ b/packages/extension-text-style/CHANGELOG.md @@ -1,5 +1,30 @@ # Change Log +## 2.5.9 + +### Patch Changes + +- Updated dependencies [84ebd51] +- Updated dependencies [0ec0af6] +- Updated dependencies [ae0254d] +- Updated dependencies [efb27fa] + - @tiptap/core@2.5.9 + +## 2.5.8 + +### Patch Changes + +- Updated dependencies [a08bf85] + - @tiptap/core@2.5.8 + +## 2.5.7 + +### Patch Changes + +- Updated dependencies [b012471] +- Updated dependencies [cc3497e] + - @tiptap/core@2.5.7 + ## 2.5.6 ### Patch Changes diff --git a/packages/extension-text-style/package.json b/packages/extension-text-style/package.json index 170bb2426d..66ba0a652e 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": "2.5.6", + "version": "2.5.9", "homepage": "https://tiptap.dev", "keywords": [ "tiptap", @@ -29,10 +29,10 @@ "dist" ], "devDependencies": { - "@tiptap/core": "^2.5.6" + "@tiptap/core": "^2.5.9" }, "peerDependencies": { - "@tiptap/core": "^2.5.6" + "@tiptap/core": "^2.5.9" }, "repository": { "type": "git", diff --git a/packages/extension-text/CHANGELOG.md b/packages/extension-text/CHANGELOG.md index 6ba0ea04e7..9363f40231 100644 --- a/packages/extension-text/CHANGELOG.md +++ b/packages/extension-text/CHANGELOG.md @@ -1,5 +1,30 @@ # Change Log +## 2.5.9 + +### Patch Changes + +- Updated dependencies [84ebd51] +- Updated dependencies [0ec0af6] +- Updated dependencies [ae0254d] +- Updated dependencies [efb27fa] + - @tiptap/core@2.5.9 + +## 2.5.8 + +### Patch Changes + +- Updated dependencies [a08bf85] + - @tiptap/core@2.5.8 + +## 2.5.7 + +### Patch Changes + +- Updated dependencies [b012471] +- Updated dependencies [cc3497e] + - @tiptap/core@2.5.7 + ## 2.5.6 ### Patch Changes diff --git a/packages/extension-text/package.json b/packages/extension-text/package.json index 6b5fe7d081..bd4513c274 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": "2.5.6", + "version": "2.5.9", "homepage": "https://tiptap.dev", "keywords": [ "tiptap", @@ -29,10 +29,10 @@ "dist" ], "devDependencies": { - "@tiptap/core": "^2.5.6" + "@tiptap/core": "^2.5.9" }, "peerDependencies": { - "@tiptap/core": "^2.5.6" + "@tiptap/core": "^2.5.9" }, "repository": { "type": "git", diff --git a/packages/extension-typography/CHANGELOG.md b/packages/extension-typography/CHANGELOG.md index f46e604b2d..64da378720 100644 --- a/packages/extension-typography/CHANGELOG.md +++ b/packages/extension-typography/CHANGELOG.md @@ -1,5 +1,30 @@ # Change Log +## 2.5.9 + +### Patch Changes + +- Updated dependencies [84ebd51] +- Updated dependencies [0ec0af6] +- Updated dependencies [ae0254d] +- Updated dependencies [efb27fa] + - @tiptap/core@2.5.9 + +## 2.5.8 + +### Patch Changes + +- Updated dependencies [a08bf85] + - @tiptap/core@2.5.8 + +## 2.5.7 + +### Patch Changes + +- Updated dependencies [b012471] +- Updated dependencies [cc3497e] + - @tiptap/core@2.5.7 + ## 2.5.6 ### Patch Changes diff --git a/packages/extension-typography/package.json b/packages/extension-typography/package.json index 00c90d0bb4..7135120e30 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": "2.5.6", + "version": "2.5.9", "homepage": "https://tiptap.dev", "keywords": [ "tiptap", @@ -29,10 +29,10 @@ "dist" ], "devDependencies": { - "@tiptap/core": "^2.5.6" + "@tiptap/core": "^2.5.9" }, "peerDependencies": { - "@tiptap/core": "^2.5.6" + "@tiptap/core": "^2.5.9" }, "repository": { "type": "git", diff --git a/packages/extension-underline/CHANGELOG.md b/packages/extension-underline/CHANGELOG.md index 7320305fd9..35761bd698 100644 --- a/packages/extension-underline/CHANGELOG.md +++ b/packages/extension-underline/CHANGELOG.md @@ -1,5 +1,30 @@ # Change Log +## 2.5.9 + +### Patch Changes + +- Updated dependencies [84ebd51] +- Updated dependencies [0ec0af6] +- Updated dependencies [ae0254d] +- Updated dependencies [efb27fa] + - @tiptap/core@2.5.9 + +## 2.5.8 + +### Patch Changes + +- Updated dependencies [a08bf85] + - @tiptap/core@2.5.8 + +## 2.5.7 + +### Patch Changes + +- Updated dependencies [b012471] +- Updated dependencies [cc3497e] + - @tiptap/core@2.5.7 + ## 2.5.6 ### Patch Changes diff --git a/packages/extension-underline/package.json b/packages/extension-underline/package.json index fdc139d536..311a578ef4 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": "2.5.6", + "version": "2.5.9", "homepage": "https://tiptap.dev", "keywords": [ "tiptap", @@ -29,10 +29,10 @@ "dist" ], "devDependencies": { - "@tiptap/core": "^2.5.6" + "@tiptap/core": "^2.5.9" }, "peerDependencies": { - "@tiptap/core": "^2.5.6" + "@tiptap/core": "^2.5.9" }, "repository": { "type": "git", diff --git a/packages/extension-youtube/CHANGELOG.md b/packages/extension-youtube/CHANGELOG.md index 101416d082..949e1767e8 100644 --- a/packages/extension-youtube/CHANGELOG.md +++ b/packages/extension-youtube/CHANGELOG.md @@ -1,5 +1,30 @@ # Change Log +## 2.5.9 + +### Patch Changes + +- Updated dependencies [84ebd51] +- Updated dependencies [0ec0af6] +- Updated dependencies [ae0254d] +- Updated dependencies [efb27fa] + - @tiptap/core@2.5.9 + +## 2.5.8 + +### Patch Changes + +- Updated dependencies [a08bf85] + - @tiptap/core@2.5.8 + +## 2.5.7 + +### Patch Changes + +- Updated dependencies [b012471] +- Updated dependencies [cc3497e] + - @tiptap/core@2.5.7 + ## 2.5.6 ### Patch Changes diff --git a/packages/extension-youtube/package.json b/packages/extension-youtube/package.json index 3fe5a652de..a3556698f3 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": "2.5.6", + "version": "2.5.9", "homepage": "https://tiptap.dev", "keywords": [ "tiptap", @@ -29,10 +29,10 @@ "dist" ], "devDependencies": { - "@tiptap/core": "^2.5.6" + "@tiptap/core": "^2.5.9" }, "peerDependencies": { - "@tiptap/core": "^2.5.6" + "@tiptap/core": "^2.5.9" }, "repository": { "type": "git", diff --git a/packages/html/CHANGELOG.md b/packages/html/CHANGELOG.md index b89fd0bc18..e9533c44d3 100644 --- a/packages/html/CHANGELOG.md +++ b/packages/html/CHANGELOG.md @@ -1,5 +1,33 @@ # Change Log +## 2.5.9 + +### Patch Changes + +- Updated dependencies [84ebd51] +- Updated dependencies [0ec0af6] +- Updated dependencies [ae0254d] +- Updated dependencies [efb27fa] + - @tiptap/core@2.5.9 + - @tiptap/pm@2.5.9 + +## 2.5.8 + +### Patch Changes + +- Updated dependencies [a08bf85] + - @tiptap/core@2.5.8 + - @tiptap/pm@2.5.8 + +## 2.5.7 + +### Patch Changes + +- Updated dependencies [b012471] +- Updated dependencies [cc3497e] + - @tiptap/core@2.5.7 + - @tiptap/pm@2.5.7 + ## 2.5.6 ### Patch Changes diff --git a/packages/html/package.json b/packages/html/package.json index 3b15966b9f..340e043b48 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": "2.5.6", + "version": "2.5.9", "homepage": "https://tiptap.dev", "keywords": [ "tiptap", @@ -29,12 +29,12 @@ "dist" ], "devDependencies": { - "@tiptap/core": "^2.5.6", - "@tiptap/pm": "^2.5.6" + "@tiptap/core": "^2.5.9", + "@tiptap/pm": "^2.5.9" }, "peerDependencies": { - "@tiptap/core": "^2.5.6", - "@tiptap/pm": "^2.5.6" + "@tiptap/core": "^2.5.9", + "@tiptap/pm": "^2.5.9" }, "dependencies": { "zeed-dom": "^0.10.9" diff --git a/packages/pm/CHANGELOG.md b/packages/pm/CHANGELOG.md index 5823fb1abf..8467cc3f31 100644 --- a/packages/pm/CHANGELOG.md +++ b/packages/pm/CHANGELOG.md @@ -1,5 +1,11 @@ # Change Log +## 2.5.9 + +## 2.5.8 + +## 2.5.7 + ## 2.5.6 ### Patch Changes diff --git a/packages/pm/package.json b/packages/pm/package.json index 9accd36791..3f20563bc0 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": "2.5.6", + "version": "2.5.9", "homepage": "https://tiptap.dev", "keywords": [ "tiptap", diff --git a/packages/react/CHANGELOG.md b/packages/react/CHANGELOG.md index 609b539b08..0d32427608 100644 --- a/packages/react/CHANGELOG.md +++ b/packages/react/CHANGELOG.md @@ -1,5 +1,51 @@ # Change Log +## 2.5.9 + +### Patch Changes + +- 7c8889a: Optimize `useEditor` and `useEditorState` to reduce number of instances created while still being performant #5432 + + The core of this change is two-fold: + + - have the effect run on every render (i.e. without a dep array) + - schedule destruction of instances, but bail on the actual destruction if the instance was still mounted and a new instance had not been created yet + + It should plug a memory leak, where editor instances could be created but not cleaned up in strict mode. + As well as fixing a bug where a re-render, with deps, was not applying new options that were set on `useEditor`. + +- Updated dependencies [84ebd51] +- Updated dependencies [0ec0af6] +- Updated dependencies [ae0254d] +- Updated dependencies [efb27fa] + - @tiptap/core@2.5.9 + - @tiptap/extension-bubble-menu@2.5.9 + - @tiptap/extension-floating-menu@2.5.9 + - @tiptap/pm@2.5.9 + +## 2.5.8 + +### Patch Changes + +- 99d7820: Resolve a bug an editor could be instantiated but not destroyed. This was causing issues with multiple instances of plugins still being active and interfering with each other +- Updated dependencies [a08bf85] + - @tiptap/core@2.5.8 + - @tiptap/extension-bubble-menu@2.5.8 + - @tiptap/extension-floating-menu@2.5.8 + - @tiptap/pm@2.5.8 + +## 2.5.7 + +### Patch Changes + +- 42dc27a: Fix, if using a deps array destroy the previous instance to avoid ghost instances +- Updated dependencies [b012471] +- Updated dependencies [cc3497e] + - @tiptap/core@2.5.7 + - @tiptap/extension-bubble-menu@2.5.7 + - @tiptap/extension-floating-menu@2.5.7 + - @tiptap/pm@2.5.7 + ## 2.5.6 ### Patch Changes diff --git a/packages/react/package.json b/packages/react/package.json index a192a4db16..598ade4b8f 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -1,7 +1,7 @@ { "name": "@tiptap/react", "description": "React components for tiptap", - "version": "2.5.6", + "version": "2.5.9", "homepage": "https://tiptap.dev", "keywords": [ "tiptap", @@ -29,22 +29,22 @@ "dist" ], "dependencies": { - "@tiptap/extension-bubble-menu": "^2.5.6", - "@tiptap/extension-floating-menu": "^2.5.6", + "@tiptap/extension-bubble-menu": "^2.5.9", + "@tiptap/extension-floating-menu": "^2.5.9", "@types/use-sync-external-store": "^0.0.6", "use-sync-external-store": "^1.2.2" }, "devDependencies": { - "@tiptap/core": "^2.5.6", - "@tiptap/pm": "^2.5.6", + "@tiptap/core": "^2.5.9", + "@tiptap/pm": "^2.5.9", "@types/react": "^18.2.14", "@types/react-dom": "^18.2.6", "react": "^18.0.0", "react-dom": "^18.0.0" }, "peerDependencies": { - "@tiptap/core": "^2.5.6", - "@tiptap/pm": "^2.5.6", + "@tiptap/core": "^2.5.9", + "@tiptap/pm": "^2.5.9", "react": "^17.0.0 || ^18.0.0", "react-dom": "^17.0.0 || ^18.0.0" }, diff --git a/packages/react/src/useEditor.ts b/packages/react/src/useEditor.ts index 6f1f64bbbb..2fde5b2ce0 100644 --- a/packages/react/src/useEditor.ts +++ b/packages/react/src/useEditor.ts @@ -1,7 +1,13 @@ import { EditorOptions } from '@tiptap/core' import { - DependencyList, useDebugValue, useEffect, useRef, useState, + DependencyList, + MutableRefObject, + useDebugValue, + useEffect, + useRef, + useState, } from 'react' +import { useSyncExternalStore } from 'use-sync-external-store/shim' import { Editor } from './Editor.js' import { useEditorState } from './useEditorState.js' @@ -30,36 +36,69 @@ export type UseEditorOptions = Partial & { }; /** - * This hook allows you to create an editor instance. - * @param options The editor options - * @param deps The dependencies to watch for changes - * @returns The editor instance - * @example const editor = useEditor({ extensions: [...] }) + * This class handles the creation, destruction, and re-creation of the editor instance. */ -export function useEditor( - options: UseEditorOptions & { immediatelyRender: true }, - deps?: DependencyList -): Editor; +class EditorInstanceManager { + /** + * The current editor instance. + */ + private editor: Editor | null = null -/** - * This hook allows you to create an editor instance. - * @param options The editor options - * @param deps The dependencies to watch for changes - * @returns The editor instance - * @example const editor = useEditor({ extensions: [...] }) - */ -export function useEditor( - options?: UseEditorOptions, - deps?: DependencyList -): Editor | null; + /** + * The most recent options to apply to the editor. + */ + private options: MutableRefObject -export function useEditor( - options: UseEditorOptions = {}, - deps: DependencyList = [], -): Editor | null { - const isMounted = useRef(false) - const [editor, setEditor] = useState(() => { - if (options.immediatelyRender === undefined) { + /** + * The subscriptions to notify when the editor instance + * has been created or destroyed. + */ + private subscriptions = new Set<() => void>() + + /** + * A timeout to destroy the editor if it was not mounted within a time frame. + */ + private scheduledDestructionTimeout: ReturnType | undefined + + /** + * Whether the editor has been mounted. + */ + private isComponentMounted = false + + /** + * The most recent dependencies array. + */ + private previousDeps: DependencyList | null = null + + /** + * The unique instance ID. This is used to identify the editor instance. And will be re-generated for each new instance. + */ + public instanceId = '' + + constructor(options: MutableRefObject) { + this.options = options + this.subscriptions = new Set<() => void>() + this.setEditor(this.getInitialEditor()) + + this.getEditor = this.getEditor.bind(this) + this.getServerSnapshot = this.getServerSnapshot.bind(this) + this.subscribe = this.subscribe.bind(this) + this.refreshEditorInstance = this.refreshEditorInstance.bind(this) + this.scheduleDestroy = this.scheduleDestroy.bind(this) + this.onRender = this.onRender.bind(this) + this.createEditor = this.createEditor.bind(this) + } + + private setEditor(editor: Editor | null) { + this.editor = editor + this.instanceId = Math.random().toString(36).slice(2, 9) + + // Notify all subscribers that the editor instance has been created + this.subscriptions.forEach(cb => cb()) + } + + private getInitialEditor() { + if (this.options.current.immediatelyRender === undefined) { if (isSSR || isNext) { // TODO in the next major release, we should throw an error here if (isDev) { @@ -77,174 +116,205 @@ export function useEditor( } // Default to immediately rendering when client-side rendering - return new Editor(options) + return this.createEditor() } - if (options.immediatelyRender && isSSR && isDev) { + if (this.options.current.immediatelyRender && isSSR && isDev) { // Warn in development, to make sure the developer is aware that tiptap cannot be SSR'd, set `immediatelyRender` to `false` to avoid hydration mismatches. throw new Error( 'Tiptap Error: SSR has been detected, and `immediatelyRender` has been set to `true` this is an unsupported configuration that may result in errors, explicitly set `immediatelyRender` to `false` to avoid hydration mismatches.', ) } - if (options.immediatelyRender) { - return new Editor(options) + if (this.options.current.immediatelyRender) { + return this.createEditor() } return null - }) + } - useDebugValue(editor) + /** + * Create a new editor instance. And attach event listeners. + */ + private createEditor(): Editor { + const editor = new Editor(this.options.current) - // This effect will handle creating/updating the editor instance - useEffect(() => { - let editorInstance: Editor | null = editor - - if (!editorInstance) { - editorInstance = new Editor(options) - // instantiate the editor if it doesn't exist - // for ssr, this is the first time the editor is created - setEditor(editorInstance) - } else if (Array.isArray(deps) && deps.length) { - // the deps array is used to re-initialize the editor instance - editorInstance = new Editor(options) - - setEditor(editorInstance) - } else { - // if the editor does exist & deps are empty, we don't need to re-initialize the editor - // we can fast-path to update the editor options on the existing instance - editorInstance.setOptions(options) - } - }, deps) - - const { - onBeforeCreate, - onBlur, - onCreate, - onDestroy, - onFocus, - onSelectionUpdate, - onTransaction, - onUpdate, - onContentError, - } = options - - const onBeforeCreateRef = useRef(onBeforeCreate) - const onBlurRef = useRef(onBlur) - const onCreateRef = useRef(onCreate) - const onDestroyRef = useRef(onDestroy) - const onFocusRef = useRef(onFocus) - const onSelectionUpdateRef = useRef(onSelectionUpdate) - const onTransactionRef = useRef(onTransaction) - const onUpdateRef = useRef(onUpdate) - const onContentErrorRef = useRef(onContentError) - - // This effect will handle updating the editor instance - // when the event handlers change. - useEffect(() => { - if (!editor) { - return - } + // Always call the most recent version of the callback function by default + editor.on('beforeCreate', (...args) => this.options.current.onBeforeCreate?.(...args)) + editor.on('blur', (...args) => this.options.current.onBlur?.(...args)) + editor.on('create', (...args) => this.options.current.onCreate?.(...args)) + editor.on('destroy', (...args) => this.options.current.onDestroy?.(...args)) + editor.on('focus', (...args) => this.options.current.onFocus?.(...args)) + editor.on('selectionUpdate', (...args) => this.options.current.onSelectionUpdate?.(...args)) + editor.on('transaction', (...args) => this.options.current.onTransaction?.(...args)) + editor.on('update', (...args) => this.options.current.onUpdate?.(...args)) + editor.on('contentError', (...args) => this.options.current.onContentError?.(...args)) - if (onBeforeCreate) { - editor.off('beforeCreate', onBeforeCreateRef.current) - editor.on('beforeCreate', onBeforeCreate) + // no need to keep track of the event listeners, they will be removed when the editor is destroyed - onBeforeCreateRef.current = onBeforeCreate - } + return editor + } - if (onBlur) { - editor.off('blur', onBlurRef.current) - editor.on('blur', onBlur) + /** + * Get the current editor instance. + */ + getEditor(): Editor | null { + return this.editor + } - onBlurRef.current = onBlur - } + /** + * Always disable the editor on the server-side. + */ + getServerSnapshot(): null { + return null + } - if (onCreate) { - editor.off('create', onCreateRef.current) - editor.on('create', onCreate) + /** + * Subscribe to the editor instance's changes. + */ + subscribe(onStoreChange: () => void) { + this.subscriptions.add(onStoreChange) - onCreateRef.current = onCreate + return () => { + this.subscriptions.delete(onStoreChange) } + } - if (onDestroy) { - editor.off('destroy', onDestroyRef.current) - editor.on('destroy', onDestroy) + /** + * On each render, we will create, update, or destroy the editor instance. + * @param deps The dependencies to watch for changes + * @returns A cleanup function + */ + onRender(deps: DependencyList) { + // The returned callback will run on each render + return () => { + this.isComponentMounted = true + // Cleanup any scheduled destructions, since we are currently rendering + clearTimeout(this.scheduledDestructionTimeout) + + if (this.editor && !this.editor.isDestroyed && deps.length === 0) { + // if the editor does exist & deps are empty, we don't need to re-initialize the editor + // we can fast-path to update the editor options on the existing instance + this.editor.setOptions(this.options.current) + } else { + // When the editor: + // - does not yet exist + // - is destroyed + // - the deps array changes + // We need to destroy the editor instance and re-initialize it + this.refreshEditorInstance(deps) + } - onDestroyRef.current = onDestroy + return () => { + this.isComponentMounted = false + this.scheduleDestroy() + } } + } - if (onFocus) { - editor.off('focus', onFocusRef.current) - editor.on('focus', onFocus) + /** + * Recreate the editor instance if the dependencies have changed. + */ + private refreshEditorInstance(deps: DependencyList) { + + if (this.editor && !this.editor.isDestroyed) { + // Editor instance already exists + if (this.previousDeps === null) { + // If lastDeps has not yet been initialized, reuse the current editor instance + this.previousDeps = deps + return + } + const depsAreEqual = this.previousDeps.length === deps.length + && this.previousDeps.every((dep, index) => dep === deps[index]) - onFocusRef.current = onFocus + if (depsAreEqual) { + // deps exist and are equal, no need to recreate + return + } } - if (onSelectionUpdate) { - editor.off('selectionUpdate', onSelectionUpdateRef.current) - editor.on('selectionUpdate', onSelectionUpdate) - - onSelectionUpdateRef.current = onSelectionUpdate + if (this.editor && !this.editor.isDestroyed) { + // Destroy the editor instance if it exists + this.editor.destroy() } - if (onTransaction) { - editor.off('transaction', onTransactionRef.current) - editor.on('transaction', onTransaction) + this.setEditor(this.createEditor()) - onTransactionRef.current = onTransaction - } + // Update the lastDeps to the current deps + this.previousDeps = deps + } - if (onUpdate) { - editor.off('update', onUpdateRef.current) - editor.on('update', onUpdate) + /** + * Schedule the destruction of the editor instance. + * This will only destroy the editor if it was not mounted on the next tick. + * This is to avoid destroying the editor instance when it's actually still mounted. + */ + private scheduleDestroy() { + const currentInstanceId = this.instanceId + const currentEditor = this.editor + + // Wait a tick to see if the component is still mounted + this.scheduledDestructionTimeout = setTimeout(() => { + if (this.isComponentMounted && this.instanceId === currentInstanceId) { + // If still mounted on the next tick, with the same instanceId, do not destroy the editor + if (currentEditor) { + // just re-apply options as they might have changed + currentEditor.setOptions(this.options.current) + } + return + } + if (currentEditor && !currentEditor.isDestroyed) { + currentEditor.destroy() + if (this.instanceId === currentInstanceId) { + this.setEditor(null) + } + } + }, 0) + } +} - onUpdateRef.current = onUpdate - } +/** + * This hook allows you to create an editor instance. + * @param options The editor options + * @param deps The dependencies to watch for changes + * @returns The editor instance + * @example const editor = useEditor({ extensions: [...] }) + */ +export function useEditor( + options: UseEditorOptions & { immediatelyRender: true }, + deps?: DependencyList +): Editor; - if (onContentError) { - editor.off('contentError', onContentErrorRef.current) - editor.on('contentError', onContentError) +/** + * This hook allows you to create an editor instance. + * @param options The editor options + * @param deps The dependencies to watch for changes + * @returns The editor instance + * @example const editor = useEditor({ extensions: [...] }) + */ +export function useEditor(options?: UseEditorOptions, deps?: DependencyList): Editor | null; - onContentErrorRef.current = onContentError - } - }, [ - onBeforeCreate, - onBlur, - onCreate, - onDestroy, - onFocus, - onSelectionUpdate, - onTransaction, - onUpdate, - onContentError, - editor, - ]) +export function useEditor( + options: UseEditorOptions = {}, + deps: DependencyList = [], +): Editor | null { + const mostRecentOptions = useRef(options) - /** - * Destroy the editor instance when the component completely unmounts - * As opposed to the cleanup function in the effect above, this will - * only be called when the component is removed from the DOM, since it has no deps. - * */ - useEffect(() => { - isMounted.current = true - return () => { - isMounted.current = false - if (editor) { - // We need to destroy the editor asynchronously to avoid memory leaks - // because the editor instance is still being used in the component. - - setTimeout(() => { - // re-use the editor instance if it hasn't been destroyed yet - // and the component is still mounted - // otherwise, asynchronously destroy the editor instance - if (!isMounted.current && !editor.isDestroyed) { - editor.destroy() - } - }) - } - } - }, []) + mostRecentOptions.current = options + + const [instanceManager] = useState(() => new EditorInstanceManager(mostRecentOptions)) + + const editor = useSyncExternalStore( + instanceManager.subscribe, + instanceManager.getEditor, + instanceManager.getServerSnapshot, + ) + + useDebugValue(editor) + + // This effect will handle creating/updating the editor instance + // eslint-disable-next-line react-hooks/exhaustive-deps + useEffect(instanceManager.onRender(deps)) // The default behavior is to re-render on each transaction // This is legacy behavior that will be removed in future versions diff --git a/packages/react/src/useEditorState.ts b/packages/react/src/useEditorState.ts index 0c8f02517e..079605a808 100644 --- a/packages/react/src/useEditorState.ts +++ b/packages/react/src/useEditorState.ts @@ -30,68 +30,83 @@ export type UseEditorStateOptions< * To synchronize the editor instance with the component state, * we need to create a separate instance that is not affected by the component re-renders. */ -function makeEditorStateInstance(initialEditor: TEditor) { - let transactionNumber = 0 - let lastTransactionNumber = 0 - let lastSnapshot: EditorStateSnapshot = { editor: initialEditor, transactionNumber: 0 } - let editor = initialEditor - const subscribers = new Set<() => void>() - - const editorInstance = { - /** - * Get the current editor instance. - */ - getSnapshot(): EditorStateSnapshot { - if (transactionNumber === lastTransactionNumber) { - return lastSnapshot +class EditorStateManager { + private transactionNumber = 0 + + private lastTransactionNumber = 0 + + private lastSnapshot: EditorStateSnapshot + + private editor: TEditor + + private subscribers = new Set<() => void>() + + constructor(initialEditor: TEditor) { + this.editor = initialEditor + this.lastSnapshot = { editor: initialEditor, transactionNumber: 0 } + + this.getSnapshot = this.getSnapshot.bind(this) + this.getServerSnapshot = this.getServerSnapshot.bind(this) + this.watch = this.watch.bind(this) + this.subscribe = this.subscribe.bind(this) + } + + /** + * Get the current editor instance. + */ + getSnapshot(): EditorStateSnapshot { + if (this.transactionNumber === this.lastTransactionNumber) { + return this.lastSnapshot + } + this.lastTransactionNumber = this.transactionNumber + this.lastSnapshot = { editor: this.editor, transactionNumber: this.transactionNumber } + return this.lastSnapshot + } + + /** + * Always disable the editor on the server-side. + */ + getServerSnapshot(): EditorStateSnapshot { + return { editor: null, transactionNumber: 0 } + } + + /** + * Subscribe to the editor instance's changes. + */ + subscribe(callback: () => void): () => void { + this.subscribers.add(callback) + return () => { + this.subscribers.delete(callback) + } + } + + /** + * Watch the editor instance for changes. + */ + watch(nextEditor: Editor | null): undefined | (() => void) { + this.editor = nextEditor as TEditor + + if (this.editor) { + /** + * This will force a re-render when the editor state changes. + * This is to support things like `editor.can().toggleBold()` in components that `useEditor`. + * This could be more efficient, but it's a good trade-off for now. + */ + const fn = () => { + this.transactionNumber += 1 + this.subscribers.forEach(callback => callback()) } - lastTransactionNumber = transactionNumber - lastSnapshot = { editor, transactionNumber } - return lastSnapshot - }, - /** - * Always disable the editor on the server-side. - */ - getServerSnapshot(): EditorStateSnapshot { - return { editor: null, transactionNumber: 0 } - }, - /** - * Subscribe to the editor instance's changes. - */ - subscribe(callback: () => void) { - subscribers.add(callback) + + const currentEditor = this.editor + + currentEditor.on('transaction', fn) return () => { - subscribers.delete(callback) + currentEditor.off('transaction', fn) } - }, - /** - * Watch the editor instance for changes. - */ - watch(nextEditor: Editor | null) { - editor = nextEditor as TEditor - - if (editor) { - /** - * This will force a re-render when the editor state changes. - * This is to support things like `editor.can().toggleBold()` in components that `useEditor`. - * This could be more efficient, but it's a good trade-off for now. - */ - const fn = () => { - transactionNumber += 1 - subscribers.forEach(callback => callback()) - } - - const currentEditor = editor - - currentEditor.on('transaction', fn) - return () => { - currentEditor.off('transaction', fn) - } - } - }, - } + } - return editorInstance + return undefined + } } export function useEditorState( @@ -104,7 +119,7 @@ export function useEditorState( export function useEditorState( options: UseEditorStateOptions | UseEditorStateOptions, ): TSelectorResult | null { - const [editorInstance] = useState(() => makeEditorStateInstance(options.editor)) + const [editorInstance] = useState(() => new EditorStateManager(options.editor)) // Using the `useSyncExternalStore` hook to sync the editor instance with the component state const selectedState = useSyncExternalStoreWithSelector( @@ -117,7 +132,7 @@ export function useEditorState( useEffect(() => { return editorInstance.watch(options.editor) - }, [options.editor]) + }, [options.editor, editorInstance]) useDebugValue(selectedState) diff --git a/packages/starter-kit/CHANGELOG.md b/packages/starter-kit/CHANGELOG.md index 00ef3517b0..50ef129221 100644 --- a/packages/starter-kit/CHANGELOG.md +++ b/packages/starter-kit/CHANGELOG.md @@ -1,5 +1,85 @@ # Change Log +## 2.5.9 + +### Patch Changes + +- Updated dependencies [84ebd51] +- Updated dependencies [0ec0af6] +- Updated dependencies [4b215f7] +- Updated dependencies [ae0254d] +- Updated dependencies [efb27fa] + - @tiptap/core@2.5.9 + - @tiptap/extension-code-block@2.5.9 + - @tiptap/extension-blockquote@2.5.9 + - @tiptap/extension-bold@2.5.9 + - @tiptap/extension-bullet-list@2.5.9 + - @tiptap/extension-code@2.5.9 + - @tiptap/extension-document@2.5.9 + - @tiptap/extension-dropcursor@2.5.9 + - @tiptap/extension-gapcursor@2.5.9 + - @tiptap/extension-hard-break@2.5.9 + - @tiptap/extension-heading@2.5.9 + - @tiptap/extension-history@2.5.9 + - @tiptap/extension-horizontal-rule@2.5.9 + - @tiptap/extension-italic@2.5.9 + - @tiptap/extension-list-item@2.5.9 + - @tiptap/extension-ordered-list@2.5.9 + - @tiptap/extension-paragraph@2.5.9 + - @tiptap/extension-strike@2.5.9 + - @tiptap/extension-text@2.5.9 + +## 2.5.8 + +### Patch Changes + +- Updated dependencies [a08bf85] + - @tiptap/core@2.5.8 + - @tiptap/extension-blockquote@2.5.8 + - @tiptap/extension-bold@2.5.8 + - @tiptap/extension-bullet-list@2.5.8 + - @tiptap/extension-code@2.5.8 + - @tiptap/extension-code-block@2.5.8 + - @tiptap/extension-document@2.5.8 + - @tiptap/extension-dropcursor@2.5.8 + - @tiptap/extension-gapcursor@2.5.8 + - @tiptap/extension-hard-break@2.5.8 + - @tiptap/extension-heading@2.5.8 + - @tiptap/extension-history@2.5.8 + - @tiptap/extension-horizontal-rule@2.5.8 + - @tiptap/extension-italic@2.5.8 + - @tiptap/extension-list-item@2.5.8 + - @tiptap/extension-ordered-list@2.5.8 + - @tiptap/extension-paragraph@2.5.8 + - @tiptap/extension-strike@2.5.8 + - @tiptap/extension-text@2.5.8 + +## 2.5.7 + +### Patch Changes + +- Updated dependencies [b012471] +- Updated dependencies [cc3497e] + - @tiptap/core@2.5.7 + - @tiptap/extension-blockquote@2.5.7 + - @tiptap/extension-bold@2.5.7 + - @tiptap/extension-bullet-list@2.5.7 + - @tiptap/extension-code@2.5.7 + - @tiptap/extension-code-block@2.5.7 + - @tiptap/extension-document@2.5.7 + - @tiptap/extension-dropcursor@2.5.7 + - @tiptap/extension-gapcursor@2.5.7 + - @tiptap/extension-hard-break@2.5.7 + - @tiptap/extension-heading@2.5.7 + - @tiptap/extension-history@2.5.7 + - @tiptap/extension-horizontal-rule@2.5.7 + - @tiptap/extension-italic@2.5.7 + - @tiptap/extension-list-item@2.5.7 + - @tiptap/extension-ordered-list@2.5.7 + - @tiptap/extension-paragraph@2.5.7 + - @tiptap/extension-strike@2.5.7 + - @tiptap/extension-text@2.5.7 + ## 2.5.6 ### Patch Changes diff --git a/packages/starter-kit/package.json b/packages/starter-kit/package.json index 503774e153..1cee70d25a 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": "2.5.6", + "version": "2.5.9", "homepage": "https://tiptap.dev", "keywords": [ "tiptap", @@ -29,25 +29,25 @@ "dist" ], "dependencies": { - "@tiptap/core": "^2.5.6", - "@tiptap/extension-blockquote": "^2.5.6", - "@tiptap/extension-bold": "^2.5.6", - "@tiptap/extension-bullet-list": "^2.5.6", - "@tiptap/extension-code": "^2.5.6", - "@tiptap/extension-code-block": "^2.5.6", - "@tiptap/extension-document": "^2.5.6", - "@tiptap/extension-dropcursor": "^2.5.6", - "@tiptap/extension-gapcursor": "^2.5.6", - "@tiptap/extension-hard-break": "^2.5.6", - "@tiptap/extension-heading": "^2.5.6", - "@tiptap/extension-history": "^2.5.6", - "@tiptap/extension-horizontal-rule": "^2.5.6", - "@tiptap/extension-italic": "^2.5.6", - "@tiptap/extension-list-item": "^2.5.6", - "@tiptap/extension-ordered-list": "^2.5.6", - "@tiptap/extension-paragraph": "^2.5.6", - "@tiptap/extension-strike": "^2.5.6", - "@tiptap/extension-text": "^2.5.6" + "@tiptap/core": "^2.5.9", + "@tiptap/extension-blockquote": "^2.5.9", + "@tiptap/extension-bold": "^2.5.9", + "@tiptap/extension-bullet-list": "^2.5.9", + "@tiptap/extension-code": "^2.5.9", + "@tiptap/extension-code-block": "^2.5.9", + "@tiptap/extension-document": "^2.5.9", + "@tiptap/extension-dropcursor": "^2.5.9", + "@tiptap/extension-gapcursor": "^2.5.9", + "@tiptap/extension-hard-break": "^2.5.9", + "@tiptap/extension-heading": "^2.5.9", + "@tiptap/extension-history": "^2.5.9", + "@tiptap/extension-horizontal-rule": "^2.5.9", + "@tiptap/extension-italic": "^2.5.9", + "@tiptap/extension-list-item": "^2.5.9", + "@tiptap/extension-ordered-list": "^2.5.9", + "@tiptap/extension-paragraph": "^2.5.9", + "@tiptap/extension-strike": "^2.5.9", + "@tiptap/extension-text": "^2.5.9" }, "repository": { "type": "git", diff --git a/packages/suggestion/CHANGELOG.md b/packages/suggestion/CHANGELOG.md index 19dca1885f..c3071b9b8a 100644 --- a/packages/suggestion/CHANGELOG.md +++ b/packages/suggestion/CHANGELOG.md @@ -1,5 +1,33 @@ # Change Log +## 2.5.9 + +### Patch Changes + +- Updated dependencies [84ebd51] +- Updated dependencies [0ec0af6] +- Updated dependencies [ae0254d] +- Updated dependencies [efb27fa] + - @tiptap/core@2.5.9 + - @tiptap/pm@2.5.9 + +## 2.5.8 + +### Patch Changes + +- Updated dependencies [a08bf85] + - @tiptap/core@2.5.8 + - @tiptap/pm@2.5.8 + +## 2.5.7 + +### Patch Changes + +- Updated dependencies [b012471] +- Updated dependencies [cc3497e] + - @tiptap/core@2.5.7 + - @tiptap/pm@2.5.7 + ## 2.5.6 ### Patch Changes diff --git a/packages/suggestion/package.json b/packages/suggestion/package.json index fe0423d4ad..7223dc12eb 100644 --- a/packages/suggestion/package.json +++ b/packages/suggestion/package.json @@ -1,7 +1,7 @@ { "name": "@tiptap/suggestion", "description": "suggestion plugin for tiptap", - "version": "2.5.6", + "version": "2.5.9", "homepage": "https://tiptap.dev", "keywords": [ "tiptap", @@ -29,12 +29,12 @@ "dist" ], "devDependencies": { - "@tiptap/core": "^2.5.6", - "@tiptap/pm": "^2.5.6" + "@tiptap/core": "^2.5.9", + "@tiptap/pm": "^2.5.9" }, "peerDependencies": { - "@tiptap/core": "^2.5.6", - "@tiptap/pm": "^2.5.6" + "@tiptap/core": "^2.5.9", + "@tiptap/pm": "^2.5.9" }, "repository": { "type": "git", diff --git a/packages/vue-2/CHANGELOG.md b/packages/vue-2/CHANGELOG.md index 0791628fad..202180a7e4 100644 --- a/packages/vue-2/CHANGELOG.md +++ b/packages/vue-2/CHANGELOG.md @@ -1,5 +1,39 @@ # Change Log +## 2.5.9 + +### Patch Changes + +- Updated dependencies [84ebd51] +- Updated dependencies [0ec0af6] +- Updated dependencies [ae0254d] +- Updated dependencies [efb27fa] + - @tiptap/core@2.5.9 + - @tiptap/extension-bubble-menu@2.5.9 + - @tiptap/extension-floating-menu@2.5.9 + - @tiptap/pm@2.5.9 + +## 2.5.8 + +### Patch Changes + +- Updated dependencies [a08bf85] + - @tiptap/core@2.5.8 + - @tiptap/extension-bubble-menu@2.5.8 + - @tiptap/extension-floating-menu@2.5.8 + - @tiptap/pm@2.5.8 + +## 2.5.7 + +### Patch Changes + +- Updated dependencies [b012471] +- Updated dependencies [cc3497e] + - @tiptap/core@2.5.7 + - @tiptap/extension-bubble-menu@2.5.7 + - @tiptap/extension-floating-menu@2.5.7 + - @tiptap/pm@2.5.7 + ## 2.5.6 ### Patch Changes diff --git a/packages/vue-2/package.json b/packages/vue-2/package.json index 42cfe31266..3ef0007912 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": "2.5.6", + "version": "2.5.9", "homepage": "https://tiptap.dev", "keywords": [ "tiptap", @@ -29,18 +29,18 @@ "dist" ], "dependencies": { - "@tiptap/extension-bubble-menu": "^2.5.6", - "@tiptap/extension-floating-menu": "^2.5.6", + "@tiptap/extension-bubble-menu": "^2.5.9", + "@tiptap/extension-floating-menu": "^2.5.9", "vue-ts-types": "^1.6.0" }, "devDependencies": { - "@tiptap/core": "^2.5.6", - "@tiptap/pm": "^2.5.6", + "@tiptap/core": "^2.5.9", + "@tiptap/pm": "^2.5.9", "vue": "^2.6.0" }, "peerDependencies": { - "@tiptap/core": "^2.5.6", - "@tiptap/pm": "^2.5.6", + "@tiptap/core": "^2.5.9", + "@tiptap/pm": "^2.5.9", "vue": "^2.6.0" }, "repository": { diff --git a/packages/vue-3/CHANGELOG.md b/packages/vue-3/CHANGELOG.md index 688a30b544..7e46f87675 100644 --- a/packages/vue-3/CHANGELOG.md +++ b/packages/vue-3/CHANGELOG.md @@ -1,5 +1,40 @@ # Change Log +## 2.5.9 + +### Patch Changes + +- Updated dependencies [84ebd51] +- Updated dependencies [0ec0af6] +- Updated dependencies [ae0254d] +- Updated dependencies [efb27fa] + - @tiptap/core@2.5.9 + - @tiptap/extension-bubble-menu@2.5.9 + - @tiptap/extension-floating-menu@2.5.9 + - @tiptap/pm@2.5.9 + +## 2.5.8 + +### Patch Changes + +- f7f644f: Correctly set editor's appContext.provide to forward full inject chain +- Updated dependencies [a08bf85] + - @tiptap/core@2.5.8 + - @tiptap/extension-bubble-menu@2.5.8 + - @tiptap/extension-floating-menu@2.5.8 + - @tiptap/pm@2.5.8 + +## 2.5.7 + +### Patch Changes + +- Updated dependencies [b012471] +- Updated dependencies [cc3497e] + - @tiptap/core@2.5.7 + - @tiptap/extension-bubble-menu@2.5.7 + - @tiptap/extension-floating-menu@2.5.7 + - @tiptap/pm@2.5.7 + ## 2.5.6 ### Patch Changes diff --git a/packages/vue-3/package.json b/packages/vue-3/package.json index 87839eed65..62ff6a2caf 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": "2.5.6", + "version": "2.5.9", "homepage": "https://tiptap.dev", "keywords": [ "tiptap", @@ -29,17 +29,17 @@ "dist" ], "dependencies": { - "@tiptap/extension-bubble-menu": "^2.5.6", - "@tiptap/extension-floating-menu": "^2.5.6" + "@tiptap/extension-bubble-menu": "^2.5.9", + "@tiptap/extension-floating-menu": "^2.5.9" }, "devDependencies": { - "@tiptap/core": "^2.5.6", - "@tiptap/pm": "^2.5.6", + "@tiptap/core": "^2.5.9", + "@tiptap/pm": "^2.5.9", "vue": "^3.0.0" }, "peerDependencies": { - "@tiptap/core": "^2.5.6", - "@tiptap/pm": "^2.5.6", + "@tiptap/core": "^2.5.9", + "@tiptap/pm": "^2.5.9", "vue": "^3.0.0" }, "repository": { diff --git a/packages/vue-3/src/Editor.ts b/packages/vue-3/src/Editor.ts index 8d10526ca9..9ed5597d33 100644 --- a/packages/vue-3/src/Editor.ts +++ b/packages/vue-3/src/Editor.ts @@ -1,3 +1,4 @@ +/* eslint-disable react-hooks/rules-of-hooks */ import { Editor as CoreEditor, EditorOptions } from '@tiptap/core' import { EditorState, Plugin, PluginKey } from '@tiptap/pm/state' import { diff --git a/packages/vue-3/src/EditorContent.ts b/packages/vue-3/src/EditorContent.ts index 7c215c3c95..da533ab587 100644 --- a/packages/vue-3/src/EditorContent.ts +++ b/packages/vue-3/src/EditorContent.ts @@ -46,11 +46,10 @@ export const EditorContent = defineComponent({ if (instance) { editor.appContext = { ...instance.appContext, - provides: { - // @ts-ignore - ...instance.provides, - ...instance.appContext.provides, - }, + // Vue internally uses prototype chain to forward/shadow injects across the entire component chain + // so don't use object spread operator or 'Object.assign' and just set `provides` as is on editor's appContext + // @ts-expect-error forward instance's 'provides' into appContext + provides: instance.provides, } } diff --git a/tests/cypress/integration/core/isNodeEmpty.spec.ts b/tests/cypress/integration/core/isNodeEmpty.spec.ts new file mode 100644 index 0000000000..e4c1dc9462 --- /dev/null +++ b/tests/cypress/integration/core/isNodeEmpty.spec.ts @@ -0,0 +1,243 @@ +/// + +import { getSchema, isNodeEmpty } from '@tiptap/core' +import Document from '@tiptap/extension-document' +import Image from '@tiptap/extension-image' +import Mention from '@tiptap/extension-mention' +import StarterKit from '@tiptap/starter-kit' + +const schema = getSchema([StarterKit, Mention]) +const modifiedSchema = getSchema([ + StarterKit.configure({ document: false }), + Document.extend({ content: 'heading block*' }), +]) +const imageSchema = getSchema([ + StarterKit.configure({ document: false }), + Document.extend({ content: 'image block*' }), + Image, +]) + +describe('isNodeEmpty', () => { + describe('ignoreWhitespace=true', () => { + it('should return true when text has only whitespace', () => { + const node = schema.nodeFromJSON({ type: 'text', text: ' \n\t\r\n' }) + + expect(isNodeEmpty(node, { ignoreWhitespace: true })).to.eq(true) + }) + + it('should return true when a paragraph has only whitespace', () => { + const node = schema.nodeFromJSON({ + type: 'paragraph', + content: [{ type: 'text', text: ' \n\t\r\n' }], + }) + + expect(isNodeEmpty(node, { ignoreWhitespace: true })).to.eq(true) + }) + + it('should return true for a hardbreak', () => { + const node = schema.nodeFromJSON({ type: 'hardBreak' }) + + expect(isNodeEmpty(node, { ignoreWhitespace: true })).to.eq(true) + }) + + it('should return true when a paragraph has only a hardbreak', () => { + const node = schema.nodeFromJSON({ + type: 'paragraph', + content: [{ type: 'hardBreak' }], + }) + + expect(isNodeEmpty(node, { ignoreWhitespace: true })).to.eq(true) + }) + }) + + describe('with default schema', () => { + it('should return false when text has content', () => { + const node = schema.nodeFromJSON({ type: 'text', text: 'Hello world!' }) + + expect(isNodeEmpty(node)).to.eq(false) + }) + + it('should return false when a paragraph has text', () => { + const node = schema.nodeFromJSON({ + type: 'paragraph', + content: [{ type: 'text', text: 'Hello world!' }], + }) + + expect(isNodeEmpty(node)).to.eq(false) + }) + + it('should return false when a paragraph has hardbreaks', () => { + const node = schema.nodeFromJSON({ + type: 'paragraph', + content: [{ type: 'hardBreak' }], + }) + + expect(isNodeEmpty(node)).to.eq(false) + }) + + it('should return false when a paragraph has a mention', () => { + const node = schema.nodeFromJSON({ + type: 'paragraph', + content: [ + { + type: 'mention', + attrs: { + id: 'Winona Ryder', + label: null, + }, + }, + ], + }) + + expect(isNodeEmpty(node)).to.eq(false) + }) + + it('should return true when a paragraph has no content', () => { + const node = schema.nodeFromJSON({ + type: 'paragraph', + content: [], + }) + + expect(isNodeEmpty(node)).to.eq(true) + }) + + it('should return true when a paragraph has additional attrs & no content', () => { + const node = schema.nodeFromJSON({ + type: 'paragraph', + content: [], + attrs: { + id: 'test', + }, + }) + + expect(isNodeEmpty(node)).to.eq(true) + }) + + it('should return true when a paragraph has additional marks & no content', () => { + const node = schema.nodeFromJSON({ + type: 'paragraph', + content: [], + attrs: { + id: 'test', + }, + marks: [{ type: 'bold' }], + }) + + expect(isNodeEmpty(node)).to.eq(true) + }) + + it('should return false when a document has text', () => { + const node = schema.nodeFromJSON({ + type: 'doc', + content: [ + { + type: 'paragraph', + content: [{ type: 'text', text: 'Hello world!' }], + }, + ], + }) + + expect(isNodeEmpty(node)).to.eq(false) + }) + it('should return true when a document has an empty paragraph', () => { + const node = schema.nodeFromJSON({ + type: 'doc', + content: [ + { + type: 'paragraph', + content: [], + }, + ], + }) + + expect(isNodeEmpty(node)).to.eq(true) + }) + }) + + describe('with modified schema', () => { + it('should return false when a document has a filled heading', () => { + const node = modifiedSchema.nodeFromJSON({ + type: 'doc', + content: [ + { + type: 'heading', + content: [{ type: 'text', text: 'Hello world!' }], + }, + ], + }) + + expect(isNodeEmpty(node)).to.eq(false) + }) + + it('should return false when a document has a filled paragraph', () => { + const node = modifiedSchema.nodeFromJSON({ + type: 'doc', + content: [ + { type: 'heading' }, + { + type: 'paragraph', + content: [{ type: 'text', text: 'Hello world!' }], + }, + ], + }) + + expect(isNodeEmpty(node)).to.eq(false) + }) + + it('should return true when a document has an empty heading', () => { + const node = modifiedSchema.nodeFromJSON({ + type: 'doc', + content: [ + { type: 'heading', content: [] }, + { type: 'paragraph', content: [] }, + ], + }) + + expect(isNodeEmpty(node)).to.eq(true) + }) + + it('should return true when a document has an empty heading with attrs', () => { + const node = modifiedSchema.nodeFromJSON({ + type: 'doc', + content: [{ type: 'heading', content: [], attrs: { level: 2 } }], + }) + + expect(isNodeEmpty(node)).to.eq(true) + }) + + it('should return true when a document has an empty heading & paragraph', () => { + const node = modifiedSchema.nodeFromJSON({ + type: 'doc', + content: [ + { type: 'heading', content: [] }, + { type: 'paragraph', content: [] }, + ], + }) + + expect(isNodeEmpty(node)).to.eq(true) + }) + it('should return true when a document has an empty heading & paragraph with attributes', () => { + const node = modifiedSchema.nodeFromJSON({ + type: 'doc', + content: [ + { type: 'heading', content: [], attrs: { id: 'test' } }, + { type: 'paragraph', content: [], attrs: { id: 'test' } }, + ], + }) + + expect(isNodeEmpty(node)).to.eq(true) + }) + + it('can handle an image node', () => { + const node = imageSchema.nodeFromJSON({ + type: 'doc', + content: [ + { type: 'image', attrs: { src: 'https://examples.com' } }, + { type: 'heading', content: [] }, + ], + }) + + expect(isNodeEmpty(node)).to.eq(false) + }) + }) +}) diff --git a/tests/cypress/integration/extensions/codeBlockLowlight.spec.ts b/tests/cypress/integration/extensions/codeBlockLowlight.spec.ts index e3b6fd6d13..00f1df6251 100644 --- a/tests/cypress/integration/extensions/codeBlockLowlight.spec.ts +++ b/tests/cypress/integration/extensions/codeBlockLowlight.spec.ts @@ -5,7 +5,9 @@ import { CodeBlockLowlight } from '@tiptap/extension-code-block-lowlight' import { Document } from '@tiptap/extension-document' import { Paragraph } from '@tiptap/extension-paragraph' import { Text } from '@tiptap/extension-text' -import { lowlight } from 'lowlight' +import { all, createLowlight } from 'lowlight' + +const lowlight = createLowlight(all) describe('code block highlight', () => { let Frontmatter diff --git a/tests/cypress/tsconfig.json b/tests/cypress/tsconfig.json index ebd9a998fd..7967d1ebd8 100644 --- a/tests/cypress/tsconfig.json +++ b/tests/cypress/tsconfig.json @@ -6,7 +6,7 @@ "sourceMap": false, "types": ["cypress", "react", "react-dom"], "paths": { - "@tiptap/*": ["packages/*/dist", "packages/*/src"], + "@tiptap/*": ["packages/*/src", "packages/*/dist"], "@tiptap/pm/*": ["../../pm/*/dist"] }, "typeRoots": ["../../node_modules/@types", "../../node_modules/"],