Compare commits
32 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 99bd9702e0 | |||
| 65bc63093a | |||
| 1ab86d8935 | |||
| ce74c6693e | |||
| 5f1f75b6d6 | |||
| 5c27a726bb | |||
| e297f7f98f | |||
| 8b9418d8fa | |||
| 78b1c50a7d | |||
| fa5cfd5fc3 | |||
| 2e1745e905 | |||
| 5a9548680f | |||
| f8d85fd633 | |||
| 2583038b0a | |||
| 47cf78e4f6 | |||
| 2502d5144d | |||
| c0fb56c71b | |||
| 47542b69ce | |||
| 1e014d7c0e | |||
| b200b3382a | |||
| 4b61f9b541 | |||
| d8308cfce4 | |||
| 56a0b9f236 | |||
| d5a1d4e26a | |||
| 8eaf6ed0de | |||
| f080e3f098 | |||
| bd5482afef | |||
| 3d81be7da8 | |||
| 5db937cbf7 | |||
| 7ebd714e2a | |||
| f71ca5802f | |||
| 16be6ff37d |
@@ -36,41 +36,41 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@floating-ui/react": "^0.26.4",
|
||||
"@hocuspocus/provider": "^2.13.5",
|
||||
"@hocuspocus/provider": "^2.13.6",
|
||||
"@plane/ui": "*",
|
||||
"@tiptap/core": "^2.1.13",
|
||||
"@tiptap/extension-blockquote": "^2.1.13",
|
||||
"@tiptap/extension-character-count": "^2.6.5",
|
||||
"@tiptap/extension-collaboration": "^2.3.2",
|
||||
"@tiptap/extension-image": "^2.1.13",
|
||||
"@tiptap/extension-list-item": "^2.1.13",
|
||||
"@tiptap/extension-mention": "^2.1.13",
|
||||
"@tiptap/extension-placeholder": "^2.3.0",
|
||||
"@tiptap/extension-task-item": "^2.1.13",
|
||||
"@tiptap/extension-task-list": "^2.1.13",
|
||||
"@tiptap/extension-text-style": "^2.7.1",
|
||||
"@tiptap/extension-underline": "^2.1.13",
|
||||
"@tiptap/pm": "^2.1.13",
|
||||
"@tiptap/react": "^2.1.13",
|
||||
"@tiptap/starter-kit": "^2.1.13",
|
||||
"@tiptap/suggestion": "^2.0.13",
|
||||
"@tiptap/core": "^2.8.0",
|
||||
"@tiptap/extension-blockquote": "^2.8.0",
|
||||
"@tiptap/extension-character-count": "^2.8.0",
|
||||
"@tiptap/extension-collaboration": "^2.8.0",
|
||||
"@tiptap/extension-image": "^2.8.0",
|
||||
"@tiptap/extension-list-item": "^2.8.0",
|
||||
"@tiptap/extension-mention": "^2.8.0",
|
||||
"@tiptap/extension-placeholder": "^2.8.0",
|
||||
"@tiptap/extension-task-item": "^2.8.0",
|
||||
"@tiptap/extension-task-list": "^2.8.0",
|
||||
"@tiptap/extension-text-style": "^2.8.0",
|
||||
"@tiptap/extension-underline": "^2.8.0",
|
||||
"@tiptap/pm": "^2.8.0",
|
||||
"@tiptap/react": "^2.8.0",
|
||||
"@tiptap/starter-kit": "^2.8.0",
|
||||
"@tiptap/suggestion": "^2.8.0",
|
||||
"class-variance-authority": "^0.7.0",
|
||||
"clsx": "^1.2.1",
|
||||
"highlight.js": "^11.8.0",
|
||||
"jsx-dom-cjs": "^8.0.3",
|
||||
"linkifyjs": "^4.1.3",
|
||||
"lowlight": "^3.0.0",
|
||||
"lucide-react": "^0.378.0",
|
||||
"lowlight": "^3.1.0",
|
||||
"lucide-react": "^0.439.0",
|
||||
"prosemirror-codemark": "^0.4.2",
|
||||
"react-moveable": "^0.54.2",
|
||||
"tailwind-merge": "^1.14.0",
|
||||
"tippy.js": "^6.3.7",
|
||||
"tiptap-markdown": "^0.8.9",
|
||||
"tiptap-markdown": "^0.8.10",
|
||||
"uuid": "^10.0.0",
|
||||
"y-indexeddb": "^9.0.12",
|
||||
"y-prosemirror": "^1.2.5",
|
||||
"y-prosemirror": "^1.2.12",
|
||||
"y-protocols": "^1.0.6",
|
||||
"yjs": "^13.6.15"
|
||||
"yjs": "^13.6.18"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@plane/eslint-config": "*",
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { HocuspocusProvider } from "@hocuspocus/provider";
|
||||
import CharacterCount from "@tiptap/extension-character-count";
|
||||
import Placeholder from "@tiptap/extension-placeholder";
|
||||
import TaskItem from "@tiptap/extension-task-item";
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
import ImageExt from "@tiptap/extension-image";
|
||||
import { ReactNodeViewRenderer } from "@tiptap/react";
|
||||
// extensions
|
||||
import { CustomImageNode } from "@/extensions";
|
||||
|
||||
export const ImageExtensionWithoutProps = () =>
|
||||
ImageExt.extend({
|
||||
@@ -16,4 +19,8 @@ export const ImageExtensionWithoutProps = () =>
|
||||
},
|
||||
};
|
||||
},
|
||||
|
||||
addNodeView() {
|
||||
return ReactNodeViewRenderer(CustomImageNode);
|
||||
},
|
||||
});
|
||||
|
||||
@@ -66,6 +66,21 @@ export const useEditor = (props: CustomEditorProps) => {
|
||||
const editorRef: MutableRefObject<Editor | null> = useRef(null);
|
||||
const savedSelectionRef = useRef(savedSelection);
|
||||
const editor = useTiptapEditor({
|
||||
immediatelyRender: true,
|
||||
shouldRerenderOnTransaction: false,
|
||||
enableContentCheck: true,
|
||||
onContentError({ editor, error, disableCollaboration }) {
|
||||
// Disable collaboration to prevent syncing invalid content
|
||||
disableCollaboration();
|
||||
|
||||
// Prevent emitting updates
|
||||
const emitUpdate = false;
|
||||
|
||||
// Disable further user input
|
||||
editor.setEditable(false, emitUpdate);
|
||||
console.log("onContentError", error);
|
||||
},
|
||||
|
||||
editorProps: {
|
||||
...CoreEditorProps({
|
||||
editorClassName,
|
||||
|
||||
@@ -45,11 +45,31 @@ export const nodeDOMAtCoords = (coords: { x: number; y: number }) => {
|
||||
".image-upload-component",
|
||||
].join(", ");
|
||||
|
||||
const hasNestedImg = (el: Element): boolean => {
|
||||
if (el.tagName.toLowerCase() === "img") return true;
|
||||
// @ts-expect-error todo
|
||||
for (const child of el.children) {
|
||||
if (hasNestedImg(child)) return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
for (const elem of elements) {
|
||||
const elemHasNestedImg = hasNestedImg(elem);
|
||||
if (elem.matches("p:first-child") && elem.parentElement?.matches(".ProseMirror")) {
|
||||
return elem;
|
||||
}
|
||||
|
||||
// if the element is a <p> tag and has a nested img i.e. the new image
|
||||
// component
|
||||
if (elem.matches("p") && elemHasNestedImg) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (elem.matches("div") && elemHasNestedImg) {
|
||||
return elem;
|
||||
}
|
||||
|
||||
// if the element is a <p> tag that is the first child of a td or th
|
||||
if (
|
||||
(elem.matches("td > p:first-child") || elem.matches("th > p:first-child")) &&
|
||||
|
||||
Reference in New Issue
Block a user