diff --git a/README.md b/README.md
index 022ba40..7946aa5 100644
--- a/README.md
+++ b/README.md
@@ -17,7 +17,7 @@ This library is a complete react-native implementation of [FastComments](https:/
It supports live commenting, chat, threads, emoticons, notifications, SSO, skins, and full customization by passing in a stylesheet object. All assets
can also be customized, and it supports toggling different assets based on dark mode.
-The benefit of this library is that it is more flexible than the `fastcomments-react-native` wrapper. Comments are rendered with native components rather than inside a webview. Note: `react-native-webview` is still required as a transitive dependency of the rich text editor (`@10play/tentap-editor`).
+The benefit of this library is that it is more flexible than the `fastcomments-react-native` wrapper. Comments are rendered with native components rather than inside a webview.
It all runs on the FastComments backend, so you only have to incorporate the UI:
@@ -40,7 +40,9 @@ Add live chat to your existing React Native application, or even build a social
### Rich Text Editor
-This library uses the 10tap editor for rich text editing functionality, which provides a powerful WYSIWYG editing experience.
+This library uses [`react-native-enriched`](https://github.com/software-mansion/react-native-enriched) for rich text editing, which provides a powerful WYSIWYG editing experience. The same editor powers iOS, Android, and the web (via `react-native-web`), so the composer behaves consistently across every platform with a single implementation.
+
+`react-native-enriched` requires the React Native New Architecture (Fabric) on native, and a bundler that resolves package `exports` conditions (Metro with package exports / RN 0.72+). Web support is currently experimental.
### Configuration Options
diff --git a/example-web/index.html b/example-web/index.html
index 343de92..54d213f 100644
--- a/example-web/index.html
+++ b/example-web/index.html
@@ -6,6 +6,9 @@
FastComments React Native SDK - Web Example
diff --git a/example-web/package-lock.json b/example-web/package-lock.json
index 469a420..68b7da0 100644
--- a/example-web/package-lock.json
+++ b/example-web/package-lock.json
@@ -8,13 +8,13 @@
"name": "fastcomments-react-native-sdk-example-web",
"version": "0.0.1",
"dependencies": {
- "react": "18.2.0",
- "react-dom": "18.2.0",
- "react-native-web": "^0.19.10"
+ "react": "^19.0.0",
+ "react-dom": "^19.0.0",
+ "react-native-web": "^0.21.0"
},
"devDependencies": {
- "@types/react": "^18.2.0",
- "@types/react-dom": "^18.2.0",
+ "@types/react": "^19.0.0",
+ "@types/react-dom": "^19.0.0",
"@vitejs/plugin-react": "^4.3.0",
"typescript": "^5.4.0",
"vite": "^5.4.0"
@@ -1206,32 +1206,24 @@
"dev": true,
"license": "MIT"
},
- "node_modules/@types/prop-types": {
- "version": "15.7.15",
- "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.15.tgz",
- "integrity": "sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==",
- "dev": true,
- "license": "MIT"
- },
"node_modules/@types/react": {
- "version": "18.3.28",
- "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.28.tgz",
- "integrity": "sha512-z9VXpC7MWrhfWipitjNdgCauoMLRdIILQsAEV+ZesIzBq/oUlxk0m3ApZuMFCXdnS4U7KrI+l3WRUEGQ8K1QKw==",
+ "version": "19.2.17",
+ "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.17.tgz",
+ "integrity": "sha512-MXfmqaVPEVgkBT/aY0aGCkRWWtByiYQXo3xdQ8r5RzuFrPiRn8Gar2tQdXSUQ2GKV3bkXckek89V8wQBY2Q/Aw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@types/prop-types": "*",
"csstype": "^3.2.2"
}
},
"node_modules/@types/react-dom": {
- "version": "18.3.7",
- "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.7.tgz",
- "integrity": "sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==",
+ "version": "19.2.3",
+ "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz",
+ "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==",
"dev": true,
"license": "MIT",
"peerDependencies": {
- "@types/react": "^18.0.0"
+ "@types/react": "^19.2.0"
}
},
"node_modules/@vitejs/plugin-react": {
@@ -1435,12 +1427,6 @@
"node": ">=6"
}
},
- "node_modules/fast-loops": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/fast-loops/-/fast-loops-1.1.4.tgz",
- "integrity": "sha512-8dbd3XWoKCTms18ize6JmQF1SFnnfj5s0B7rRry22EofgMu7B6LKHVh+XfFqFGsqnbH54xgeO83PzpKI+ODhlg==",
- "license": "MIT"
- },
"node_modules/fbjs": {
"version": "3.0.5",
"resolved": "https://registry.npmjs.org/fbjs/-/fbjs-3.0.5.tgz",
@@ -1494,13 +1480,12 @@
"license": "BSD-3-Clause"
},
"node_modules/inline-style-prefixer": {
- "version": "6.0.4",
- "resolved": "https://registry.npmjs.org/inline-style-prefixer/-/inline-style-prefixer-6.0.4.tgz",
- "integrity": "sha512-FwXmZC2zbeeS7NzGjJ6pAiqRhXR0ugUShSNb6GApMl6da0/XGc4MOJsoWAywia52EEWbXNSy0pzkwz/+Y+swSg==",
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/inline-style-prefixer/-/inline-style-prefixer-7.0.1.tgz",
+ "integrity": "sha512-lhYo5qNTQp3EvSSp3sRvXMbVQTLrvGV6DycRMJ5dm2BLMiJ30wpXKdDdgX+GmJZ5uQMucwRKHamXSst3Sj/Giw==",
"license": "MIT",
"dependencies": {
- "css-in-js-utils": "^3.1.0",
- "fast-loops": "^1.1.3"
+ "css-in-js-utils": "^3.1.0"
}
},
"node_modules/js-tokens": {
@@ -1683,48 +1668,44 @@
}
},
"node_modules/react": {
- "version": "18.2.0",
- "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz",
- "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==",
+ "version": "19.2.7",
+ "resolved": "https://registry.npmjs.org/react/-/react-19.2.7.tgz",
+ "integrity": "sha512-HNe9WslTbXmFK8o8cmwgAeJFSBvt1bPdHCVKtaaV+WlAN36mpT4hcRpwbf3fY56ar2oIXzsBpOAiIRHAdY0OlQ==",
"license": "MIT",
- "dependencies": {
- "loose-envify": "^1.1.0"
- },
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/react-dom": {
- "version": "18.2.0",
- "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz",
- "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==",
+ "version": "19.2.7",
+ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.7.tgz",
+ "integrity": "sha512-t0BRVXvbiE/o20Hfw669rLbMCDWtYZLvmJigy2f0MxsXF+71pxhR3xOkspmsO8h3ZlNzyibAmtCa3l4lYKk6gQ==",
"license": "MIT",
"dependencies": {
- "loose-envify": "^1.1.0",
- "scheduler": "^0.23.0"
+ "scheduler": "^0.27.0"
},
"peerDependencies": {
- "react": "^18.2.0"
+ "react": "^19.2.7"
}
},
"node_modules/react-native-web": {
- "version": "0.19.13",
- "resolved": "https://registry.npmjs.org/react-native-web/-/react-native-web-0.19.13.tgz",
- "integrity": "sha512-etv3bN8rJglrRCp/uL4p7l8QvUNUC++QwDbdZ8CB7BvZiMvsxfFIRM1j04vxNldG3uo2puRd6OSWR3ibtmc29A==",
+ "version": "0.21.2",
+ "resolved": "https://registry.npmjs.org/react-native-web/-/react-native-web-0.21.2.tgz",
+ "integrity": "sha512-SO2t9/17zM4iEnFvlu2DA9jqNbzNhoUP+AItkoCOyFmDMOhUnBBznBDCYN92fGdfAkfQlWzPoez6+zLxFNsZEg==",
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.18.6",
"@react-native/normalize-colors": "^0.74.1",
"fbjs": "^3.0.4",
- "inline-style-prefixer": "^6.0.1",
+ "inline-style-prefixer": "^7.0.1",
"memoize-one": "^6.0.0",
"nullthrows": "^1.1.1",
"postcss-value-parser": "^4.2.0",
"styleq": "^0.1.3"
},
"peerDependencies": {
- "react": "^18.0.0",
- "react-dom": "^18.0.0"
+ "react": "^18.0.0 || ^19.0.0",
+ "react-dom": "^18.0.0 || ^19.0.0"
}
},
"node_modules/react-refresh": {
@@ -1783,13 +1764,10 @@
}
},
"node_modules/scheduler": {
- "version": "0.23.2",
- "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz",
- "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==",
- "license": "MIT",
- "dependencies": {
- "loose-envify": "^1.1.0"
- }
+ "version": "0.27.0",
+ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz",
+ "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==",
+ "license": "MIT"
},
"node_modules/semver": {
"version": "6.3.1",
diff --git a/example-web/package.json b/example-web/package.json
index 6b0e9fc..d7a6672 100644
--- a/example-web/package.json
+++ b/example-web/package.json
@@ -10,13 +10,13 @@
"preview": "vite preview"
},
"dependencies": {
- "react": "18.2.0",
- "react-dom": "18.2.0",
- "react-native-web": "^0.19.10"
+ "react": "^19.0.0",
+ "react-dom": "^19.0.0",
+ "react-native-web": "^0.21.0"
},
"devDependencies": {
- "@types/react": "^18.2.0",
- "@types/react-dom": "^18.2.0",
+ "@types/react": "^19.0.0",
+ "@types/react-dom": "^19.0.0",
"@vitejs/plugin-react": "^4.3.0",
"typescript": "^5.4.0",
"vite": "^5.4.0"
diff --git a/example-web/vite.config.ts b/example-web/vite.config.ts
index 5110473..67fb460 100644
--- a/example-web/vite.config.ts
+++ b/example-web/vite.config.ts
@@ -54,7 +54,26 @@ export default defineConfig({
resolve: {
alias: [
{ find: /^fastcomments-react-native-sdk$/, replacement: path.join(sdkRoot, 'index.ts') },
+ // `react-native-enriched`'s web build (and react-native-render-html) import
+ // the bare `react-native` specifier (e.g. `processColor`). The custom
+ // `reactNativeWebAlias` plugin handles top-level resolves, but Rollup's
+ // commonjs resolver bypasses it for nested dep imports during build, pulling
+ // in the real (Flow-typed) react-native and failing to parse. An exact-match
+ // alias redirects it to react-native-web everywhere. The `$` anchor avoids
+ // catching `react-native-enriched` / `react-native-web` themselves.
+ { find: /^react-native$/, replacement: path.dirname(require.resolve('react-native-web/package.json')) },
+ // react-native-web's ESM dist imports inline-style-prefixer's CJS `lib/`
+ // deep paths (e.g. `inline-style-prefixer/lib/plugins/cursor`). Served raw
+ // to the browser, those CJS files expose no ESM `default` export and throw
+ // "doesn't provide an export named: 'default'". The package also ships a
+ // real ESM build under `es/`; redirect the deep `lib/` paths there.
+ { find: /^inline-style-prefixer\/lib\/(.*)$/, replacement: path.join(path.dirname(require.resolve('inline-style-prefixer/package.json')), 'es/$1') },
],
+ // The demo imports the SDK from source (`../src`), whose files `import 'react'`.
+ // Without deduping, that resolves to the SDK root's own React copy while the
+ // app uses example-web's React 19 -> two React instances -> "invalid hook
+ // call". Force a single copy (example-web's React 19) for the whole graph.
+ dedupe: ['react', 'react-dom'],
extensions: ['.web.tsx', '.web.ts', '.web.jsx', '.web.js', '.tsx', '.ts', '.jsx', '.js', '.json'],
mainFields: ['module', 'browser', 'main'],
},
@@ -81,10 +100,20 @@ export default defineConfig({
'react-native-web > memoize-one',
'react-native-web > styleq',
'react-native-web > postcss-value-parser',
+ // react-native-web's ESM dist also imports these CJS *sub-entry* points
+ // directly. They aren't reachable from each package's main entry, so the
+ // `> pkg` includes above don't cover them, and served raw they expose no
+ // ESM named/default export ("doesn't provide an export named ..."). List
+ // them so Vite pre-bundles each with CJS->ESM interop.
+ 'styleq/transform-localize-style',
+ 'fbjs/lib/invariant',
+ 'fbjs/lib/warning',
+ // react-native-web's renderer imports `{ createRoot }` from this CJS
+ // sub-entry; same raw-CJS named-export problem as the deps above.
+ 'react-dom/client',
'lodash',
'fastcomments-typescript',
- 'react-quill-new',
- 'quill',
+ 'react-native-enriched',
],
exclude: ['react-native'],
},
diff --git a/package-lock.json b/package-lock.json
index ce9721e..c05c870 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -28,12 +28,10 @@
"metro-react-native-babel-preset": "^0.66.2",
"pod-install": "^0.1.0",
"prettier": "^2.0.5",
- "quill": "^2.0.3",
"react": "18.3.1",
"react-native": "^0.69.4",
"react-native-builder-bob": "^0.18.2",
- "react-native-enriched": "^0.5.2",
- "react-quill-new": "^3.8.3",
+ "react-native-enriched": "^0.7.0",
"react-test-renderer": "^18.3.1",
"ts-clean": "^1.0.3",
"ts-jest": "^29.0.1",
@@ -43,21 +41,12 @@
"peerDependencies": {
"react": "*",
"react-native": "*",
- "react-native-enriched": ">=0.4.0",
- "react-quill-new": ">=3.8.0"
- },
- "peerDependenciesMeta": {
- "react-native-enriched": {
- "optional": true
- },
- "react-quill-new": {
- "optional": true
- }
+ "react-native-enriched": ">=0.7.0"
}
},
"../fastcomments-sdk-js": {
"name": "fastcomments-sdk",
- "version": "3.2.2",
+ "version": "3.2.3",
"dev": true,
"license": "MIT",
"devDependencies": {
@@ -2095,6 +2084,37 @@
"integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==",
"dev": true
},
+ "node_modules/@floating-ui/core": {
+ "version": "1.7.5",
+ "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.5.tgz",
+ "integrity": "sha512-1Ih4WTWyw0+lKyFMcBHGbb5U5FtuHJuujoyyr5zTaWS5EYMeT6Jb2AuDeftsCsEuchO+mM2ij5+q9crhydzLhQ==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@floating-ui/utils": "^0.2.11"
+ }
+ },
+ "node_modules/@floating-ui/dom": {
+ "version": "1.7.6",
+ "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.6.tgz",
+ "integrity": "sha512-9gZSAI5XM36880PPMm//9dfiEngYoC6Am2izES1FF406YFsjvyBMmeJ2g4SAju3xWwtuynNRFL2s9hgxpLI5SQ==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@floating-ui/core": "^1.7.5",
+ "@floating-ui/utils": "^0.2.11"
+ }
+ },
+ "node_modules/@floating-ui/utils": {
+ "version": "0.2.11",
+ "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.11.tgz",
+ "integrity": "sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true
+ },
"node_modules/@hapi/hoek": {
"version": "9.3.0",
"resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz",
@@ -3512,6 +3532,13 @@
"integrity": "sha512-K0aGNn1TjalKj+65D7ycc1//H9roAQ51GJVk5ZJQFb2teECGmzd86bYDC0aYdbRf7gtovescq4Zt6FR0tgXiHQ==",
"dev": true
},
+ "node_modules/@remirror/core-constants": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@remirror/core-constants/-/core-constants-3.0.0.tgz",
+ "integrity": "sha512-42aWfPrimMfDKDi4YegyS7x+/0tlzaqwPQCULLanv3DMIlu96KTJR0fM5isWX2UViOqlGnX6YFgqWepcX+XMNg==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/@sideway/address": {
"version": "4.1.5",
"resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz",
@@ -3646,6 +3673,303 @@
"node": ">=8"
}
},
+ "node_modules/@tiptap/core": {
+ "version": "3.20.4",
+ "resolved": "https://registry.npmjs.org/@tiptap/core/-/core-3.20.4.tgz",
+ "integrity": "sha512-3i/DG89TFY/b34T5P+j35UcjYuB5d3+9K8u6qID+iUqNPiza015HPIZLuPfE5elNwVdV3EXIoPo0LLeBLgXXAg==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/ueberdosis"
+ },
+ "peerDependencies": {
+ "@tiptap/pm": "^3.20.4"
+ }
+ },
+ "node_modules/@tiptap/extension-blockquote": {
+ "version": "3.20.4",
+ "resolved": "https://registry.npmjs.org/@tiptap/extension-blockquote/-/extension-blockquote-3.20.4.tgz",
+ "integrity": "sha512-9sskyyhYj2oKat//lyZVXCp9YrPt4oJAZnGHYWXS0xlskjsLElrfKKlM4vpbhGss3VrhQRoEGqWLnIaJYPF1zw==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/ueberdosis"
+ },
+ "peerDependencies": {
+ "@tiptap/core": "^3.20.4"
+ }
+ },
+ "node_modules/@tiptap/extension-bold": {
+ "version": "3.20.4",
+ "resolved": "https://registry.npmjs.org/@tiptap/extension-bold/-/extension-bold-3.20.4.tgz",
+ "integrity": "sha512-Md7/mNAeJCY+VLJc8JRGI+8XkVPKiOGB1NgqQPdh3aYtxXQDChQOZoJEQl6TuudDxZ85bLZB67NjZlx3jo8/0g==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/ueberdosis"
+ },
+ "peerDependencies": {
+ "@tiptap/core": "^3.20.4"
+ }
+ },
+ "node_modules/@tiptap/extension-bubble-menu": {
+ "version": "3.24.0",
+ "resolved": "https://registry.npmjs.org/@tiptap/extension-bubble-menu/-/extension-bubble-menu-3.24.0.tgz",
+ "integrity": "sha512-jRXD+JPu9ayvq78g8hsCxx4q/qUFtrdfIYirRSf5YUseuuUbtfrq83AsGabcygpUTefjJkMQoXNITkh6294Ggw==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@floating-ui/dom": "^1.0.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/ueberdosis"
+ },
+ "peerDependencies": {
+ "@tiptap/core": "3.24.0",
+ "@tiptap/pm": "3.24.0"
+ }
+ },
+ "node_modules/@tiptap/extension-code": {
+ "version": "3.20.4",
+ "resolved": "https://registry.npmjs.org/@tiptap/extension-code/-/extension-code-3.20.4.tgz",
+ "integrity": "sha512-7j8Hi964bH1SZ9oLdZC1fkqWz27mliSDV7M8lmL/M14+Qw42D/VOAKS4Aw9OCFtHMlTsjLR6qsoVxL8Lpkt6NA==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/ueberdosis"
+ },
+ "peerDependencies": {
+ "@tiptap/core": "^3.20.4"
+ }
+ },
+ "node_modules/@tiptap/extension-document": {
+ "version": "3.20.4",
+ "resolved": "https://registry.npmjs.org/@tiptap/extension-document/-/extension-document-3.20.4.tgz",
+ "integrity": "sha512-zF1CIFVLt8MfSpWWnPwtGyxPOsT0xYM2qJKcXf2yZcTG37wDKmUi6heG53vGigIavbQlLaAFvs+1mNdOu2x/0A==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/ueberdosis"
+ },
+ "peerDependencies": {
+ "@tiptap/core": "^3.20.4"
+ }
+ },
+ "node_modules/@tiptap/extension-floating-menu": {
+ "version": "3.24.0",
+ "resolved": "https://registry.npmjs.org/@tiptap/extension-floating-menu/-/extension-floating-menu-3.24.0.tgz",
+ "integrity": "sha512-7QEbf3mUzFAkejjQGX9f0L507oMtnOBRwHt2skUTR+9yXgudsN8zaDBSSRHLeMWGk9b7L293ZMA6zCRrZaHrfA==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/ueberdosis"
+ },
+ "peerDependencies": {
+ "@floating-ui/dom": "^1.0.0",
+ "@tiptap/core": "3.24.0",
+ "@tiptap/pm": "3.24.0"
+ }
+ },
+ "node_modules/@tiptap/extension-heading": {
+ "version": "3.20.4",
+ "resolved": "https://registry.npmjs.org/@tiptap/extension-heading/-/extension-heading-3.20.4.tgz",
+ "integrity": "sha512-xsnkmTGggJc5P2iCwS1lv8KFG31xC/GNPJKoi/3UH67j/lKDhA3AdtshsLeyv2FKtTtYDb8oV0IqzHB1MM6a7w==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/ueberdosis"
+ },
+ "peerDependencies": {
+ "@tiptap/core": "^3.20.4"
+ }
+ },
+ "node_modules/@tiptap/extension-italic": {
+ "version": "3.20.4",
+ "resolved": "https://registry.npmjs.org/@tiptap/extension-italic/-/extension-italic-3.20.4.tgz",
+ "integrity": "sha512-4ZqiWr7cmqPFux8tj1ZLiYytyWf343IvQemNX6AvVWvscrJcrfj3YX4Le2BA0RW3A3M6RpLQXXozuF8vxYFDeQ==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/ueberdosis"
+ },
+ "peerDependencies": {
+ "@tiptap/core": "^3.20.4"
+ }
+ },
+ "node_modules/@tiptap/extension-link": {
+ "version": "3.20.4",
+ "resolved": "https://registry.npmjs.org/@tiptap/extension-link/-/extension-link-3.20.4.tgz",
+ "integrity": "sha512-JNDSkWrVdb8NSvbQXwHWvK5tCMbTWwOHFOweknQZ1JPK4dei9FJVofYQaHyW4bJBdcCjds3NZSnXE8DM9iAWmg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "linkifyjs": "^4.3.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/ueberdosis"
+ },
+ "peerDependencies": {
+ "@tiptap/core": "^3.20.4",
+ "@tiptap/pm": "^3.20.4"
+ }
+ },
+ "node_modules/@tiptap/extension-list": {
+ "version": "3.20.4",
+ "resolved": "https://registry.npmjs.org/@tiptap/extension-list/-/extension-list-3.20.4.tgz",
+ "integrity": "sha512-X+5plTKhOioNcQ4KsAFJJSb/3+zR8Xhdpow4HzXtoV1KcbdDey1fhZdpsfkbrzCL0s6/wAgwZuAchCK7HujurQ==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/ueberdosis"
+ },
+ "peerDependencies": {
+ "@tiptap/core": "^3.20.4",
+ "@tiptap/pm": "^3.20.4"
+ }
+ },
+ "node_modules/@tiptap/extension-paragraph": {
+ "version": "3.20.4",
+ "resolved": "https://registry.npmjs.org/@tiptap/extension-paragraph/-/extension-paragraph-3.20.4.tgz",
+ "integrity": "sha512-lm6fOScWuZAF/Sfp97igUwFd3L1QHIVLAWP5NVdh0DTLrEIt4rMBmsww+yOpMQRhvz2uTgMbMXynrimhzi/QVw==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/ueberdosis"
+ },
+ "peerDependencies": {
+ "@tiptap/core": "^3.20.4"
+ }
+ },
+ "node_modules/@tiptap/extension-strike": {
+ "version": "3.20.4",
+ "resolved": "https://registry.npmjs.org/@tiptap/extension-strike/-/extension-strike-3.20.4.tgz",
+ "integrity": "sha512-It1Px9uDGTsVqyyg6cy7DigLoenljpQwqdI0jssM7QclZrHnsrye9fZxBBiiuCzzV1305MxKgHvratkHwqmVNA==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/ueberdosis"
+ },
+ "peerDependencies": {
+ "@tiptap/core": "^3.20.4"
+ }
+ },
+ "node_modules/@tiptap/extension-text": {
+ "version": "3.20.4",
+ "resolved": "https://registry.npmjs.org/@tiptap/extension-text/-/extension-text-3.20.4.tgz",
+ "integrity": "sha512-jchJcBZixDEO2J66Zx5dchsI2mA6IYsROqF8P1poxL4ienH7RVQRCTsBNnSfIeOtREKKWeOU/tEs5fcpvvGwIQ==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/ueberdosis"
+ },
+ "peerDependencies": {
+ "@tiptap/core": "^3.20.4"
+ }
+ },
+ "node_modules/@tiptap/extension-underline": {
+ "version": "3.20.4",
+ "resolved": "https://registry.npmjs.org/@tiptap/extension-underline/-/extension-underline-3.20.4.tgz",
+ "integrity": "sha512-0OjMc3FDujX16G+jhvqcY/mLot8SrNtDu8ggUwNLAfiI/QIvMVgk7giFD71DATC/4Nb8i/iwAEegTD8MxBIXCg==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/ueberdosis"
+ },
+ "peerDependencies": {
+ "@tiptap/core": "^3.20.4"
+ }
+ },
+ "node_modules/@tiptap/extensions": {
+ "version": "3.20.4",
+ "resolved": "https://registry.npmjs.org/@tiptap/extensions/-/extensions-3.20.4.tgz",
+ "integrity": "sha512-8p6hVT65DjuQjtEdlH6ewX9SOJHlVQAOee3sWIJQmeJNRnZNvqPIBLleebUqDiljNTpxBv6s6QWkSTKgf3btwg==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/ueberdosis"
+ },
+ "peerDependencies": {
+ "@tiptap/core": "^3.20.4",
+ "@tiptap/pm": "^3.20.4"
+ }
+ },
+ "node_modules/@tiptap/pm": {
+ "version": "3.20.4",
+ "resolved": "https://registry.npmjs.org/@tiptap/pm/-/pm-3.20.4.tgz",
+ "integrity": "sha512-rCHYSBToilBEuI6PtjziHDdRkABH/XqwJ7dG4Amn/SD3yGiZKYCiEApQlTUS2zZeo8DsLeuqqqB4vEOeD4OEPg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "prosemirror-changeset": "^2.3.0",
+ "prosemirror-collab": "^1.3.1",
+ "prosemirror-commands": "^1.6.2",
+ "prosemirror-dropcursor": "^1.8.1",
+ "prosemirror-gapcursor": "^1.3.2",
+ "prosemirror-history": "^1.4.1",
+ "prosemirror-inputrules": "^1.4.0",
+ "prosemirror-keymap": "^1.2.2",
+ "prosemirror-markdown": "^1.13.1",
+ "prosemirror-menu": "^1.2.4",
+ "prosemirror-model": "^1.24.1",
+ "prosemirror-schema-basic": "^1.2.3",
+ "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.38.1"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/ueberdosis"
+ }
+ },
+ "node_modules/@tiptap/react": {
+ "version": "3.20.4",
+ "resolved": "https://registry.npmjs.org/@tiptap/react/-/react-3.20.4.tgz",
+ "integrity": "sha512-1B8iWsHWwb5TeyVaUs8BRPzwWo4PsLQcl03urHaz0zTJ8DauopqvxzV3+lem1OkzRHn7wnrapDvwmIGoROCaQw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/use-sync-external-store": "^0.0.6",
+ "fast-equals": "^5.3.3",
+ "use-sync-external-store": "^1.4.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/ueberdosis"
+ },
+ "optionalDependencies": {
+ "@tiptap/extension-bubble-menu": "^3.20.4",
+ "@tiptap/extension-floating-menu": "^3.20.4"
+ },
+ "peerDependencies": {
+ "@tiptap/core": "^3.20.4",
+ "@tiptap/pm": "^3.20.4",
+ "@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",
+ "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0"
+ }
+ },
"node_modules/@types/babel__core": {
"version": "7.1.19",
"resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.19.tgz",
@@ -3762,11 +4086,36 @@
"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
"dev": true
},
+ "node_modules/@types/linkify-it": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz",
+ "integrity": "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/@types/lodash": {
"version": "4.14.185",
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.185.tgz",
"integrity": "sha512-evMDG1bC4rgQg4ku9tKpuMh5iBNEwNa3tf9zRHdP1qlv+1WUg44xat4IxCE14gIpZRGUUWAx2VhItCZc25NfMA=="
},
+ "node_modules/@types/markdown-it": {
+ "version": "14.1.2",
+ "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-14.1.2.tgz",
+ "integrity": "sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/linkify-it": "^5",
+ "@types/mdurl": "^2"
+ }
+ },
+ "node_modules/@types/mdurl": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-2.0.0.tgz",
+ "integrity": "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/@types/node": {
"version": "18.7.18",
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.7.18.tgz",
@@ -3840,6 +4189,13 @@
"resolved": "https://registry.npmjs.org/@types/urijs/-/urijs-1.19.19.tgz",
"integrity": "sha512-FDJNkyhmKLw7uEvTxx5tSXfPeQpO0iy73Ry+PmYZJvQy0QIWX8a7kJ4kLWRf+EbTPJEPDSgPXHaM7pzr5lmvCg=="
},
+ "node_modules/@types/use-sync-external-store": {
+ "version": "0.0.6",
+ "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.6.tgz",
+ "integrity": "sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/@types/ws": {
"version": "8.18.1",
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz",
@@ -5096,6 +5452,13 @@
"node": ">=4"
}
},
+ "node_modules/crelt": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.6.tgz",
+ "integrity": "sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/cross-spawn": {
"version": "6.0.5",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
@@ -5589,13 +5952,6 @@
"node": ">=6"
}
},
- "node_modules/eventemitter3": {
- "version": "5.0.4",
- "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz",
- "integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==",
- "dev": true,
- "license": "MIT"
- },
"node_modules/execa": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz",
@@ -5858,12 +6214,15 @@
"node": ">=0.10.0"
}
},
- "node_modules/fast-diff": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz",
- "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==",
+ "node_modules/fast-equals": {
+ "version": "5.4.0",
+ "resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-5.4.0.tgz",
+ "integrity": "sha512-jt2DW/aNFNwke7AUd+Z+e6pz39KO5rzdbbFCg2sGafS4mk13MI7Z8O5z9cADNn5lhGODIgLwug6TZO2ctf7kcw==",
"dev": true,
- "license": "Apache-2.0"
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.0.0"
+ }
},
"node_modules/fast-glob": {
"version": "3.2.12",
@@ -9481,6 +9840,33 @@
"integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
"dev": true
},
+ "node_modules/linkify-it": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.1.tgz",
+ "integrity": "sha512-wVoTjP4Q6R0NW5hiZkVJaFZPWgtXfoGF+6LucL3/FtiNjmcHhYjEr5f1Kqjirc1nBW07J/ZuRFumqr2oqccEWg==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/puzrin"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/markdown-it"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "uc.micro": "^2.0.0"
+ }
+ },
+ "node_modules/linkifyjs": {
+ "version": "4.3.3",
+ "resolved": "https://registry.npmjs.org/linkifyjs/-/linkifyjs-4.3.3.tgz",
+ "integrity": "sha512-P8aEP5U/D1/IlTY2OeYsErdwh9bGuLE30NcXtKEjgdHcahveQoQwM2yZNsioQHsWFz0P7KKudisbrzCgR0sDHg==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/load-json-file": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz",
@@ -9522,34 +9908,12 @@
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
},
- "node_modules/lodash-es": {
- "version": "4.18.1",
- "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.18.1.tgz",
- "integrity": "sha512-J8xewKD/Gk22OZbhpOVSwcs60zhd95ESDwezOFuA3/099925PdHJ7OFHNTGtajL3AlZkykD32HykiMo+BIBI8A==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/lodash.clonedeep": {
- "version": "4.5.0",
- "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
- "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==",
- "dev": true,
- "license": "MIT"
- },
"node_modules/lodash.debounce": {
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
"integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==",
"dev": true
},
- "node_modules/lodash.isequal": {
- "version": "4.5.0",
- "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
- "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==",
- "deprecated": "This package is deprecated. Use require('node:util').isDeepStrictEqual instead.",
- "dev": true,
- "license": "MIT"
- },
"node_modules/lodash.memoize": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
@@ -9696,6 +10060,61 @@
"node": ">=0.10.0"
}
},
+ "node_modules/markdown-it": {
+ "version": "14.2.0",
+ "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.2.0.tgz",
+ "integrity": "sha512-1TGiQiJVRQ3NPmZH6sx5Cfnmg6GQm9jvC1ch4TK511NjSJvjzKLzn5pPfZRNZkRPZP0HqCioSndqH8v2nRaWVQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/puzrin"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/markdown-it"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "argparse": "^2.0.1",
+ "entities": "^4.4.0",
+ "linkify-it": "^5.0.1",
+ "mdurl": "^2.0.0",
+ "punycode.js": "^2.3.1",
+ "uc.micro": "^2.1.0"
+ },
+ "bin": {
+ "markdown-it": "bin/markdown-it.mjs"
+ }
+ },
+ "node_modules/markdown-it/node_modules/argparse": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+ "dev": true,
+ "license": "Python-2.0"
+ },
+ "node_modules/markdown-it/node_modules/entities": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
+ "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=0.12"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
+ "node_modules/mdurl": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz",
+ "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/memoize-one": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz",
@@ -10958,6 +11377,13 @@
"node": ">=8"
}
},
+ "node_modules/orderedmap": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/orderedmap/-/orderedmap-2.1.1.tgz",
+ "integrity": "sha512-TvAWxi0nDe1j/rtMcWcIj94+Ffe6n7zhow33h40SKxmsmozs6dz/e+EajymfoFcHd7sxNn8yHM8839uixMOV6g==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/os-tmpdir": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
@@ -11028,13 +11454,6 @@
"node": ">=6"
}
},
- "node_modules/parchment": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/parchment/-/parchment-3.0.0.tgz",
- "integrity": "sha512-HUrJFQ/StvgmXRcQ1ftY6VEZUq3jA2t9ncFN4F84J/vN0/FPpQF+8FKXb3l6fLces6q0uOHj6NJn+2xvZnxO6A==",
- "dev": true,
- "license": "BSD-3-Clause"
- },
"node_modules/parent-module": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
@@ -11366,6 +11785,232 @@
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
},
+ "node_modules/prosemirror-changeset": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/prosemirror-changeset/-/prosemirror-changeset-2.4.1.tgz",
+ "integrity": "sha512-96WBLhOaYhJ+kPhLg3uW359Tz6I/MfcrQfL4EGv4SrcqKEMC1gmoGrXHecPE8eOwTVCJ4IwgfzM8fFad25wNfw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "prosemirror-transform": "^1.0.0"
+ }
+ },
+ "node_modules/prosemirror-collab": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/prosemirror-collab/-/prosemirror-collab-1.3.1.tgz",
+ "integrity": "sha512-4SnynYR9TTYaQVXd/ieUvsVV4PDMBzrq2xPUWutHivDuOshZXqQ5rGbZM84HEaXKbLdItse7weMGOUdDVcLKEQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "prosemirror-state": "^1.0.0"
+ }
+ },
+ "node_modules/prosemirror-commands": {
+ "version": "1.7.1",
+ "resolved": "https://registry.npmjs.org/prosemirror-commands/-/prosemirror-commands-1.7.1.tgz",
+ "integrity": "sha512-rT7qZnQtx5c0/y/KlYaGvtG411S97UaL6gdp6RIZ23DLHanMYLyfGBV5DtSnZdthQql7W+lEVbpSfwtO8T+L2w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "prosemirror-model": "^1.0.0",
+ "prosemirror-state": "^1.0.0",
+ "prosemirror-transform": "^1.10.2"
+ }
+ },
+ "node_modules/prosemirror-dropcursor": {
+ "version": "1.8.2",
+ "resolved": "https://registry.npmjs.org/prosemirror-dropcursor/-/prosemirror-dropcursor-1.8.2.tgz",
+ "integrity": "sha512-CCk6Gyx9+Tt2sbYk5NK0nB1ukHi2ryaRgadV/LvyNuO3ena1payM2z6Cg0vO1ebK8cxbzo41ku2DE5Axj1Zuiw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "prosemirror-state": "^1.0.0",
+ "prosemirror-transform": "^1.1.0",
+ "prosemirror-view": "^1.1.0"
+ }
+ },
+ "node_modules/prosemirror-gapcursor": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/prosemirror-gapcursor/-/prosemirror-gapcursor-1.4.1.tgz",
+ "integrity": "sha512-pMdYaEnjNMSwl11yjEGtgTmLkR08m/Vl+Jj443167p9eB3HVQKhYCc4gmHVDsLPODfZfjr/MmirsdyZziXbQKw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "prosemirror-keymap": "^1.0.0",
+ "prosemirror-model": "^1.0.0",
+ "prosemirror-state": "^1.0.0",
+ "prosemirror-view": "^1.0.0"
+ }
+ },
+ "node_modules/prosemirror-history": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/prosemirror-history/-/prosemirror-history-1.5.0.tgz",
+ "integrity": "sha512-zlzTiH01eKA55UAf1MEjtssJeHnGxO0j4K4Dpx+gnmX9n+SHNlDqI2oO1Kv1iPN5B1dm5fsljCfqKF9nFL6HRg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "prosemirror-state": "^1.2.2",
+ "prosemirror-transform": "^1.0.0",
+ "prosemirror-view": "^1.31.0",
+ "rope-sequence": "^1.3.0"
+ }
+ },
+ "node_modules/prosemirror-inputrules": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/prosemirror-inputrules/-/prosemirror-inputrules-1.5.1.tgz",
+ "integrity": "sha512-7wj4uMjKaXWAQ1CDgxNzNtR9AlsuwzHfdFH1ygEHA2KHF2DOEaXl1CJfNPAKCg9qNEh4rum975QLaCiQPyY6Fw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "prosemirror-state": "^1.0.0",
+ "prosemirror-transform": "^1.0.0"
+ }
+ },
+ "node_modules/prosemirror-keymap": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/prosemirror-keymap/-/prosemirror-keymap-1.2.3.tgz",
+ "integrity": "sha512-4HucRlpiLd1IPQQXNqeo81BGtkY8Ai5smHhKW9jjPKRc2wQIxksg7Hl1tTI2IfT2B/LgX6bfYvXxEpJl7aKYKw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "prosemirror-state": "^1.0.0",
+ "w3c-keyname": "^2.2.0"
+ }
+ },
+ "node_modules/prosemirror-markdown": {
+ "version": "1.13.4",
+ "resolved": "https://registry.npmjs.org/prosemirror-markdown/-/prosemirror-markdown-1.13.4.tgz",
+ "integrity": "sha512-D98dm4cQ3Hs6EmjK500TdAOew4Z03EV71ajEFiWra3Upr7diytJsjF4mPV2dW+eK5uNectiRj0xFxYI9NLXDbw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/markdown-it": "^14.0.0",
+ "markdown-it": "^14.0.0",
+ "prosemirror-model": "^1.25.0"
+ }
+ },
+ "node_modules/prosemirror-menu": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/prosemirror-menu/-/prosemirror-menu-1.3.2.tgz",
+ "integrity": "sha512-6VgUJTYod0nMBlCaYJGhXGLu7Gt4AvcwcOq0YfJCY/6Uh+3S7UsWhpy6rJFCBFOmonq1hD8KyWOtZhkppd4YPg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "crelt": "^1.0.0",
+ "prosemirror-commands": "^1.0.0",
+ "prosemirror-history": "^1.0.0",
+ "prosemirror-state": "^1.0.0"
+ }
+ },
+ "node_modules/prosemirror-model": {
+ "version": "1.25.7",
+ "resolved": "https://registry.npmjs.org/prosemirror-model/-/prosemirror-model-1.25.7.tgz",
+ "integrity": "sha512-A79aN8QEFUwI6cax8Yq4Rpcx1TJZ3Kagn+ii7qLo4/V8H3mMiHrhFyhTyHHvpSnOgMPpWiDGSwM3etwrxE50ug==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "orderedmap": "^2.0.0"
+ }
+ },
+ "node_modules/prosemirror-schema-basic": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/prosemirror-schema-basic/-/prosemirror-schema-basic-1.2.4.tgz",
+ "integrity": "sha512-ELxP4TlX3yr2v5rM7Sb70SqStq5NvI15c0j9j/gjsrO5vaw+fnnpovCLEGIcpeGfifkuqJwl4fon6b+KdrODYQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "prosemirror-model": "^1.25.0"
+ }
+ },
+ "node_modules/prosemirror-schema-list": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/prosemirror-schema-list/-/prosemirror-schema-list-1.5.1.tgz",
+ "integrity": "sha512-927lFx/uwyQaGwJxLWCZRkjXG0p48KpMj6ueoYiu4JX05GGuGcgzAy62dfiV8eFZftgyBUvLx76RsMe20fJl+Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "prosemirror-model": "^1.0.0",
+ "prosemirror-state": "^1.0.0",
+ "prosemirror-transform": "^1.7.3"
+ }
+ },
+ "node_modules/prosemirror-state": {
+ "version": "1.4.4",
+ "resolved": "https://registry.npmjs.org/prosemirror-state/-/prosemirror-state-1.4.4.tgz",
+ "integrity": "sha512-6jiYHH2CIGbCfnxdHbXZ12gySFY/fz/ulZE333G6bPqIZ4F+TXo9ifiR86nAHpWnfoNjOb3o5ESi7J8Uz1jXHw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "prosemirror-model": "^1.0.0",
+ "prosemirror-transform": "^1.0.0",
+ "prosemirror-view": "^1.27.0"
+ }
+ },
+ "node_modules/prosemirror-tables": {
+ "version": "1.8.5",
+ "resolved": "https://registry.npmjs.org/prosemirror-tables/-/prosemirror-tables-1.8.5.tgz",
+ "integrity": "sha512-V/0cDCsHKHe/tfWkeCmthNUcEp1IVO3p6vwN8XtwE9PZQLAZJigbw3QoraAdfJPir4NKJtNvOB8oYGKRl+t0Dw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "prosemirror-keymap": "^1.2.3",
+ "prosemirror-model": "^1.25.4",
+ "prosemirror-state": "^1.4.4",
+ "prosemirror-transform": "^1.10.5",
+ "prosemirror-view": "^1.41.4"
+ }
+ },
+ "node_modules/prosemirror-trailing-node": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/prosemirror-trailing-node/-/prosemirror-trailing-node-3.0.0.tgz",
+ "integrity": "sha512-xiun5/3q0w5eRnGYfNlW1uU9W6x5MoFKWwq/0TIRgt09lv7Hcser2QYV8t4muXbEr+Fwo0geYn79Xs4GKywrRQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@remirror/core-constants": "3.0.0",
+ "escape-string-regexp": "^4.0.0"
+ },
+ "peerDependencies": {
+ "prosemirror-model": "^1.22.1",
+ "prosemirror-state": "^1.4.2",
+ "prosemirror-view": "^1.33.8"
+ }
+ },
+ "node_modules/prosemirror-trailing-node/node_modules/escape-string-regexp": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/prosemirror-transform": {
+ "version": "1.12.0",
+ "resolved": "https://registry.npmjs.org/prosemirror-transform/-/prosemirror-transform-1.12.0.tgz",
+ "integrity": "sha512-GxboyN4AMIsoHNtz5uf2r2Ru551i5hWeCMD6E2Ib4Eogqoub0NflniaBPVQ4MrGE5yZ8JV9tUHg9qcZTTrcN4w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "prosemirror-model": "^1.21.0"
+ }
+ },
+ "node_modules/prosemirror-view": {
+ "version": "1.41.8",
+ "resolved": "https://registry.npmjs.org/prosemirror-view/-/prosemirror-view-1.41.8.tgz",
+ "integrity": "sha512-TnKDdohEatgyZNGCDWIdccOHXhYloJwbwU+phw/a23KBvJIR9lWQWW7WHHK3vBdOLDNuF7TaX98GObUZOWkOnA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "prosemirror-model": "^1.20.0",
+ "prosemirror-state": "^1.0.0",
+ "prosemirror-transform": "^1.1.0"
+ }
+ },
"node_modules/pump": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
@@ -11376,6 +12021,16 @@
"once": "^1.3.1"
}
},
+ "node_modules/punycode.js": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz",
+ "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/queue-microtask": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
@@ -11405,37 +12060,6 @@
"node": ">=4"
}
},
- "node_modules/quill": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/quill/-/quill-2.0.3.tgz",
- "integrity": "sha512-xEYQBqfYx/sfb33VJiKnSJp8ehloavImQ2A6564GAbqG55PGw1dAWUn1MUbQB62t0azawUS2CZZhWCjO8gRvTw==",
- "dev": true,
- "license": "BSD-3-Clause",
- "dependencies": {
- "eventemitter3": "^5.0.1",
- "lodash-es": "^4.17.21",
- "parchment": "^3.0.0",
- "quill-delta": "^5.1.0"
- },
- "engines": {
- "npm": ">=8.2.3"
- }
- },
- "node_modules/quill-delta": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/quill-delta/-/quill-delta-5.1.0.tgz",
- "integrity": "sha512-X74oCeRI4/p0ucjb5Ma8adTXd9Scumz367kkMK5V/IatcX6A0vlgLgKbzXWy5nZmCGeNJm2oQX0d2Eqj+ZIlCA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "fast-diff": "^1.3.0",
- "lodash.clonedeep": "^4.5.0",
- "lodash.isequal": "^4.5.0"
- },
- "engines": {
- "node": ">= 12.0.0"
- }
- },
"node_modules/ramda": {
"version": "0.27.2",
"resolved": "https://registry.npmjs.org/ramda/-/ramda-0.27.2.tgz",
@@ -11890,15 +12514,33 @@
}
},
"node_modules/react-native-enriched": {
- "version": "0.5.2",
- "resolved": "https://registry.npmjs.org/react-native-enriched/-/react-native-enriched-0.5.2.tgz",
- "integrity": "sha512-9texMnu5+CXLCuVJv987UmzgB70F8Q3okOm2zqZ8jYSEz8IGyd7kbJdZ4J1rW99x3hYaeV+u+cSECzrCj7F4EA==",
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/react-native-enriched/-/react-native-enriched-0.7.0.tgz",
+ "integrity": "sha512-WrhaRUMM8HaV+6XwESS1k7i1/QxZb4K2lpELIxLTiXXMdUP5b9207AjXp6d8Op0XulvFNC8HJdDdanQZUUI6Zg==",
"dev": true,
"license": "MIT",
"workspaces": [
"apps/example",
"apps/example-web"
],
+ "dependencies": {
+ "@tiptap/core": "3.20.4",
+ "@tiptap/extension-blockquote": "3.20.4",
+ "@tiptap/extension-bold": "3.20.4",
+ "@tiptap/extension-code": "3.20.4",
+ "@tiptap/extension-document": "3.20.4",
+ "@tiptap/extension-heading": "3.20.4",
+ "@tiptap/extension-italic": "3.20.4",
+ "@tiptap/extension-link": "3.20.4",
+ "@tiptap/extension-list": "3.20.4",
+ "@tiptap/extension-paragraph": "3.20.4",
+ "@tiptap/extension-strike": "3.20.4",
+ "@tiptap/extension-text": "3.20.4",
+ "@tiptap/extension-underline": "3.20.4",
+ "@tiptap/extensions": "3.20.4",
+ "@tiptap/pm": "3.20.4",
+ "@tiptap/react": "3.20.4"
+ },
"peerDependencies": {
"react": "*",
"react-native": "*"
@@ -11975,23 +12617,7 @@
"dev": true,
"license": "MIT",
"dependencies": {
- "async-limiter": "~1.0.0"
- }
- },
- "node_modules/react-quill-new": {
- "version": "3.8.3",
- "resolved": "https://registry.npmjs.org/react-quill-new/-/react-quill-new-3.8.3.tgz",
- "integrity": "sha512-c96PYqFTo0pI4R3e79B3rH9LUIce1kIQbmTBu/imJQZk8305ogyLyBqKKjG2UoInDlquXqePSzmBo2aVia3ttw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "lodash-es": "^4.17.21",
- "quill": "~2.0.3"
- },
- "peerDependencies": {
- "quill-delta": "^5.1.0",
- "react": "^16 || ^17 || ^18 || ^19",
- "react-dom": "^16 || ^17 || ^18 || ^19"
+ "async-limiter": "~1.0.0"
}
},
"node_modules/react-refresh": {
@@ -12463,6 +13089,13 @@
"rimraf": "bin.js"
}
},
+ "node_modules/rope-sequence": {
+ "version": "1.3.4",
+ "resolved": "https://registry.npmjs.org/rope-sequence/-/rope-sequence-1.3.4.tgz",
+ "integrity": "sha512-UT5EDe2cu2E/6O4igUr5PSFs23nvvukicWHx6GnOPlHAiiYbzNuCRQCuiUdHJQcqKalLKlrYJnjY0ySGsXNQXQ==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/run-parallel": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
@@ -14078,6 +14711,13 @@
"node": ">=4.2.0"
}
},
+ "node_modules/uc.micro": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz",
+ "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/uglify-es": {
"version": "3.3.10",
"resolved": "https://registry.npmjs.org/uglify-es/-/uglify-es-3.3.10.tgz",
@@ -14301,12 +14941,13 @@
}
},
"node_modules/use-sync-external-store": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz",
- "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==",
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz",
+ "integrity": "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==",
"dev": true,
+ "license": "MIT",
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0 || ^18.0.0"
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/util-deprecate": {
@@ -14365,6 +15006,13 @@
"integrity": "sha512-gQpnTgkubC6hQgdIcRdYGDSDc+SaujOdyesZQMv6JlfQee/9Mp0Qhnys6WxDWvQnL5WZdT7o2Ul187aSt0Rq+w==",
"dev": true
},
+ "node_modules/w3c-keyname": {
+ "version": "2.2.8",
+ "resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz",
+ "integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/walker": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz",
@@ -16013,6 +16661,34 @@
"integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==",
"dev": true
},
+ "@floating-ui/core": {
+ "version": "1.7.5",
+ "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.5.tgz",
+ "integrity": "sha512-1Ih4WTWyw0+lKyFMcBHGbb5U5FtuHJuujoyyr5zTaWS5EYMeT6Jb2AuDeftsCsEuchO+mM2ij5+q9crhydzLhQ==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "@floating-ui/utils": "^0.2.11"
+ }
+ },
+ "@floating-ui/dom": {
+ "version": "1.7.6",
+ "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.6.tgz",
+ "integrity": "sha512-9gZSAI5XM36880PPMm//9dfiEngYoC6Am2izES1FF406YFsjvyBMmeJ2g4SAju3xWwtuynNRFL2s9hgxpLI5SQ==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "@floating-ui/core": "^1.7.5",
+ "@floating-ui/utils": "^0.2.11"
+ }
+ },
+ "@floating-ui/utils": {
+ "version": "0.2.11",
+ "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.11.tgz",
+ "integrity": "sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg==",
+ "dev": true,
+ "optional": true
+ },
"@hapi/hoek": {
"version": "9.3.0",
"resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz",
@@ -17158,6 +17834,12 @@
"integrity": "sha512-K0aGNn1TjalKj+65D7ycc1//H9roAQ51GJVk5ZJQFb2teECGmzd86bYDC0aYdbRf7gtovescq4Zt6FR0tgXiHQ==",
"dev": true
},
+ "@remirror/core-constants": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@remirror/core-constants/-/core-constants-3.0.0.tgz",
+ "integrity": "sha512-42aWfPrimMfDKDi4YegyS7x+/0tlzaqwPQCULLanv3DMIlu96KTJR0fM5isWX2UViOqlGnX6YFgqWepcX+XMNg==",
+ "dev": true
+ },
"@sideway/address": {
"version": "4.1.5",
"resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz",
@@ -17258,6 +17940,149 @@
}
}
},
+ "@tiptap/core": {
+ "version": "3.20.4",
+ "resolved": "https://registry.npmjs.org/@tiptap/core/-/core-3.20.4.tgz",
+ "integrity": "sha512-3i/DG89TFY/b34T5P+j35UcjYuB5d3+9K8u6qID+iUqNPiza015HPIZLuPfE5elNwVdV3EXIoPo0LLeBLgXXAg==",
+ "dev": true
+ },
+ "@tiptap/extension-blockquote": {
+ "version": "3.20.4",
+ "resolved": "https://registry.npmjs.org/@tiptap/extension-blockquote/-/extension-blockquote-3.20.4.tgz",
+ "integrity": "sha512-9sskyyhYj2oKat//lyZVXCp9YrPt4oJAZnGHYWXS0xlskjsLElrfKKlM4vpbhGss3VrhQRoEGqWLnIaJYPF1zw==",
+ "dev": true
+ },
+ "@tiptap/extension-bold": {
+ "version": "3.20.4",
+ "resolved": "https://registry.npmjs.org/@tiptap/extension-bold/-/extension-bold-3.20.4.tgz",
+ "integrity": "sha512-Md7/mNAeJCY+VLJc8JRGI+8XkVPKiOGB1NgqQPdh3aYtxXQDChQOZoJEQl6TuudDxZ85bLZB67NjZlx3jo8/0g==",
+ "dev": true
+ },
+ "@tiptap/extension-bubble-menu": {
+ "version": "3.24.0",
+ "resolved": "https://registry.npmjs.org/@tiptap/extension-bubble-menu/-/extension-bubble-menu-3.24.0.tgz",
+ "integrity": "sha512-jRXD+JPu9ayvq78g8hsCxx4q/qUFtrdfIYirRSf5YUseuuUbtfrq83AsGabcygpUTefjJkMQoXNITkh6294Ggw==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "@floating-ui/dom": "^1.0.0"
+ }
+ },
+ "@tiptap/extension-code": {
+ "version": "3.20.4",
+ "resolved": "https://registry.npmjs.org/@tiptap/extension-code/-/extension-code-3.20.4.tgz",
+ "integrity": "sha512-7j8Hi964bH1SZ9oLdZC1fkqWz27mliSDV7M8lmL/M14+Qw42D/VOAKS4Aw9OCFtHMlTsjLR6qsoVxL8Lpkt6NA==",
+ "dev": true
+ },
+ "@tiptap/extension-document": {
+ "version": "3.20.4",
+ "resolved": "https://registry.npmjs.org/@tiptap/extension-document/-/extension-document-3.20.4.tgz",
+ "integrity": "sha512-zF1CIFVLt8MfSpWWnPwtGyxPOsT0xYM2qJKcXf2yZcTG37wDKmUi6heG53vGigIavbQlLaAFvs+1mNdOu2x/0A==",
+ "dev": true
+ },
+ "@tiptap/extension-floating-menu": {
+ "version": "3.24.0",
+ "resolved": "https://registry.npmjs.org/@tiptap/extension-floating-menu/-/extension-floating-menu-3.24.0.tgz",
+ "integrity": "sha512-7QEbf3mUzFAkejjQGX9f0L507oMtnOBRwHt2skUTR+9yXgudsN8zaDBSSRHLeMWGk9b7L293ZMA6zCRrZaHrfA==",
+ "dev": true,
+ "optional": true
+ },
+ "@tiptap/extension-heading": {
+ "version": "3.20.4",
+ "resolved": "https://registry.npmjs.org/@tiptap/extension-heading/-/extension-heading-3.20.4.tgz",
+ "integrity": "sha512-xsnkmTGggJc5P2iCwS1lv8KFG31xC/GNPJKoi/3UH67j/lKDhA3AdtshsLeyv2FKtTtYDb8oV0IqzHB1MM6a7w==",
+ "dev": true
+ },
+ "@tiptap/extension-italic": {
+ "version": "3.20.4",
+ "resolved": "https://registry.npmjs.org/@tiptap/extension-italic/-/extension-italic-3.20.4.tgz",
+ "integrity": "sha512-4ZqiWr7cmqPFux8tj1ZLiYytyWf343IvQemNX6AvVWvscrJcrfj3YX4Le2BA0RW3A3M6RpLQXXozuF8vxYFDeQ==",
+ "dev": true
+ },
+ "@tiptap/extension-link": {
+ "version": "3.20.4",
+ "resolved": "https://registry.npmjs.org/@tiptap/extension-link/-/extension-link-3.20.4.tgz",
+ "integrity": "sha512-JNDSkWrVdb8NSvbQXwHWvK5tCMbTWwOHFOweknQZ1JPK4dei9FJVofYQaHyW4bJBdcCjds3NZSnXE8DM9iAWmg==",
+ "dev": true,
+ "requires": {
+ "linkifyjs": "^4.3.2"
+ }
+ },
+ "@tiptap/extension-list": {
+ "version": "3.20.4",
+ "resolved": "https://registry.npmjs.org/@tiptap/extension-list/-/extension-list-3.20.4.tgz",
+ "integrity": "sha512-X+5plTKhOioNcQ4KsAFJJSb/3+zR8Xhdpow4HzXtoV1KcbdDey1fhZdpsfkbrzCL0s6/wAgwZuAchCK7HujurQ==",
+ "dev": true
+ },
+ "@tiptap/extension-paragraph": {
+ "version": "3.20.4",
+ "resolved": "https://registry.npmjs.org/@tiptap/extension-paragraph/-/extension-paragraph-3.20.4.tgz",
+ "integrity": "sha512-lm6fOScWuZAF/Sfp97igUwFd3L1QHIVLAWP5NVdh0DTLrEIt4rMBmsww+yOpMQRhvz2uTgMbMXynrimhzi/QVw==",
+ "dev": true
+ },
+ "@tiptap/extension-strike": {
+ "version": "3.20.4",
+ "resolved": "https://registry.npmjs.org/@tiptap/extension-strike/-/extension-strike-3.20.4.tgz",
+ "integrity": "sha512-It1Px9uDGTsVqyyg6cy7DigLoenljpQwqdI0jssM7QclZrHnsrye9fZxBBiiuCzzV1305MxKgHvratkHwqmVNA==",
+ "dev": true
+ },
+ "@tiptap/extension-text": {
+ "version": "3.20.4",
+ "resolved": "https://registry.npmjs.org/@tiptap/extension-text/-/extension-text-3.20.4.tgz",
+ "integrity": "sha512-jchJcBZixDEO2J66Zx5dchsI2mA6IYsROqF8P1poxL4ienH7RVQRCTsBNnSfIeOtREKKWeOU/tEs5fcpvvGwIQ==",
+ "dev": true
+ },
+ "@tiptap/extension-underline": {
+ "version": "3.20.4",
+ "resolved": "https://registry.npmjs.org/@tiptap/extension-underline/-/extension-underline-3.20.4.tgz",
+ "integrity": "sha512-0OjMc3FDujX16G+jhvqcY/mLot8SrNtDu8ggUwNLAfiI/QIvMVgk7giFD71DATC/4Nb8i/iwAEegTD8MxBIXCg==",
+ "dev": true
+ },
+ "@tiptap/extensions": {
+ "version": "3.20.4",
+ "resolved": "https://registry.npmjs.org/@tiptap/extensions/-/extensions-3.20.4.tgz",
+ "integrity": "sha512-8p6hVT65DjuQjtEdlH6ewX9SOJHlVQAOee3sWIJQmeJNRnZNvqPIBLleebUqDiljNTpxBv6s6QWkSTKgf3btwg==",
+ "dev": true
+ },
+ "@tiptap/pm": {
+ "version": "3.20.4",
+ "resolved": "https://registry.npmjs.org/@tiptap/pm/-/pm-3.20.4.tgz",
+ "integrity": "sha512-rCHYSBToilBEuI6PtjziHDdRkABH/XqwJ7dG4Amn/SD3yGiZKYCiEApQlTUS2zZeo8DsLeuqqqB4vEOeD4OEPg==",
+ "dev": true,
+ "requires": {
+ "prosemirror-changeset": "^2.3.0",
+ "prosemirror-collab": "^1.3.1",
+ "prosemirror-commands": "^1.6.2",
+ "prosemirror-dropcursor": "^1.8.1",
+ "prosemirror-gapcursor": "^1.3.2",
+ "prosemirror-history": "^1.4.1",
+ "prosemirror-inputrules": "^1.4.0",
+ "prosemirror-keymap": "^1.2.2",
+ "prosemirror-markdown": "^1.13.1",
+ "prosemirror-menu": "^1.2.4",
+ "prosemirror-model": "^1.24.1",
+ "prosemirror-schema-basic": "^1.2.3",
+ "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.38.1"
+ }
+ },
+ "@tiptap/react": {
+ "version": "3.20.4",
+ "resolved": "https://registry.npmjs.org/@tiptap/react/-/react-3.20.4.tgz",
+ "integrity": "sha512-1B8iWsHWwb5TeyVaUs8BRPzwWo4PsLQcl03urHaz0zTJ8DauopqvxzV3+lem1OkzRHn7wnrapDvwmIGoROCaQw==",
+ "dev": true,
+ "requires": {
+ "@tiptap/extension-bubble-menu": "^3.20.4",
+ "@tiptap/extension-floating-menu": "^3.20.4",
+ "@types/use-sync-external-store": "^0.0.6",
+ "fast-equals": "^5.3.3",
+ "use-sync-external-store": "^1.4.0"
+ }
+ },
"@types/babel__core": {
"version": "7.1.19",
"resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.19.tgz",
@@ -17367,11 +18192,33 @@
}
}
},
+ "@types/linkify-it": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz",
+ "integrity": "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==",
+ "dev": true
+ },
"@types/lodash": {
"version": "4.14.185",
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.185.tgz",
"integrity": "sha512-evMDG1bC4rgQg4ku9tKpuMh5iBNEwNa3tf9zRHdP1qlv+1WUg44xat4IxCE14gIpZRGUUWAx2VhItCZc25NfMA=="
},
+ "@types/markdown-it": {
+ "version": "14.1.2",
+ "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-14.1.2.tgz",
+ "integrity": "sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==",
+ "dev": true,
+ "requires": {
+ "@types/linkify-it": "^5",
+ "@types/mdurl": "^2"
+ }
+ },
+ "@types/mdurl": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-2.0.0.tgz",
+ "integrity": "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==",
+ "dev": true
+ },
"@types/node": {
"version": "18.7.18",
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.7.18.tgz",
@@ -17440,6 +18287,12 @@
"resolved": "https://registry.npmjs.org/@types/urijs/-/urijs-1.19.19.tgz",
"integrity": "sha512-FDJNkyhmKLw7uEvTxx5tSXfPeQpO0iy73Ry+PmYZJvQy0QIWX8a7kJ4kLWRf+EbTPJEPDSgPXHaM7pzr5lmvCg=="
},
+ "@types/use-sync-external-store": {
+ "version": "0.0.6",
+ "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.6.tgz",
+ "integrity": "sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==",
+ "dev": true
+ },
"@types/ws": {
"version": "8.18.1",
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz",
@@ -18380,6 +19233,12 @@
"parse-json": "^4.0.0"
}
},
+ "crelt": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.6.tgz",
+ "integrity": "sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==",
+ "dev": true
+ },
"cross-spawn": {
"version": "6.0.5",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
@@ -18735,12 +19594,6 @@
"integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==",
"dev": true
},
- "eventemitter3": {
- "version": "5.0.4",
- "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz",
- "integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==",
- "dev": true
- },
"execa": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz",
@@ -18953,10 +19806,10 @@
}
}
},
- "fast-diff": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz",
- "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==",
+ "fast-equals": {
+ "version": "5.4.0",
+ "resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-5.4.0.tgz",
+ "integrity": "sha512-jt2DW/aNFNwke7AUd+Z+e6pz39KO5rzdbbFCg2sGafS4mk13MI7Z8O5z9cADNn5lhGODIgLwug6TZO2ctf7kcw==",
"dev": true
},
"fast-glob": {
@@ -21703,6 +22556,21 @@
"integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
"dev": true
},
+ "linkify-it": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.1.tgz",
+ "integrity": "sha512-wVoTjP4Q6R0NW5hiZkVJaFZPWgtXfoGF+6LucL3/FtiNjmcHhYjEr5f1Kqjirc1nBW07J/ZuRFumqr2oqccEWg==",
+ "dev": true,
+ "requires": {
+ "uc.micro": "^2.0.0"
+ }
+ },
+ "linkifyjs": {
+ "version": "4.3.3",
+ "resolved": "https://registry.npmjs.org/linkifyjs/-/linkifyjs-4.3.3.tgz",
+ "integrity": "sha512-P8aEP5U/D1/IlTY2OeYsErdwh9bGuLE30NcXtKEjgdHcahveQoQwM2yZNsioQHsWFz0P7KKudisbrzCgR0sDHg==",
+ "dev": true
+ },
"load-json-file": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz",
@@ -21737,30 +22605,12 @@
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
},
- "lodash-es": {
- "version": "4.18.1",
- "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.18.1.tgz",
- "integrity": "sha512-J8xewKD/Gk22OZbhpOVSwcs60zhd95ESDwezOFuA3/099925PdHJ7OFHNTGtajL3AlZkykD32HykiMo+BIBI8A==",
- "dev": true
- },
- "lodash.clonedeep": {
- "version": "4.5.0",
- "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
- "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==",
- "dev": true
- },
"lodash.debounce": {
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
"integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==",
"dev": true
},
- "lodash.isequal": {
- "version": "4.5.0",
- "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
- "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==",
- "dev": true
- },
"lodash.memoize": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
@@ -21875,6 +22725,40 @@
"object-visit": "^1.0.0"
}
},
+ "markdown-it": {
+ "version": "14.2.0",
+ "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.2.0.tgz",
+ "integrity": "sha512-1TGiQiJVRQ3NPmZH6sx5Cfnmg6GQm9jvC1ch4TK511NjSJvjzKLzn5pPfZRNZkRPZP0HqCioSndqH8v2nRaWVQ==",
+ "dev": true,
+ "requires": {
+ "argparse": "^2.0.1",
+ "entities": "^4.4.0",
+ "linkify-it": "^5.0.1",
+ "mdurl": "^2.0.0",
+ "punycode.js": "^2.3.1",
+ "uc.micro": "^2.1.0"
+ },
+ "dependencies": {
+ "argparse": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+ "dev": true
+ },
+ "entities": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
+ "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
+ "dev": true
+ }
+ }
+ },
+ "mdurl": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz",
+ "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==",
+ "dev": true
+ },
"memoize-one": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz",
@@ -22893,6 +23777,12 @@
}
}
},
+ "orderedmap": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/orderedmap/-/orderedmap-2.1.1.tgz",
+ "integrity": "sha512-TvAWxi0nDe1j/rtMcWcIj94+Ffe6n7zhow33h40SKxmsmozs6dz/e+EajymfoFcHd7sxNn8yHM8839uixMOV6g==",
+ "dev": true
+ },
"os-tmpdir": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
@@ -22938,12 +23828,6 @@
"integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
"dev": true
},
- "parchment": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/parchment/-/parchment-3.0.0.tgz",
- "integrity": "sha512-HUrJFQ/StvgmXRcQ1ftY6VEZUq3jA2t9ncFN4F84J/vN0/FPpQF+8FKXb3l6fLces6q0uOHj6NJn+2xvZnxO6A==",
- "dev": true
- },
"parent-module": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
@@ -23199,6 +24083,204 @@
}
}
},
+ "prosemirror-changeset": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/prosemirror-changeset/-/prosemirror-changeset-2.4.1.tgz",
+ "integrity": "sha512-96WBLhOaYhJ+kPhLg3uW359Tz6I/MfcrQfL4EGv4SrcqKEMC1gmoGrXHecPE8eOwTVCJ4IwgfzM8fFad25wNfw==",
+ "dev": true,
+ "requires": {
+ "prosemirror-transform": "^1.0.0"
+ }
+ },
+ "prosemirror-collab": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/prosemirror-collab/-/prosemirror-collab-1.3.1.tgz",
+ "integrity": "sha512-4SnynYR9TTYaQVXd/ieUvsVV4PDMBzrq2xPUWutHivDuOshZXqQ5rGbZM84HEaXKbLdItse7weMGOUdDVcLKEQ==",
+ "dev": true,
+ "requires": {
+ "prosemirror-state": "^1.0.0"
+ }
+ },
+ "prosemirror-commands": {
+ "version": "1.7.1",
+ "resolved": "https://registry.npmjs.org/prosemirror-commands/-/prosemirror-commands-1.7.1.tgz",
+ "integrity": "sha512-rT7qZnQtx5c0/y/KlYaGvtG411S97UaL6gdp6RIZ23DLHanMYLyfGBV5DtSnZdthQql7W+lEVbpSfwtO8T+L2w==",
+ "dev": true,
+ "requires": {
+ "prosemirror-model": "^1.0.0",
+ "prosemirror-state": "^1.0.0",
+ "prosemirror-transform": "^1.10.2"
+ }
+ },
+ "prosemirror-dropcursor": {
+ "version": "1.8.2",
+ "resolved": "https://registry.npmjs.org/prosemirror-dropcursor/-/prosemirror-dropcursor-1.8.2.tgz",
+ "integrity": "sha512-CCk6Gyx9+Tt2sbYk5NK0nB1ukHi2ryaRgadV/LvyNuO3ena1payM2z6Cg0vO1ebK8cxbzo41ku2DE5Axj1Zuiw==",
+ "dev": true,
+ "requires": {
+ "prosemirror-state": "^1.0.0",
+ "prosemirror-transform": "^1.1.0",
+ "prosemirror-view": "^1.1.0"
+ }
+ },
+ "prosemirror-gapcursor": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/prosemirror-gapcursor/-/prosemirror-gapcursor-1.4.1.tgz",
+ "integrity": "sha512-pMdYaEnjNMSwl11yjEGtgTmLkR08m/Vl+Jj443167p9eB3HVQKhYCc4gmHVDsLPODfZfjr/MmirsdyZziXbQKw==",
+ "dev": true,
+ "requires": {
+ "prosemirror-keymap": "^1.0.0",
+ "prosemirror-model": "^1.0.0",
+ "prosemirror-state": "^1.0.0",
+ "prosemirror-view": "^1.0.0"
+ }
+ },
+ "prosemirror-history": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/prosemirror-history/-/prosemirror-history-1.5.0.tgz",
+ "integrity": "sha512-zlzTiH01eKA55UAf1MEjtssJeHnGxO0j4K4Dpx+gnmX9n+SHNlDqI2oO1Kv1iPN5B1dm5fsljCfqKF9nFL6HRg==",
+ "dev": true,
+ "requires": {
+ "prosemirror-state": "^1.2.2",
+ "prosemirror-transform": "^1.0.0",
+ "prosemirror-view": "^1.31.0",
+ "rope-sequence": "^1.3.0"
+ }
+ },
+ "prosemirror-inputrules": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/prosemirror-inputrules/-/prosemirror-inputrules-1.5.1.tgz",
+ "integrity": "sha512-7wj4uMjKaXWAQ1CDgxNzNtR9AlsuwzHfdFH1ygEHA2KHF2DOEaXl1CJfNPAKCg9qNEh4rum975QLaCiQPyY6Fw==",
+ "dev": true,
+ "requires": {
+ "prosemirror-state": "^1.0.0",
+ "prosemirror-transform": "^1.0.0"
+ }
+ },
+ "prosemirror-keymap": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/prosemirror-keymap/-/prosemirror-keymap-1.2.3.tgz",
+ "integrity": "sha512-4HucRlpiLd1IPQQXNqeo81BGtkY8Ai5smHhKW9jjPKRc2wQIxksg7Hl1tTI2IfT2B/LgX6bfYvXxEpJl7aKYKw==",
+ "dev": true,
+ "requires": {
+ "prosemirror-state": "^1.0.0",
+ "w3c-keyname": "^2.2.0"
+ }
+ },
+ "prosemirror-markdown": {
+ "version": "1.13.4",
+ "resolved": "https://registry.npmjs.org/prosemirror-markdown/-/prosemirror-markdown-1.13.4.tgz",
+ "integrity": "sha512-D98dm4cQ3Hs6EmjK500TdAOew4Z03EV71ajEFiWra3Upr7diytJsjF4mPV2dW+eK5uNectiRj0xFxYI9NLXDbw==",
+ "dev": true,
+ "requires": {
+ "@types/markdown-it": "^14.0.0",
+ "markdown-it": "^14.0.0",
+ "prosemirror-model": "^1.25.0"
+ }
+ },
+ "prosemirror-menu": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/prosemirror-menu/-/prosemirror-menu-1.3.2.tgz",
+ "integrity": "sha512-6VgUJTYod0nMBlCaYJGhXGLu7Gt4AvcwcOq0YfJCY/6Uh+3S7UsWhpy6rJFCBFOmonq1hD8KyWOtZhkppd4YPg==",
+ "dev": true,
+ "requires": {
+ "crelt": "^1.0.0",
+ "prosemirror-commands": "^1.0.0",
+ "prosemirror-history": "^1.0.0",
+ "prosemirror-state": "^1.0.0"
+ }
+ },
+ "prosemirror-model": {
+ "version": "1.25.7",
+ "resolved": "https://registry.npmjs.org/prosemirror-model/-/prosemirror-model-1.25.7.tgz",
+ "integrity": "sha512-A79aN8QEFUwI6cax8Yq4Rpcx1TJZ3Kagn+ii7qLo4/V8H3mMiHrhFyhTyHHvpSnOgMPpWiDGSwM3etwrxE50ug==",
+ "dev": true,
+ "requires": {
+ "orderedmap": "^2.0.0"
+ }
+ },
+ "prosemirror-schema-basic": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/prosemirror-schema-basic/-/prosemirror-schema-basic-1.2.4.tgz",
+ "integrity": "sha512-ELxP4TlX3yr2v5rM7Sb70SqStq5NvI15c0j9j/gjsrO5vaw+fnnpovCLEGIcpeGfifkuqJwl4fon6b+KdrODYQ==",
+ "dev": true,
+ "requires": {
+ "prosemirror-model": "^1.25.0"
+ }
+ },
+ "prosemirror-schema-list": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/prosemirror-schema-list/-/prosemirror-schema-list-1.5.1.tgz",
+ "integrity": "sha512-927lFx/uwyQaGwJxLWCZRkjXG0p48KpMj6ueoYiu4JX05GGuGcgzAy62dfiV8eFZftgyBUvLx76RsMe20fJl+Q==",
+ "dev": true,
+ "requires": {
+ "prosemirror-model": "^1.0.0",
+ "prosemirror-state": "^1.0.0",
+ "prosemirror-transform": "^1.7.3"
+ }
+ },
+ "prosemirror-state": {
+ "version": "1.4.4",
+ "resolved": "https://registry.npmjs.org/prosemirror-state/-/prosemirror-state-1.4.4.tgz",
+ "integrity": "sha512-6jiYHH2CIGbCfnxdHbXZ12gySFY/fz/ulZE333G6bPqIZ4F+TXo9ifiR86nAHpWnfoNjOb3o5ESi7J8Uz1jXHw==",
+ "dev": true,
+ "requires": {
+ "prosemirror-model": "^1.0.0",
+ "prosemirror-transform": "^1.0.0",
+ "prosemirror-view": "^1.27.0"
+ }
+ },
+ "prosemirror-tables": {
+ "version": "1.8.5",
+ "resolved": "https://registry.npmjs.org/prosemirror-tables/-/prosemirror-tables-1.8.5.tgz",
+ "integrity": "sha512-V/0cDCsHKHe/tfWkeCmthNUcEp1IVO3p6vwN8XtwE9PZQLAZJigbw3QoraAdfJPir4NKJtNvOB8oYGKRl+t0Dw==",
+ "dev": true,
+ "requires": {
+ "prosemirror-keymap": "^1.2.3",
+ "prosemirror-model": "^1.25.4",
+ "prosemirror-state": "^1.4.4",
+ "prosemirror-transform": "^1.10.5",
+ "prosemirror-view": "^1.41.4"
+ }
+ },
+ "prosemirror-trailing-node": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/prosemirror-trailing-node/-/prosemirror-trailing-node-3.0.0.tgz",
+ "integrity": "sha512-xiun5/3q0w5eRnGYfNlW1uU9W6x5MoFKWwq/0TIRgt09lv7Hcser2QYV8t4muXbEr+Fwo0geYn79Xs4GKywrRQ==",
+ "dev": true,
+ "requires": {
+ "@remirror/core-constants": "3.0.0",
+ "escape-string-regexp": "^4.0.0"
+ },
+ "dependencies": {
+ "escape-string-regexp": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+ "dev": true
+ }
+ }
+ },
+ "prosemirror-transform": {
+ "version": "1.12.0",
+ "resolved": "https://registry.npmjs.org/prosemirror-transform/-/prosemirror-transform-1.12.0.tgz",
+ "integrity": "sha512-GxboyN4AMIsoHNtz5uf2r2Ru551i5hWeCMD6E2Ib4Eogqoub0NflniaBPVQ4MrGE5yZ8JV9tUHg9qcZTTrcN4w==",
+ "dev": true,
+ "requires": {
+ "prosemirror-model": "^1.21.0"
+ }
+ },
+ "prosemirror-view": {
+ "version": "1.41.8",
+ "resolved": "https://registry.npmjs.org/prosemirror-view/-/prosemirror-view-1.41.8.tgz",
+ "integrity": "sha512-TnKDdohEatgyZNGCDWIdccOHXhYloJwbwU+phw/a23KBvJIR9lWQWW7WHHK3vBdOLDNuF7TaX98GObUZOWkOnA==",
+ "dev": true,
+ "requires": {
+ "prosemirror-model": "^1.20.0",
+ "prosemirror-state": "^1.0.0",
+ "prosemirror-transform": "^1.1.0"
+ }
+ },
"pump": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
@@ -23209,6 +24291,12 @@
"once": "^1.3.1"
}
},
+ "punycode.js": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz",
+ "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==",
+ "dev": true
+ },
"queue-microtask": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
@@ -23221,29 +24309,6 @@
"integrity": "sha512-tRS7sTgyxMXtLum8L65daJnHUhfDUgboRdcWW2bR9vBfrj2+O5HSMbQOJfJJjIVSPFqbBCF37FpwWXGitDc5tA==",
"dev": true
},
- "quill": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/quill/-/quill-2.0.3.tgz",
- "integrity": "sha512-xEYQBqfYx/sfb33VJiKnSJp8ehloavImQ2A6564GAbqG55PGw1dAWUn1MUbQB62t0azawUS2CZZhWCjO8gRvTw==",
- "dev": true,
- "requires": {
- "eventemitter3": "^5.0.1",
- "lodash-es": "^4.17.21",
- "parchment": "^3.0.0",
- "quill-delta": "^5.1.0"
- }
- },
- "quill-delta": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/quill-delta/-/quill-delta-5.1.0.tgz",
- "integrity": "sha512-X74oCeRI4/p0ucjb5Ma8adTXd9Scumz367kkMK5V/IatcX6A0vlgLgKbzXWy5nZmCGeNJm2oQX0d2Eqj+ZIlCA==",
- "dev": true,
- "requires": {
- "fast-diff": "^1.3.0",
- "lodash.clonedeep": "^4.5.0",
- "lodash.isequal": "^4.5.0"
- }
- },
"ramda": {
"version": "0.27.2",
"resolved": "https://registry.npmjs.org/ramda/-/ramda-0.27.2.tgz",
@@ -23622,10 +24687,28 @@
}
},
"react-native-enriched": {
- "version": "0.5.2",
- "resolved": "https://registry.npmjs.org/react-native-enriched/-/react-native-enriched-0.5.2.tgz",
- "integrity": "sha512-9texMnu5+CXLCuVJv987UmzgB70F8Q3okOm2zqZ8jYSEz8IGyd7kbJdZ4J1rW99x3hYaeV+u+cSECzrCj7F4EA==",
- "dev": true
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/react-native-enriched/-/react-native-enriched-0.7.0.tgz",
+ "integrity": "sha512-WrhaRUMM8HaV+6XwESS1k7i1/QxZb4K2lpELIxLTiXXMdUP5b9207AjXp6d8Op0XulvFNC8HJdDdanQZUUI6Zg==",
+ "dev": true,
+ "requires": {
+ "@tiptap/core": "3.20.4",
+ "@tiptap/extension-blockquote": "3.20.4",
+ "@tiptap/extension-bold": "3.20.4",
+ "@tiptap/extension-code": "3.20.4",
+ "@tiptap/extension-document": "3.20.4",
+ "@tiptap/extension-heading": "3.20.4",
+ "@tiptap/extension-italic": "3.20.4",
+ "@tiptap/extension-link": "3.20.4",
+ "@tiptap/extension-list": "3.20.4",
+ "@tiptap/extension-paragraph": "3.20.4",
+ "@tiptap/extension-strike": "3.20.4",
+ "@tiptap/extension-text": "3.20.4",
+ "@tiptap/extension-underline": "3.20.4",
+ "@tiptap/extensions": "3.20.4",
+ "@tiptap/pm": "3.20.4",
+ "@tiptap/react": "3.20.4"
+ }
},
"react-native-gradle-plugin": {
"version": "0.0.7",
@@ -23649,16 +24732,6 @@
"urijs": "^1.19.6"
}
},
- "react-quill-new": {
- "version": "3.8.3",
- "resolved": "https://registry.npmjs.org/react-quill-new/-/react-quill-new-3.8.3.tgz",
- "integrity": "sha512-c96PYqFTo0pI4R3e79B3rH9LUIce1kIQbmTBu/imJQZk8305ogyLyBqKKjG2UoInDlquXqePSzmBo2aVia3ttw==",
- "dev": true,
- "requires": {
- "lodash-es": "^4.17.21",
- "quill": "~2.0.3"
- }
- },
"react-refresh": {
"version": "0.4.3",
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.4.3.tgz",
@@ -24025,6 +25098,12 @@
"glob": "^7.1.3"
}
},
+ "rope-sequence": {
+ "version": "1.3.4",
+ "resolved": "https://registry.npmjs.org/rope-sequence/-/rope-sequence-1.3.4.tgz",
+ "integrity": "sha512-UT5EDe2cu2E/6O4igUr5PSFs23nvvukicWHx6GnOPlHAiiYbzNuCRQCuiUdHJQcqKalLKlrYJnjY0ySGsXNQXQ==",
+ "dev": true
+ },
"run-parallel": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
@@ -25282,6 +26361,12 @@
"integrity": "sha512-goMHfm00nWPa8UvR/CPSvykqf6dVV8x/dp0c5mFTMTIu0u0FlGWRioyy7Nn0PGAdHxpJZnuO/ut+PpQ8UiHAig==",
"dev": true
},
+ "uc.micro": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz",
+ "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==",
+ "dev": true
+ },
"uglify-es": {
"version": "3.3.10",
"resolved": "https://registry.npmjs.org/uglify-es/-/uglify-es-3.3.10.tgz",
@@ -25440,9 +26525,9 @@
"dev": true
},
"use-sync-external-store": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz",
- "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==",
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz",
+ "integrity": "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==",
"dev": true
},
"util-deprecate": {
@@ -25490,6 +26575,12 @@
"integrity": "sha512-gQpnTgkubC6hQgdIcRdYGDSDc+SaujOdyesZQMv6JlfQee/9Mp0Qhnys6WxDWvQnL5WZdT7o2Ul187aSt0Rq+w==",
"dev": true
},
+ "w3c-keyname": {
+ "version": "2.2.8",
+ "resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz",
+ "integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==",
+ "dev": true
+ },
"walker": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz",
diff --git a/package.json b/package.json
index 824a62b..5b43f80 100644
--- a/package.json
+++ b/package.json
@@ -63,12 +63,10 @@
"metro-react-native-babel-preset": "^0.66.2",
"pod-install": "^0.1.0",
"prettier": "^2.0.5",
- "quill": "^2.0.3",
"react": "18.3.1",
"react-native": "^0.69.4",
"react-native-builder-bob": "^0.18.2",
- "react-native-enriched": "^0.5.2",
- "react-quill-new": "^3.8.3",
+ "react-native-enriched": "^0.7.0",
"react-test-renderer": "^18.3.1",
"ts-clean": "^1.0.3",
"ts-jest": "^29.0.1",
@@ -85,15 +83,6 @@
"peerDependencies": {
"react": "*",
"react-native": "*",
- "react-native-enriched": ">=0.4.0",
- "react-quill-new": ">=3.8.0"
- },
- "peerDependenciesMeta": {
- "react-native-enriched": {
- "optional": true
- },
- "react-quill-new": {
- "optional": true
- }
+ "react-native-enriched": ">=0.7.0"
}
}
diff --git a/src/components/comment-text-area.native.tsx b/src/components/comment-text-area.tsx
similarity index 57%
rename from src/components/comment-text-area.native.tsx
rename to src/components/comment-text-area.tsx
index fc1e77e..184fcee 100644
--- a/src/components/comment-text-area.native.tsx
+++ b/src/components/comment-text-area.tsx
@@ -12,6 +12,7 @@ import {
ScrollView,
TouchableOpacity,
Image,
+ Platform,
} from "react-native";
import React, { useCallback, useEffect, useMemo, useRef, useState } from "react";
import {
@@ -20,13 +21,33 @@ import {
type OnChangeStateEvent,
} from 'react-native-enriched';
import type { NativeSyntheticEvent } from 'react-native';
-import { MentionPopup } from './mention-popup';
+import { MentionPopup, MentionPopupHandle } from './mention-popup';
+import { MentionPortal } from './mention-portal';
import { MentionUser } from '../services/mentions';
+import { detectMentionQuery, htmlToPlainText, replaceActiveMention } from '../services/mention-detection';
// Library's own event types follow snake->camelCase with `strikeThrough`.
// eslint-disable-next-line @typescript-eslint/no-explicit-any
type OnChangeHtmlEvent = { value: string };
+// react-native-enriched's web build renders tiptap's contenteditable
+// (`.ProseMirror`) inside a wrapper (`.eti-editor`) that receives our `style`
+// (minHeight/flex). The contenteditable itself only auto-sizes to its content
+// (one line), so the lower part of the bordered box is a dead, unclickable div.
+// The library ships no CSS to stretch it. Inject a tiny web-only rule once so
+// the editor fills its wrapper and the whole box is clickable/typable.
+const WEB_EDITOR_STYLE_ID = 'fastcomments-enriched-web-fill';
+function ensureWebEditorFillStyles() {
+ if (typeof document === 'undefined') return;
+ if (document.getElementById(WEB_EDITOR_STYLE_ID)) return;
+ const el = document.createElement('style');
+ el.id = WEB_EDITOR_STYLE_ID;
+ el.textContent =
+ '.eti-editor{display:flex;flex-direction:column;}' +
+ '.eti-editor>.tiptap,.eti-editor>.ProseMirror{flex:1 1 auto;}';
+ document.head.appendChild(el);
+}
+
export interface ValueObserver {
getValue?: () => string
}
@@ -66,6 +87,7 @@ type ActiveFormats = {
italic: boolean
underline: boolean
strikethrough: boolean
+ code: boolean
};
const defaultToolbarButtons: ToolbarButtonConfig = {
@@ -78,44 +100,9 @@ const defaultToolbarButtons: ToolbarButtonConfig = {
gif: true,
};
-/**
- * Strip simple HTML tags / decode common entities so we can detect `@...` triggers
- * in rich-text HTML the editor emits. Comment editors typically wrap text in
- * /
with breaks; we just need readable text for the trigger regex.
- */
-function htmlToPlainText(html: string): string {
- if (!html) return '';
- const stripped = html
- .replace(/
(\n)?/gi, '\n')
- .replace(/<\/(p|div|li)>/gi, '\n')
- .replace(/<[^>]+>/g, '');
- return stripped
- .replace(/ /g, ' ')
- .replace(/&/g, '&')
- .replace(/</g, '<')
- .replace(/>/g, '>')
- .replace(/"/g, '"')
- .replace(/'/g, "'");
-}
-
-/**
- * Returns the active mention query (text after the most recent `@` that starts
- * a token) or undefined when no mention is active. A trailing space terminates
- * the mention.
- */
-export function detectMentionQuery(value: string): string | undefined {
- const text = htmlToPlainText(value);
- const atIdx = text.lastIndexOf('@');
- if (atIdx === -1) return undefined;
- if (atIdx > 0) {
- const prev = text.charAt(atIdx - 1);
- if (!/\s/.test(prev)) return undefined;
- }
- const after = text.substring(atIdx + 1);
- if (/\n/.test(after)) return undefined;
- if (after.length > 0 && /\s$/.test(after)) return undefined;
- return after;
-}
+// Re-exported for any existing importers (the implementations now live in the
+// dependency-free `../services/mention-detection` module).
+export { detectMentionQuery, htmlToPlainText };
export function CommentTextArea({
emoticonBarConfig,
@@ -138,12 +125,94 @@ export function CommentTextArea({
const editorRef = useRef
(null);
const htmlRef = useRef(value || '');
+ // For keyboard-driving the mention popup (web): the wrapper DOM node we
+ // attach a capture-phase keydown listener to, the popup's imperative handle,
+ // and a ref mirror of `mentionQuery` so that once-attached listener sees the
+ // current open state without re-binding.
+ const wrapperRef = useRef(null);
+ const editorBoxRef = useRef(null);
+ const mentionPopupRef = useRef(null);
+ const mentionActiveRef = useRef(false);
const [imageUploadProgress, setImageUploadProgress] = useState(null);
- const [active, setActive] = useState({ bold: false, italic: false, underline: false, strikethrough: false });
+ const [active, setActive] = useState({ bold: false, italic: false, underline: false, strikethrough: false, code: false });
const [mentionQuery, setMentionQuery] = useState(undefined);
+ // On web the composer lives inside the scrollable comment list (as its
+ // header), so an `absolute` popup gets clipped by the list's overflow and
+ // painted under later comment-row cells. Position it `fixed` (measured off
+ // the editor box) to escape both. Native keeps the in-flow `absolute` overlay.
+ const [mentionOverlayStyle, setMentionOverlayStyle] = useState | null>(null);
+ mentionActiveRef.current = mentionQuery !== undefined;
const buttons = { ...defaultToolbarButtons, ...toolbarButtons };
+ useEffect(() => {
+ if (Platform.OS === 'web') ensureWebEditorFillStyles();
+ }, []);
+
+ // Web-only: drive the mention popup from the keyboard. react-native-enriched's
+ // web editor forwards keydown but always returns false to ProseMirror, so it
+ // can't tell PM "handled - don't move the cursor / insert a newline". Instead
+ // we listen on the wrapper in the CAPTURE phase: the event is intercepted
+ // before it reaches the contenteditable, so stopping it keeps PM from acting.
+ useEffect(() => {
+ if (Platform.OS !== 'web') return;
+ // The tsconfig has no DOM lib (this is an RN project), so we type the web
+ // key event minimally rather than relying on the global KeyboardEvent
+ // (which resolves to react-native's unrelated KeyboardEvent type).
+ type WebKeyEvent = { key: string; preventDefault: () => void; stopPropagation: () => void };
+ const node = wrapperRef.current as unknown as {
+ addEventListener?: (t: string, h: (e: WebKeyEvent) => void, c?: boolean) => void;
+ removeEventListener?: (t: string, h: (e: WebKeyEvent) => void, c?: boolean) => void;
+ } | null;
+ if (!node || typeof node.addEventListener !== 'function') return;
+ const onKeyDown = (e: WebKeyEvent) => {
+ if (!mentionActiveRef.current) return;
+ const key = e.key;
+ if (key === 'Escape') {
+ e.preventDefault();
+ e.stopPropagation();
+ setMentionQuery(undefined);
+ return;
+ }
+ if (key === 'ArrowDown' || key === 'ArrowUp' || key === 'Enter' || key === 'Tab') {
+ if (mentionPopupRef.current?.handleKey(key)) {
+ e.preventDefault();
+ e.stopPropagation();
+ }
+ }
+ };
+ node.addEventListener('keydown', onKeyDown, true);
+ return () => node.removeEventListener?.('keydown', onKeyDown, true);
+ }, []);
+
+ // Web-only: keep the fixed-positioned mention popup anchored under the editor
+ // box while it's open (reposition on scroll/resize since `fixed` is relative
+ // to the viewport).
+ useEffect(() => {
+ if (Platform.OS !== 'web') return;
+ if (mentionQuery === undefined) {
+ setMentionOverlayStyle(null);
+ return;
+ }
+ const win = globalThis as unknown as {
+ addEventListener?: (t: string, h: () => void, c?: boolean) => void;
+ removeEventListener?: (t: string, h: () => void, c?: boolean) => void;
+ };
+ const reposition = () => {
+ const box = editorBoxRef.current as unknown as { getBoundingClientRect?: () => { bottom: number; left: number; width: number } } | null;
+ const rect = box?.getBoundingClientRect?.();
+ if (!rect) return;
+ setMentionOverlayStyle({ position: 'fixed', top: rect.bottom, left: rect.left, width: rect.width, zIndex: 2147483000 });
+ };
+ reposition();
+ win.addEventListener?.('scroll', reposition, true);
+ win.addEventListener?.('resize', reposition);
+ return () => {
+ win.removeEventListener?.('scroll', reposition, true);
+ win.removeEventListener?.('resize', reposition);
+ };
+ }, [mentionQuery]);
+
useEffect(() => {
if (value !== undefined && value !== htmlRef.current) {
htmlRef.current = value;
@@ -170,23 +239,7 @@ export function CommentTextArea({
const handleMentionSelect = useCallback((user: MentionUser) => {
const label = user.displayName || user.name;
- const current = htmlRef.current || '';
- const plain = htmlToPlainText(current);
- const atIdx = plain.lastIndexOf('@');
- // Only safely rewrite when the editor's value is plain text (no HTML
- // markup difference). When the editor has rich HTML, we replace the
- // raw current value with a plain-text-friendly mention insert; the
- // editor will re-render via setValue.
- let nextValue: string;
- if (current === plain) {
- nextValue = current.substring(0, atIdx) + `@${label} `;
- } else {
- nextValue = current.replace(/@[^@<>\n]*$/, `@${label} `);
- if (nextValue === current) {
- // Fallback: append.
- nextValue = current + `@${label} `;
- }
- }
+ const nextValue = replaceActiveMention(htmlRef.current || '', label);
htmlRef.current = nextValue;
editorRef.current?.setValue(nextValue);
setMentionQuery(undefined);
@@ -199,6 +252,7 @@ export function CommentTextArea({
italic: !!s.italic?.isActive,
underline: !!s.underline?.isActive,
strikethrough: !!s.strikeThrough?.isActive,
+ code: !!s.inlineCode?.isActive,
});
}, []);
@@ -270,37 +324,57 @@ export function CommentTextArea({
const activeBackground = hasDarkBackground ? '#666' : '#d8d8d8';
return (
-
-
- onFocus() : undefined}
- style={{
- minHeight: useSingleLineCommentInput ? 32 : 92,
- flex: 1,
- backgroundColor: 'transparent',
- }}
- />
-
+
+ {/* Relative anchor so that on native the mention popup overlays
+ (position:absolute, top:100%) directly under the editor box. On web
+ the popup is positioned `fixed` instead (see mentionOverlayStyle) to
+ escape the scrollable comment list that clips/stacks over it. */}
+
+
+ onFocus() : undefined}
+ style={{
+ minHeight: useSingleLineCommentInput ? 32 : 92,
+ flex: 1,
+ backgroundColor: 'transparent',
+ }}
+ />
+
-
+
+
+
+
+
+
{emoticonBarConfig?.emoticons && (
@@ -361,6 +435,15 @@ export function CommentTextArea({
S
)}
+ {buttons.code && (
+ editorRef.current?.toggleInlineCode()}
+ activeOpacity={0.7}
+ >
+ {"<>"}
+
+ )}
{buttons.image && pickImage && (
string
-}
-
-export interface FocusObserver {
- setFocused?: (focused: boolean) => void
-}
-
-export interface EmoticonBarConfig {
- emoticons?: Array<[string, React.ReactNode]>
- addEmoticon?: (src: string) => void
-}
-
-export interface ToolbarButtonConfig {
- bold?: boolean
- italic?: boolean
- underline?: boolean
- strikethrough?: boolean
- code?: boolean
- image?: boolean
- gif?: boolean
-}
-
-export interface CommentTextAreaProps extends Pick {
- emoticonBarConfig?: EmoticonBarConfig
- focusObserver?: FocusObserver
- store: FastCommentsStore
- styles: IFastCommentsStyles
- output: ValueObserver
- onFocus?: () => void
- value?: string
- toolbarButtons?: ToolbarButtonConfig
-}
-
-type ActiveFormats = {
- bold: boolean
- italic: boolean
- underline: boolean
- strike: boolean
- code: boolean
-};
-
-const defaultToolbarButtons: ToolbarButtonConfig = {
- bold: true,
- italic: true,
- underline: true,
- strikethrough: true,
- code: false,
- image: true,
- gif: true,
-};
-
-// Quill accepts a fixed set of format names. We only whitelist ones we expose
-// via the toolbar plus link/image so paste-with-formatting still renders.
-const allowedFormats = ['bold', 'italic', 'underline', 'strike', 'code', 'link', 'image'];
-
-export function CommentTextArea({
- emoticonBarConfig,
- focusObserver,
- store,
- styles,
- output,
- onFocus,
- pickImage,
- pickGIF,
- value,
- toolbarButtons,
-}: CommentTextAreaProps) {
- const maxLength = useStoreValue(store, (s) => s.config.maxCommentCharacterLength) || 2000;
- const hasDarkBackground = useStoreValue(store, (s) => !!s.config.hasDarkBackground);
- const apiHost = useStoreValue(store, (s) => s.apiHost);
- const tenantId = useStoreValue(store, (s) => s.config.tenantId);
- const imageAssets = useStoreValue(store, (s) => s.imageAssets);
- const useSingleLineCommentInput = useStoreValue(store, (s) => !!s.config.useSingleLineCommentInput);
-
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- const quillRef = useRef(null);
- const [html, setHtml] = useState(value || '');
- useEffect(() => { ensureQuillFillStyles(); }, []);
- const [imageUploadProgress, setImageUploadProgress] = useState(null);
- const [active, setActive] = useState({ bold: false, italic: false, underline: false, strike: false, code: false });
-
- const buttons = { ...defaultToolbarButtons, ...toolbarButtons };
-
- useEffect(() => {
- if (value !== undefined && value !== html) {
- setHtml(value);
- }
- }, [value]);
-
- useEffect(() => {
- if (!focusObserver) return;
- focusObserver.setFocused = (focused) => {
- const editor = quillRef.current?.getEditor?.();
- if (!editor) return;
- if (focused) editor.focus();
- else editor.blur();
- };
- }, [focusObserver]);
-
- output.getValue = () => html.substring(0, maxLength);
-
- const updateActive = useCallback(() => {
- const editor = quillRef.current?.getEditor?.();
- if (!editor) return;
- const fmts = editor.getFormat();
- setActive({
- bold: !!fmts.bold,
- italic: !!fmts.italic,
- underline: !!fmts.underline,
- strike: !!fmts.strike,
- code: !!fmts.code,
- });
- }, []);
-
- const toggleFormat = useCallback((name: keyof ActiveFormats) => {
- const editor = quillRef.current?.getEditor?.();
- if (!editor) return;
- editor.focus();
- const current = editor.getFormat();
- editor.format(name, !current[name]);
- updateActive();
- }, [updateActive]);
-
- const insertImageByUrl = useCallback((url: string) => {
- const editor = quillRef.current?.getEditor?.();
- if (!editor) return;
- const range = editor.getSelection(true) || { index: editor.getLength(), length: 0 };
- editor.insertEmbed(range.index, 'image', url, 'user');
- editor.setSelection(range.index + 1, 0);
- }, []);
-
- const handleImageUpload = async () => {
- if (!pickImage) return;
- try {
- const photoData = await pickImage();
- if (!photoData) return;
- if (typeof photoData === 'string' && photoData.startsWith('http')) {
- insertImageByUrl(photoData);
- return;
- }
- setImageUploadProgress(0);
- const formData = new FormData();
- formData.append('file', photoData as string);
- const xhr = new XMLHttpRequest();
- xhr.open('POST', apiHost + '/upload-image/' + tenantId);
- xhr.upload.onprogress = (ev) => {
- if (ev.lengthComputable) setImageUploadProgress(ev.loaded / ev.total);
- };
- const url = await new Promise((resolve, reject) => {
- xhr.onload = () => {
- setImageUploadProgress(null);
- if (xhr.status === 200) resolve(JSON.parse(xhr.response).url);
- else reject(new Error(xhr.response));
- };
- xhr.onerror = () => {
- setImageUploadProgress(null);
- reject(new Error('Upload failed'));
- };
- xhr.send(formData);
- });
- insertImageByUrl(url);
- } catch (err) {
- console.error('Image upload failed:', err);
- setImageUploadProgress(null);
- }
- };
-
- const handleGIFPick = async () => {
- if (!pickGIF) return;
- try {
- const url = await pickGIF();
- if (url) insertImageByUrl(url);
- } catch (err) {
- console.error('GIF pick failed:', err);
- }
- };
-
- if (emoticonBarConfig) {
- emoticonBarConfig.addEmoticon = (src: string) => {
- insertImageByUrl(src);
- };
- }
-
- const quillModules = useMemo(() => ({ toolbar: false }), []);
-
- const toolbarButtonStyle = useMemo(() => ({
- backgroundColor: hasDarkBackground ? '#444' : 'white',
- paddingHorizontal: 8,
- paddingVertical: 6,
- borderRadius: 4,
- borderWidth: 1,
- borderColor: styles.commentTextArea?.textarea?.borderColor || (hasDarkBackground ? '#555' : '#a2a2a2'),
- minWidth: 28,
- alignItems: 'center' as const,
- justifyContent: 'center' as const,
- marginRight: 6,
- }), [hasDarkBackground, styles.commentTextArea?.textarea?.borderColor]);
-
- const activeBackground = hasDarkBackground ? '#666' : '#d8d8d8';
-
- return (
-
-
- {
- setHtml(content);
- updateActive();
- }}
- onChangeSelection={updateActive}
- onFocus={onFocus as any}
- modules={quillModules}
- formats={allowedFormats}
- />
-
-
- {emoticonBarConfig?.emoticons && (
-
- {emoticonBarConfig.emoticons.map(([src, element], index) => (
- emoticonBarConfig.addEmoticon?.(src)}
- style={styles.commentTextAreaEmoticonBar?.button}
- >
- {element}
-
- ))}
-
- )}
-
-
- {buttons.bold && (
- toggleFormat('bold')}
- activeOpacity={0.7}
- >
- B
-
- )}
- {buttons.italic && (
- toggleFormat('italic')}
- activeOpacity={0.7}
- >
- I
-
- )}
- {buttons.underline && (
- toggleFormat('underline')}
- activeOpacity={0.7}
- >
- U
-
- )}
- {buttons.strikethrough && (
- toggleFormat('strike')}
- activeOpacity={0.7}
- >
- S
-
- )}
- {buttons.code && (
- toggleFormat('code')}
- activeOpacity={0.7}
- >
- {"<>"}
-
- )}
- {buttons.image && pickImage && (
-
-
-
- )}
- {buttons.gif && pickGIF && (
-
-
-
- )}
-
-
- {imageUploadProgress !== null && (
-
-
-
-
- {Math.round(imageUploadProgress * 100)}%
-
-
-
- )}
-
- );
-}
diff --git a/src/components/mention-popup.tsx b/src/components/mention-popup.tsx
index 8cbfe0a..02303cf 100644
--- a/src/components/mention-popup.tsx
+++ b/src/components/mention-popup.tsx
@@ -1,4 +1,4 @@
-import React, { useEffect, useMemo, useRef, useState } from 'react';
+import React, { forwardRef, useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react';
import {
ActivityIndicator,
Image,
@@ -23,7 +23,20 @@ export interface MentionPopupProps {
onSelect: (user: MentionUser) => void;
}
-export function MentionPopup({ store, styles, query, onSelect }: MentionPopupProps) {
+/**
+ * Imperative handle so the editor can drive the popup from the keyboard
+ * (arrow keys to move the highlight, Enter/Tab to select). `handleKey` returns
+ * true when it consumed the key, so the caller knows to preventDefault.
+ */
+export interface MentionPopupHandle {
+ isOpen: () => boolean;
+ handleKey: (key: string) => boolean;
+}
+
+export const MentionPopup = forwardRef(function MentionPopup(
+ { store, styles, query, onSelect },
+ ref
+) {
const tenantId = useStoreValue(store, (s) => s.config.tenantId);
const urlId = useStoreValue(store, (s) => s.config.urlId);
const ssoConfigString = useStoreValue(store, (s) => s.ssoConfigString);
@@ -33,6 +46,7 @@ export function MentionPopup({ store, styles, query, onSelect }: MentionPopupPro
const [users, setUsers] = useState([]);
const [loading, setLoading] = useState(false);
+ const [selectedIndex, setSelectedIndex] = useState(0);
const requestSeqRef = useRef(0);
useEffect(() => {
@@ -71,6 +85,32 @@ export function MentionPopup({ store, styles, query, onSelect }: MentionPopupPro
return () => clearTimeout(handle);
}, [query, store, tenantId, urlId, ssoConfigString]);
+ // Highlight the first result whenever the result set changes.
+ useEffect(() => {
+ setSelectedIndex(0);
+ }, [users]);
+
+ useImperativeHandle(ref, () => ({
+ isOpen: () => query !== undefined && users.length > 0,
+ handleKey: (key: string): boolean => {
+ if (query === undefined || users.length === 0) return false;
+ if (key === 'ArrowDown') {
+ setSelectedIndex((i) => (i + 1) % users.length);
+ return true;
+ }
+ if (key === 'ArrowUp') {
+ setSelectedIndex((i) => (i - 1 + users.length) % users.length);
+ return true;
+ }
+ if (key === 'Enter' || key === 'Tab') {
+ const user = users[selectedIndex] || users[0];
+ if (user) onSelect(user);
+ return true;
+ }
+ return false;
+ },
+ }), [query, users, selectedIndex, onSelect]);
+
const popupStyle = useMemo(() => ({
backgroundColor: hasDarkBackground ? '#2c2c2c' : 'white',
borderRadius: 8,
@@ -108,14 +148,16 @@ export function MentionPopup({ store, styles, query, onSelect }: MentionPopupPro
)}
{users.length > 0 && (
- {users.map((user) => {
+ {users.map((user, index) => {
const label = user.displayName || user.name;
+ const isSelected = index === selectedIndex;
return (
onSelect(user)}
+ onPressIn={() => setSelectedIndex(index)}
style={[
{
flexDirection: 'row',
@@ -124,6 +166,7 @@ export function MentionPopup({ store, styles, query, onSelect }: MentionPopupPro
paddingHorizontal: 12,
},
styles.mentionPopup?.item,
+ isSelected && { backgroundColor: hasDarkBackground ? '#3a3a3a' : '#eef2ff' },
]}
>
);
-}
+});
diff --git a/src/components/mention-portal.tsx b/src/components/mention-portal.tsx
new file mode 100644
index 0000000..5f6fea9
--- /dev/null
+++ b/src/components/mention-portal.tsx
@@ -0,0 +1,10 @@
+import * as React from 'react';
+
+/**
+ * Native (and any non-web bundler / jest) has no DOM portal, so render the
+ * mention dropdown in place. The web variant (mention-portal.web.tsx) portals it
+ * to document.body so it can escape the scrollable comment list.
+ */
+export function MentionPortal({ children }: { children: React.ReactNode }) {
+ return <>{children}>;
+}
diff --git a/src/components/mention-portal.web.tsx b/src/components/mention-portal.web.tsx
new file mode 100644
index 0000000..88b85b1
--- /dev/null
+++ b/src/components/mention-portal.web.tsx
@@ -0,0 +1,18 @@
+import * as React from 'react';
+// `react-dom` is only present in a web bundler context (it's a react-native-web
+// peer). The SDK's own tsconfig has no react-dom installed, so suppress the
+// resolution error here; web bundlers (vite/webpack) resolve it fine.
+// @ts-ignore - resolved by the web bundler, not the SDK's tsconfig
+import { createPortal } from 'react-dom';
+
+/**
+ * Render the mention dropdown into document.body. The composer lives inside the
+ * scrollable, transformed comment list, which clips an absolutely/fixed
+ * positioned popup and paints later comment-row cells on top of it. Portaling to
+ * body escapes that container entirely; the popup is then positioned via a fixed
+ * style measured off the editor box (see comment-text-area `mentionOverlayStyle`).
+ */
+export function MentionPortal({ children }: { children: React.ReactNode }) {
+ if (typeof document === 'undefined') return <>{children}>;
+ return createPortal(children, document.body);
+}
diff --git a/src/components/reply-area.tsx b/src/components/reply-area.tsx
index f2ee755..ce1b900 100644
--- a/src/components/reply-area.tsx
+++ b/src/components/reply-area.tsx
@@ -180,6 +180,17 @@ async function submit(
(currentUserBeforeSubmit && 'email' in currentUserBeforeSubmit && (currentUserBeforeSubmit as any).email)
))))
) {
+ // The submit can't proceed (no text, or guest hasn't supplied the
+ // name/email this tenant requires). The caller turned the spinner on
+ // before awaiting us; reset it so it doesn't hang forever, and surface
+ // the name/email form when identity is what's missing.
+ const missingIdentity =
+ !!replyState.comment &&
+ !allowAnon &&
+ !(replyState.username || (currentUserBeforeSubmit as any)?.username);
+ const patch: Partial = { isReplySaving: false };
+ if (missingIdentity) patch.showAuthInputForm = true;
+ setReplyState(patch);
return;
}
@@ -260,15 +271,18 @@ async function submit(
incOverallCommentCount(latest.config.countAll, store, comment.parentId);
if (response.user) {
- const responseUser = response.user;
- if (latest.config.simpleSSO) {
- latest.setCurrentUser({
- ...(latest.currentUser as object),
- ...responseUser,
- } as FastCommentsSessionUser);
- } else {
- latest.setCurrentUser(responseUser as FastCommentsSessionUser);
- }
+ // Merge the server's user into the existing session, like the web
+ // widget (frontend/comment-ui copies each response.user key onto
+ // currentUser). The server returns an authorized user with the
+ // email/username the guest just entered; consuming it hides the
+ // name/email form and populates the top bar. Merging (vs replacing)
+ // preserves any fields the response omits (e.g. avatar).
+ const existingUser = latest.currentUser as object | null;
+ latest.setCurrentUser(
+ (existingUser
+ ? { ...existingUser, ...response.user }
+ : response.user) as FastCommentsSessionUser
+ );
onAuthenticationChange &&
onAuthenticationChange('user-set', store.getState().currentUser, comment);
}
@@ -279,12 +293,19 @@ async function submit(
'sessionId' in response.user &&
response.user.sessionId
) {
- latest.setCurrentUser({
- ...(latest.currentUser as object),
- sessionId: response.user.sessionId,
- } as FastCommentsSessionUser);
- onAuthenticationChange &&
- onAuthenticationChange('session-id-set', store.getState().currentUser, comment);
+ // Apply the sessionId on top of the freshly-merged user. Reading
+ // `store.getState().currentUser` (not the stale `latest` snapshot
+ // captured before the merge above) avoids reverting to the prior
+ // anon user, which is what kept the auth form showing after submit.
+ const mergedUser = store.getState().currentUser as object | null;
+ if (mergedUser) {
+ latest.setCurrentUser({
+ ...mergedUser,
+ sessionId: response.user.sessionId,
+ } as FastCommentsSessionUser);
+ onAuthenticationChange &&
+ onAuthenticationChange('session-id-set', store.getState().currentUser, comment);
+ }
}
if (replyingToId === null && !latest.config.disableSuccessMessage) showSuccessMessage = true;
const newCurrentUserId =
@@ -368,7 +389,16 @@ export function ReplyArea(props: ReplyAreaProps) {
const ssoConfig = useStoreValue(store, (s) => s.config.sso || s.config.simpleSSO);
const inlineReactImages = useStoreValue(store, (s) => s.config.inlineReactImages);
- const needsAuth = !currentUser && !!parentComment;
+ // Mirror the web widget (frontend/shared/get-reply-area-html.ts): a guest must
+ // supply a name (and email, unless the tenant allows fully-anonymous) before
+ // commenting. Show the auth prompt when there's no authorized user, or when an
+ // anon session still owes us an email. The old `!currentUser && !!parentComment`
+ // was wrong: it only prompted on replies and treated the anon session (which
+ // exists from connect, with no username/email) as fully logged in - so root
+ // comments silently failed validation.
+ const currentUserAny = currentUser as { authorized?: boolean; isAnonSession?: boolean; email?: string } | null | undefined;
+ const anonSessionNeedsEmail = !!(currentUserAny && currentUserAny.isAnonSession && !currentUserAny.email && !allowAnon);
+ const needsAuth = !currentUserAny || !currentUserAny.authorized || anonSessionNeedsEmail;
const valueGetter: ValueObserver = {};
const focusObserver: FocusObserver = {};
@@ -413,7 +443,7 @@ export function ReplyArea(props: ReplyAreaProps) {
let commentSubmitButton = null;
let authFormArea = null;
- if (!currentUser && ssoConfig && !allowAnon) {
+ if (needsAuth && ssoConfig && !allowAnon) {
if (ssoConfig.loginURL || ssoConfig.loginCallback) {
ssoLoginWrapper = (
@@ -586,7 +616,11 @@ export function ReplyArea(props: ReplyAreaProps) {
);
}
+ // Like the frontend, render the name/email inputs whenever the guest still
+ // needs to identify themselves (recomputed each render so it tracks the
+ // anon session loading in), plus the explicit toggle / signup-error cases.
const showAuth =
+ needsAuth ||
commentReplyState.showAuthInputForm ||
(commentReplyState.lastSaveResponse?.code &&
SignUpErrorsTranslationIds[commentReplyState.lastSaveResponse.code!]);
@@ -607,7 +641,7 @@ export function ReplyArea(props: ReplyAreaProps) {
textContentType="emailAddress"
keyboardType="email-address"
autoComplete="email"
- value={commentReplyState.email}
+ value={commentReplyState.email || ''}
returnKeyType={enableCommenterLinks ? 'next' : 'send'}
onChangeText={(value) => setCommentReplyState({ email: value })}
/>
@@ -619,7 +653,7 @@ export function ReplyArea(props: ReplyAreaProps) {
placeholder={translations.PUBLICLY_DISPLAYED_USERNAME}
textContentType="username"
autoComplete="username"
- value={commentReplyState.username}
+ value={commentReplyState.username || ''}
returnKeyType={enableCommenterLinks ? 'next' : 'send'}
onChangeText={(value) => setCommentReplyState({ username: value })}
/>
diff --git a/src/resources/styles.ts b/src/resources/styles.ts
index a51344f..7ff06ec 100644
--- a/src/resources/styles.ts
+++ b/src/resources/styles.ts
@@ -1,13 +1,16 @@
import {IFastCommentsStyles} from "../types";
import {ViewStyle} from "react-native";
+// The loading state is a sole, full-area render (the widget early-returns this
+// while fetching). It must NOT be `position: absolute`: an absolutely-positioned
+// sole child is out of flow, so its container collapses to 0 height, and on web
+// (where the host's #root is not always a flex container that propagates height)
+// a 0-height `inset: 0` box centers the spinner on y=0 - i.e. half off the top of
+// the screen. Filling via normal flow (flex + a minHeight floor) centers it
+// reliably on both web and native.
const LoadingOverlay: ViewStyle = {
- position: 'absolute',
- top: 0,
- left: 0,
- right: 0,
- bottom: 0,
flex: 1,
+ minHeight: 200,
alignItems: 'center',
justifyContent: 'center',
backgroundColor: '#ffffff50'
diff --git a/src/services/__tests__/mention-detection.test.ts b/src/services/__tests__/mention-detection.test.ts
new file mode 100644
index 0000000..a46c6b1
--- /dev/null
+++ b/src/services/__tests__/mention-detection.test.ts
@@ -0,0 +1,120 @@
+import { detectMentionQuery, htmlToPlainText, replaceActiveMention } from '../mention-detection';
+
+// Committed mentions end with a non-breaking space (so the trailing space isn't
+// collapsed by the HTML editor). Tests assert against it explicitly.
+const NBSP = '\u00a0';
+
+describe('detectMentionQuery', () => {
+ describe('plain text (legacy / native paths)', () => {
+ it('returns the query after a leading @', () => {
+ expect(detectMentionQuery('@a')).toBe('a');
+ expect(detectMentionQuery('@alice')).toBe('alice');
+ });
+
+ it('returns the query after an @ at a word boundary', () => {
+ expect(detectMentionQuery('hello @bob')).toBe('bob');
+ });
+
+ it('returns undefined with no @', () => {
+ expect(detectMentionQuery('hello world')).toBeUndefined();
+ });
+
+ it('returns undefined when @ is mid-token (e.g. an email)', () => {
+ expect(detectMentionQuery('me@example')).toBeUndefined();
+ });
+
+ it('terminates the mention on a trailing space', () => {
+ expect(detectMentionQuery('@bob ')).toBeUndefined();
+ });
+
+ it('terminates at the first space - no re-trigger after a completed mention', () => {
+ // After selecting a mention we insert "@name " as plain text; once the
+ // user keeps typing ("@name hello") the query must NOT reactivate.
+ expect(detectMentionQuery('@asdad hello')).toBeUndefined();
+ expect(detectMentionQuery('@asdad hello world
')).toBeUndefined();
+ });
+
+ it('treats a non-breaking space as a terminator too', () => {
+ // The committed mention "@nameĀ " must not be read as an active query.
+ expect(detectMentionQuery('@asdad' + NBSP)).toBeUndefined();
+ expect(detectMentionQuery('@asdad' + NBSP + 'hello
')).toBeUndefined();
+ });
+
+ it('still tracks a single token being typed', () => {
+ expect(detectMentionQuery('@asd
')).toBe('asd');
+ });
+
+ it('a second, fresh mention after a completed one is active', () => {
+ expect(detectMentionQuery('@asdad hello @bo
')).toBe('bo');
+ });
+ });
+
+ // The web (tiptap) editor - and react-native-enriched generally - emit the
+ // value wrapped in block elements (e.g. `...
`). The
+ // `` becomes a trailing newline in plain text, which previously made the
+ // detector bail and the mention popup never appear on web.
+ describe('block-wrapped HTML (real editor output)', () => {
+ it('detects a mention in -wrapped HTML', () => {
+ expect(detectMentionQuery('
@a
')).toBe('a');
+ expect(detectMentionQuery('@alice
')).toBe('alice');
+ });
+
+ it('detects a mention in the web build full-document HTML', () => {
+ expect(detectMentionQuery('@a
')).toBe('a');
+ expect(detectMentionQuery('hello @bob
')).toBe('bob');
+ });
+
+ it('still terminates on a trailing space inside block HTML', () => {
+ expect(detectMentionQuery('@bob
')).toBeUndefined();
+ });
+
+ it('does not trigger when the @ is on an earlier line/paragraph', () => {
+ // User typed "@foo", pressed enter, and is now typing on a new line.
+ expect(detectMentionQuery('@foo
bar
')).toBeUndefined();
+ });
+
+ it('detects a mention typed on a later line', () => {
+ expect(detectMentionQuery('line one
@bob
')).toBe('bob');
+ });
+ });
+});
+
+describe('replaceActiveMention', () => {
+ it('replaces the @query inline in block-wrapped HTML (no new line)', () => {
+ // Regression: previously produced "@a
@audrey" which
+ // re-parsed to "@a\n@audrey".
+ expect(replaceActiveMention('@a
', 'audrey')).toBe('@audrey' + NBSP + '
');
+ expect(replaceActiveMention('@a
', 'audrey')).toBe('@audrey' + NBSP + '
');
+ });
+
+ it('replaces the @query in plain text', () => {
+ expect(replaceActiveMention('@a', 'audrey')).toBe('@audrey' + NBSP);
+ expect(replaceActiveMention('hello @bo', 'Bob Smith')).toBe('hello @Bob Smith' + NBSP);
+ });
+
+ it('keeps text before the mention intact', () => {
+ expect(replaceActiveMention('great point @al
', 'Alice')).toBe('great point @Alice' + NBSP + '
');
+ });
+
+ it('handles a bare @ (empty query)', () => {
+ expect(replaceActiveMention('hi @
', 'x')).toBe('hi @x' + NBSP + '
');
+ });
+
+ it('escapes HTML-significant characters in the label', () => {
+ expect(replaceActiveMention('@a
', 'a&c')).toBe('@a<b>&c' + NBSP + '
');
+ });
+
+ it('ends with a non-breaking space so the next keystroke does not re-trigger', () => {
+ const result = replaceActiveMention('@as
', 'asdad');
+ expect(result).toBe('@asdad' + NBSP + '
');
+ // detection on the committed value must be inactive
+ expect(detectMentionQuery(result)).toBeUndefined();
+ });
+});
+
+describe('htmlToPlainText', () => {
+ it('strips tags and decodes entities', () => {
+ expect(htmlToPlainText('a & b
')).toBe('a & b\n');
+ expect(htmlToPlainText('')).toBe('');
+ });
+});
diff --git a/src/services/mention-detection.ts b/src/services/mention-detection.ts
new file mode 100644
index 0000000..661de04
--- /dev/null
+++ b/src/services/mention-detection.ts
@@ -0,0 +1,78 @@
+// Pure helpers for detecting an in-progress `@mention` from the rich-text HTML
+// the comment editor emits. Kept dependency-free (no react-native) so they can
+// be unit-tested directly and shared across platforms.
+
+// Non-breaking space inserted after a committed mention. A regular trailing
+// space collapses in HTML (the editor trims "@name
"), which would let
+// the user's next keystrokes attach to the name and re-trigger detection. NBSP
+// is preserved and still counts as whitespace for the regexes below.
+const MENTION_TRAILING_SPACE = '\u00a0';
+
+/**
+ * Strip simple HTML tags / decode common entities so we can detect `@...` triggers
+ * in rich-text HTML the editor emits. Comment editors typically wrap text in
+ * /
with breaks; we just need readable text for the trigger regex.
+ */
+export function htmlToPlainText(html: string): string {
+ if (!html) return '';
+ const stripped = html
+ .replace(/
(\n)?/gi, '\n')
+ .replace(/<\/(p|div|li)>/gi, '\n')
+ .replace(/<[^>]+>/g, '');
+ return stripped
+ .replace(/ /g, ' ')
+ .replace(/&/g, '&')
+ .replace(/</g, '<')
+ .replace(/>/g, '>')
+ .replace(/"/g, '"')
+ .replace(/'/g, "'");
+}
+
+/**
+ * Returns the active mention query (text after the most recent `@` that starts
+ * a token) or undefined when no mention is active. The query is a single token:
+ * any whitespace after the `@` ends it.
+ */
+export function detectMentionQuery(value: string): string | undefined {
+ // Block elements (,
, ) become newlines in plain text, so the
+ // editor's value almost always ends in one (`@a
` -> "@a\n"). That
+ // trailing newline is structural, not typed, but the whitespace guard below
+ // would treat it as "the mention ended" - which is why the popup never showed
+ // on web/native rich-text. Drop trailing newlines (only) before detecting.
+ const text = htmlToPlainText(value).replace(/\n+$/, '');
+ const atIdx = text.lastIndexOf('@');
+ if (atIdx === -1) return undefined;
+ if (atIdx > 0) {
+ const prev = text.charAt(atIdx - 1);
+ if (!/\s/.test(prev)) return undefined;
+ }
+ const after = text.substring(atIdx + 1);
+ // Any whitespace after the `@` ends the trigger token. This dismisses on a
+ // trailing space and - importantly - stops the popup from reactivating when
+ // the user keeps typing past a completed mention (we insert mentions as plain
+ // "@name " text, so the old `@name` would otherwise keep matching).
+ if (/\s/.test(after)) return undefined;
+ return after;
+}
+
+/**
+ * Replace the active `@query` in the editor's value with the committed mention
+ * (`@label` + a non-breaking space). Operates on the literal value string so it
+ * works for both plain text and the block-wrapped HTML the rich editor emits.
+ * The previous end-anchored regex failed on HTML like `@a
`
+ * (the `@a` isn't at the end), fell through to appending, and the appended text
+ * re-parsed onto a new line ("@a\n@label"). Splicing at the located `@query`
+ * keeps the mention inline.
+ */
+export function replaceActiveMention(value: string, label: string): string {
+ const escLabel = label
+ .replace(/&/g, '&')
+ .replace(//g, '>');
+ const replacement = '@' + escLabel + MENTION_TRAILING_SPACE;
+ const query = detectMentionQuery(value);
+ const needle = query !== undefined ? '@' + query : '@';
+ const lastIdx = value.lastIndexOf(needle);
+ if (lastIdx === -1) return value + replacement;
+ return value.substring(0, lastIdx) + replacement + value.substring(lastIdx + needle.length);
+}
diff --git a/tests-ui/framework/mocks/react-native-enriched.tsx b/tests-ui/framework/mocks/react-native-enriched.tsx
index 2e7af8a..bfa6286 100644
--- a/tests-ui/framework/mocks/react-native-enriched.tsx
+++ b/tests-ui/framework/mocks/react-native-enriched.tsx
@@ -22,6 +22,7 @@ export type EnrichedTextInputInstance = {
toggleItalic: () => void;
toggleUnderline: () => void;
toggleStrikeThrough: () => void;
+ toggleInlineCode: () => void;
};
export type OnChangeStateEvent = {
@@ -29,6 +30,7 @@ export type OnChangeStateEvent = {
italic?: { isActive?: boolean };
underline?: { isActive?: boolean };
strikeThrough?: { isActive?: boolean };
+ inlineCode?: { isActive?: boolean };
};
export interface EnrichedTextInputProps {
@@ -60,6 +62,7 @@ export const EnrichedTextInput = forwardRef {},
toggleUnderline: () => {},
toggleStrikeThrough: () => {},
+ toggleInlineCode: () => {},
}));
return (
diff --git a/tests-ui/specs/mentions.test.tsx b/tests-ui/specs/mentions.test.tsx
index 9a2f03e..75373d2 100644
--- a/tests-ui/specs/mentions.test.tsx
+++ b/tests-ui/specs/mentions.test.tsx
@@ -52,8 +52,9 @@ maybe('Mention UI tests', () => {
label: 'commentInput visible',
});
- // Type "@Tester a" to trigger the mention search.
- fireEvent.changeText(getByTestId('commentInput'), '@Tester a');
+ // Type "@Tester" to trigger the mention search (the query is a single
+ // token - a space ends it - and "Tester" prefix-matches all seeded users).
+ fireEvent.changeText(getByTestId('commentInput'), '@Tester');
// Wait for the popup to appear.
await pollUntil(() => !!queryByTestId('mentionPopup'), {
@@ -118,14 +119,14 @@ maybe('Mention UI tests', () => {
});
// Trigger the mention search.
- fireEvent.changeText(getByTestId('commentInput'), '@Tester a');
+ fireEvent.changeText(getByTestId('commentInput'), '@Tester');
await pollUntil(() => !!queryByTestId('mentionPopup'), {
timeoutMs: 15000,
label: 'mentionPopup visible',
});
// Type a trailing space; popup should be dismissed.
- fireEvent.changeText(getByTestId('commentInput'), '@Tester a ');
+ fireEvent.changeText(getByTestId('commentInput'), '@Tester ');
await pollUntil(() => queryByTestId('mentionPopup') === null, {
timeoutMs: 5000,
label: 'mentionPopup dismissed after trailing space',
diff --git a/yarn.lock b/yarn.lock
index 238d28b..b00d312 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1081,6 +1081,26 @@
resolved "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz"
integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==
+"@floating-ui/core@^1.7.5":
+ version "1.7.5"
+ resolved "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.5.tgz"
+ integrity sha512-1Ih4WTWyw0+lKyFMcBHGbb5U5FtuHJuujoyyr5zTaWS5EYMeT6Jb2AuDeftsCsEuchO+mM2ij5+q9crhydzLhQ==
+ dependencies:
+ "@floating-ui/utils" "^0.2.11"
+
+"@floating-ui/dom@^1.0.0":
+ version "1.7.6"
+ resolved "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.6.tgz"
+ integrity sha512-9gZSAI5XM36880PPMm//9dfiEngYoC6Am2izES1FF406YFsjvyBMmeJ2g4SAju3xWwtuynNRFL2s9hgxpLI5SQ==
+ dependencies:
+ "@floating-ui/core" "^1.7.5"
+ "@floating-ui/utils" "^0.2.11"
+
+"@floating-ui/utils@^0.2.11":
+ version "0.2.11"
+ resolved "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.11.tgz"
+ integrity sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg==
+
"@hapi/hoek@^9.0.0", "@hapi/hoek@^9.3.0":
version "9.3.0"
resolved "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz"
@@ -1621,6 +1641,11 @@
resolved "https://registry.npmjs.org/@react-native/polyfills/-/polyfills-2.0.0.tgz"
integrity sha512-K0aGNn1TjalKj+65D7ycc1//H9roAQ51GJVk5ZJQFb2teECGmzd86bYDC0aYdbRf7gtovescq4Zt6FR0tgXiHQ==
+"@remirror/core-constants@3.0.0":
+ version "3.0.0"
+ resolved "https://registry.npmjs.org/@remirror/core-constants/-/core-constants-3.0.0.tgz"
+ integrity sha512-42aWfPrimMfDKDi4YegyS7x+/0tlzaqwPQCULLanv3DMIlu96KTJR0fM5isWX2UViOqlGnX6YFgqWepcX+XMNg==
+
"@sideway/address@^4.1.5":
version "4.1.5"
resolved "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz"
@@ -1666,6 +1691,126 @@
pretty-format "^29.7.0"
redent "^3.0.0"
+"@tiptap/core@3.20.4":
+ version "3.20.4"
+ resolved "https://registry.npmjs.org/@tiptap/core/-/core-3.20.4.tgz"
+ integrity sha512-3i/DG89TFY/b34T5P+j35UcjYuB5d3+9K8u6qID+iUqNPiza015HPIZLuPfE5elNwVdV3EXIoPo0LLeBLgXXAg==
+
+"@tiptap/extension-blockquote@3.20.4":
+ version "3.20.4"
+ resolved "https://registry.npmjs.org/@tiptap/extension-blockquote/-/extension-blockquote-3.20.4.tgz"
+ integrity sha512-9sskyyhYj2oKat//lyZVXCp9YrPt4oJAZnGHYWXS0xlskjsLElrfKKlM4vpbhGss3VrhQRoEGqWLnIaJYPF1zw==
+
+"@tiptap/extension-bold@3.20.4":
+ version "3.20.4"
+ resolved "https://registry.npmjs.org/@tiptap/extension-bold/-/extension-bold-3.20.4.tgz"
+ integrity sha512-Md7/mNAeJCY+VLJc8JRGI+8XkVPKiOGB1NgqQPdh3aYtxXQDChQOZoJEQl6TuudDxZ85bLZB67NjZlx3jo8/0g==
+
+"@tiptap/extension-bubble-menu@^3.20.4":
+ version "3.24.0"
+ resolved "https://registry.npmjs.org/@tiptap/extension-bubble-menu/-/extension-bubble-menu-3.24.0.tgz"
+ integrity sha512-jRXD+JPu9ayvq78g8hsCxx4q/qUFtrdfIYirRSf5YUseuuUbtfrq83AsGabcygpUTefjJkMQoXNITkh6294Ggw==
+ dependencies:
+ "@floating-ui/dom" "^1.0.0"
+
+"@tiptap/extension-code@3.20.4":
+ version "3.20.4"
+ resolved "https://registry.npmjs.org/@tiptap/extension-code/-/extension-code-3.20.4.tgz"
+ integrity sha512-7j8Hi964bH1SZ9oLdZC1fkqWz27mliSDV7M8lmL/M14+Qw42D/VOAKS4Aw9OCFtHMlTsjLR6qsoVxL8Lpkt6NA==
+
+"@tiptap/extension-document@3.20.4":
+ version "3.20.4"
+ resolved "https://registry.npmjs.org/@tiptap/extension-document/-/extension-document-3.20.4.tgz"
+ integrity sha512-zF1CIFVLt8MfSpWWnPwtGyxPOsT0xYM2qJKcXf2yZcTG37wDKmUi6heG53vGigIavbQlLaAFvs+1mNdOu2x/0A==
+
+"@tiptap/extension-floating-menu@^3.20.4":
+ version "3.24.0"
+ resolved "https://registry.npmjs.org/@tiptap/extension-floating-menu/-/extension-floating-menu-3.24.0.tgz"
+ integrity sha512-7QEbf3mUzFAkejjQGX9f0L507oMtnOBRwHt2skUTR+9yXgudsN8zaDBSSRHLeMWGk9b7L293ZMA6zCRrZaHrfA==
+
+"@tiptap/extension-heading@3.20.4":
+ version "3.20.4"
+ resolved "https://registry.npmjs.org/@tiptap/extension-heading/-/extension-heading-3.20.4.tgz"
+ integrity sha512-xsnkmTGggJc5P2iCwS1lv8KFG31xC/GNPJKoi/3UH67j/lKDhA3AdtshsLeyv2FKtTtYDb8oV0IqzHB1MM6a7w==
+
+"@tiptap/extension-italic@3.20.4":
+ version "3.20.4"
+ resolved "https://registry.npmjs.org/@tiptap/extension-italic/-/extension-italic-3.20.4.tgz"
+ integrity sha512-4ZqiWr7cmqPFux8tj1ZLiYytyWf343IvQemNX6AvVWvscrJcrfj3YX4Le2BA0RW3A3M6RpLQXXozuF8vxYFDeQ==
+
+"@tiptap/extension-link@3.20.4":
+ version "3.20.4"
+ resolved "https://registry.npmjs.org/@tiptap/extension-link/-/extension-link-3.20.4.tgz"
+ integrity sha512-JNDSkWrVdb8NSvbQXwHWvK5tCMbTWwOHFOweknQZ1JPK4dei9FJVofYQaHyW4bJBdcCjds3NZSnXE8DM9iAWmg==
+ dependencies:
+ linkifyjs "^4.3.2"
+
+"@tiptap/extension-list@3.20.4":
+ version "3.20.4"
+ resolved "https://registry.npmjs.org/@tiptap/extension-list/-/extension-list-3.20.4.tgz"
+ integrity sha512-X+5plTKhOioNcQ4KsAFJJSb/3+zR8Xhdpow4HzXtoV1KcbdDey1fhZdpsfkbrzCL0s6/wAgwZuAchCK7HujurQ==
+
+"@tiptap/extension-paragraph@3.20.4":
+ version "3.20.4"
+ resolved "https://registry.npmjs.org/@tiptap/extension-paragraph/-/extension-paragraph-3.20.4.tgz"
+ integrity sha512-lm6fOScWuZAF/Sfp97igUwFd3L1QHIVLAWP5NVdh0DTLrEIt4rMBmsww+yOpMQRhvz2uTgMbMXynrimhzi/QVw==
+
+"@tiptap/extension-strike@3.20.4":
+ version "3.20.4"
+ resolved "https://registry.npmjs.org/@tiptap/extension-strike/-/extension-strike-3.20.4.tgz"
+ integrity sha512-It1Px9uDGTsVqyyg6cy7DigLoenljpQwqdI0jssM7QclZrHnsrye9fZxBBiiuCzzV1305MxKgHvratkHwqmVNA==
+
+"@tiptap/extension-text@3.20.4":
+ version "3.20.4"
+ resolved "https://registry.npmjs.org/@tiptap/extension-text/-/extension-text-3.20.4.tgz"
+ integrity sha512-jchJcBZixDEO2J66Zx5dchsI2mA6IYsROqF8P1poxL4ienH7RVQRCTsBNnSfIeOtREKKWeOU/tEs5fcpvvGwIQ==
+
+"@tiptap/extension-underline@3.20.4":
+ version "3.20.4"
+ resolved "https://registry.npmjs.org/@tiptap/extension-underline/-/extension-underline-3.20.4.tgz"
+ integrity sha512-0OjMc3FDujX16G+jhvqcY/mLot8SrNtDu8ggUwNLAfiI/QIvMVgk7giFD71DATC/4Nb8i/iwAEegTD8MxBIXCg==
+
+"@tiptap/extensions@3.20.4":
+ version "3.20.4"
+ resolved "https://registry.npmjs.org/@tiptap/extensions/-/extensions-3.20.4.tgz"
+ integrity sha512-8p6hVT65DjuQjtEdlH6ewX9SOJHlVQAOee3sWIJQmeJNRnZNvqPIBLleebUqDiljNTpxBv6s6QWkSTKgf3btwg==
+
+"@tiptap/pm@3.20.4":
+ version "3.20.4"
+ resolved "https://registry.npmjs.org/@tiptap/pm/-/pm-3.20.4.tgz"
+ integrity sha512-rCHYSBToilBEuI6PtjziHDdRkABH/XqwJ7dG4Amn/SD3yGiZKYCiEApQlTUS2zZeo8DsLeuqqqB4vEOeD4OEPg==
+ dependencies:
+ prosemirror-changeset "^2.3.0"
+ prosemirror-collab "^1.3.1"
+ prosemirror-commands "^1.6.2"
+ prosemirror-dropcursor "^1.8.1"
+ prosemirror-gapcursor "^1.3.2"
+ prosemirror-history "^1.4.1"
+ prosemirror-inputrules "^1.4.0"
+ prosemirror-keymap "^1.2.2"
+ prosemirror-markdown "^1.13.1"
+ prosemirror-menu "^1.2.4"
+ prosemirror-model "^1.24.1"
+ prosemirror-schema-basic "^1.2.3"
+ 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.38.1"
+
+"@tiptap/react@3.20.4":
+ version "3.20.4"
+ resolved "https://registry.npmjs.org/@tiptap/react/-/react-3.20.4.tgz"
+ integrity sha512-1B8iWsHWwb5TeyVaUs8BRPzwWo4PsLQcl03urHaz0zTJ8DauopqvxzV3+lem1OkzRHn7wnrapDvwmIGoROCaQw==
+ dependencies:
+ "@types/use-sync-external-store" "^0.0.6"
+ fast-equals "^5.3.3"
+ use-sync-external-store "^1.4.0"
+ optionalDependencies:
+ "@tiptap/extension-bubble-menu" "^3.20.4"
+ "@tiptap/extension-floating-menu" "^3.20.4"
+
"@types/babel__core@^7.1.14":
version "7.1.19"
resolved "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.19.tgz"
@@ -1733,11 +1878,29 @@
expect "^29.0.0"
pretty-format "^29.0.0"
+"@types/linkify-it@^5":
+ version "5.0.0"
+ resolved "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz"
+ integrity sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==
+
"@types/lodash@^4.14.184":
version "4.14.185"
resolved "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.185.tgz"
integrity sha512-evMDG1bC4rgQg4ku9tKpuMh5iBNEwNa3tf9zRHdP1qlv+1WUg44xat4IxCE14gIpZRGUUWAx2VhItCZc25NfMA==
+"@types/markdown-it@^14.0.0":
+ version "14.1.2"
+ resolved "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-14.1.2.tgz"
+ integrity sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==
+ dependencies:
+ "@types/linkify-it" "^5"
+ "@types/mdurl" "^2"
+
+"@types/mdurl@^2":
+ version "2.0.0"
+ resolved "https://registry.npmjs.org/@types/mdurl/-/mdurl-2.0.0.tgz"
+ integrity sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==
+
"@types/node@*":
version "18.7.18"
resolved "https://registry.npmjs.org/@types/node/-/node-18.7.18.tgz"
@@ -1795,6 +1958,11 @@
resolved "https://registry.npmjs.org/@types/urijs/-/urijs-1.19.19.tgz"
integrity sha512-FDJNkyhmKLw7uEvTxx5tSXfPeQpO0iy73Ry+PmYZJvQy0QIWX8a7kJ4kLWRf+EbTPJEPDSgPXHaM7pzr5lmvCg==
+"@types/use-sync-external-store@^0.0.6":
+ version "0.0.6"
+ resolved "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.6.tgz"
+ integrity sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==
+
"@types/ws@^8.18.1":
version "8.18.1"
resolved "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz"
@@ -1933,6 +2101,11 @@ argparse@^1.0.7:
dependencies:
sprintf-js "~1.0.2"
+argparse@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz"
+ integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==
+
arr-diff@^4.0.0:
version "4.0.0"
resolved "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz"
@@ -2612,6 +2785,11 @@ cosmiconfig@^7.0.1:
path-type "^4.0.0"
yaml "^1.10.0"
+crelt@^1.0.0:
+ version "1.0.6"
+ resolved "https://registry.npmjs.org/crelt/-/crelt-1.0.6.tgz"
+ integrity sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==
+
cross-spawn@^6.0.0:
version "6.0.5"
resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz"
@@ -2901,6 +3079,11 @@ entities@^3.0.1:
resolved "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz"
integrity sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==
+entities@^4.4.0:
+ version "4.5.0"
+ resolved "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz"
+ integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==
+
envinfo@^7.7.2:
version "7.14.0"
resolved "https://registry.npmjs.org/envinfo/-/envinfo-7.14.0.tgz"
@@ -2948,6 +3131,11 @@ escape-string-regexp@^2.0.0:
resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz"
integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==
+escape-string-regexp@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz"
+ integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==
+
esprima@^4.0.0, esprima@~4.0.0:
version "4.0.1"
resolved "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz"
@@ -2968,11 +3156,6 @@ event-target-shim@^5.0.0, event-target-shim@^5.0.1:
resolved "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz"
integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==
-eventemitter3@^5.0.1:
- version "5.0.4"
- resolved "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz"
- integrity sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==
-
execa@^1.0.0:
version "1.0.0"
resolved "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz"
@@ -3074,10 +3257,10 @@ extglob@^2.0.4:
snapdragon "^0.8.1"
to-regex "^3.0.1"
-fast-diff@^1.3.0:
- version "1.3.0"
- resolved "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz"
- integrity sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==
+fast-equals@^5.3.3:
+ version "5.4.0"
+ resolved "https://registry.npmjs.org/fast-equals/-/fast-equals-5.4.0.tgz"
+ integrity sha512-jt2DW/aNFNwke7AUd+Z+e6pz39KO5rzdbbFCg2sGafS4mk13MI7Z8O5z9cADNn5lhGODIgLwug6TZO2ctf7kcw==
fast-glob@^2.0.2:
version "2.2.7"
@@ -3108,7 +3291,7 @@ fast-json-stable-stringify@^2.1.0, fast-json-stable-stringify@2.x:
integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==
"fastcomments-sdk@file:../fastcomments-sdk-js":
- version "3.2.2"
+ version "3.2.3"
resolved "file:../fastcomments-sdk-js"
fastcomments-typescript@^3.0.0:
@@ -4500,6 +4683,18 @@ lines-and-columns@^1.1.6:
resolved "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz"
integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==
+linkify-it@^5.0.1:
+ version "5.0.1"
+ resolved "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.1.tgz"
+ integrity sha512-wVoTjP4Q6R0NW5hiZkVJaFZPWgtXfoGF+6LucL3/FtiNjmcHhYjEr5f1Kqjirc1nBW07J/ZuRFumqr2oqccEWg==
+ dependencies:
+ uc.micro "^2.0.0"
+
+linkifyjs@^4.3.2:
+ version "4.3.3"
+ resolved "https://registry.npmjs.org/linkifyjs/-/linkifyjs-4.3.3.tgz"
+ integrity sha512-P8aEP5U/D1/IlTY2OeYsErdwh9bGuLE30NcXtKEjgdHcahveQoQwM2yZNsioQHsWFz0P7KKudisbrzCgR0sDHg==
+
load-json-file@^4.0.0:
version "4.0.0"
resolved "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz"
@@ -4540,26 +4735,11 @@ locate-path@^6.0.0:
dependencies:
p-locate "^5.0.0"
-lodash-es@^4.17.21:
- version "4.18.1"
- resolved "https://registry.npmjs.org/lodash-es/-/lodash-es-4.18.1.tgz"
- integrity sha512-J8xewKD/Gk22OZbhpOVSwcs60zhd95ESDwezOFuA3/099925PdHJ7OFHNTGtajL3AlZkykD32HykiMo+BIBI8A==
-
-lodash.clonedeep@^4.5.0:
- version "4.5.0"
- resolved "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz"
- integrity sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==
-
lodash.debounce@^4.0.8:
version "4.0.8"
resolved "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz"
integrity sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==
-lodash.isequal@^4.5.0:
- version "4.5.0"
- resolved "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz"
- integrity sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==
-
lodash.memoize@4.x:
version "4.1.2"
resolved "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz"
@@ -4663,6 +4843,23 @@ map-visit@^1.0.0:
dependencies:
object-visit "^1.0.0"
+markdown-it@^14.0.0:
+ version "14.2.0"
+ resolved "https://registry.npmjs.org/markdown-it/-/markdown-it-14.2.0.tgz"
+ integrity sha512-1TGiQiJVRQ3NPmZH6sx5Cfnmg6GQm9jvC1ch4TK511NjSJvjzKLzn5pPfZRNZkRPZP0HqCioSndqH8v2nRaWVQ==
+ dependencies:
+ argparse "^2.0.1"
+ entities "^4.4.0"
+ linkify-it "^5.0.1"
+ mdurl "^2.0.0"
+ punycode.js "^2.3.1"
+ uc.micro "^2.1.0"
+
+mdurl@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz"
+ integrity sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==
+
memoize-one@^5.0.0:
version "5.2.1"
resolved "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz"
@@ -5444,6 +5641,11 @@ ora@^5.4.1:
strip-ansi "^6.0.0"
wcwidth "^1.0.1"
+orderedmap@^2.0.0:
+ version "2.1.1"
+ resolved "https://registry.npmjs.org/orderedmap/-/orderedmap-2.1.1.tgz"
+ integrity sha512-TvAWxi0nDe1j/rtMcWcIj94+Ffe6n7zhow33h40SKxmsmozs6dz/e+EajymfoFcHd7sxNn8yHM8839uixMOV6g==
+
os-tmpdir@^1.0.0:
version "1.0.2"
resolved "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz"
@@ -5527,11 +5729,6 @@ p-try@^2.0.0:
resolved "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz"
integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==
-parchment@^3.0.0:
- version "3.0.0"
- resolved "https://registry.npmjs.org/parchment/-/parchment-3.0.0.tgz"
- integrity sha512-HUrJFQ/StvgmXRcQ1ftY6VEZUq3jA2t9ncFN4F84J/vN0/FPpQF+8FKXb3l6fLces6q0uOHj6NJn+2xvZnxO6A==
-
parent-module@^1.0.0:
version "1.0.1"
resolved "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz"
@@ -5757,6 +5954,160 @@ prop-types@^15.5.7:
object-assign "^4.1.1"
react-is "^16.13.1"
+prosemirror-changeset@^2.3.0:
+ version "2.4.1"
+ resolved "https://registry.npmjs.org/prosemirror-changeset/-/prosemirror-changeset-2.4.1.tgz"
+ integrity sha512-96WBLhOaYhJ+kPhLg3uW359Tz6I/MfcrQfL4EGv4SrcqKEMC1gmoGrXHecPE8eOwTVCJ4IwgfzM8fFad25wNfw==
+ dependencies:
+ prosemirror-transform "^1.0.0"
+
+prosemirror-collab@^1.3.1:
+ version "1.3.1"
+ resolved "https://registry.npmjs.org/prosemirror-collab/-/prosemirror-collab-1.3.1.tgz"
+ integrity sha512-4SnynYR9TTYaQVXd/ieUvsVV4PDMBzrq2xPUWutHivDuOshZXqQ5rGbZM84HEaXKbLdItse7weMGOUdDVcLKEQ==
+ dependencies:
+ prosemirror-state "^1.0.0"
+
+prosemirror-commands@^1.0.0, prosemirror-commands@^1.6.2:
+ version "1.7.1"
+ resolved "https://registry.npmjs.org/prosemirror-commands/-/prosemirror-commands-1.7.1.tgz"
+ integrity sha512-rT7qZnQtx5c0/y/KlYaGvtG411S97UaL6gdp6RIZ23DLHanMYLyfGBV5DtSnZdthQql7W+lEVbpSfwtO8T+L2w==
+ dependencies:
+ prosemirror-model "^1.0.0"
+ prosemirror-state "^1.0.0"
+ prosemirror-transform "^1.10.2"
+
+prosemirror-dropcursor@^1.8.1:
+ version "1.8.2"
+ resolved "https://registry.npmjs.org/prosemirror-dropcursor/-/prosemirror-dropcursor-1.8.2.tgz"
+ integrity sha512-CCk6Gyx9+Tt2sbYk5NK0nB1ukHi2ryaRgadV/LvyNuO3ena1payM2z6Cg0vO1ebK8cxbzo41ku2DE5Axj1Zuiw==
+ dependencies:
+ prosemirror-state "^1.0.0"
+ prosemirror-transform "^1.1.0"
+ prosemirror-view "^1.1.0"
+
+prosemirror-gapcursor@^1.3.2:
+ version "1.4.1"
+ resolved "https://registry.npmjs.org/prosemirror-gapcursor/-/prosemirror-gapcursor-1.4.1.tgz"
+ integrity sha512-pMdYaEnjNMSwl11yjEGtgTmLkR08m/Vl+Jj443167p9eB3HVQKhYCc4gmHVDsLPODfZfjr/MmirsdyZziXbQKw==
+ dependencies:
+ prosemirror-keymap "^1.0.0"
+ prosemirror-model "^1.0.0"
+ prosemirror-state "^1.0.0"
+ prosemirror-view "^1.0.0"
+
+prosemirror-history@^1.0.0, prosemirror-history@^1.4.1:
+ version "1.5.0"
+ resolved "https://registry.npmjs.org/prosemirror-history/-/prosemirror-history-1.5.0.tgz"
+ integrity sha512-zlzTiH01eKA55UAf1MEjtssJeHnGxO0j4K4Dpx+gnmX9n+SHNlDqI2oO1Kv1iPN5B1dm5fsljCfqKF9nFL6HRg==
+ dependencies:
+ prosemirror-state "^1.2.2"
+ prosemirror-transform "^1.0.0"
+ prosemirror-view "^1.31.0"
+ rope-sequence "^1.3.0"
+
+prosemirror-inputrules@^1.4.0:
+ version "1.5.1"
+ resolved "https://registry.npmjs.org/prosemirror-inputrules/-/prosemirror-inputrules-1.5.1.tgz"
+ integrity sha512-7wj4uMjKaXWAQ1CDgxNzNtR9AlsuwzHfdFH1ygEHA2KHF2DOEaXl1CJfNPAKCg9qNEh4rum975QLaCiQPyY6Fw==
+ dependencies:
+ prosemirror-state "^1.0.0"
+ prosemirror-transform "^1.0.0"
+
+prosemirror-keymap@^1.0.0, prosemirror-keymap@^1.2.2, prosemirror-keymap@^1.2.3:
+ version "1.2.3"
+ resolved "https://registry.npmjs.org/prosemirror-keymap/-/prosemirror-keymap-1.2.3.tgz"
+ integrity sha512-4HucRlpiLd1IPQQXNqeo81BGtkY8Ai5smHhKW9jjPKRc2wQIxksg7Hl1tTI2IfT2B/LgX6bfYvXxEpJl7aKYKw==
+ dependencies:
+ prosemirror-state "^1.0.0"
+ w3c-keyname "^2.2.0"
+
+prosemirror-markdown@^1.13.1:
+ version "1.13.4"
+ resolved "https://registry.npmjs.org/prosemirror-markdown/-/prosemirror-markdown-1.13.4.tgz"
+ integrity sha512-D98dm4cQ3Hs6EmjK500TdAOew4Z03EV71ajEFiWra3Upr7diytJsjF4mPV2dW+eK5uNectiRj0xFxYI9NLXDbw==
+ dependencies:
+ "@types/markdown-it" "^14.0.0"
+ markdown-it "^14.0.0"
+ prosemirror-model "^1.25.0"
+
+prosemirror-menu@^1.2.4:
+ version "1.3.2"
+ resolved "https://registry.npmjs.org/prosemirror-menu/-/prosemirror-menu-1.3.2.tgz"
+ integrity sha512-6VgUJTYod0nMBlCaYJGhXGLu7Gt4AvcwcOq0YfJCY/6Uh+3S7UsWhpy6rJFCBFOmonq1hD8KyWOtZhkppd4YPg==
+ dependencies:
+ crelt "^1.0.0"
+ prosemirror-commands "^1.0.0"
+ prosemirror-history "^1.0.0"
+ prosemirror-state "^1.0.0"
+
+prosemirror-model@^1.0.0, prosemirror-model@^1.20.0, prosemirror-model@^1.21.0, prosemirror-model@^1.24.1, prosemirror-model@^1.25.0, prosemirror-model@^1.25.4:
+ version "1.25.7"
+ resolved "https://registry.npmjs.org/prosemirror-model/-/prosemirror-model-1.25.7.tgz"
+ integrity sha512-A79aN8QEFUwI6cax8Yq4Rpcx1TJZ3Kagn+ii7qLo4/V8H3mMiHrhFyhTyHHvpSnOgMPpWiDGSwM3etwrxE50ug==
+ dependencies:
+ orderedmap "^2.0.0"
+
+prosemirror-schema-basic@^1.2.3:
+ version "1.2.4"
+ resolved "https://registry.npmjs.org/prosemirror-schema-basic/-/prosemirror-schema-basic-1.2.4.tgz"
+ integrity sha512-ELxP4TlX3yr2v5rM7Sb70SqStq5NvI15c0j9j/gjsrO5vaw+fnnpovCLEGIcpeGfifkuqJwl4fon6b+KdrODYQ==
+ dependencies:
+ prosemirror-model "^1.25.0"
+
+prosemirror-schema-list@^1.5.0:
+ version "1.5.1"
+ resolved "https://registry.npmjs.org/prosemirror-schema-list/-/prosemirror-schema-list-1.5.1.tgz"
+ integrity sha512-927lFx/uwyQaGwJxLWCZRkjXG0p48KpMj6ueoYiu4JX05GGuGcgzAy62dfiV8eFZftgyBUvLx76RsMe20fJl+Q==
+ dependencies:
+ prosemirror-model "^1.0.0"
+ prosemirror-state "^1.0.0"
+ prosemirror-transform "^1.7.3"
+
+prosemirror-state@^1.0.0, prosemirror-state@^1.2.2, prosemirror-state@^1.4.3, prosemirror-state@^1.4.4:
+ version "1.4.4"
+ resolved "https://registry.npmjs.org/prosemirror-state/-/prosemirror-state-1.4.4.tgz"
+ integrity sha512-6jiYHH2CIGbCfnxdHbXZ12gySFY/fz/ulZE333G6bPqIZ4F+TXo9ifiR86nAHpWnfoNjOb3o5ESi7J8Uz1jXHw==
+ dependencies:
+ prosemirror-model "^1.0.0"
+ prosemirror-transform "^1.0.0"
+ prosemirror-view "^1.27.0"
+
+prosemirror-tables@^1.6.4:
+ version "1.8.5"
+ resolved "https://registry.npmjs.org/prosemirror-tables/-/prosemirror-tables-1.8.5.tgz"
+ integrity sha512-V/0cDCsHKHe/tfWkeCmthNUcEp1IVO3p6vwN8XtwE9PZQLAZJigbw3QoraAdfJPir4NKJtNvOB8oYGKRl+t0Dw==
+ dependencies:
+ prosemirror-keymap "^1.2.3"
+ prosemirror-model "^1.25.4"
+ prosemirror-state "^1.4.4"
+ prosemirror-transform "^1.10.5"
+ prosemirror-view "^1.41.4"
+
+prosemirror-trailing-node@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.npmjs.org/prosemirror-trailing-node/-/prosemirror-trailing-node-3.0.0.tgz"
+ integrity sha512-xiun5/3q0w5eRnGYfNlW1uU9W6x5MoFKWwq/0TIRgt09lv7Hcser2QYV8t4muXbEr+Fwo0geYn79Xs4GKywrRQ==
+ dependencies:
+ "@remirror/core-constants" "3.0.0"
+ escape-string-regexp "^4.0.0"
+
+prosemirror-transform@^1.0.0, prosemirror-transform@^1.1.0, prosemirror-transform@^1.10.2, prosemirror-transform@^1.10.5, prosemirror-transform@^1.7.3:
+ version "1.12.0"
+ resolved "https://registry.npmjs.org/prosemirror-transform/-/prosemirror-transform-1.12.0.tgz"
+ integrity sha512-GxboyN4AMIsoHNtz5uf2r2Ru551i5hWeCMD6E2Ib4Eogqoub0NflniaBPVQ4MrGE5yZ8JV9tUHg9qcZTTrcN4w==
+ dependencies:
+ prosemirror-model "^1.21.0"
+
+prosemirror-view@^1.0.0, prosemirror-view@^1.1.0, prosemirror-view@^1.27.0, prosemirror-view@^1.31.0, prosemirror-view@^1.38.1, prosemirror-view@^1.41.4:
+ version "1.41.8"
+ resolved "https://registry.npmjs.org/prosemirror-view/-/prosemirror-view-1.41.8.tgz"
+ integrity sha512-TnKDdohEatgyZNGCDWIdccOHXhYloJwbwU+phw/a23KBvJIR9lWQWW7WHHK3vBdOLDNuF7TaX98GObUZOWkOnA==
+ dependencies:
+ prosemirror-model "^1.20.0"
+ prosemirror-state "^1.0.0"
+ prosemirror-transform "^1.1.0"
+
pump@^3.0.0:
version "3.0.0"
resolved "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz"
@@ -5765,6 +6116,11 @@ pump@^3.0.0:
end-of-stream "^1.1.0"
once "^1.3.1"
+punycode.js@^2.3.1:
+ version "2.3.1"
+ resolved "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz"
+ integrity sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==
+
queue-microtask@^1.2.2:
version "1.2.3"
resolved "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz"
@@ -5775,25 +6131,6 @@ quick-lru@^1.0.0:
resolved "https://registry.npmjs.org/quick-lru/-/quick-lru-1.1.0.tgz"
integrity sha512-tRS7sTgyxMXtLum8L65daJnHUhfDUgboRdcWW2bR9vBfrj2+O5HSMbQOJfJJjIVSPFqbBCF37FpwWXGitDc5tA==
-quill-delta@^5.1.0:
- version "5.1.0"
- resolved "https://registry.npmjs.org/quill-delta/-/quill-delta-5.1.0.tgz"
- integrity sha512-X74oCeRI4/p0ucjb5Ma8adTXd9Scumz367kkMK5V/IatcX6A0vlgLgKbzXWy5nZmCGeNJm2oQX0d2Eqj+ZIlCA==
- dependencies:
- fast-diff "^1.3.0"
- lodash.clonedeep "^4.5.0"
- lodash.isequal "^4.5.0"
-
-quill@^2.0.3, quill@~2.0.3:
- version "2.0.3"
- resolved "https://registry.npmjs.org/quill/-/quill-2.0.3.tgz"
- integrity sha512-xEYQBqfYx/sfb33VJiKnSJp8ehloavImQ2A6564GAbqG55PGw1dAWUn1MUbQB62t0azawUS2CZZhWCjO8gRvTw==
- dependencies:
- eventemitter3 "^5.0.1"
- lodash-es "^4.17.21"
- parchment "^3.0.0"
- quill-delta "^5.1.0"
-
ramda@^0.27.2:
version "0.27.2"
resolved "https://registry.npmjs.org/ramda/-/ramda-0.27.2.tgz"
@@ -5869,10 +6206,27 @@ react-native-codegen@^0.69.2:
jscodeshift "^0.13.1"
nullthrows "^1.1.1"
-react-native-enriched@^0.5.2:
- version "0.5.2"
- resolved "https://registry.npmjs.org/react-native-enriched/-/react-native-enriched-0.5.2.tgz"
- integrity sha512-9texMnu5+CXLCuVJv987UmzgB70F8Q3okOm2zqZ8jYSEz8IGyd7kbJdZ4J1rW99x3hYaeV+u+cSECzrCj7F4EA==
+react-native-enriched@^0.7.0:
+ version "0.7.0"
+ resolved "https://registry.npmjs.org/react-native-enriched/-/react-native-enriched-0.7.0.tgz"
+ integrity sha512-WrhaRUMM8HaV+6XwESS1k7i1/QxZb4K2lpELIxLTiXXMdUP5b9207AjXp6d8Op0XulvFNC8HJdDdanQZUUI6Zg==
+ dependencies:
+ "@tiptap/core" "3.20.4"
+ "@tiptap/extension-blockquote" "3.20.4"
+ "@tiptap/extension-bold" "3.20.4"
+ "@tiptap/extension-code" "3.20.4"
+ "@tiptap/extension-document" "3.20.4"
+ "@tiptap/extension-heading" "3.20.4"
+ "@tiptap/extension-italic" "3.20.4"
+ "@tiptap/extension-link" "3.20.4"
+ "@tiptap/extension-list" "3.20.4"
+ "@tiptap/extension-paragraph" "3.20.4"
+ "@tiptap/extension-strike" "3.20.4"
+ "@tiptap/extension-text" "3.20.4"
+ "@tiptap/extension-underline" "3.20.4"
+ "@tiptap/extensions" "3.20.4"
+ "@tiptap/pm" "3.20.4"
+ "@tiptap/react" "3.20.4"
react-native-gradle-plugin@^0.0.7:
version "0.0.7"
@@ -5933,14 +6287,6 @@ react-native@^0.69.4:
whatwg-fetch "^3.0.0"
ws "^6.1.4"
-react-quill-new@^3.8.3:
- version "3.8.3"
- resolved "https://registry.npmjs.org/react-quill-new/-/react-quill-new-3.8.3.tgz"
- integrity sha512-c96PYqFTo0pI4R3e79B3rH9LUIce1kIQbmTBu/imJQZk8305ogyLyBqKKjG2UoInDlquXqePSzmBo2aVia3ttw==
- dependencies:
- lodash-es "^4.17.21"
- quill "~2.0.3"
-
react-refresh@^0.4.0:
version "0.4.3"
resolved "https://registry.npmjs.org/react-refresh/-/react-refresh-0.4.3.tgz"
@@ -6201,6 +6547,11 @@ rimraf@~2.6.2:
dependencies:
glob "^7.1.3"
+rope-sequence@^1.3.0:
+ version "1.3.4"
+ resolved "https://registry.npmjs.org/rope-sequence/-/rope-sequence-1.3.4.tgz"
+ integrity sha512-UT5EDe2cu2E/6O4igUr5PSFs23nvvukicWHx6GnOPlHAiiYbzNuCRQCuiUdHJQcqKalLKlrYJnjY0ySGsXNQXQ==
+
run-parallel@^1.1.9:
version "1.2.0"
resolved "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz"
@@ -6852,6 +7203,11 @@ typescript@^4.7.4:
resolved "https://registry.npmjs.org/typescript/-/typescript-4.8.3.tgz"
integrity sha512-goMHfm00nWPa8UvR/CPSvykqf6dVV8x/dp0c5mFTMTIu0u0FlGWRioyy7Nn0PGAdHxpJZnuO/ut+PpQ8UiHAig==
+uc.micro@^2.0.0, uc.micro@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz"
+ integrity sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==
+
uglify-es@^3.1.9:
version "3.3.10"
resolved "https://registry.npmjs.org/uglify-es/-/uglify-es-3.3.10.tgz"
@@ -6939,10 +7295,10 @@ urix@^0.1.0:
resolved "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz"
integrity sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==
-use-sync-external-store@^1.0.0:
- version "1.2.0"
- resolved "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz"
- integrity sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==
+use-sync-external-store@^1.0.0, use-sync-external-store@^1.4.0:
+ version "1.6.0"
+ resolved "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz"
+ integrity sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==
use@^3.1.0:
version "3.1.1"
@@ -6986,6 +7342,11 @@ vlq@^1.0.0:
resolved "https://registry.npmjs.org/vlq/-/vlq-1.0.1.tgz"
integrity sha512-gQpnTgkubC6hQgdIcRdYGDSDc+SaujOdyesZQMv6JlfQee/9Mp0Qhnys6WxDWvQnL5WZdT7o2Ul187aSt0Rq+w==
+w3c-keyname@^2.2.0:
+ version "2.2.8"
+ resolved "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz"
+ integrity sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==
+
walker@^1.0.7, walker@^1.0.8:
version "1.0.8"
resolved "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz"