From 99c51a54f17c3b27a7afe98148c26affaa3c83e6 Mon Sep 17 00:00:00 2001 From: Lee Kelleher Date: Thu, 2 Oct 2025 08:44:00 +0100 Subject: [PATCH] Tiptap RTE: Upgrade to Tiptap v3 (#20318) * Upgrade to Tiptap v3 * Uses `@ts-expect-error` to ignore the TS complication errors These can be removed once Tiptap has resolved the TypeScript definitions. * Off-topic: corrected `flags` property in the mock data Added in PR #19915 * Update src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/link/link.tiptap-extension.ts Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> --- src/Umbraco.Web.UI.Client/package-lock.json | 435 ++++++++---------- ...block.tipap-api.ts => block.tiptap-api.ts} | 81 +--- .../block/block.tiptap-extension.ts | 90 ++++ .../packages/tiptap/extensions/block/index.ts | 1 + .../tiptap/extensions/block/manifests.ts | 2 +- .../core/rich-text-essentials.tiptap-api.ts | 4 +- .../src/packages/tiptap/extensions/index.ts | 1 - .../extensions/link/link.tiptap-extension.ts | 17 +- .../media-upload/media-upload.tiptap-api.ts | 10 +- .../tiptap/extensions/trailing-node/index.ts | 1 - .../trailing-node/trailing-node.tiptap-api.ts | 2 +- .../trailing-node.tiptap-extension.ts | 74 --- .../source-editor.tiptap-toolbar-api.ts | 6 +- .../word-count/word-count.tiptap-api.ts | 5 +- .../src/packages/tiptap/externals.ts | 23 +- .../src/packages/tiptap/package.json | 43 +- 16 files changed, 346 insertions(+), 449 deletions(-) rename src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/block/{block.tipap-api.ts => block.tiptap-api.ts} (52%) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/block/block.tiptap-extension.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/block/index.ts delete mode 100644 src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/trailing-node/index.ts delete mode 100644 src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/trailing-node/trailing-node.tiptap-extension.ts diff --git a/src/Umbraco.Web.UI.Client/package-lock.json b/src/Umbraco.Web.UI.Client/package-lock.json index 9891579289..25708f76a9 100644 --- a/src/Umbraco.Web.UI.Client/package-lock.json +++ b/src/Umbraco.Web.UI.Client/package-lock.json @@ -2159,437 +2159,397 @@ } }, "node_modules/@tiptap/core": { - "version": "2.26.1", - "resolved": "https://registry.npmjs.org/@tiptap/core/-/core-2.26.1.tgz", - "integrity": "sha512-fymyd/XZvYiHjBoLt1gxs024xP/LY26d43R1vluYq7AHBL/7DE3ywzy+1GEsGyAv5Je2L0KBhNIR/izbq3Kaqg==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/@tiptap/core/-/core-3.6.2.tgz", + "integrity": "sha512-XKZYrCVFsyQGF6dXQR73YR222l/76wkKfZ+2/4LCrem5qtcOarmv5pYxjUBG8mRuBPskTTBImSFTeQltJIUNCg==", "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/pm": "^2.7.0" + "@tiptap/pm": "^3.6.2" } }, "node_modules/@tiptap/extension-blockquote": { - "version": "2.26.1", - "resolved": "https://registry.npmjs.org/@tiptap/extension-blockquote/-/extension-blockquote-2.26.1.tgz", - "integrity": "sha512-viQ6AHRhjCYYipKK6ZepBzwZpkuMvO9yhRHeUZDvlSOAh8rvsUTSre0y74nu8QRYUt4a44lJJ6BpphJK7bEgYA==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-blockquote/-/extension-blockquote-3.6.2.tgz", + "integrity": "sha512-TSl41UZhi3ugJMDaf91CA4F5NeFylgTSm6GqnZAHOE6IREdCpAK3qej2zaW3EzfpzxW7sRGLlytkZRvpeyjgJA==", "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.7.0" + "@tiptap/core": "^3.6.2" } }, "node_modules/@tiptap/extension-bold": { - "version": "2.26.1", - "resolved": "https://registry.npmjs.org/@tiptap/extension-bold/-/extension-bold-2.26.1.tgz", - "integrity": "sha512-zCce9PRuTNhadFir71luLo99HERDpGJ0EEflGm7RN8I1SnNi9gD5ooK42BOIQtejGCJqg3hTPZiYDJC2hXvckQ==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-bold/-/extension-bold-3.6.2.tgz", + "integrity": "sha512-Q9KO8CCPCAXYqHzIw8b/ookVmrfqfCg2cyh9h9Hvw6nhO4LOOnJMcGVmWsrpFItbwCGMafI5iY9SbSj7RpCyuw==", "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.7.0" + "@tiptap/core": "^3.6.2" } }, "node_modules/@tiptap/extension-bullet-list": { - "version": "2.26.1", - "resolved": "https://registry.npmjs.org/@tiptap/extension-bullet-list/-/extension-bullet-list-2.26.1.tgz", - "integrity": "sha512-HHakuV4ckYCDOnBbne088FvCEP4YICw+wgPBz/V2dfpiFYQ4WzT0LPK9s7OFMCN+ROraoug+1ryN1Z1KdIgujQ==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-bullet-list/-/extension-bullet-list-3.6.2.tgz", + "integrity": "sha512-Y5Uhir+za7xMm6RAe592aNNlLvCayVSQt2HfSckOr+c/v/Zd2bFUHv0ef6l/nUzUhDBs32Bg9SvfWx/yyMyNEw==", "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.7.0" - } - }, - "node_modules/@tiptap/extension-character-count": { - "version": "2.26.1", - "resolved": "https://registry.npmjs.org/@tiptap/extension-character-count/-/extension-character-count-2.26.1.tgz", - "integrity": "sha512-F7LP1a9GF28thbApowWT2I41baqX74HMUTrV9LGrNXaOkW2gxZz+CDOzfHsbHyfuwfIxIjv07Qf/HKA6Cc1qbA==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/ueberdosis" - }, - "peerDependencies": { - "@tiptap/core": "^2.7.0", - "@tiptap/pm": "^2.7.0" + "@tiptap/extension-list": "^3.6.2" } }, "node_modules/@tiptap/extension-code": { - "version": "2.26.1", - "resolved": "https://registry.npmjs.org/@tiptap/extension-code/-/extension-code-2.26.1.tgz", - "integrity": "sha512-GU9deB1A/Tr4FMPu71CvlcjGKwRhGYz60wQ8m4aM+ELZcVIcZRa1ebR8bExRIEWnvRztQuyRiCQzw2N0xQJ1QQ==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-code/-/extension-code-3.6.2.tgz", + "integrity": "sha512-U6jilbcpCxtLZAgJrTapXzzVJTXnS78kJITFSOLyGCTyGSm6PXatQ4hnaxVGmNet66GySONGjhwAVZ8+l94Rwg==", "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.7.0" + "@tiptap/core": "^3.6.2" } }, "node_modules/@tiptap/extension-code-block": { - "version": "2.26.1", - "resolved": "https://registry.npmjs.org/@tiptap/extension-code-block/-/extension-code-block-2.26.1.tgz", - "integrity": "sha512-/TDDOwONl0qEUc4+B6V9NnWtSjz95eg7/8uCb8Y8iRbGvI9vT4/znRKofFxstvKmW4URu/H74/g0ywV57h0B+A==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-code-block/-/extension-code-block-3.6.2.tgz", + "integrity": "sha512-5jfoiQ/3AUrIyuVU1NmEXar6sZFnY7wDFf3ZU2zpcBUG++yg/CmpOe5bXpoolczhl58cM/jyBG5gumQjyOxLNg==", "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.7.0", - "@tiptap/pm": "^2.7.0" + "@tiptap/core": "^3.6.2", + "@tiptap/pm": "^3.6.2" } }, "node_modules/@tiptap/extension-document": { - "version": "2.26.1", - "resolved": "https://registry.npmjs.org/@tiptap/extension-document/-/extension-document-2.26.1.tgz", - "integrity": "sha512-2P2IZp1NRAE+21mRuFBiP3X2WKfZ6kUC23NJKpn8bcOamY3obYqCt0ltGPhE4eR8n8QAl2fI/3jIgjR07dC8ow==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-document/-/extension-document-3.6.2.tgz", + "integrity": "sha512-4qg3KWL3aO1M7hfDpZR6/vSo7Cfqr3McyGUfqb/BXqYDW1DwT8jJkDTcHrGU7WUKRlWgoyPyzM8pZiGlP0uQHg==", "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.7.0" + "@tiptap/core": "^3.6.2" } }, "node_modules/@tiptap/extension-dropcursor": { - "version": "2.26.1", - "resolved": "https://registry.npmjs.org/@tiptap/extension-dropcursor/-/extension-dropcursor-2.26.1.tgz", - "integrity": "sha512-JkDQU2ZYFOuT5mNYb8OiWGwD1HcjbtmX8tLNugQbToECmz9WvVPqJmn7V/q8VGpP81iEECz/IsyRmuf2kSD4uA==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-dropcursor/-/extension-dropcursor-3.6.2.tgz", + "integrity": "sha512-6R5sma/i2TKd5h9OpIcy3a0wOGp5BNT/zIgnE/1HTmKi40eNcCAVe8sxd6+iWA5ETONP1E48kDy4hqA5ZzZCiQ==", "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.7.0", - "@tiptap/pm": "^2.7.0" + "@tiptap/extensions": "^3.6.2" } }, "node_modules/@tiptap/extension-gapcursor": { - "version": "2.26.1", - "resolved": "https://registry.npmjs.org/@tiptap/extension-gapcursor/-/extension-gapcursor-2.26.1.tgz", - "integrity": "sha512-KOiMZc3PwJS3hR0nSq5d0TJi2jkNZkLZElcT6pCEnhRHzPH6dRMu9GM5Jj798ZRUy0T9UFcKJalFZaDxnmRnpg==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-gapcursor/-/extension-gapcursor-3.6.2.tgz", + "integrity": "sha512-gXg+EvUKlv3ZO1GxKkRmAsi/V4yyA8AzLW6ppOcYrM2CKf6epmPaVRgAjdwHCA6cm3QuCBJyWeGTCAjhjNakhw==", "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.7.0", - "@tiptap/pm": "^2.7.0" + "@tiptap/extensions": "^3.6.2" } }, "node_modules/@tiptap/extension-hard-break": { - "version": "2.26.1", - "resolved": "https://registry.npmjs.org/@tiptap/extension-hard-break/-/extension-hard-break-2.26.1.tgz", - "integrity": "sha512-d6uStdNKi8kjPlHAyO59M6KGWATNwhLCD7dng0NXfwGndc22fthzIk/6j9F6ltQx30huy5qQram6j3JXwNACoA==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-hard-break/-/extension-hard-break-3.6.2.tgz", + "integrity": "sha512-ncuPBHhGY58QjluJvEH6vXotaa1QZ/vphXBGAr55kiATZwMIEHgwh2Hgc6AiFTcw057gabGn6jNFDfRB+HjbmA==", "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.7.0" + "@tiptap/core": "^3.6.2" } }, "node_modules/@tiptap/extension-heading": { - "version": "2.26.1", - "resolved": "https://registry.npmjs.org/@tiptap/extension-heading/-/extension-heading-2.26.1.tgz", - "integrity": "sha512-KSzL8WZV3pjJG9ke4RaU70+B5UlYR2S6olNt5UCAawM+fi11mobVztiBoC19xtpSVqIXC1AmXOqUgnuSvmE4ZA==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-heading/-/extension-heading-3.6.2.tgz", + "integrity": "sha512-JQ2yjwXGAiwGc+MhS1mULBr354MHfmWqVDQLRg8ey6LkdXggTDDJ1Ni3GrUS7B5YcA/ICdhr4krXaQpNkT5Syw==", "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.7.0" - } - }, - "node_modules/@tiptap/extension-history": { - "version": "2.26.1", - "resolved": "https://registry.npmjs.org/@tiptap/extension-history/-/extension-history-2.26.1.tgz", - "integrity": "sha512-m6YR1gkkauIDo3PRl0gP+7Oc4n5OqDzcjVh6LvWREmZP8nmi94hfseYbqOXUb6RPHIc0JKF02eiRifT4MSd2nw==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/ueberdosis" - }, - "peerDependencies": { - "@tiptap/core": "^2.7.0", - "@tiptap/pm": "^2.7.0" + "@tiptap/core": "^3.6.2" } }, "node_modules/@tiptap/extension-horizontal-rule": { - "version": "2.26.1", - "resolved": "https://registry.npmjs.org/@tiptap/extension-horizontal-rule/-/extension-horizontal-rule-2.26.1.tgz", - "integrity": "sha512-mT6baqOhs/NakgrAeDeed194E/ZJFGL692H0C7f1N7WDRaWxUu2oR0LrnRqSH5OyPjELkzu6nQnNy0+0tFGHHg==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-horizontal-rule/-/extension-horizontal-rule-3.6.2.tgz", + "integrity": "sha512-3TlPqedPDM9QkRTUPhOTxNxQVPSsBwlsuLrAZOgyM1y871Xi7M1DFX0h9LLXuqzPndYzUY16NjrfBGFJX+O56w==", "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.7.0", - "@tiptap/pm": "^2.7.0" + "@tiptap/core": "^3.6.2", + "@tiptap/pm": "^3.6.2" } }, "node_modules/@tiptap/extension-image": { - "version": "2.26.1", - "resolved": "https://registry.npmjs.org/@tiptap/extension-image/-/extension-image-2.26.1.tgz", - "integrity": "sha512-96+MaYBJebQlR/ik5W72GLUfXdEoxFs+6jsoERxbM5qEdhb7TEnodBFtWZOwgDO27kFd6rSNZuW9r5KJNtljEg==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-image/-/extension-image-3.6.2.tgz", + "integrity": "sha512-AuetGUr1sGH18UDREk0EMt7jYnFkBFsnYlXNNcp0g0rGACRKaCD7Bzv451nHc8m1WYOpqMAyTTlRg+eYs442xA==", "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.7.0" + "@tiptap/core": "^3.6.2" } }, "node_modules/@tiptap/extension-italic": { - "version": "2.26.1", - "resolved": "https://registry.npmjs.org/@tiptap/extension-italic/-/extension-italic-2.26.1.tgz", - "integrity": "sha512-pOs6oU4LyGO89IrYE4jbE8ZYsPwMMIiKkYfXcfeD9NtpGNBnjeVXXF5I9ndY2ANrCAgC8k58C3/powDRf0T2yA==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-italic/-/extension-italic-3.6.2.tgz", + "integrity": "sha512-46zYKqM3o9w1A2G9hWr0ERGbJpqIncoH45XIfLdAI6ZldZVVf+NeXMGwjOPf4+03cZ5/emk3MRTnVp9vF4ToIg==", "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.7.0" + "@tiptap/core": "^3.6.2" } }, "node_modules/@tiptap/extension-link": { - "version": "2.26.1", - "resolved": "https://registry.npmjs.org/@tiptap/extension-link/-/extension-link-2.26.1.tgz", - "integrity": "sha512-7yfum5Jymkue/uOSTQPt2SmkZIdZx7t3QhZLqBU7R9ettkdSCBgEGok6N+scJM1R1Zes+maSckLm0JZw5BKYNA==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-link/-/extension-link-3.6.2.tgz", + "integrity": "sha512-3yiRDWa187h30e6iUOJeejZLsbzbJthLfBwTeJGx7pHh7RngsEW82npBRuqLoI3udhJGTkXbzwAFZ9qOGOjl1Q==", "license": "MIT", "dependencies": { - "linkifyjs": "^4.2.0" + "linkifyjs": "^4.3.2" }, "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.7.0", - "@tiptap/pm": "^2.7.0" + "@tiptap/core": "^3.6.2", + "@tiptap/pm": "^3.6.2" + } + }, + "node_modules/@tiptap/extension-list": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-list/-/extension-list-3.6.2.tgz", + "integrity": "sha512-ZLaEHGVq4eL26hZZFE9e7RArk2rEjcVstN/YTRTKElTnLaf58kLTKN3nlgy1PWGwzfWGUuXURBuEBLaq5l6djg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^3.6.2", + "@tiptap/pm": "^3.6.2" } }, "node_modules/@tiptap/extension-list-item": { - "version": "2.26.1", - "resolved": "https://registry.npmjs.org/@tiptap/extension-list-item/-/extension-list-item-2.26.1.tgz", - "integrity": "sha512-quOXckC73Luc3x+Dcm88YAEBW+Crh3x5uvtQOQtn2GEG91AshrvbnhGRiYnfvEN7UhWIS+FYI5liHFcRKSUKrQ==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-list-item/-/extension-list-item-3.6.2.tgz", + "integrity": "sha512-ma/D2GKylpNB04FfNI3tDMY+C9nz7Yk85H21YTIGv8QL5KlDK97L6orydmx6IVRc2nNMZQVitBIEKDOXcczX9w==", "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.7.0" + "@tiptap/extension-list": "^3.6.2" + } + }, + "node_modules/@tiptap/extension-list-keymap": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-list-keymap/-/extension-list-keymap-3.6.2.tgz", + "integrity": "sha512-1kl/lggH+LL/FUwcSx8p761ebk9L5ZGK06mGyDDU9XiGLS310CktZYLnpEuFgn/oMPbRHo26oNl9SXLn1/U53A==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/extension-list": "^3.6.2" } }, "node_modules/@tiptap/extension-ordered-list": { - "version": "2.26.1", - "resolved": "https://registry.npmjs.org/@tiptap/extension-ordered-list/-/extension-ordered-list-2.26.1.tgz", - "integrity": "sha512-UHKNRxq6TBnXMGFSq91knD6QaHsyyOwLOsXMzupmKM5Su0s+CRXEjfav3qKlbb9e4m7D7S/a0aPm8nC9KIXNhQ==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-ordered-list/-/extension-ordered-list-3.6.2.tgz", + "integrity": "sha512-KdJ5MLIw19N+XiqQ2COXGtaq9TzUbtlLE5dgYCJQ2EumeZKIGELvUnHjrnIB9gH/gRlMs+hprLTh23xVUDJovg==", "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.7.0" + "@tiptap/extension-list": "^3.6.2" } }, "node_modules/@tiptap/extension-paragraph": { - "version": "2.26.1", - "resolved": "https://registry.npmjs.org/@tiptap/extension-paragraph/-/extension-paragraph-2.26.1.tgz", - "integrity": "sha512-UezvM9VDRAVJlX1tykgHWSD1g3MKfVMWWZ+Tg+PE4+kizOwoYkRWznVPgCAxjmyHajxpCKRXgqTZkOxjJ9Kjzg==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-paragraph/-/extension-paragraph-3.6.2.tgz", + "integrity": "sha512-jeJWj2xKib3392iHQEcB7wYZ30dUgXuwqpCTwtN9eANor+Zvv6CpDKBs1R2al6BYFbIJCgKeTulqxce0yoC80g==", "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.7.0" - } - }, - "node_modules/@tiptap/extension-placeholder": { - "version": "2.26.1", - "resolved": "https://registry.npmjs.org/@tiptap/extension-placeholder/-/extension-placeholder-2.26.1.tgz", - "integrity": "sha512-MBlqbkd+63btY7Qu+SqrXvWjPwooGZDsLTtl7jp52BczBl61cq9yygglt9XpM11TFMBdySgdLHBrLtQ0B7fBlw==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/ueberdosis" - }, - "peerDependencies": { - "@tiptap/core": "^2.7.0", - "@tiptap/pm": "^2.7.0" + "@tiptap/core": "^3.6.2" } }, "node_modules/@tiptap/extension-strike": { - "version": "2.26.1", - "resolved": "https://registry.npmjs.org/@tiptap/extension-strike/-/extension-strike-2.26.1.tgz", - "integrity": "sha512-CkoRH+pAi6MgdCh7K0cVZl4N2uR4pZdabXAnFSoLZRSg6imLvEUmWHfSi1dl3Z7JOvd3a4yZ4NxerQn5MWbJ7g==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-strike/-/extension-strike-3.6.2.tgz", + "integrity": "sha512-976u5WaioIN/0xCjl/UIEypmzACzxgVz6OGgfIsYyreMUiPjhhgzXb0A/2Po5p3nZpKcaMcxifOdhqdw+lDpIQ==", "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.7.0" + "@tiptap/core": "^3.6.2" } }, "node_modules/@tiptap/extension-subscript": { - "version": "2.26.1", - "resolved": "https://registry.npmjs.org/@tiptap/extension-subscript/-/extension-subscript-2.26.1.tgz", - "integrity": "sha512-tnXu18nBbTE6PqmkcpoPun5VxElupYacNfl2WkLB/trN3rBJbyDkn0diS8pL0Ku1vPNi2kSfrHq78/PbX0O1iA==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-subscript/-/extension-subscript-3.6.2.tgz", + "integrity": "sha512-knI9mlRPwRSTza8y5K7x3w3Lg/m5dXAqbxpjCwTxEzu3ngbaUyLEDfQ4TCViwgqCWTefDtPI/FEiKl1MTVcw9g==", "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.7.0" + "@tiptap/core": "^3.6.2", + "@tiptap/pm": "^3.6.2" } }, "node_modules/@tiptap/extension-superscript": { - "version": "2.26.1", - "resolved": "https://registry.npmjs.org/@tiptap/extension-superscript/-/extension-superscript-2.26.1.tgz", - "integrity": "sha512-YTUmppwJchqXxE4nf+wTMuZuUU9/9ibg8p73rif6WxldjuH0RGZQRY8ad5Ha1c5clG+60e0nrXthqqLgvWfjtw==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-superscript/-/extension-superscript-3.6.2.tgz", + "integrity": "sha512-DbxTVrbX6cYSn8vSQ0kScgJ37x3EzNX6a83XO1OhByH3pH1oPqZyzBtLLNt5ocaMFQHEGawhwoGjNpzOCSoajA==", "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.7.0" + "@tiptap/core": "^3.6.2", + "@tiptap/pm": "^3.6.2" } }, "node_modules/@tiptap/extension-table": { - "version": "2.26.1", - "resolved": "https://registry.npmjs.org/@tiptap/extension-table/-/extension-table-2.26.1.tgz", - "integrity": "sha512-LQ63CK53qx2ZsbLTB4mUX0YCoGC0GbYQ82jS3kD+K7M/mb9MCkefvDk6rA8rXF8TjfGnv6o/Fseoot8uhH3qfg==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-table/-/extension-table-3.6.2.tgz", + "integrity": "sha512-ozRPpxTXrYABTU/zQq3JlytUUXvQDaEcl19YUR1mL/7Ctf4zRBvSnBHCuP/1Cu+4oHX4zdako/G++Z5qJxa65A==", "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.7.0", - "@tiptap/pm": "^2.7.0" - } - }, - "node_modules/@tiptap/extension-table-cell": { - "version": "2.26.1", - "resolved": "https://registry.npmjs.org/@tiptap/extension-table-cell/-/extension-table-cell-2.26.1.tgz", - "integrity": "sha512-0P5zY+WGFnULggJkX6+CevmFoBmVv1aUiBBXfcFuLG2mnUsS3QALQTowFtz/0/VbtbjzcOSStaGDHRJxPbk9XQ==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/ueberdosis" - }, - "peerDependencies": { - "@tiptap/core": "^2.7.0" - } - }, - "node_modules/@tiptap/extension-table-header": { - "version": "2.26.1", - "resolved": "https://registry.npmjs.org/@tiptap/extension-table-header/-/extension-table-header-2.26.1.tgz", - "integrity": "sha512-SAwTW9H+sjVYjoeU5z8pVDMHn3r3FCi+zp2KAxsEsmujcd7qrQdY0cAjQtWjckCq6H3sQkbICa+xlCCd7C8ZAQ==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/ueberdosis" - }, - "peerDependencies": { - "@tiptap/core": "^2.7.0" - } - }, - "node_modules/@tiptap/extension-table-row": { - "version": "2.26.1", - "resolved": "https://registry.npmjs.org/@tiptap/extension-table-row/-/extension-table-row-2.26.1.tgz", - "integrity": "sha512-c4oLrUfj1EVVDpbfKX36v7nnaeI4NxML2KRTQXocvcY65VCe0bPQh8ujpPgPcnKEzdWYdIuAX9RbEAkiYWe8Ww==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/ueberdosis" - }, - "peerDependencies": { - "@tiptap/core": "^2.7.0" + "@tiptap/core": "^3.6.2", + "@tiptap/pm": "^3.6.2" } }, "node_modules/@tiptap/extension-text": { - "version": "2.26.1", - "resolved": "https://registry.npmjs.org/@tiptap/extension-text/-/extension-text-2.26.1.tgz", - "integrity": "sha512-p2n8WVMd/2vckdJlol24acaTDIZAhI7qle5cM75bn01sOEZoFlSw6SwINOULrUCzNJsYb43qrLEibZb4j2LeQw==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-text/-/extension-text-3.6.2.tgz", + "integrity": "sha512-fFSUEv1H3lM92yr6jZdELk0gog8rPTK5hTf08kP8RsY8pA80Br1ADVenejrMV4UNTmT1JWTXGBGhMqfQFHUvAQ==", "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.7.0" + "@tiptap/core": "^3.6.2" } }, "node_modules/@tiptap/extension-text-align": { - "version": "2.26.1", - "resolved": "https://registry.npmjs.org/@tiptap/extension-text-align/-/extension-text-align-2.26.1.tgz", - "integrity": "sha512-x6mpNGELy2QtSPBoQqNgiXO9PjZoB+O2EAfXA9YRiBDSIRNOrw+7vOVpi+IgzswFmhMNgIYUVfQRud4FHUCNew==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-text-align/-/extension-text-align-3.6.2.tgz", + "integrity": "sha512-P3IYe6pyOe9hZoSQfHypFioLbGrr24d55/RkvNnwSd8qzd0RhjXIyiuOmYLcXdLio4PkJ+KjbZcptQ9zW8Mh4g==", "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.7.0" + "@tiptap/core": "^3.6.2" } }, "node_modules/@tiptap/extension-text-style": { - "version": "2.26.1", - "resolved": "https://registry.npmjs.org/@tiptap/extension-text-style/-/extension-text-style-2.26.1.tgz", - "integrity": "sha512-t9Nc/UkrbCfnSHEUi1gvUQ2ZPzvfdYFT5TExoV2DTiUCkhG6+mecT5bTVFGW3QkPmbToL+nFhGn4ZRMDD0SP3Q==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-text-style/-/extension-text-style-3.6.2.tgz", + "integrity": "sha512-1N5suFcjZLdccYN+5zjFGFPV6YsLWbz0aYnLcwUvrRSxMm5VkOqKSm5ZLV11rikU06WgkfpLCtmZ5jpl0piD9Q==", "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.7.0" + "@tiptap/core": "^3.6.2" } }, "node_modules/@tiptap/extension-underline": { - "version": "2.26.1", - "resolved": "https://registry.npmjs.org/@tiptap/extension-underline/-/extension-underline-2.26.1.tgz", - "integrity": "sha512-/fufv41WDMdf0a4xmFAxONoAz08TonJXX6NEoSJmuGKO59M/Y0Pz8DTK1g32Wk44kn7dyScDiPlvvndl+UOv0A==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-underline/-/extension-underline-3.6.2.tgz", + "integrity": "sha512-IrG6vjxTMI2EeyhZCtx0sNTEu83PsAvzIh4vxmG1fUi/RYokks+sFbgGMuq0jtO96iVNEszlpAC/vaqfxFJwew==", "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.7.0" + "@tiptap/core": "^3.6.2" + } + }, + "node_modules/@tiptap/extensions": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/@tiptap/extensions/-/extensions-3.6.2.tgz", + "integrity": "sha512-tg7/DgaI6SpkeawryapUtNoBxsJUMJl3+nSjTfTvsaNXed+BHzLPsvmPbzlF9ScrAbVEx8nj6CCkneECYIQ4CQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^3.6.2", + "@tiptap/pm": "^3.6.2" } }, "node_modules/@tiptap/pm": { - "version": "2.26.1", - "resolved": "https://registry.npmjs.org/@tiptap/pm/-/pm-2.26.1.tgz", - "integrity": "sha512-8aF+mY/vSHbGFqyG663ds84b+vca5Lge3tHdTMTKazxCnhXR9dn2oQJMnZ78YZvdRbkPkMJJHti9h3K7u2UQvw==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/@tiptap/pm/-/pm-3.6.2.tgz", + "integrity": "sha512-g+NXjqjbj6NfHOMl22uNWVYIu8oCq7RFfbnpohPMsSKJLaHYE8mJR++7T6P5R9FoqhIFdwizg1jTpwRU5CHqXQ==", "license": "MIT", "dependencies": { "prosemirror-changeset": "^2.3.0", @@ -2602,14 +2562,50 @@ "prosemirror-keymap": "^1.2.2", "prosemirror-markdown": "^1.13.1", "prosemirror-menu": "^1.2.4", - "prosemirror-model": "^1.23.0", + "prosemirror-model": "^1.24.1", "prosemirror-schema-basic": "^1.2.3", - "prosemirror-schema-list": "^1.4.1", + "prosemirror-schema-list": "^1.5.0", "prosemirror-state": "^1.4.3", "prosemirror-tables": "^1.6.4", "prosemirror-trailing-node": "^3.0.0", "prosemirror-transform": "^1.10.2", - "prosemirror-view": "^1.37.0" + "prosemirror-view": "^1.38.1" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + } + }, + "node_modules/@tiptap/starter-kit": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/@tiptap/starter-kit/-/starter-kit-3.6.2.tgz", + "integrity": "sha512-nPzraIx/f1cOUNqG1LSC0OTnEu3mudcN3jQVuyGh3dvdOnik7FUciJEVfHKnloAyeoijidEeiLpiGHInp2uREg==", + "license": "MIT", + "dependencies": { + "@tiptap/core": "^3.6.2", + "@tiptap/extension-blockquote": "^3.6.2", + "@tiptap/extension-bold": "^3.6.2", + "@tiptap/extension-bullet-list": "^3.6.2", + "@tiptap/extension-code": "^3.6.2", + "@tiptap/extension-code-block": "^3.6.2", + "@tiptap/extension-document": "^3.6.2", + "@tiptap/extension-dropcursor": "^3.6.2", + "@tiptap/extension-gapcursor": "^3.6.2", + "@tiptap/extension-hard-break": "^3.6.2", + "@tiptap/extension-heading": "^3.6.2", + "@tiptap/extension-horizontal-rule": "^3.6.2", + "@tiptap/extension-italic": "^3.6.2", + "@tiptap/extension-link": "^3.6.2", + "@tiptap/extension-list": "^3.6.2", + "@tiptap/extension-list-item": "^3.6.2", + "@tiptap/extension-list-keymap": "^3.6.2", + "@tiptap/extension-ordered-list": "^3.6.2", + "@tiptap/extension-paragraph": "^3.6.2", + "@tiptap/extension-strike": "^3.6.2", + "@tiptap/extension-text": "^3.6.2", + "@tiptap/extension-underline": "^3.6.2", + "@tiptap/extensions": "^3.6.2", + "@tiptap/pm": "^3.6.2" }, "funding": { "type": "github", @@ -17184,39 +17180,16 @@ "src/packages/tiptap": { "name": "@umbraco-backoffice/tiptap", "dependencies": { - "@tiptap/core": "2.26.1", - "@tiptap/extension-blockquote": "2.26.1", - "@tiptap/extension-bold": "2.26.1", - "@tiptap/extension-bullet-list": "2.26.1", - "@tiptap/extension-character-count": "2.26.1", - "@tiptap/extension-code": "2.26.1", - "@tiptap/extension-code-block": "2.26.1", - "@tiptap/extension-document": "2.26.1", - "@tiptap/extension-dropcursor": "2.26.1", - "@tiptap/extension-gapcursor": "2.26.1", - "@tiptap/extension-hard-break": "2.26.1", - "@tiptap/extension-heading": "2.26.1", - "@tiptap/extension-history": "2.26.1", - "@tiptap/extension-horizontal-rule": "2.26.1", - "@tiptap/extension-image": "2.26.1", - "@tiptap/extension-italic": "2.26.1", - "@tiptap/extension-link": "2.26.1", - "@tiptap/extension-list-item": "2.26.1", - "@tiptap/extension-ordered-list": "2.26.1", - "@tiptap/extension-paragraph": "2.26.1", - "@tiptap/extension-placeholder": "2.26.1", - "@tiptap/extension-strike": "2.26.1", - "@tiptap/extension-subscript": "2.26.1", - "@tiptap/extension-superscript": "2.26.1", - "@tiptap/extension-table": "2.26.1", - "@tiptap/extension-table-cell": "2.26.1", - "@tiptap/extension-table-header": "2.26.1", - "@tiptap/extension-table-row": "2.26.1", - "@tiptap/extension-text": "2.26.1", - "@tiptap/extension-text-align": "2.26.1", - "@tiptap/extension-text-style": "2.26.1", - "@tiptap/extension-underline": "2.26.1", - "@tiptap/pm": "2.26.1" + "@tiptap/core": "3.6.2", + "@tiptap/extension-image": "3.6.2", + "@tiptap/extension-subscript": "3.6.2", + "@tiptap/extension-superscript": "3.6.2", + "@tiptap/extension-table": "3.6.2", + "@tiptap/extension-text-align": "3.6.2", + "@tiptap/extension-text-style": "3.6.2", + "@tiptap/extensions": "3.6.2", + "@tiptap/pm": "3.6.2", + "@tiptap/starter-kit": "3.6.2" } }, "src/packages/translation": { diff --git a/src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/block/block.tipap-api.ts b/src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/block/block.tiptap-api.ts similarity index 52% rename from src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/block/block.tipap-api.ts rename to src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/block/block.tiptap-api.ts index f5f6b131bd..3af34ec0dc 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/block/block.tipap-api.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/block/block.tiptap-api.ts @@ -1,5 +1,5 @@ -import { Node } from '../../externals.js'; import { UmbTiptapExtensionApiBase } from '../tiptap-extension-api-base.js'; +import { umbRteBlock, umbRteBlockInline } from './block.tiptap-extension.js'; import { distinctUntilChanged } from '@umbraco-cms/backoffice/external/rxjs'; import { UMB_BLOCK_RTE_DATA_CONTENT_KEY } from '@umbraco-cms/backoffice/rte'; import { UMB_BLOCK_RTE_MANAGER_CONTEXT } from '@umbraco-cms/backoffice/block-rte'; @@ -7,85 +7,6 @@ import type { UmbBlockDataModel } from '@umbraco-cms/backoffice/block'; import type { UmbBlockRteLayoutModel } from '@umbraco-cms/backoffice/block-rte'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; -declare module '@tiptap/core' { - interface Commands { - umbRteBlock: { - setBlock: (options: { contentKey: string }) => ReturnType; - }; - umbRteBlockInline: { - setBlockInline: (options: { contentKey: string }) => ReturnType; - }; - } -} - -const umbRteBlock = Node.create({ - name: 'umbRteBlock', - group: 'block', - content: undefined, // The block does not have any content, it is just a wrapper. - atom: true, // The block is an atom, meaning it is a single unit that cannot be split. - marks: '', // We do not allow marks on the block - draggable: true, - selectable: true, - - addAttributes() { - return { - [UMB_BLOCK_RTE_DATA_CONTENT_KEY]: { - isRequired: true, - }, - }; - }, - - parseHTML() { - return [{ tag: `umb-rte-block[${UMB_BLOCK_RTE_DATA_CONTENT_KEY}]` }]; - }, - - renderHTML({ HTMLAttributes }) { - return ['umb-rte-block', HTMLAttributes]; - }, - - addCommands() { - return { - setBlock: - (options) => - ({ commands }) => { - const attrs = { [UMB_BLOCK_RTE_DATA_CONTENT_KEY]: options.contentKey }; - return commands.insertContent({ - type: this.name, - attrs, - }); - }, - }; - }, -}); - -const umbRteBlockInline = umbRteBlock.extend({ - name: 'umbRteBlockInline', - group: 'inline', - inline: true, - - parseHTML() { - return [{ tag: `umb-rte-block-inline[${UMB_BLOCK_RTE_DATA_CONTENT_KEY}]` }]; - }, - - renderHTML({ HTMLAttributes }) { - return ['umb-rte-block-inline', HTMLAttributes]; - }, - - addCommands() { - return { - setBlockInline: - (options) => - ({ commands }) => { - const attrs = { [UMB_BLOCK_RTE_DATA_CONTENT_KEY]: options.contentKey }; - return commands.insertContent({ - type: this.name, - attrs, - }); - }, - }; - }, -}); - export default class UmbTiptapBlockElementApi extends UmbTiptapExtensionApiBase { constructor(host: UmbControllerHost) { super(host); diff --git a/src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/block/block.tiptap-extension.ts b/src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/block/block.tiptap-extension.ts new file mode 100644 index 0000000000..a91f4d7973 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/block/block.tiptap-extension.ts @@ -0,0 +1,90 @@ +import { Node } from '../../externals.js'; +import { UMB_BLOCK_RTE_DATA_CONTENT_KEY } from '@umbraco-cms/backoffice/rte'; + +declare module '@tiptap/core' { + interface Commands { + umbRteBlock: { + setBlock: (options: { contentKey: string }) => ReturnType; + }; + umbRteBlockInline: { + setBlockInline: (options: { contentKey: string }) => ReturnType; + }; + } +} + +export const umbRteBlock = Node.create({ + name: 'umbRteBlock', + group: 'block', + content: undefined, // The block does not have any content, it is just a wrapper. + atom: true, // The block is an atom, meaning it is a single unit that cannot be split. + marks: '', // We do not allow marks on the block + draggable: true, + selectable: true, + + addAttributes() { + return { + [UMB_BLOCK_RTE_DATA_CONTENT_KEY]: { + isRequired: true, + }, + }; + }, + + parseHTML() { + return [{ tag: `umb-rte-block[${UMB_BLOCK_RTE_DATA_CONTENT_KEY}]` }]; + }, + + renderHTML({ HTMLAttributes }) { + return ['umb-rte-block', HTMLAttributes]; + }, + + addCommands() { + return { + setBlock: + (options) => + ({ commands }) => { + const attrs = { [UMB_BLOCK_RTE_DATA_CONTENT_KEY]: options.contentKey }; + return commands.insertContent({ + type: this.name, + attrs, + }); + }, + }; + }, +}); + +export const umbRteBlockInline = umbRteBlock.extend({ + name: 'umbRteBlockInline', + group: 'inline', + inline: true, + + parseHTML() { + return [{ tag: `umb-rte-block-inline[${UMB_BLOCK_RTE_DATA_CONTENT_KEY}]` }]; + }, + + // TODO: [v17] Remove the `@ts-expect-error` once Tiptap has resolved the TypeScript definitions. [LK:2025-10-01] + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-expect-error + renderHTML({ HTMLAttributes }) { + return ['umb-rte-block-inline', HTMLAttributes]; + }, + + addCommands() { + return { + setBlockInline: + // TODO: [v17] Remove the `@ts-expect-error` once Tiptap has resolved the TypeScript definitions. [LK:2025-10-01] + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-expect-error + (options) => + // TODO: [v17] Remove the `@ts-expect-error` once Tiptap has resolved the TypeScript definitions. [LK:2025-10-01] + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-expect-error + ({ commands }) => { + const attrs = { [UMB_BLOCK_RTE_DATA_CONTENT_KEY]: options.contentKey }; + return commands.insertContent({ + type: this.name, + attrs, + }); + }, + }; + }, +}); diff --git a/src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/block/index.ts b/src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/block/index.ts new file mode 100644 index 0000000000..dfc4bccefe --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/block/index.ts @@ -0,0 +1 @@ +export * from './block.tiptap-extension.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/block/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/block/manifests.ts index 06cac85ba4..bee2331d93 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/block/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/block/manifests.ts @@ -6,7 +6,7 @@ export const manifests: Array import('./block.tipap-api.js'), + api: () => import('./block.tiptap-api.js'), meta: { icon: 'icon-plugin', label: 'Block', diff --git a/src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/core/rich-text-essentials.tiptap-api.ts b/src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/core/rich-text-essentials.tiptap-api.ts index 694d2b2e79..b79eae87c4 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/core/rich-text-essentials.tiptap-api.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/core/rich-text-essentials.tiptap-api.ts @@ -1,6 +1,6 @@ -import { Document, Dropcursor, Gapcursor, HardBreak, History, Paragraph, Text } from '../../externals.js'; +import { Document, Dropcursor, Gapcursor, HardBreak, Paragraph, Text, UndoRedo } from '../../externals.js'; import { UmbTiptapExtensionApiBase } from '../tiptap-extension-api-base.js'; export default class UmbTiptapRichTextEssentialsExtensionApi extends UmbTiptapExtensionApiBase { - getTiptapExtensions = () => [Document, Dropcursor, Gapcursor, HardBreak, History, Paragraph, Text]; + getTiptapExtensions = () => [Document, Dropcursor, Gapcursor, HardBreak, Paragraph, Text, UndoRedo]; } diff --git a/src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/index.ts b/src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/index.ts index 6303cdf51a..e6d46b8484 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/index.ts @@ -16,6 +16,5 @@ export * from './link/index.js'; export * from './table/index.js'; export * from './text-direction/index.js'; export * from './text-indent/index.js'; -export * from './trailing-node/index.js'; export type * from './types.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/link/link.tiptap-extension.ts b/src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/link/link.tiptap-extension.ts index 65f9678595..0384aa3ed6 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/link/link.tiptap-extension.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/link/link.tiptap-extension.ts @@ -5,6 +5,9 @@ export const UmbLink = Link.extend({ addAttributes() { return { + // TODO: [v17] Remove the `@ts-expect-error` once Tiptap has resolved the TypeScript definitions. [LK:2025-10-01] + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-expect-error ...this.parent?.(), 'data-anchor': { default: null }, title: { default: null }, @@ -17,6 +20,9 @@ export const UmbLink = Link.extend({ addOptions() { return { + // TODO: [v17] Remove the `@ts-expect-error` once Tiptap has resolved the TypeScript definitions. [LK:2025-10-01] + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-expect-error ...this.parent?.(), HTMLAttributes: { target: '', @@ -27,12 +33,21 @@ export const UmbLink = Link.extend({ addCommands() { return { + // TODO: [v17] Remove the `@ts-expect-error` once Tiptap has resolved the TypeScript definitions. [LK:2025-10-01] + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-expect-error setUmbLink: (attributes) => { + // TODO: [v17] Remove the `@ts-expect-error` once Tiptap has resolved the TypeScript definitions. [LK:2025-10-01] + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-expect-error return ({ chain }) => { return chain().setMark(this.name, attributes).setMeta('preventAutolink', true).run(); }; }, unsetUmbLink: () => { + // TODO: [v17] Remove the `@ts-expect-error` once Tiptap has resolved the TypeScript definitions. [LK:2025-10-01] + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-expect-error return ({ chain }) => { return chain().unsetMark(this.name, { extendEmptyMarkRange: true }).setMeta('preventAutolink', true).run(); }; @@ -44,7 +59,7 @@ export const UmbLink = Link.extend({ declare module '@tiptap/core' { interface Commands { umbLink: { - setUmbLink: (options: { + setUmbLink: (attributes: { type: string; href: string; 'data-anchor'?: string | null; diff --git a/src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/media-upload/media-upload.tiptap-api.ts b/src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/media-upload/media-upload.tiptap-api.ts index d158b9e51b..47c940f253 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/media-upload/media-upload.tiptap-api.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/media-upload/media-upload.tiptap-api.ts @@ -56,9 +56,9 @@ export default class UmbTiptapMediaUploadExtensionApi extends UmbTiptapExtension return [ Extension.create({ name: 'umbMediaUpload', - onCreate() { - this.parent?.(); - const host = this.editor.view.dom; + onCreate({ editor }) { + this.parent?.({ editor }); + const host = editor.view.dom; host.addEventListener('dragover', (event) => { // Required to allow drop events @@ -71,7 +71,7 @@ export default class UmbTiptapMediaUploadExtensionApi extends UmbTiptapExtension const files = event.dataTransfer?.files; if (!files) return; - self.#uploadTemporaryFile(files, this.editor); + self.#uploadTemporaryFile(files, editor); }); host.addEventListener('paste', (event) => { @@ -84,7 +84,7 @@ export default class UmbTiptapMediaUploadExtensionApi extends UmbTiptapExtension const files = event.clipboardData?.files; if (!files) return; - self.#uploadTemporaryFile(files, this.editor); + self.#uploadTemporaryFile(files, editor); }); }, }), diff --git a/src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/trailing-node/index.ts b/src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/trailing-node/index.ts deleted file mode 100644 index db3bca0c1e..0000000000 --- a/src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/trailing-node/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './trailing-node.tiptap-extension.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/trailing-node/trailing-node.tiptap-api.ts b/src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/trailing-node/trailing-node.tiptap-api.ts index 521ceab4a0..c407e016b6 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/trailing-node/trailing-node.tiptap-api.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/trailing-node/trailing-node.tiptap-api.ts @@ -1,5 +1,5 @@ +import { TrailingNode } from '../../externals.js'; import { UmbTiptapExtensionApiBase } from '../tiptap-extension-api-base.js'; -import { TrailingNode } from './trailing-node.tiptap-extension.js'; export default class UmbTiptapTrailingNodeExtensionApi extends UmbTiptapExtensionApiBase { getTiptapExtensions = () => [TrailingNode]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/trailing-node/trailing-node.tiptap-extension.ts b/src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/trailing-node/trailing-node.tiptap-extension.ts deleted file mode 100644 index 28ff71a50f..0000000000 --- a/src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/trailing-node/trailing-node.tiptap-extension.ts +++ /dev/null @@ -1,74 +0,0 @@ -/* eslint-disable local-rules/enforce-umbraco-external-imports */ -/* This Source Code has been derived from Tiptap. - * https://github.com/ueberdosis/tiptap/blob/v2.11.5/demos/src/Experiments/TrailingNode/Vue/trailing-node.ts - * SPDX-License-Identifier: MIT - * Copyright © 2023 Tiptap GmbH. - * Modifications are licensed under the MIT License. - */ - -import { Extension } from '../../externals.js'; -import { Plugin, PluginKey } from '@tiptap/pm/state'; - -// eslint-disable-next-line @typescript-eslint/ban-ts-comment -// @ts-ignore -// eslint-disable-next-line jsdoc/require-jsdoc -function nodeEqualsType({ types, node }) { - return (Array.isArray(types) && types.includes(node.type)) || node.type === types; -} - -export interface UmbTiptapTrailingNodeOptions { - node: string; - notAfter: string[]; -} - -export const TrailingNode = Extension.create({ - name: 'trailingNode', - - addOptions() { - return { - node: 'paragraph', - notAfter: ['paragraph'], - }; - }, - - addProseMirrorPlugins() { - const plugin = new PluginKey(this.name); - const disabledNodes = Object.entries(this.editor.schema.nodes) - .map(([, value]) => value) - .filter((node) => this.options.notAfter.includes(node.name)); - - return [ - new Plugin({ - key: plugin, - appendTransaction: (_, __, state) => { - const { doc, tr, schema } = state; - const shouldInsertNodeAtEnd = plugin.getState(state); - const endPosition = doc.content.size; - const type = schema.nodes[this.options.node]; - - if (!shouldInsertNodeAtEnd) { - return; - } - - return tr.insert(endPosition, type.create()); - }, - state: { - init: (_, state) => { - const lastNode = state.tr.doc.lastChild; - - return !nodeEqualsType({ node: lastNode, types: disabledNodes }); - }, - apply: (tr, value) => { - if (!tr.docChanged) { - return value; - } - - const lastNode = tr.doc.lastChild; - - return !nodeEqualsType({ node: lastNode, types: disabledNodes }); - }, - }, - }), - ]; - }, -}); diff --git a/src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/view-source/source-editor.tiptap-toolbar-api.ts b/src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/view-source/source-editor.tiptap-toolbar-api.ts index 5cfbde5e26..2263a8e5c5 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/view-source/source-editor.tiptap-toolbar-api.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/view-source/source-editor.tiptap-toolbar-api.ts @@ -1,8 +1,8 @@ import { UmbTiptapToolbarElementApiBase } from '../tiptap-toolbar-element-api-base.js'; -import { UMB_CODE_EDITOR_MODAL } from '@umbraco-cms/backoffice/code-editor'; -import { umbOpenModal } from '@umbraco-cms/backoffice/modal'; import type { Editor } from '../../externals.js'; import { UmbLocalizationController } from '@umbraco-cms/backoffice/localization-api'; +import { umbOpenModal } from '@umbraco-cms/backoffice/modal'; +import { UMB_CODE_EDITOR_MODAL } from '@umbraco-cms/backoffice/code-editor'; export default class UmbTiptapToolbarSourceEditorExtensionApi extends UmbTiptapToolbarElementApiBase { #localize = new UmbLocalizationController(this); @@ -21,6 +21,6 @@ export default class UmbTiptapToolbarSourceEditorExtensionApi extends UmbTiptapT if (!data) return; - editor?.commands.setContent(data.content, true); + editor?.commands.setContent(data.content); } } diff --git a/src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/word-count/word-count.tiptap-api.ts b/src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/word-count/word-count.tiptap-api.ts index 16ffae9cc8..6b3bf8b869 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/word-count/word-count.tiptap-api.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/tiptap/extensions/word-count/word-count.tiptap-api.ts @@ -1,9 +1,6 @@ -import { UmbTiptapExtensionApiBase } from '../tiptap-extension-api-base.js'; -import { css } from '@umbraco-cms/backoffice/external/lit'; import { CharacterCount } from '../../externals.js'; +import { UmbTiptapExtensionApiBase } from '../tiptap-extension-api-base.js'; export default class UmbTiptapWordCountExtensionApi extends UmbTiptapExtensionApiBase { getTiptapExtensions = () => [CharacterCount.configure()]; - - override getStyles = () => css``; } diff --git a/src/Umbraco.Web.UI.Client/src/packages/tiptap/externals.ts b/src/Umbraco.Web.UI.Client/src/packages/tiptap/externals.ts index 7340599c4b..a34560b3f8 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/tiptap/externals.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/tiptap/externals.ts @@ -1,19 +1,23 @@ +// Work-in-progress upgrade to Tiptap v3. [LK] +// Watch this issue: https://github.com/ueberdosis/tiptap/issues/6670 +// +// Docs: +// https://tiptap.dev/docs/guides/upgrade-tiptap-v2 +// https://tiptap.dev/docs/resources/whats-new +// https://github.com/ueberdosis/tiptap/issues + // REQUIRED EXTENSIONS export * from '@tiptap/core'; +export * from '@tiptap/extensions'; export { Document } from '@tiptap/extension-document'; -export { Dropcursor } from '@tiptap/extension-dropcursor'; -export { Gapcursor } from '@tiptap/extension-gapcursor'; export { HardBreak } from '@tiptap/extension-hard-break'; -export { History } from '@tiptap/extension-history'; export { Paragraph } from '@tiptap/extension-paragraph'; -export { Placeholder } from '@tiptap/extension-placeholder'; export { Text } from '@tiptap/extension-text'; // OPTIONAL EXTENSIONS export { Blockquote } from '@tiptap/extension-blockquote'; export { Bold } from '@tiptap/extension-bold'; -export { BulletList } from '@tiptap/extension-bullet-list'; -export { CharacterCount } from '@tiptap/extension-character-count'; +export { BulletList, OrderedList, ListItem } from '@tiptap/extension-list'; export { Code } from '@tiptap/extension-code'; export { CodeBlock } from '@tiptap/extension-code-block'; export { Heading } from '@tiptap/extension-heading'; @@ -21,15 +25,10 @@ export { HorizontalRule } from '@tiptap/extension-horizontal-rule'; export { Image } from '@tiptap/extension-image'; export { Italic } from '@tiptap/extension-italic'; export { Link } from '@tiptap/extension-link'; -export { ListItem } from '@tiptap/extension-list-item'; -export { OrderedList } from '@tiptap/extension-ordered-list'; export { Strike } from '@tiptap/extension-strike'; export { Subscript } from '@tiptap/extension-subscript'; export { Superscript } from '@tiptap/extension-superscript'; -export { Table } from '@tiptap/extension-table'; -export { TableCell } from '@tiptap/extension-table-cell'; -export { TableHeader } from '@tiptap/extension-table-header'; -export { TableRow } from '@tiptap/extension-table-row'; +export { Table, TableCell, TableHeader, TableRow } from '@tiptap/extension-table'; export { TextAlign } from '@tiptap/extension-text-align'; export { TextStyle } from '@tiptap/extension-text-style'; export { Underline } from '@tiptap/extension-underline'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/tiptap/package.json b/src/Umbraco.Web.UI.Client/src/packages/tiptap/package.json index 25f5cd443c..07743105d8 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/tiptap/package.json +++ b/src/Umbraco.Web.UI.Client/src/packages/tiptap/package.json @@ -6,38 +6,15 @@ "build": "vite build" }, "dependencies": { - "@tiptap/core": "2.26.1", - "@tiptap/extension-blockquote": "2.26.1", - "@tiptap/extension-bold": "2.26.1", - "@tiptap/extension-bullet-list": "2.26.1", - "@tiptap/extension-character-count": "2.26.1", - "@tiptap/extension-code-block": "2.26.1", - "@tiptap/extension-code": "2.26.1", - "@tiptap/extension-document": "2.26.1", - "@tiptap/extension-dropcursor": "2.26.1", - "@tiptap/extension-gapcursor": "2.26.1", - "@tiptap/extension-hard-break": "2.26.1", - "@tiptap/extension-heading": "2.26.1", - "@tiptap/extension-history": "2.26.1", - "@tiptap/extension-horizontal-rule": "2.26.1", - "@tiptap/extension-image": "2.26.1", - "@tiptap/extension-italic": "2.26.1", - "@tiptap/extension-link": "2.26.1", - "@tiptap/extension-list-item": "2.26.1", - "@tiptap/extension-ordered-list": "2.26.1", - "@tiptap/extension-paragraph": "2.26.1", - "@tiptap/extension-placeholder": "2.26.1", - "@tiptap/extension-strike": "2.26.1", - "@tiptap/extension-subscript": "2.26.1", - "@tiptap/extension-superscript": "2.26.1", - "@tiptap/extension-table": "2.26.1", - "@tiptap/extension-table-cell": "2.26.1", - "@tiptap/extension-table-header": "2.26.1", - "@tiptap/extension-table-row": "2.26.1", - "@tiptap/extension-text-align": "2.26.1", - "@tiptap/extension-text-style": "2.26.1", - "@tiptap/extension-text": "2.26.1", - "@tiptap/extension-underline": "2.26.1", - "@tiptap/pm": "2.26.1" + "@tiptap/core": "3.6.2", + "@tiptap/extension-image": "3.6.2", + "@tiptap/extension-subscript": "3.6.2", + "@tiptap/extension-superscript": "3.6.2", + "@tiptap/extension-table": "3.6.2", + "@tiptap/extension-text-align": "3.6.2", + "@tiptap/extension-text-style": "3.6.2", + "@tiptap/starter-kit": "3.6.2", + "@tiptap/extensions": "3.6.2", + "@tiptap/pm": "3.6.2" } }