diff --git a/app/helpers/frontend_asset_helper.rb b/app/helpers/frontend_asset_helper.rb index ae4a17097e4..a8288a34c07 100644 --- a/app/helpers/frontend_asset_helper.rb +++ b/app/helpers/frontend_asset_helper.rb @@ -73,17 +73,6 @@ module FrontendAssetHelper javascript_include_tag(path, nonce: content_security_policy_nonce, **) end - private - - def lookup_frontend_asset(unhashed_file_name) - hashed_file_name = ::OpenProject::Assets.lookup_asset(unhashed_file_name) - frontend_asset_path(hashed_file_name) - end - - def frontend_asset_path(file_name) - "/assets/frontend/#{file_name}" - end - def variable_asset_path(path) if FrontendAssetHelper.assets_proxied? File.join( @@ -97,4 +86,15 @@ module FrontendAssetHelper lookup_frontend_asset(path) end end + + private + + def lookup_frontend_asset(unhashed_file_name) + hashed_file_name = ::OpenProject::Assets.lookup_asset(unhashed_file_name) + frontend_asset_path(hashed_file_name) + end + + def frontend_asset_path(file_name) + "/assets/frontend/#{file_name}" + end end diff --git a/frontend/angular.json b/frontend/angular.json index 0b8eea4d986..1553a13847b 100644 --- a/frontend/angular.json +++ b/frontend/angular.json @@ -52,8 +52,11 @@ "input": "src/backlogs.scss", "bundleName": "backlogs" }, + { + "input": "node_modules/@blocknote/mantine/src/style.css", + "bundleName": "blocknote" + }, "src/styles.scss", - "node_modules/@blocknote/mantine/src/style.css", "node_modules/codemirror/lib/codemirror.css", "src/vendor/jquery-ui-1.14.1/jquery-ui.css", "src/vendor/jquery-ui-1.14.1/jquery-ui.structure.css", diff --git a/frontend/op-blocknote-extensions-0.0.16.tgz b/frontend/op-blocknote-extensions-0.0.16.tgz new file mode 100644 index 00000000000..15c5b35e6ed Binary files /dev/null and b/frontend/op-blocknote-extensions-0.0.16.tgz differ diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 65d09f2aa64..eb8d44bd0b4 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -24,9 +24,9 @@ "@appsignal/javascript": "^1.6.1", "@appsignal/plugin-breadcrumbs-console": "^1.1.37", "@appsignal/plugin-breadcrumbs-network": "^1.1.24", - "@blocknote/core": "^0.41.1", - "@blocknote/mantine": "^0.41.1", - "@blocknote/react": "^0.41.1", + "@blocknote/core": "https://pkg.pr.new/TypeCellOS/BlockNote/@blocknote/core@2223", + "@blocknote/mantine": "https://pkg.pr.new/TypeCellOS/BlockNote/@blocknote/mantine@2223", + "@blocknote/react": "https://pkg.pr.new/TypeCellOS/BlockNote/@blocknote/react@2223", "@braintree/sanitize-url": "^7.1.1", "@datorama/akita": "^8.0.1", "@floating-ui/dom": "^1.2.1", @@ -108,7 +108,7 @@ "ng2-dragula": "^6.0.0", "ngx-cookie-service": "^20.1.1", "observable-array": "0.0.4", - "op-blocknote-extensions": "https://github.com/opf/op-blocknote-extensions/releases/download/v0.0.15/op-blocknote-extensions-0.0.15.tgz", + "op-blocknote-extensions": "file:op-blocknote-extensions-0.0.16.tgz", "pako": "^2.0.3", "qr-creator": "^1.0.0", "react": "^19.2.0", @@ -3154,36 +3154,37 @@ } }, "node_modules/@blocknote/core": { - "version": "0.41.1", - "resolved": "https://registry.npmjs.org/@blocknote/core/-/core-0.41.1.tgz", - "integrity": "sha512-p/wxXzpl0/c9QwqXWcZ4KXzI+OjVzQOzSNaO5KrtDPDi7M1Bj6sc9L0+/V/8Wyo+XTY+tZOrtu6qCXVYIEJ/Rw==", + "version": "0.44.0", + "resolved": "https://pkg.pr.new/TypeCellOS/BlockNote/@blocknote/core@2223", + "integrity": "sha512-+VZ+Nb2tbyeZ/l7kwu63+TPrqoOdpNWDLVhSiA2AYC9gRNg+I4epzk9PXOVqEGFHEY8KowKigwybSgpE35mRmw==", "license": "MPL-2.0", "dependencies": { "@emoji-mart/data": "^1.2.1", + "@handlewithcare/prosemirror-inputrules": "0.1.3", "@shikijs/types": "3.13.0", - "@tiptap/core": "^3.4.3", - "@tiptap/extension-bold": "^3", - "@tiptap/extension-code": "^3", - "@tiptap/extension-gapcursor": "^3", - "@tiptap/extension-history": "^3", - "@tiptap/extension-horizontal-rule": "^3", - "@tiptap/extension-italic": "^3", - "@tiptap/extension-link": "^3", - "@tiptap/extension-paragraph": "^3", - "@tiptap/extension-strike": "^3", - "@tiptap/extension-text": "^3", - "@tiptap/extension-underline": "^3", - "@tiptap/pm": "^3.4.3", + "@tanstack/store": "0.7.7", + "@tiptap/core": "^3.11.0", + "@tiptap/extension-bold": "^3.7.2", + "@tiptap/extension-code": "^3.7.2", + "@tiptap/extension-gapcursor": "^3.7.2", + "@tiptap/extension-horizontal-rule": "^3.7.2", + "@tiptap/extension-italic": "^3.7.2", + "@tiptap/extension-link": "^3.7.2", + "@tiptap/extension-paragraph": "^3.7.2", + "@tiptap/extension-strike": "^3.7.2", + "@tiptap/extension-text": "^3.7.2", + "@tiptap/extension-underline": "^3.7.2", + "@tiptap/pm": "^3.11.0", "emoji-mart": "^5.6.0", - "fast-deep-equal": "^3", + "fast-deep-equal": "^3.1.3", "hast-util-from-dom": "^5.0.1", "prosemirror-dropcursor": "^1.8.2", "prosemirror-highlight": "^0.13.0", - "prosemirror-model": "^1.25.3", - "prosemirror-state": "^1.4.3", - "prosemirror-tables": "^1.6.4", - "prosemirror-transform": "^1.10.4", - "prosemirror-view": "^1.41.2", + "prosemirror-model": "^1.25.4", + "prosemirror-state": "^1.4.4", + "prosemirror-tables": "^1.8.1", + "prosemirror-transform": "^1.10.5", + "prosemirror-view": "^1.41.3", "rehype-format": "^5.0.1", "rehype-parse": "^9.0.1", "rehype-remark": "^10.0.1", @@ -3200,7 +3201,7 @@ "yjs": "^13.6.27" }, "peerDependencies": { - "@hocuspocus/provider": "^2.15.2" + "@hocuspocus/provider": "^2.15.2 || ^3.0.0" }, "peerDependenciesMeta": { "@hocuspocus/provider": { @@ -3217,44 +3218,55 @@ } }, "node_modules/@blocknote/mantine": { - "version": "0.41.1", - "resolved": "https://registry.npmjs.org/@blocknote/mantine/-/mantine-0.41.1.tgz", - "integrity": "sha512-0geMa5zRd3d67xpDCGAclW4y0yQ8Hn0ldjzUz7ilB/9NpYt+f9Y5uuuaK4DwchwYuMmCLDrtjtAh/jfmdSnnjw==", + "version": "0.44.0", + "resolved": "https://pkg.pr.new/TypeCellOS/BlockNote/@blocknote/mantine@2223", + "integrity": "sha512-JaAQx2IsdhD4nPteqflMkRSjl35OZUypyh082Ws8SPF2WeYOnroiG3SghsKmvOD1zobRq9DTp7v+lfYiL31kLQ==", "license": "MPL-2.0", "dependencies": { - "@blocknote/core": "0.41.1", - "@blocknote/react": "0.41.1", - "react-icons": "^5.2.1" + "@blocknote/core": "https://pkg.pr.new/TypeCellOS/BlockNote/@blocknote/core@0ed01199d6d20336bd710e53de4ef83fd4157a1c", + "@blocknote/react": "https://pkg.pr.new/TypeCellOS/BlockNote/@blocknote/react@0ed01199d6d20336bd710e53de4ef83fd4157a1c", + "react-icons": "^5.5.0" }, "peerDependencies": { - "@mantine/core": "^8.3.2", - "@mantine/hooks": "^8.3.2", + "@mantine/core": "^8.3.4", + "@mantine/hooks": "^8.3.4", "@mantine/utils": "^6.0.22", "react": "^18.0 || ^19.0 || >= 19.0.0-rc", "react-dom": "^18.0 || ^19.0 || >= 19.0.0-rc" } }, "node_modules/@blocknote/react": { - "version": "0.41.1", - "resolved": "https://registry.npmjs.org/@blocknote/react/-/react-0.41.1.tgz", - "integrity": "sha512-W1lRcyjpgNOZzASIbdX/fvEQ3ZML7FzHyS2xA9CskxOPrGvxHWREn+vper/hkchlTZ4I2dTx/IWwGAECT+2AvA==", + "version": "0.44.0", + "resolved": "https://pkg.pr.new/TypeCellOS/BlockNote/@blocknote/react@2223", + "integrity": "sha512-3WsNtboME09tpvz1pV2mOsCYyxihHmzFHpvp7Bh7LkrJpf8ihuWbxL1yGQKjyVLukMMOiiB10lhqG771k9hB0Q==", "license": "MPL-2.0", "dependencies": { - "@blocknote/core": "0.41.1", + "@blocknote/core": "https://pkg.pr.new/TypeCellOS/BlockNote/@blocknote/core@0ed01199d6d20336bd710e53de4ef83fd4157a1c", "@emoji-mart/data": "^1.2.1", "@floating-ui/react": "^0.27.16", - "@tiptap/core": "^3.4.3", - "@tiptap/pm": "^3.4.3", - "@tiptap/react": "^3.4.3", + "@floating-ui/utils": "0.2.10", + "@tanstack/react-store": "0.7.7", + "@tiptap/core": "^3.11.0", + "@tiptap/pm": "^3.11.0", + "@tiptap/react": "^3.11.0", + "@types/use-sync-external-store": "1.5.0", "emoji-mart": "^5.6.0", + "fast-deep-equal": "^3.1.3", "lodash.merge": "^4.6.2", - "react-icons": "^5.2.1" + "react-icons": "^5.5.0", + "use-sync-external-store": "1.6.0" }, "peerDependencies": { "react": "^18.0 || ^19.0 || >= 19.0.0-rc", "react-dom": "^18.0 || ^19.0 || >= 19.0.0-rc" } }, + "node_modules/@blocknote/react/node_modules/@types/use-sync-external-store": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-1.5.0.tgz", + "integrity": "sha512-5dyB8nLC/qogMrlCizZnYWQTA4lnb/v+It+sqNl5YnSRAPMlIqY/X0Xn+gZw8vOL+TgTTr28VEbn3uf8fUtAkw==", + "license": "MIT" + }, "node_modules/@braintree/sanitize-url": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/@braintree/sanitize-url/-/sanitize-url-7.1.1.tgz", @@ -4205,6 +4217,21 @@ "webauthn-json": "dist/bin/main.js" } }, + "node_modules/@handlewithcare/prosemirror-inputrules": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@handlewithcare/prosemirror-inputrules/-/prosemirror-inputrules-0.1.3.tgz", + "integrity": "sha512-LjGitwgSFHICeU6Mfbt+0Bp4BuWyvHfDYJIf7rq1qdNO88tFcWV3CSqw75o/YbsnUObDgp5Dn+gXIQLRwiyCbg==", + "license": "MIT", + "dependencies": { + "prosemirror-history": "^1.4.1", + "prosemirror-transform": "^1.0.0" + }, + "peerDependencies": { + "prosemirror-model": "^1.0.0", + "prosemirror-state": "^1.0.0", + "prosemirror-view": "^1.0.0" + } + }, "node_modules/@hocuspocus/common": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/@hocuspocus/common/-/common-3.4.0.tgz", @@ -7398,36 +7425,64 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/@tanstack/react-store": { + "version": "0.7.7", + "resolved": "https://registry.npmjs.org/@tanstack/react-store/-/react-store-0.7.7.tgz", + "integrity": "sha512-qqT0ufegFRDGSof9D/VqaZgjNgp4tRPHZIJq2+QIHkMUtHjaJ0lYrrXjeIUJvjnTbgPfSD1XgOMEt0lmANn6Zg==", + "license": "MIT", + "dependencies": { + "@tanstack/store": "0.7.7", + "use-sync-external-store": "^1.5.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/@tanstack/store": { + "version": "0.7.7", + "resolved": "https://registry.npmjs.org/@tanstack/store/-/store-0.7.7.tgz", + "integrity": "sha512-xa6pTan1bcaqYDS9BDpSiS63qa6EoDkPN9RsRaxHuDdVDNntzq3xNwR5YKTU/V3SkSyC9T4YVOPh2zRQN0nhIQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, "node_modules/@tiptap/core": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/@tiptap/core/-/core-3.7.0.tgz", - "integrity": "sha512-RQELiZdRyEISe3m3DnNnJtnE0hTV+6S6/BAC89E/UK6ZAlhwg3t08ouM33AoA1/R4QhTml8ITxCk1y7Re3Jdyg==", + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/@tiptap/core/-/core-3.12.0.tgz", + "integrity": "sha512-yy5LHOHgdR5Z3bID9g6Hj6IofqBw8HIHtT8E3SYZXnEWBUhsoXpJVAukXv0wWEZmIbae5PpQYIuklw/QXw26Pw==", "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/pm": "^3.7.0" + "@tiptap/pm": "^3.12.0" } }, "node_modules/@tiptap/extension-bold": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-bold/-/extension-bold-3.7.0.tgz", - "integrity": "sha512-gzK6nz/kVgZ33kNjMCE+5UFOEkWMPFPaM2fJ2J1r6yE8sV9jOCVBRXJ4Oe5vL1tW3jL6G7vBoDhg12f3pLxqvg==", + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-bold/-/extension-bold-3.12.0.tgz", + "integrity": "sha512-XH6BaC2HRkPaM7QdpThVtqlLDsWgjOjRc20JKBQIhH6+KFcSb4KiyRExVUdKqueTcSZwSGlu9/4uaecu3Ref4g==", "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^3.7.0" + "@tiptap/core": "^3.12.0" } }, "node_modules/@tiptap/extension-bubble-menu": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-bubble-menu/-/extension-bubble-menu-3.7.0.tgz", - "integrity": "sha512-vhoviZIlthAEFcHRDnx+Yw/xzazXPkddOB8IntbaYeh65pshi6XNAgq2RHBXg9fIdChsULqTX4SpX8xwP1Hbxg==", + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-bubble-menu/-/extension-bubble-menu-3.12.0.tgz", + "integrity": "sha512-l6PleGtsN8Nk6CS2DX9AWET2vf1eD97bzUpmF8rcF2XNRDJIcLnductBxmdm0t/Icr6sgxEBnJ4E2kIB9IeX4w==", "license": "MIT", "optional": true, "dependencies": { @@ -7438,27 +7493,27 @@ "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^3.7.0", - "@tiptap/pm": "^3.7.0" + "@tiptap/core": "^3.12.0", + "@tiptap/pm": "^3.12.0" } }, "node_modules/@tiptap/extension-code": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-code/-/extension-code-3.7.0.tgz", - "integrity": "sha512-x14eubaUWBNWnBnc+OWmant4KEYcypTAAcs6rpUqcNieEZz7yw1bvvSUoIAdwl4XPflhcxHnioXpISBzBF5msQ==", + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-code/-/extension-code-3.12.0.tgz", + "integrity": "sha512-6e5tAIfBBfA693VkHyGSEdIwGv59l9zIsajguJqON9En6bd9L6UFKaCZV8NUZtMxc64Yr3rMtdwBacsrhX2BoQ==", "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^3.7.0" + "@tiptap/core": "^3.12.0" } }, "node_modules/@tiptap/extension-floating-menu": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-floating-menu/-/extension-floating-menu-3.7.0.tgz", - "integrity": "sha512-9DPLssUWUXs88cgNNVLAYr7emDOnEDzjDRp69hwi5rqa0rXS/wdJ2Cw9yjBGZ0AB1galyjimjQ6nfqw8bymCjg==", + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-floating-menu/-/extension-floating-menu-3.12.0.tgz", + "integrity": "sha512-0aSUvJbO8H2DeiDYV5eC90JjM89RVs7nK+ljpGwy0W3W11Ho2uMGS1eznCfR4sLZW4HKTNIjyHIxq18ESIKSGQ==", "license": "MIT", "optional": true, "funding": { @@ -7467,67 +7522,54 @@ }, "peerDependencies": { "@floating-ui/dom": "^1.0.0", - "@tiptap/core": "^3.7.0", - "@tiptap/pm": "^3.7.0" + "@tiptap/core": "^3.12.0", + "@tiptap/pm": "^3.12.0" } }, "node_modules/@tiptap/extension-gapcursor": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-gapcursor/-/extension-gapcursor-3.7.0.tgz", - "integrity": "sha512-v556NDRpfvMGDqybBHhyL88/PpPKdpLHgH+F/yGlormOBJohTFHhJtRzJu9LiXrPOh9MQtNDHTlSoHn+BuWMlQ==", + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-gapcursor/-/extension-gapcursor-3.12.0.tgz", + "integrity": "sha512-A3sjuiqnzqPOOvkgkeKs1vP4YsTC7e6ThbVBNhcP4sOD++CFERUh9nxFw0iEEbDR1BnITaKpC3v06SkdjS94oQ==", "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/extensions": "^3.7.0" - } - }, - "node_modules/@tiptap/extension-history": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-history/-/extension-history-3.7.0.tgz", - "integrity": "sha512-uL9xMAWeswDH9SBh4ztJCz1cmAJrU7yBS7B6y8iCNr1hP9aFRfrjUhLecN7ZOFDZZJxsUgKLjg4Ie+EfUgjoGQ==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/ueberdosis" - }, - "peerDependencies": { - "@tiptap/extensions": "^3.7.0" + "@tiptap/extensions": "^3.12.0" } }, "node_modules/@tiptap/extension-horizontal-rule": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-horizontal-rule/-/extension-horizontal-rule-3.7.0.tgz", - "integrity": "sha512-uC21megLkompajwV2wT1WDKQR07Ni6A+extmAuVbTKDFZNKcdUyzCLVb0pSc4Oj1OkegdfEAgjrvllSeYN/7sA==", + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-horizontal-rule/-/extension-horizontal-rule-3.12.0.tgz", + "integrity": "sha512-OGbkDNqZPhxG0EpGa6I8l2Fy98Tuccr+nLoeAazxu5YzlUma34KtTNGZdo+38VU7giddr7zIHRJKJNt0hrOz5g==", "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^3.7.0", - "@tiptap/pm": "^3.7.0" + "@tiptap/core": "^3.12.0", + "@tiptap/pm": "^3.12.0" } }, "node_modules/@tiptap/extension-italic": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-italic/-/extension-italic-3.7.0.tgz", - "integrity": "sha512-jB1NqWey6eJiGl4S9ZwtuDNiaVNn+VGP4O7t652wJFLYmzpuBHo2zW2MEuXnMn1OC/RIEFSnEz68n1pHmT0OGw==", + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-italic/-/extension-italic-3.12.0.tgz", + "integrity": "sha512-duCzXPP4PeQbNdGvKQT0V10/2LNEn3qpwlJraGl5M+7s2samADK4rQ7buv4EaO9BgmVlg8iHlGPwXoKWmoSOfQ==", "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^3.7.0" + "@tiptap/core": "^3.12.0" } }, "node_modules/@tiptap/extension-link": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-link/-/extension-link-3.7.0.tgz", - "integrity": "sha512-J53OJEhnii1+8rk0lDEI5gcXl2h0VU/SaYsanRr0nTNntYcWRApJ/Ct+DmDiZj3u7/O02Uqa2hi28KtO4al0gw==", + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-link/-/extension-link-3.12.0.tgz", + "integrity": "sha512-C363e6JgIX/McpYWAgJxbUHZecPYs6mcZzrg6lqjgjUDPAiHXEY3WR/lHCC3XuZ4ZAvffRsKXcjX6ewdIkf4Uw==", "license": "MIT", "dependencies": { "linkifyjs": "^4.3.2" @@ -7537,60 +7579,60 @@ "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^3.7.0", - "@tiptap/pm": "^3.7.0" + "@tiptap/core": "^3.12.0", + "@tiptap/pm": "^3.12.0" } }, "node_modules/@tiptap/extension-paragraph": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-paragraph/-/extension-paragraph-3.7.0.tgz", - "integrity": "sha512-FvpXEHuZs6oe9ZRR/dxsNWkap72KMYqNhtBxbZVj88vREq2kAOB6YSU//83cJI9qxCuhWWG2yJEllKuRq2UIPg==", + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-paragraph/-/extension-paragraph-3.12.0.tgz", + "integrity": "sha512-J8HPJajgV0cIkA4wK7wBNJSpiNmi5Vd/Ii94hi6wpCbIdMMkfj8ngeXzVjVO/6Hpm2Xyr21OPbv2g3I6pgVAGA==", "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^3.7.0" + "@tiptap/core": "^3.12.0" } }, "node_modules/@tiptap/extension-strike": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-strike/-/extension-strike-3.7.0.tgz", - "integrity": "sha512-aijZWz7mCn2RUkqL3ZwTn1CYG9ETbryOIwVwX9fMs4xm3rwQ0D8dWBvZbkBEVg3CfZ2tz3HfWtMR0rbvcTl5Qg==", + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-strike/-/extension-strike-3.12.0.tgz", + "integrity": "sha512-OSR9SB3ycrKH0gCUkCWdd0IoNCp15xpbV0h7D8ElQBZ249c/FZrm6kGwB25fzdyA8ZlTpWrfwnoHxmMcOCMVIg==", "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^3.7.0" + "@tiptap/core": "^3.12.0" } }, "node_modules/@tiptap/extension-text": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-text/-/extension-text-3.7.0.tgz", - "integrity": "sha512-LWENBReuqpssEdtg98j9E6zSmSBCJZKmv8Wx0C5AtwdkeCs8KaEcjkBa5RF3buVoW3aJZs/3vm0DZz0oNxqI3Q==", + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-text/-/extension-text-3.12.0.tgz", + "integrity": "sha512-7AlIYbmEeT3zAYCWrPTunaZkyIWriJtEAmUzURlQVVKmNv6kCTyJcqX7N0Db8z8Z19UFHaVAODL8yXYde4QB/w==", "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^3.7.0" + "@tiptap/core": "^3.12.0" } }, "node_modules/@tiptap/extension-underline": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-underline/-/extension-underline-3.7.0.tgz", - "integrity": "sha512-x9Pgus0d8lv5h+ZwJvmrgNawUTK/sKfACrzdQQmq6BhNtWCbTX718jJ3RhJAjZiVZC6Xp1JlVc4GWiGI6SqZCA==", + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-underline/-/extension-underline-3.12.0.tgz", + "integrity": "sha512-Woh/nk1/7c31D14dIaU5i9d4NMK06TBeEA+uBidhZp+JAXVGMeQGm0K2iJxBXNvNrc6aKGlZ57W1o3CPUWOlWQ==", "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^3.7.0" + "@tiptap/core": "^3.12.0" } }, "node_modules/@tiptap/extensions": { @@ -7607,9 +7649,9 @@ } }, "node_modules/@tiptap/pm": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/@tiptap/pm/-/pm-3.7.0.tgz", - "integrity": "sha512-eCL/8yuNSADajyfvuhXygFUvSMFGQq+32qQ3SRumQ1KL2d9Jc9DAVeEACa/z8+4gwic5Z2VwDJh469WsGPf/NQ==", + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/@tiptap/pm/-/pm-3.12.0.tgz", + "integrity": "sha512-A2Hs6fdd9nFyIzdmJ9zoJvVuGsdwbQB+QA0TgBMTWwjyTRilpMeIhMX2qXNDzPFVy2aS4+QjvIpcHeArfbJ2bQ==", "license": "MIT", "dependencies": { "prosemirror-changeset": "^2.3.0", @@ -7637,13 +7679,13 @@ } }, "node_modules/@tiptap/react": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/@tiptap/react/-/react-3.7.0.tgz", - "integrity": "sha512-GPo5S/nR1jYyWHlvXNivbt/voC40B12zS4S/sHRgGtxhuBaYIMPJRCaRQixwPJJ9QslhanizKJMuqwSCPYPLbQ==", + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/@tiptap/react/-/react-3.12.0.tgz", + "integrity": "sha512-ZKKOg8fjRg7dIkctve3OE2Sf19yIj6rf1aMd9mNLtOvv2HYd0MdtDJ8Bl3dMIOf2/OhafhvGSVEVGt76ye3W4Q==", "license": "MIT", "dependencies": { "@types/use-sync-external-store": "^0.0.6", - "fast-deep-equal": "^3.1.3", + "fast-equals": "^5.3.3", "use-sync-external-store": "^1.4.0" }, "funding": { @@ -7651,12 +7693,12 @@ "url": "https://github.com/sponsors/ueberdosis" }, "optionalDependencies": { - "@tiptap/extension-bubble-menu": "^3.7.0", - "@tiptap/extension-floating-menu": "^3.7.0" + "@tiptap/extension-bubble-menu": "^3.12.0", + "@tiptap/extension-floating-menu": "^3.12.0" }, "peerDependencies": { - "@tiptap/core": "^3.7.0", - "@tiptap/pm": "^3.7.0", + "@tiptap/core": "^3.12.0", + "@tiptap/pm": "^3.12.0", "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", "@types/react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0", "react": "^17.0.0 || ^18.0.0 || ^19.0.0", @@ -12777,6 +12819,15 @@ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, + "node_modules/fast-equals": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-5.3.3.tgz", + "integrity": "sha512-/boTcHZeIAQ2r/tL11voclBHDeP9WPxLt+tyAbVSyyXuUFyh0Tne7gJZTqGbxnvj79TjLdCXLOY7UIPhyG5MTw==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/fast-glob": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", @@ -18276,13 +18327,13 @@ } }, "node_modules/op-blocknote-extensions": { - "version": "0.0.15", - "resolved": "https://github.com/opf/op-blocknote-extensions/releases/download/v0.0.15/op-blocknote-extensions-0.0.15.tgz", - "integrity": "sha512-NhRC6Nh786TzLXLGbAr1YKlwXzldk1rar3qEC/2Mub1++9MUG4UsGubnLCt6gLFDY+kos1PIww47ydq2bo8Uxg==", + "version": "0.0.16", + "resolved": "file:op-blocknote-extensions-0.0.16.tgz", + "integrity": "sha512-17Lkk76zfWxqXusc7oi7gMPg1ZhuH0uewJfR3TIS3FOpSYqS7QgS39HkGXLlnz7ZSnHUTxRoJ3xJdBeZfkgg5w==", "dependencies": { - "@blocknote/core": "^0.41.1", - "@blocknote/mantine": "^0.41.1", - "@blocknote/react": "^0.41.1", + "@blocknote/core": "^0.44.0", + "@blocknote/mantine": "^0.44.0", + "@blocknote/react": "^0.44.0", "@primer/octicons-react": "^19.20.0", "i18next": "^25.6.3", "react-i18next": "^16.3.5", @@ -19219,9 +19270,10 @@ } }, "node_modules/prosemirror-model": { - "version": "1.25.3", - "resolved": "https://registry.npmjs.org/prosemirror-model/-/prosemirror-model-1.25.3.tgz", - "integrity": "sha512-dY2HdaNXlARknJbrManZ1WyUtos+AP97AmvqdOQtWtrrC5g4mohVX5DTi9rXNFSk09eczLq9GuNTtq3EfMeMGA==", + "version": "1.25.4", + "resolved": "https://registry.npmjs.org/prosemirror-model/-/prosemirror-model-1.25.4.tgz", + "integrity": "sha512-PIM7E43PBxKce8OQeezAs9j4TP+5yDpZVbuurd1h5phUxEKIu+G2a+EUZzIC5nS1mJktDJWzbqS23n1tsAf5QA==", + "license": "MIT", "dependencies": { "orderedmap": "^2.0.0" } @@ -19247,9 +19299,9 @@ } }, "node_modules/prosemirror-state": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/prosemirror-state/-/prosemirror-state-1.4.3.tgz", - "integrity": "sha512-goFKORVbvPuAQaXhpbemJFRKJ2aixr+AZMGiquiqKxaucC6hlpHNZHWgz5R7dS4roHiwq9vDctE//CZ++o0W1Q==", + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/prosemirror-state/-/prosemirror-state-1.4.4.tgz", + "integrity": "sha512-6jiYHH2CIGbCfnxdHbXZ12gySFY/fz/ulZE333G6bPqIZ4F+TXo9ifiR86nAHpWnfoNjOb3o5ESi7J8Uz1jXHw==", "license": "MIT", "dependencies": { "prosemirror-model": "^1.0.0", @@ -19258,9 +19310,9 @@ } }, "node_modules/prosemirror-tables": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/prosemirror-tables/-/prosemirror-tables-1.7.1.tgz", - "integrity": "sha512-eRQ97Bf+i9Eby99QbyAiyov43iOKgWa7QCGly+lrDt7efZ1v8NWolhXiB43hSDGIXT1UXgbs4KJN3a06FGpr1Q==", + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/prosemirror-tables/-/prosemirror-tables-1.8.1.tgz", + "integrity": "sha512-DAgDoUYHCcc6tOGpLVPSU1k84kCUWTWnfWX3UDy2Delv4ryH0KqTD6RBI6k4yi9j9I8gl3j8MkPpRD/vWPZbug==", "license": "MIT", "dependencies": { "prosemirror-keymap": "^1.2.2", @@ -19286,9 +19338,9 @@ } }, "node_modules/prosemirror-transform": { - "version": "1.10.4", - "resolved": "https://registry.npmjs.org/prosemirror-transform/-/prosemirror-transform-1.10.4.tgz", - "integrity": "sha512-pwDy22nAnGqNR1feOQKHxoFkkUtepoFAd3r2hbEDsnf4wp57kKA36hXsB3njA9FtONBEwSDnDeCiJe+ItD+ykw==", + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/prosemirror-transform/-/prosemirror-transform-1.10.5.tgz", + "integrity": "sha512-RPDQCxIDhIBb1o36xxwsaeAvivO8VLJcgBtzmOwQ64bMtsVFh5SSuJ6dWSxO1UsHTiTXPCgQm3PDJt7p6IOLbw==", "license": "MIT", "dependencies": { "prosemirror-model": "^1.21.0" @@ -25771,35 +25823,35 @@ } }, "@blocknote/core": { - "version": "0.41.1", - "resolved": "https://registry.npmjs.org/@blocknote/core/-/core-0.41.1.tgz", - "integrity": "sha512-p/wxXzpl0/c9QwqXWcZ4KXzI+OjVzQOzSNaO5KrtDPDi7M1Bj6sc9L0+/V/8Wyo+XTY+tZOrtu6qCXVYIEJ/Rw==", + "version": "https://pkg.pr.new/TypeCellOS/BlockNote/@blocknote/core@2223", + "integrity": "sha512-+VZ+Nb2tbyeZ/l7kwu63+TPrqoOdpNWDLVhSiA2AYC9gRNg+I4epzk9PXOVqEGFHEY8KowKigwybSgpE35mRmw==", "requires": { "@emoji-mart/data": "^1.2.1", + "@handlewithcare/prosemirror-inputrules": "0.1.3", "@shikijs/types": "3.13.0", - "@tiptap/core": "^3.4.3", - "@tiptap/extension-bold": "^3", - "@tiptap/extension-code": "^3", - "@tiptap/extension-gapcursor": "^3", - "@tiptap/extension-history": "^3", - "@tiptap/extension-horizontal-rule": "^3", - "@tiptap/extension-italic": "^3", - "@tiptap/extension-link": "^3", - "@tiptap/extension-paragraph": "^3", - "@tiptap/extension-strike": "^3", - "@tiptap/extension-text": "^3", - "@tiptap/extension-underline": "^3", - "@tiptap/pm": "^3.4.3", + "@tanstack/store": "0.7.7", + "@tiptap/core": "^3.11.0", + "@tiptap/extension-bold": "^3.7.2", + "@tiptap/extension-code": "^3.7.2", + "@tiptap/extension-gapcursor": "^3.7.2", + "@tiptap/extension-horizontal-rule": "^3.7.2", + "@tiptap/extension-italic": "^3.7.2", + "@tiptap/extension-link": "^3.7.2", + "@tiptap/extension-paragraph": "^3.7.2", + "@tiptap/extension-strike": "^3.7.2", + "@tiptap/extension-text": "^3.7.2", + "@tiptap/extension-underline": "^3.7.2", + "@tiptap/pm": "^3.11.0", "emoji-mart": "^5.6.0", - "fast-deep-equal": "^3", + "fast-deep-equal": "^3.1.3", "hast-util-from-dom": "^5.0.1", "prosemirror-dropcursor": "^1.8.2", "prosemirror-highlight": "^0.13.0", - "prosemirror-model": "^1.25.3", - "prosemirror-state": "^1.4.3", - "prosemirror-tables": "^1.6.4", - "prosemirror-transform": "^1.10.4", - "prosemirror-view": "^1.41.2", + "prosemirror-model": "^1.25.4", + "prosemirror-state": "^1.4.4", + "prosemirror-tables": "^1.8.1", + "prosemirror-transform": "^1.10.5", + "prosemirror-view": "^1.41.3", "rehype-format": "^5.0.1", "rehype-parse": "^9.0.1", "rehype-remark": "^10.0.1", @@ -25824,29 +25876,39 @@ } }, "@blocknote/mantine": { - "version": "0.41.1", - "resolved": "https://registry.npmjs.org/@blocknote/mantine/-/mantine-0.41.1.tgz", - "integrity": "sha512-0geMa5zRd3d67xpDCGAclW4y0yQ8Hn0ldjzUz7ilB/9NpYt+f9Y5uuuaK4DwchwYuMmCLDrtjtAh/jfmdSnnjw==", + "version": "https://pkg.pr.new/TypeCellOS/BlockNote/@blocknote/mantine@2223", + "integrity": "sha512-JaAQx2IsdhD4nPteqflMkRSjl35OZUypyh082Ws8SPF2WeYOnroiG3SghsKmvOD1zobRq9DTp7v+lfYiL31kLQ==", "requires": { - "@blocknote/core": "0.41.1", - "@blocknote/react": "0.41.1", - "react-icons": "^5.2.1" + "@blocknote/core": "https://pkg.pr.new/TypeCellOS/BlockNote/@blocknote/core@0ed01199d6d20336bd710e53de4ef83fd4157a1c", + "@blocknote/react": "https://pkg.pr.new/TypeCellOS/BlockNote/@blocknote/react@0ed01199d6d20336bd710e53de4ef83fd4157a1c", + "react-icons": "^5.5.0" } }, "@blocknote/react": { - "version": "0.41.1", - "resolved": "https://registry.npmjs.org/@blocknote/react/-/react-0.41.1.tgz", - "integrity": "sha512-W1lRcyjpgNOZzASIbdX/fvEQ3ZML7FzHyS2xA9CskxOPrGvxHWREn+vper/hkchlTZ4I2dTx/IWwGAECT+2AvA==", + "version": "https://pkg.pr.new/TypeCellOS/BlockNote/@blocknote/react@2223", + "integrity": "sha512-3WsNtboME09tpvz1pV2mOsCYyxihHmzFHpvp7Bh7LkrJpf8ihuWbxL1yGQKjyVLukMMOiiB10lhqG771k9hB0Q==", "requires": { - "@blocknote/core": "0.41.1", + "@blocknote/core": "https://pkg.pr.new/TypeCellOS/BlockNote/@blocknote/core@0ed01199d6d20336bd710e53de4ef83fd4157a1c", "@emoji-mart/data": "^1.2.1", "@floating-ui/react": "^0.27.16", - "@tiptap/core": "^3.4.3", - "@tiptap/pm": "^3.4.3", - "@tiptap/react": "^3.4.3", + "@floating-ui/utils": "0.2.10", + "@tanstack/react-store": "0.7.7", + "@tiptap/core": "^3.11.0", + "@tiptap/pm": "^3.11.0", + "@tiptap/react": "^3.11.0", + "@types/use-sync-external-store": "1.5.0", "emoji-mart": "^5.6.0", + "fast-deep-equal": "^3.1.3", "lodash.merge": "^4.6.2", - "react-icons": "^5.2.1" + "react-icons": "^5.5.0", + "use-sync-external-store": "1.6.0" + }, + "dependencies": { + "@types/use-sync-external-store": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-1.5.0.tgz", + "integrity": "sha512-5dyB8nLC/qogMrlCizZnYWQTA4lnb/v+It+sqNl5YnSRAPMlIqY/X0Xn+gZw8vOL+TgTTr28VEbn3uf8fUtAkw==" + } } }, "@braintree/sanitize-url": { @@ -26440,6 +26502,15 @@ "resolved": "https://registry.npmjs.org/@github/webauthn-json/-/webauthn-json-2.1.1.tgz", "integrity": "sha512-XrftRn4z75SnaJOmZQbt7Mk+IIjqVHw+glDGOxuHwXkZBZh/MBoRS7MHjSZMDaLhT4RjN2VqiEU7EOYleuJWSQ==" }, + "@handlewithcare/prosemirror-inputrules": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@handlewithcare/prosemirror-inputrules/-/prosemirror-inputrules-0.1.3.tgz", + "integrity": "sha512-LjGitwgSFHICeU6Mfbt+0Bp4BuWyvHfDYJIf7rq1qdNO88tFcWV3CSqw75o/YbsnUObDgp5Dn+gXIQLRwiyCbg==", + "requires": { + "prosemirror-history": "^1.4.1", + "prosemirror-transform": "^1.0.0" + } + }, "@hocuspocus/common": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/@hocuspocus/common/-/common-3.4.0.tgz", @@ -28376,83 +28447,92 @@ } } }, + "@tanstack/react-store": { + "version": "0.7.7", + "resolved": "https://registry.npmjs.org/@tanstack/react-store/-/react-store-0.7.7.tgz", + "integrity": "sha512-qqT0ufegFRDGSof9D/VqaZgjNgp4tRPHZIJq2+QIHkMUtHjaJ0lYrrXjeIUJvjnTbgPfSD1XgOMEt0lmANn6Zg==", + "requires": { + "@tanstack/store": "0.7.7", + "use-sync-external-store": "^1.5.0" + } + }, + "@tanstack/store": { + "version": "0.7.7", + "resolved": "https://registry.npmjs.org/@tanstack/store/-/store-0.7.7.tgz", + "integrity": "sha512-xa6pTan1bcaqYDS9BDpSiS63qa6EoDkPN9RsRaxHuDdVDNntzq3xNwR5YKTU/V3SkSyC9T4YVOPh2zRQN0nhIQ==" + }, "@tiptap/core": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/@tiptap/core/-/core-3.7.0.tgz", - "integrity": "sha512-RQELiZdRyEISe3m3DnNnJtnE0hTV+6S6/BAC89E/UK6ZAlhwg3t08ouM33AoA1/R4QhTml8ITxCk1y7Re3Jdyg==" + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/@tiptap/core/-/core-3.12.0.tgz", + "integrity": "sha512-yy5LHOHgdR5Z3bID9g6Hj6IofqBw8HIHtT8E3SYZXnEWBUhsoXpJVAukXv0wWEZmIbae5PpQYIuklw/QXw26Pw==" }, "@tiptap/extension-bold": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-bold/-/extension-bold-3.7.0.tgz", - "integrity": "sha512-gzK6nz/kVgZ33kNjMCE+5UFOEkWMPFPaM2fJ2J1r6yE8sV9jOCVBRXJ4Oe5vL1tW3jL6G7vBoDhg12f3pLxqvg==" + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-bold/-/extension-bold-3.12.0.tgz", + "integrity": "sha512-XH6BaC2HRkPaM7QdpThVtqlLDsWgjOjRc20JKBQIhH6+KFcSb4KiyRExVUdKqueTcSZwSGlu9/4uaecu3Ref4g==" }, "@tiptap/extension-bubble-menu": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-bubble-menu/-/extension-bubble-menu-3.7.0.tgz", - "integrity": "sha512-vhoviZIlthAEFcHRDnx+Yw/xzazXPkddOB8IntbaYeh65pshi6XNAgq2RHBXg9fIdChsULqTX4SpX8xwP1Hbxg==", + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-bubble-menu/-/extension-bubble-menu-3.12.0.tgz", + "integrity": "sha512-l6PleGtsN8Nk6CS2DX9AWET2vf1eD97bzUpmF8rcF2XNRDJIcLnductBxmdm0t/Icr6sgxEBnJ4E2kIB9IeX4w==", "optional": true, "requires": { "@floating-ui/dom": "^1.0.0" } }, "@tiptap/extension-code": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-code/-/extension-code-3.7.0.tgz", - "integrity": "sha512-x14eubaUWBNWnBnc+OWmant4KEYcypTAAcs6rpUqcNieEZz7yw1bvvSUoIAdwl4XPflhcxHnioXpISBzBF5msQ==" + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-code/-/extension-code-3.12.0.tgz", + "integrity": "sha512-6e5tAIfBBfA693VkHyGSEdIwGv59l9zIsajguJqON9En6bd9L6UFKaCZV8NUZtMxc64Yr3rMtdwBacsrhX2BoQ==" }, "@tiptap/extension-floating-menu": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-floating-menu/-/extension-floating-menu-3.7.0.tgz", - "integrity": "sha512-9DPLssUWUXs88cgNNVLAYr7emDOnEDzjDRp69hwi5rqa0rXS/wdJ2Cw9yjBGZ0AB1galyjimjQ6nfqw8bymCjg==", + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-floating-menu/-/extension-floating-menu-3.12.0.tgz", + "integrity": "sha512-0aSUvJbO8H2DeiDYV5eC90JjM89RVs7nK+ljpGwy0W3W11Ho2uMGS1eznCfR4sLZW4HKTNIjyHIxq18ESIKSGQ==", "optional": true }, "@tiptap/extension-gapcursor": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-gapcursor/-/extension-gapcursor-3.7.0.tgz", - "integrity": "sha512-v556NDRpfvMGDqybBHhyL88/PpPKdpLHgH+F/yGlormOBJohTFHhJtRzJu9LiXrPOh9MQtNDHTlSoHn+BuWMlQ==" - }, - "@tiptap/extension-history": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-history/-/extension-history-3.7.0.tgz", - "integrity": "sha512-uL9xMAWeswDH9SBh4ztJCz1cmAJrU7yBS7B6y8iCNr1hP9aFRfrjUhLecN7ZOFDZZJxsUgKLjg4Ie+EfUgjoGQ==" + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-gapcursor/-/extension-gapcursor-3.12.0.tgz", + "integrity": "sha512-A3sjuiqnzqPOOvkgkeKs1vP4YsTC7e6ThbVBNhcP4sOD++CFERUh9nxFw0iEEbDR1BnITaKpC3v06SkdjS94oQ==" }, "@tiptap/extension-horizontal-rule": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-horizontal-rule/-/extension-horizontal-rule-3.7.0.tgz", - "integrity": "sha512-uC21megLkompajwV2wT1WDKQR07Ni6A+extmAuVbTKDFZNKcdUyzCLVb0pSc4Oj1OkegdfEAgjrvllSeYN/7sA==" + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-horizontal-rule/-/extension-horizontal-rule-3.12.0.tgz", + "integrity": "sha512-OGbkDNqZPhxG0EpGa6I8l2Fy98Tuccr+nLoeAazxu5YzlUma34KtTNGZdo+38VU7giddr7zIHRJKJNt0hrOz5g==" }, "@tiptap/extension-italic": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-italic/-/extension-italic-3.7.0.tgz", - "integrity": "sha512-jB1NqWey6eJiGl4S9ZwtuDNiaVNn+VGP4O7t652wJFLYmzpuBHo2zW2MEuXnMn1OC/RIEFSnEz68n1pHmT0OGw==" + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-italic/-/extension-italic-3.12.0.tgz", + "integrity": "sha512-duCzXPP4PeQbNdGvKQT0V10/2LNEn3qpwlJraGl5M+7s2samADK4rQ7buv4EaO9BgmVlg8iHlGPwXoKWmoSOfQ==" }, "@tiptap/extension-link": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-link/-/extension-link-3.7.0.tgz", - "integrity": "sha512-J53OJEhnii1+8rk0lDEI5gcXl2h0VU/SaYsanRr0nTNntYcWRApJ/Ct+DmDiZj3u7/O02Uqa2hi28KtO4al0gw==", + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-link/-/extension-link-3.12.0.tgz", + "integrity": "sha512-C363e6JgIX/McpYWAgJxbUHZecPYs6mcZzrg6lqjgjUDPAiHXEY3WR/lHCC3XuZ4ZAvffRsKXcjX6ewdIkf4Uw==", "requires": { "linkifyjs": "^4.3.2" } }, "@tiptap/extension-paragraph": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-paragraph/-/extension-paragraph-3.7.0.tgz", - "integrity": "sha512-FvpXEHuZs6oe9ZRR/dxsNWkap72KMYqNhtBxbZVj88vREq2kAOB6YSU//83cJI9qxCuhWWG2yJEllKuRq2UIPg==" + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-paragraph/-/extension-paragraph-3.12.0.tgz", + "integrity": "sha512-J8HPJajgV0cIkA4wK7wBNJSpiNmi5Vd/Ii94hi6wpCbIdMMkfj8ngeXzVjVO/6Hpm2Xyr21OPbv2g3I6pgVAGA==" }, "@tiptap/extension-strike": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-strike/-/extension-strike-3.7.0.tgz", - "integrity": "sha512-aijZWz7mCn2RUkqL3ZwTn1CYG9ETbryOIwVwX9fMs4xm3rwQ0D8dWBvZbkBEVg3CfZ2tz3HfWtMR0rbvcTl5Qg==" + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-strike/-/extension-strike-3.12.0.tgz", + "integrity": "sha512-OSR9SB3ycrKH0gCUkCWdd0IoNCp15xpbV0h7D8ElQBZ249c/FZrm6kGwB25fzdyA8ZlTpWrfwnoHxmMcOCMVIg==" }, "@tiptap/extension-text": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-text/-/extension-text-3.7.0.tgz", - "integrity": "sha512-LWENBReuqpssEdtg98j9E6zSmSBCJZKmv8Wx0C5AtwdkeCs8KaEcjkBa5RF3buVoW3aJZs/3vm0DZz0oNxqI3Q==" + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-text/-/extension-text-3.12.0.tgz", + "integrity": "sha512-7AlIYbmEeT3zAYCWrPTunaZkyIWriJtEAmUzURlQVVKmNv6kCTyJcqX7N0Db8z8Z19UFHaVAODL8yXYde4QB/w==" }, "@tiptap/extension-underline": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-underline/-/extension-underline-3.7.0.tgz", - "integrity": "sha512-x9Pgus0d8lv5h+ZwJvmrgNawUTK/sKfACrzdQQmq6BhNtWCbTX718jJ3RhJAjZiVZC6Xp1JlVc4GWiGI6SqZCA==" + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-underline/-/extension-underline-3.12.0.tgz", + "integrity": "sha512-Woh/nk1/7c31D14dIaU5i9d4NMK06TBeEA+uBidhZp+JAXVGMeQGm0K2iJxBXNvNrc6aKGlZ57W1o3CPUWOlWQ==" }, "@tiptap/extensions": { "version": "3.11.0", @@ -28460,9 +28540,9 @@ "integrity": "sha512-g43beA73ZMLezez1st9LEwYrRHZ0FLzlsSlOZKk7sdmtHLmuqWHf4oyb0XAHol1HZIdGv104rYaGNgmQXr1ecQ==" }, "@tiptap/pm": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/@tiptap/pm/-/pm-3.7.0.tgz", - "integrity": "sha512-eCL/8yuNSADajyfvuhXygFUvSMFGQq+32qQ3SRumQ1KL2d9Jc9DAVeEACa/z8+4gwic5Z2VwDJh469WsGPf/NQ==", + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/@tiptap/pm/-/pm-3.12.0.tgz", + "integrity": "sha512-A2Hs6fdd9nFyIzdmJ9zoJvVuGsdwbQB+QA0TgBMTWwjyTRilpMeIhMX2qXNDzPFVy2aS4+QjvIpcHeArfbJ2bQ==", "requires": { "prosemirror-changeset": "^2.3.0", "prosemirror-collab": "^1.3.1", @@ -28485,14 +28565,14 @@ } }, "@tiptap/react": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/@tiptap/react/-/react-3.7.0.tgz", - "integrity": "sha512-GPo5S/nR1jYyWHlvXNivbt/voC40B12zS4S/sHRgGtxhuBaYIMPJRCaRQixwPJJ9QslhanizKJMuqwSCPYPLbQ==", + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/@tiptap/react/-/react-3.12.0.tgz", + "integrity": "sha512-ZKKOg8fjRg7dIkctve3OE2Sf19yIj6rf1aMd9mNLtOvv2HYd0MdtDJ8Bl3dMIOf2/OhafhvGSVEVGt76ye3W4Q==", "requires": { - "@tiptap/extension-bubble-menu": "^3.7.0", - "@tiptap/extension-floating-menu": "^3.7.0", + "@tiptap/extension-bubble-menu": "^3.12.0", + "@tiptap/extension-floating-menu": "^3.12.0", "@types/use-sync-external-store": "^0.0.6", - "fast-deep-equal": "^3.1.3", + "fast-equals": "^5.3.3", "use-sync-external-store": "^1.4.0" } }, @@ -32252,6 +32332,11 @@ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, + "fast-equals": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-5.3.3.tgz", + "integrity": "sha512-/boTcHZeIAQ2r/tL11voclBHDeP9WPxLt+tyAbVSyyXuUFyh0Tne7gJZTqGbxnvj79TjLdCXLOY7UIPhyG5MTw==" + }, "fast-glob": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", @@ -35995,12 +36080,12 @@ } }, "op-blocknote-extensions": { - "version": "https://github.com/opf/op-blocknote-extensions/releases/download/v0.0.15/op-blocknote-extensions-0.0.15.tgz", - "integrity": "sha512-NhRC6Nh786TzLXLGbAr1YKlwXzldk1rar3qEC/2Mub1++9MUG4UsGubnLCt6gLFDY+kos1PIww47ydq2bo8Uxg==", + "version": "file:op-blocknote-extensions-0.0.16.tgz", + "integrity": "sha512-17Lkk76zfWxqXusc7oi7gMPg1ZhuH0uewJfR3TIS3FOpSYqS7QgS39HkGXLlnz7ZSnHUTxRoJ3xJdBeZfkgg5w==", "requires": { - "@blocknote/core": "^0.41.1", - "@blocknote/mantine": "^0.41.1", - "@blocknote/react": "^0.41.1", + "@blocknote/core": "^0.44.0", + "@blocknote/mantine": "^0.44.0", + "@blocknote/react": "^0.44.0", "@primer/octicons-react": "^19.20.0", "i18next": "^25.6.3", "react-i18next": "^16.3.5", @@ -36641,9 +36726,9 @@ } }, "prosemirror-model": { - "version": "1.25.3", - "resolved": "https://registry.npmjs.org/prosemirror-model/-/prosemirror-model-1.25.3.tgz", - "integrity": "sha512-dY2HdaNXlARknJbrManZ1WyUtos+AP97AmvqdOQtWtrrC5g4mohVX5DTi9rXNFSk09eczLq9GuNTtq3EfMeMGA==", + "version": "1.25.4", + "resolved": "https://registry.npmjs.org/prosemirror-model/-/prosemirror-model-1.25.4.tgz", + "integrity": "sha512-PIM7E43PBxKce8OQeezAs9j4TP+5yDpZVbuurd1h5phUxEKIu+G2a+EUZzIC5nS1mJktDJWzbqS23n1tsAf5QA==", "requires": { "orderedmap": "^2.0.0" } @@ -36667,9 +36752,9 @@ } }, "prosemirror-state": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/prosemirror-state/-/prosemirror-state-1.4.3.tgz", - "integrity": "sha512-goFKORVbvPuAQaXhpbemJFRKJ2aixr+AZMGiquiqKxaucC6hlpHNZHWgz5R7dS4roHiwq9vDctE//CZ++o0W1Q==", + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/prosemirror-state/-/prosemirror-state-1.4.4.tgz", + "integrity": "sha512-6jiYHH2CIGbCfnxdHbXZ12gySFY/fz/ulZE333G6bPqIZ4F+TXo9ifiR86nAHpWnfoNjOb3o5ESi7J8Uz1jXHw==", "requires": { "prosemirror-model": "^1.0.0", "prosemirror-transform": "^1.0.0", @@ -36677,9 +36762,9 @@ } }, "prosemirror-tables": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/prosemirror-tables/-/prosemirror-tables-1.7.1.tgz", - "integrity": "sha512-eRQ97Bf+i9Eby99QbyAiyov43iOKgWa7QCGly+lrDt7efZ1v8NWolhXiB43hSDGIXT1UXgbs4KJN3a06FGpr1Q==", + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/prosemirror-tables/-/prosemirror-tables-1.8.1.tgz", + "integrity": "sha512-DAgDoUYHCcc6tOGpLVPSU1k84kCUWTWnfWX3UDy2Delv4ryH0KqTD6RBI6k4yi9j9I8gl3j8MkPpRD/vWPZbug==", "requires": { "prosemirror-keymap": "^1.2.2", "prosemirror-model": "^1.25.0", @@ -36698,9 +36783,9 @@ } }, "prosemirror-transform": { - "version": "1.10.4", - "resolved": "https://registry.npmjs.org/prosemirror-transform/-/prosemirror-transform-1.10.4.tgz", - "integrity": "sha512-pwDy22nAnGqNR1feOQKHxoFkkUtepoFAd3r2hbEDsnf4wp57kKA36hXsB3njA9FtONBEwSDnDeCiJe+ItD+ykw==", + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/prosemirror-transform/-/prosemirror-transform-1.10.5.tgz", + "integrity": "sha512-RPDQCxIDhIBb1o36xxwsaeAvivO8VLJcgBtzmOwQ64bMtsVFh5SSuJ6dWSxO1UsHTiTXPCgQm3PDJt7p6IOLbw==", "requires": { "prosemirror-model": "^1.21.0" } diff --git a/frontend/package.json b/frontend/package.json index dc25d34848c..54b747caa76 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -79,9 +79,9 @@ "@appsignal/javascript": "^1.6.1", "@appsignal/plugin-breadcrumbs-console": "^1.1.37", "@appsignal/plugin-breadcrumbs-network": "^1.1.24", - "@blocknote/core": "^0.41.1", - "@blocknote/mantine": "^0.41.1", - "@blocknote/react": "^0.41.1", + "@blocknote/core": "https://pkg.pr.new/TypeCellOS/BlockNote/@blocknote/core@2223", + "@blocknote/mantine": "https://pkg.pr.new/TypeCellOS/BlockNote/@blocknote/mantine@2223", + "@blocknote/react": "https://pkg.pr.new/TypeCellOS/BlockNote/@blocknote/react@2223", "@braintree/sanitize-url": "^7.1.1", "@datorama/akita": "^8.0.1", "@floating-ui/dom": "^1.2.1", @@ -163,7 +163,7 @@ "ng2-dragula": "^6.0.0", "ngx-cookie-service": "^20.1.1", "observable-array": "0.0.4", - "op-blocknote-extensions": "https://github.com/opf/op-blocknote-extensions/releases/download/v0.0.15/op-blocknote-extensions-0.0.15.tgz", + "op-blocknote-extensions": "file:op-blocknote-extensions-0.0.16.tgz", "pako": "^2.0.3", "qr-creator": "^1.0.0", "react": "^19.2.0", diff --git a/frontend/src/elements/block-note-element.ts b/frontend/src/elements/block-note-element.ts new file mode 100644 index 00000000000..c6c1aa08216 --- /dev/null +++ b/frontend/src/elements/block-note-element.ts @@ -0,0 +1,104 @@ +/* + * -- copyright + * OpenProject is an open source project management software. + * Copyright (C) 2023 the OpenProject GmbH + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version 3. + * + * OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: + * Copyright (C) 2006-2013 Jean-Philippe Lang + * Copyright (C) 2010-2013 the ChiliProject Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * See COPYRIGHT and LICENSE files for more details. + * ++ + */ + +import { User } from '@blocknote/core/comments'; +import { HocuspocusProvider } from '@hocuspocus/provider'; +import { LiveCollaborationManager } from 'core-stimulus/helpers/live-collaboration-helpers'; +import React from 'react'; +import { createRoot } from 'react-dom/client'; +import OpBlockNoteContainer from '../react/OpBlockNoteContainer'; +import { ShadowDomWrapper } from 'op-blocknote-extensions'; + +class BlockNoteElement extends HTMLElement { + private mount:HTMLDivElement; + + constructor() { + super(); + + const shadowRoot = this.attachShadow({ mode: 'open' }); + this.mount = document.createElement('div'); + shadowRoot.appendChild(this.mount); + + const blockNoteStylesheetUrl = this.getAttribute('blocknote-stylesheet-url'); + if (blockNoteStylesheetUrl) { + const link = document.createElement('link'); + link.setAttribute('rel', 'stylesheet'); + link.setAttribute('href', blockNoteStylesheetUrl); + shadowRoot.appendChild(link); + } + } + + connectedCallback() { + const root = createRoot(this.mount); + + const collaborationEnabled = this.getAttribute('collaboration-enabled') === 'true'; + if (collaborationEnabled) { + LiveCollaborationManager.onReady((hocuspocusProvider) => { + root.render(this.BlockNoteReactContainer(hocuspocusProvider)); + }); + } else { + root.render(this.BlockNoteReactContainer()); + } + } + + BlockNoteReactContainer(hocuspocusProvider?:HocuspocusProvider) { + return React.createElement( + ShadowDomWrapper, + { target: this.mount }, + React.createElement( + OpBlockNoteContainer, + { + activeUser: this.parseActiveUser()!, + readOnly: this.getAttribute('read-only') === 'true', + openProjectUrl: this.getAttribute('open-project-url') ?? '', + attachmentsUploadUrl: this.getAttribute('attachments-upload-url') ?? '', + attachmentsCollectionKey: this.getAttribute('attachments-collection-key') ?? '', + hocuspocusProvider: hocuspocusProvider, + } + ) + ); + } + + private parseActiveUser():User | null { + const userData = this.getAttribute('active-user'); + if (userData) { + try { + return JSON.parse(userData) as User; + } catch (e) { + console.error('Failed to parse active user data:', e); + return null; + } + } + return null; + } + +} + +customElements.define('op-block-note', BlockNoteElement); diff --git a/frontend/src/main.ts b/frontend/src/main.ts index d723df2c3b1..07f707364b2 100644 --- a/frontend/src/main.ts +++ b/frontend/src/main.ts @@ -8,6 +8,7 @@ import { environment } from './environments/environment'; import { configureErrorReporter } from 'core-app/core/errors/configure-reporter'; import { initializeGlobalListeners } from 'core-app/core/setup/globals/global-listeners'; import { getMetaElement } from 'core-app/core/setup/globals/global-helpers'; +import 'core-elements/block-note-element'; import 'core-app/core/setup/init-vendors'; import 'core-app/core/setup/init-globals'; diff --git a/frontend/src/react/OpBlockNoteContainer.tsx b/frontend/src/react/OpBlockNoteContainer.tsx index 2f2df80348e..d444223c2f6 100644 --- a/frontend/src/react/OpBlockNoteContainer.tsx +++ b/frontend/src/react/OpBlockNoteContainer.tsx @@ -35,7 +35,7 @@ import { OpBlockNoteEditor } from './components/OpBlockNoteEditor'; import { useCollaboration } from './hooks/useCollaboration'; export interface OpBlockNoteContainerProps { - inputField:HTMLInputElement; + inputField?:HTMLInputElement; inputText?:string; activeUser:User; readOnly:boolean; @@ -109,3 +109,4 @@ export default function OpBlockNoteContainer({ inputField, /> ); } + diff --git a/frontend/src/react/components/OpBlockNoteEditor.tsx b/frontend/src/react/components/OpBlockNoteEditor.tsx index 100afaa01dc..bd56703b4bd 100644 --- a/frontend/src/react/components/OpBlockNoteEditor.tsx +++ b/frontend/src/react/components/OpBlockNoteEditor.tsx @@ -28,8 +28,9 @@ * ++ */ -import { BlockNoteEditorOptions, BlockNoteSchema, filterSuggestionItems } from '@blocknote/core'; +import { BlockNoteEditorOptions, BlockNoteSchema } from '@blocknote/core'; import { User } from '@blocknote/core/comments'; +import { filterSuggestionItems } from '@blocknote/core/extensions'; import { BlockNoteView } from '@blocknote/mantine'; import { getDefaultReactSlashMenuItems, SuggestionMenuController, useCreateBlockNote } from '@blocknote/react'; import { HocuspocusProvider } from '@hocuspocus/provider'; diff --git a/frontend/src/stimulus/controllers/dynamic/block-note.controller.ts b/frontend/src/stimulus/controllers/dynamic/block-note.controller.ts deleted file mode 100644 index a070272f1e4..00000000000 --- a/frontend/src/stimulus/controllers/dynamic/block-note.controller.ts +++ /dev/null @@ -1,92 +0,0 @@ -/* - * -- copyright - * OpenProject is an open source project management software. - * Copyright (C) 2023 the OpenProject GmbH - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version 3. - * - * OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: - * Copyright (C) 2006-2013 Jean-Philippe Lang - * Copyright (C) 2010-2013 the ChiliProject Team - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * See COPYRIGHT and LICENSE files for more details. - * ++ - */ - -import { User } from '@blocknote/core/comments'; -import type { HocuspocusProvider } from '@hocuspocus/provider'; -import { Controller } from '@hotwired/stimulus'; -import { LiveCollaborationManager } from 'core-stimulus/helpers/live-collaboration-helpers'; -import React from 'react'; -import { createRoot } from 'react-dom/client'; -import OpBlockNoteContainer from '../../../react/OpBlockNoteContainer'; - -export default class extends Controller { - static targets = [ - 'blockNoteEditor', - 'blockNoteInputField', - ]; - - declare readonly blockNoteEditorTarget:HTMLElement; - declare readonly blockNoteInputFieldTarget:HTMLInputElement; - - static values = { - inputText: String, - activeUser: Object, - readonly: Boolean, - openProjectUrl: String, - attachmentsUploadUrl: String, - attachmentsCollectionKey: String, - - collaborationEnabled: Boolean, - }; - - declare readonly inputTextValue:string; - declare readonly activeUserValue:User; - declare readonly readonlyValue:boolean; - declare readonly openProjectUrlValue:string; - declare readonly attachmentsUploadUrlValue:string; - declare readonly attachmentsCollectionKeyValue:string; - - declare readonly collaborationEnabledValue:string; - - connect() { - const root = createRoot(this.blockNoteEditorTarget); - - if (this.collaborationEnabledValue) { - LiveCollaborationManager.onReady((hocuspocusProvider) => { - root.render(this.BlockNoteReactContainer(hocuspocusProvider)); - }); - } else { - root.render(this.BlockNoteReactContainer()); - } - } - - BlockNoteReactContainer(hocuspocusProvider?:HocuspocusProvider) { - return React.createElement(OpBlockNoteContainer, { - inputField: this.blockNoteInputFieldTarget, - inputText: this.inputTextValue, - activeUser: this.activeUserValue, - readOnly: this.readonlyValue, - openProjectUrl: this.openProjectUrlValue, - attachmentsUploadUrl: this.attachmentsUploadUrlValue, - attachmentsCollectionKey: this.attachmentsCollectionKeyValue, - hocuspocusProvider: hocuspocusProvider, - }); - } -} diff --git a/frontend/tsconfig.json b/frontend/tsconfig.json index 5f54b619226..e57a76a4264 100644 --- a/frontend/tsconfig.json +++ b/frontend/tsconfig.json @@ -22,6 +22,7 @@ "@ng-select/ng-select/*": ["./node_modules/@ng-select/ng-select/*"], "core-app/*": ["./src/app/*"], "core-components/*": ["./src/app/components/*"], + "core-elements/*": ["./src/elements/*"], "core-stimulus/*": ["./src/stimulus/*"], "core-turbo/*": ["./src/turbo/*"], "core-typings/*": ["./src/typings/*"], diff --git a/lib/primer/open_project/forms/block_note_editor.html.erb b/lib/primer/open_project/forms/block_note_editor.html.erb index 0c8e08ae02f..bb10ec7e52a 100644 --- a/lib/primer/open_project/forms/block_note_editor.html.erb +++ b/lib/primer/open_project/forms/block_note_editor.html.erb @@ -30,28 +30,17 @@ %> <%= - render FormControl.new( - input: @input, - class: @input.classes, - data: { - controller: "block-note", - block_note_input_text_value: value, - block_note_active_user_value: active_user, - block_note_readonly_value: readonly, - block_note_attachments_upload_url_value: attachments_upload_url, - block_note_attachments_collection_key_value: attachments_collection_key, - block_note_collaboration_enabled_value: collaboration_enabled, - test_selector: "blocknote-document-description" - } - ) do -%> - <%= @input.builder.hidden_field(name, value:, data: { block_note_target: "blockNoteInputField" }) %> - <%= - render( - Primer::BaseComponent.new( - tag: :div, mt: 1, mb: 1, - data: { block_note_target: "blockNoteEditor" } - ) + render( + Primer::BaseComponent.new( + tag: "op-block-note", mt: 1, mb: 1, + "collaboration-enabled": collaboration_enabled, + "active-user": active_user.to_json, + "read-only": readonly, + "open-project-url": root_url, + "attachments-upload-url": attachments_upload_url, + "attachments-collection-key": attachments_collection_key, + "blocknote-stylesheet-url": blocknote_stylesheet_url, + "data-test-selector": "blocknote-document-description" ) - %> -<% end %> + ) +%> diff --git a/lib/primer/open_project/forms/block_note_editor.rb b/lib/primer/open_project/forms/block_note_editor.rb index 2373b9c8b97..aecca65c3e3 100644 --- a/lib/primer/open_project/forms/block_note_editor.rb +++ b/lib/primer/open_project/forms/block_note_editor.rb @@ -34,6 +34,7 @@ module Primer # :nodoc: class BlockNoteEditor < Primer::Forms::BaseComponent include ::OpenProject::StaticRouting::UrlHelpers + include FrontendAssetHelper attr_reader :input, :value, @@ -41,6 +42,7 @@ module Primer :active_user, :attachments_upload_url, :attachments_collection_key, + :blocknote_stylesheet_url, :collaboration_enabled delegate :name, to: :@input @@ -56,6 +58,7 @@ module Primer } @attachments_upload_url = attachments_upload_url @attachments_collection_key = attachments_collection_key + @blocknote_stylesheet_url = variable_asset_path("blocknote.css") @collaboration_enabled = true end diff --git a/modules/documents/spec/features/attachment_upload_spec.rb b/modules/documents/spec/features/attachment_upload_spec.rb index 9f30a60738c..63de5ee40d4 100644 --- a/modules/documents/spec/features/attachment_upload_spec.rb +++ b/modules/documents/spec/features/attachment_upload_spec.rb @@ -220,7 +220,7 @@ RSpec.describe "Upload attachment to documents", before do DocumentType.destroy_all visit document_path(document) - expect(page).to have_css(".document-form--long-description") # rubocop:disable RSpec/ExpectInHook + expect(page).to have_css("op-block-note") # rubocop:disable RSpec/ExpectInHook expect(page).not_to have_element("opce-ckeditor-augmented-textarea") # rubocop:disable RSpec/ExpectInHook end diff --git a/spec/support/form_fields/primerized/block_note_editor_input.rb b/spec/support/form_fields/primerized/block_note_editor_input.rb index b8241f23d7c..7b16eb820bd 100644 --- a/spec/support/form_fields/primerized/block_note_editor_input.rb +++ b/spec/support/form_fields/primerized/block_note_editor_input.rb @@ -21,8 +21,48 @@ module FormFields end def find_editor - page.find("div[role='textbox']") + # page.find("op-block-note") + + element = page.evaluate_script <<~JS + document.querySelector('op-block-note') + .shadowRoot.querySelector('div[role="textbox"]') + JS + + element.click + element end end end end + +# def open_add_image_dialog +# send_keys_to_editor("/image") +# send_keys_to_editor(:enter) +# end + +# def open_command_dialog +# send_keys_to_editor("/") +# end + +# def fill_in_with_content(content) +# send_keys_to_editor(content) +# end + +# private + +# def send_keys_to_editor(text) +# page.execute_script(<<~JS, text.to_s) +# const host = document.querySelector('op-block-note'); +# const el = host.shadowRoot.querySelector('div[role="textbox"]'); +# el.focus(); + +# const text = arguments[0]; +# if (text === 'enter') { +# el.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter', code: 'Enter', bubbles: true })); +# el.dispatchEvent(new KeyboardEvent('keypress', { key: 'Enter', code: 'Enter', bubbles: true })); +# el.dispatchEvent(new KeyboardEvent('keyup', { key: 'Enter', code: 'Enter', bubbles: true })); +# } else { +# document.execCommand('insertText', false, text); +# } +# JS +# end