From 2421ea53a0d18f306aaf18d8feab8c63aaf5445d Mon Sep 17 00:00:00 2001 From: Diogo Cadavez Date: Tue, 18 Jun 2024 16:29:12 +0200 Subject: [PATCH 1/7] Updated core files to make BlockNote work correctly with Shadow roots & added arabic translation & updated past extension to support pasting images --- .../core/src/api/parsers/pasteExtension.ts | 37 +++ packages/core/src/api/parsers/utils.ts | 27 +++ .../extensions/FilePanel/FilePanelPlugin.ts | 16 +- .../FormattingToolbarPlugin.ts | 6 +- .../LinkToolbar/LinkToolbarPlugin.ts | 20 +- .../Placeholder/PlaceholderPlugin.ts | 15 +- .../src/extensions/SideMenu/SideMenuPlugin.ts | 81 +++++-- .../SuggestionMenu/SuggestionPlugin.ts | 13 +- .../TableHandles/TableHandlesPlugin.ts | 63 +++-- packages/core/src/i18n/locales/ar.ts | 215 +++++++----------- 10 files changed, 315 insertions(+), 178 deletions(-) create mode 100644 packages/core/src/api/parsers/utils.ts diff --git a/packages/core/src/api/parsers/pasteExtension.ts b/packages/core/src/api/parsers/pasteExtension.ts index c9648e0878..466873dced 100644 --- a/packages/core/src/api/parsers/pasteExtension.ts +++ b/packages/core/src/api/parsers/pasteExtension.ts @@ -4,11 +4,14 @@ import { Plugin } from "prosemirror-state"; import type { BlockNoteEditor } from "../../editor/BlockNoteEditor"; import { BlockSchema, InlineContentSchema, StyleSchema } from "../../schema"; import { nestedListsToBlockNoteStructure } from "./html/util/nestedLists"; +import { PartialBlock } from "../../blocks/defaultBlocks"; +import { createBlobFromFile } from "./utils"; const acceptedMIMETypes = [ "blocknote/html", "text/html", "text/plain", + "Files", ] as const; export const createPasteFromClipboardExtension = < @@ -49,6 +52,40 @@ export const createPasteFromClipboardExtension = < ); data = htmlNode.innerHTML; + } else if (format === "Files") { + const items = event.clipboardData!.items; + if (items) { + for (let i = 0; i < items.length; i++) { + //Img pasted + if (items[i].type.indexOf("image") !== -1) { + event.preventDefault(); + const file = items[i].getAsFile(); + if (file) { + createBlobFromFile(file).then((imageBlob) => { + if (imageBlob) { + const currentBlock = + editor.getTextCursorPosition().block; + const imgBlock = { + type: "image", + props: { + url: URL.createObjectURL(imageBlob), + caption: "", + width: 100, + }, + } as PartialBlock; + editor.insertBlocks( + [imgBlock], + currentBlock, + "after" + ); + } + }); + } + break; + } + } + } + return true; } editor._tiptapEditor.view.pasteHTML(data); } diff --git a/packages/core/src/api/parsers/utils.ts b/packages/core/src/api/parsers/utils.ts new file mode 100644 index 0000000000..7a16f3e1eb --- /dev/null +++ b/packages/core/src/api/parsers/utils.ts @@ -0,0 +1,27 @@ +/** + * Create a Blob from a File object + * @param file + * @returns Blob or null + */ +export function createBlobFromFile(file: File): Promise { + return new Promise((resolve) => { + if (!file) { + resolve(null); + } + + const reader = new FileReader(); + reader.onload = () => { + const result = reader.result as string; + fetch(result) + .then((res) => res.blob()) + .then((blob) => { + resolve(blob); + }) + .catch(() => { + resolve(null); + }); + }; + + reader.readAsDataURL(file); + }); +} diff --git a/packages/core/src/extensions/FilePanel/FilePanelPlugin.ts b/packages/core/src/extensions/FilePanel/FilePanelPlugin.ts index 4211fc8b55..b738467dc9 100644 --- a/packages/core/src/extensions/FilePanel/FilePanelPlugin.ts +++ b/packages/core/src/extensions/FilePanel/FilePanelPlugin.ts @@ -49,7 +49,8 @@ export class FilePanelView // Setting capture=true ensures that any parent container of the editor that // gets scrolled will trigger the scroll event. Scroll events do not bubble // and so won't propagate to the document by default. - document.addEventListener("scroll", this.scrollHandler, true); + // document.addEventListener("scroll", this.scrollHandler, true); + pmView.root.addEventListener("scroll", this.scrollHandler, true); } mouseDownHandler = () => { @@ -69,7 +70,10 @@ export class FilePanelView scrollHandler = () => { if (this.state?.show) { - const blockElement = document.querySelector( + // const blockElement = document.querySelector( + // `[data-node-type="blockContainer"][data-id="${this.state.block.id}"]` + // )!; + const blockElement = this.pmView.root.querySelector( `[data-node-type="blockContainer"][data-id="${this.state.block.id}"]` )!; @@ -84,7 +88,10 @@ export class FilePanelView } = this.pluginKey.getState(view.state); if (!this.state?.show && pluginState.block && this.editor.isEditable) { - const blockElement = document.querySelector( + // const blockElement = document.querySelector( + // `[data-node-type="blockContainer"][data-id="${pluginState.block.id}"]` + // )!; + const blockElement = this.pmView.root.querySelector( `[data-node-type="blockContainer"][data-id="${pluginState.block.id}"]` )!; @@ -124,7 +131,8 @@ export class FilePanelView this.pmView.dom.removeEventListener("dragstart", this.dragstartHandler); - document.removeEventListener("scroll", this.scrollHandler, true); + // document.removeEventListener("scroll", this.scrollHandler, true); + this.pmView.root.removeEventListener("scroll", this.scrollHandler, true); } } diff --git a/packages/core/src/extensions/FormattingToolbar/FormattingToolbarPlugin.ts b/packages/core/src/extensions/FormattingToolbar/FormattingToolbarPlugin.ts index a44d9db6bc..05567a42cb 100644 --- a/packages/core/src/extensions/FormattingToolbar/FormattingToolbarPlugin.ts +++ b/packages/core/src/extensions/FormattingToolbar/FormattingToolbarPlugin.ts @@ -62,7 +62,8 @@ export class FormattingToolbarView implements PluginView { // Setting capture=true ensures that any parent container of the editor that // gets scrolled will trigger the scroll event. Scroll events do not bubble // and so won't propagate to the document by default. - document.addEventListener("scroll", this.scrollHandler, true); + // document.addEventListener("scroll", this.scrollHandler, true); + pmView.root.addEventListener("scroll", this.scrollHandler, true); } viewMousedownHandler = () => { @@ -147,7 +148,8 @@ export class FormattingToolbarView implements PluginView { this.pmView.dom.removeEventListener("dragstart", this.dragHandler); this.pmView.dom.removeEventListener("dragover", this.dragHandler); - document.removeEventListener("scroll", this.scrollHandler, true); + // document.removeEventListener("scroll", this.scrollHandler, true); + this.pmView.root.removeEventListener("scroll", this.scrollHandler, true); } closeMenu = () => { diff --git a/packages/core/src/extensions/LinkToolbar/LinkToolbarPlugin.ts b/packages/core/src/extensions/LinkToolbar/LinkToolbarPlugin.ts index 95e1156c2d..13d8eb954c 100644 --- a/packages/core/src/extensions/LinkToolbar/LinkToolbarPlugin.ts +++ b/packages/core/src/extensions/LinkToolbar/LinkToolbarPlugin.ts @@ -61,12 +61,18 @@ class LinkToolbarView implements PluginView { }; this.pmView.dom.addEventListener("mouseover", this.mouseOverHandler); - document.addEventListener("click", this.clickHandler, true); + // document.addEventListener("click", this.clickHandler, true); + this.pmView.root.addEventListener( + "click", + this.clickHandler as EventListener, + true + ); // Setting capture=true ensures that any parent container of the editor that // gets scrolled will trigger the scroll event. Scroll events do not bubble // and so won't propagate to the document by default. - document.addEventListener("scroll", this.scrollHandler, true); + // document.addEventListener("scroll", this.scrollHandler, true); + this.pmView.root.addEventListener("scroll", this.scrollHandler, true); } mouseOverHandler = (event: MouseEvent) => { @@ -271,8 +277,14 @@ class LinkToolbarView implements PluginView { destroy() { this.pmView.dom.removeEventListener("mouseover", this.mouseOverHandler); - document.removeEventListener("scroll", this.scrollHandler, true); - document.removeEventListener("click", this.clickHandler, true); + // document.removeEventListener("scroll", this.scrollHandler, true); + // document.removeEventListener("click", this.clickHandler, true); + this.pmView.root.removeEventListener("scroll", this.scrollHandler, true); + this.pmView.root.removeEventListener( + "click", + this.clickHandler as EventListener, + true + ); } } diff --git a/packages/core/src/extensions/Placeholder/PlaceholderPlugin.ts b/packages/core/src/extensions/Placeholder/PlaceholderPlugin.ts index 3cb98ff5f2..2979d879ca 100644 --- a/packages/core/src/extensions/Placeholder/PlaceholderPlugin.ts +++ b/packages/core/src/extensions/Placeholder/PlaceholderPlugin.ts @@ -12,11 +12,18 @@ export const PlaceholderPlugin = ( key: PLUGIN_KEY, view: () => { const styleEl = document.createElement("style"); + // editor.view.root.append(styleEl); const nonce = editor._tiptapEditor.options.injectNonce; if (nonce) { styleEl.setAttribute("nonce", nonce); } - document.head.appendChild(styleEl); + // document.head.appendChild(styleEl); + if (editor._tiptapEditor.view.root instanceof ShadowRoot) { + editor._tiptapEditor.view.root.append(styleEl); + } else if (editor._tiptapEditor.view.root instanceof Document) { + editor._tiptapEditor.view.root.head.appendChild(styleEl); + } + const styleSheet = styleEl.sheet!; const getBaseSelector = (additionalSelectors = "") => @@ -62,7 +69,11 @@ export const PlaceholderPlugin = ( return { destroy: () => { - document.head.removeChild(styleEl); + if (editor._tiptapEditor.view.root instanceof ShadowRoot) { + editor._tiptapEditor.view.root.removeChild(styleEl); + } else if (editor._tiptapEditor.view.root instanceof Document) { + editor._tiptapEditor.view.root.head.removeChild(styleEl); + } }, }; }, diff --git a/packages/core/src/extensions/SideMenu/SideMenuPlugin.ts b/packages/core/src/extensions/SideMenu/SideMenuPlugin.ts index 5e73ed79d1..488c7872e3 100644 --- a/packages/core/src/extensions/SideMenu/SideMenuPlugin.ts +++ b/packages/core/src/extensions/SideMenu/SideMenuPlugin.ts @@ -128,7 +128,7 @@ function setDragImage(view: EditorView, from: number, to = from) { } // dataTransfer.setDragImage(element) only works if element is attached to the DOM. - unsetDragImage(); + unsetDragImage(view.root); dragImageElement = parentClone; // TODO: This is hacky, need a better way of assigning classes to the editor so that they can also be applied to the @@ -146,12 +146,14 @@ function setDragImage(view: EditorView, from: number, to = from) { dragImageElement.className = dragImageElement.className + " bn-drag-preview " + inheritedClasses; - document.body.appendChild(dragImageElement); + // document.body.appendChild(dragImageElement); + view.root.appendChild(dragImageElement); } -function unsetDragImage() { +function unsetDragImage(rootEl: Document | ShadowRoot) { if (dragImageElement !== undefined) { - document.body.removeChild(dragImageElement); + // document.body.removeChild(dragImageElement); + rootEl.removeChild(dragImageElement); dragImageElement = undefined; } } @@ -177,7 +179,8 @@ function dragStart< top: e.clientY, }; - const elements = document.elementsFromPoint(coords.left, coords.top); + // const elements = document.elementsFromPoint(coords.left, coords.top); + const elements = view.root.elementsFromPoint(coords.left, coords.top); let blockEl = undefined; for (const element of elements) { @@ -283,22 +286,42 @@ export class SideMenuView< this.pmView.dom.firstChild! as HTMLElement ).getBoundingClientRect().x; - document.body.addEventListener("drop", this.onDrop, true); - document.body.addEventListener("dragover", this.onDragOver); + // document.body.addEventListener("drop", this.onDrop, true); + this.pmView.root.addEventListener( + "drop", + this.onDrop as EventListener, + true + ); + // document.body.addEventListener("dragover", this.onDragOver); + this.pmView.root.addEventListener( + "dragover", + this.onDragOver as EventListener + ); this.pmView.dom.addEventListener("dragstart", this.onDragStart); // Shows or updates menu position whenever the cursor moves, if the menu isn't frozen. - document.body.addEventListener("mousemove", this.onMouseMove, true); + // document.body.addEventListener("mousemove", this.onMouseMove, true); + this.pmView.root.addEventListener( + "mousemove", + this.onMouseMove as EventListener, + true + ); // Unfreezes the menu whenever the user clicks. this.pmView.dom.addEventListener("mousedown", this.onMouseDown); // Hides and unfreezes the menu whenever the user presses a key. - document.body.addEventListener("keydown", this.onKeyDown, true); + // document.body.addEventListener("keydown", this.onKeyDown, true); + this.pmView.root.addEventListener( + "keydown", + this.onKeyDown as EventListener, + true + ); // Setting capture=true ensures that any parent container of the editor that // gets scrolled will trigger the scroll event. Scroll events do not bubble // and so won't propagate to the document by default. - document.addEventListener("scroll", this.onScroll, true); + // document.addEventListener("scroll", this.onScroll, true); + this.pmView.root.addEventListener("scroll", this.onScroll, true); } updateState = () => { @@ -322,7 +345,11 @@ export class SideMenuView< top: this.mousePos.y, }; - const elements = document.elementsFromPoint(coords.left, coords.top); + // const elements = document.elementsFromPoint(coords.left, coords.top); + const elements = this.pmView.root.elementsFromPoint( + coords.left, + coords.top + ); let block = undefined; for (const element of elements) { @@ -553,13 +580,33 @@ export class SideMenuView< this.state.show = false; this.emitUpdate(this.state); } - document.body.removeEventListener("mousemove", this.onMouseMove, true); - document.body.removeEventListener("dragover", this.onDragOver); + // document.body.removeEventListener("mousemove", this.onMouseMove, true); + this.pmView.root.removeEventListener( + "mousemove", + this.onMouseMove as EventListener, + true + ); + // document.body.removeEventListener("dragover", this.onDragOver); + this.pmView.root.removeEventListener( + "dragover", + this.onDragOver as EventListener + ); this.pmView.dom.removeEventListener("dragstart", this.onDragStart); - document.body.removeEventListener("drop", this.onDrop, true); - document.removeEventListener("scroll", this.onScroll, true); + // document.body.removeEventListener("drop", this.onDrop, true); + this.pmView.root.removeEventListener( + "drop", + this.onDrop as EventListener, + true + ); + // document.removeEventListener("scroll", this.onScroll, true); + this.pmView.root.removeEventListener("scroll", this.onScroll, true); this.pmView.dom.removeEventListener("mousedown", this.onMouseDown); - document.body.removeEventListener("keydown", this.onKeyDown, true); + // document.body.removeEventListener("keydown", this.onKeyDown, true); + this.pmView.root.removeEventListener( + "keydown", + this.onKeyDown as EventListener, + true + ); } addBlock() { @@ -665,7 +712,7 @@ export class SideMenuProsemirrorPlugin< /** * Handles drag & drop events for blocks. */ - blockDragEnd = () => unsetDragImage(); + blockDragEnd = () => unsetDragImage(this.editor.prosemirrorView.root); /** * Freezes the side menu. When frozen, the side menu will stay * attached to the same block regardless of which block is hovered by the diff --git a/packages/core/src/extensions/SuggestionMenu/SuggestionPlugin.ts b/packages/core/src/extensions/SuggestionMenu/SuggestionPlugin.ts index a557b165d3..85eb76c24e 100644 --- a/packages/core/src/extensions/SuggestionMenu/SuggestionPlugin.ts +++ b/packages/core/src/extensions/SuggestionMenu/SuggestionPlugin.ts @@ -20,7 +20,7 @@ class SuggestionMenuView< > { public state?: SuggestionMenuState; public emitUpdate: (triggerCharacter: string) => void; - + private rootEl?: Document | ShadowRoot; pluginState: SuggestionPluginState; constructor( @@ -37,15 +37,18 @@ class SuggestionMenuView< emitUpdate(menuName, this.state); }; + this.rootEl = this.editor._tiptapEditor.view.root; + // Setting capture=true ensures that any parent container of the editor that // gets scrolled will trigger the scroll event. Scroll events do not bubble // and so won't propagate to the document by default. - document.addEventListener("scroll", this.handleScroll, true); + // document.addEventListener("scroll", this.handleScroll, true); + this.rootEl.addEventListener("scroll", this.handleScroll, true); } handleScroll = () => { if (this.state?.show) { - const decorationNode = document.querySelector( + const decorationNode = this.rootEl?.querySelector( `[data-decoration-id="${this.pluginState!.decorationId}"]` ); this.state.referencePos = decorationNode!.getBoundingClientRect(); @@ -79,7 +82,7 @@ class SuggestionMenuView< return; } - const decorationNode = document.querySelector( + const decorationNode = this.rootEl?.querySelector( `[data-decoration-id="${this.pluginState!.decorationId}"]` ); @@ -95,7 +98,7 @@ class SuggestionMenuView< } destroy() { - document.removeEventListener("scroll", this.handleScroll, true); + this.rootEl?.removeEventListener("scroll", this.handleScroll, true); } closeMenu = () => { diff --git a/packages/core/src/extensions/TableHandles/TableHandlesPlugin.ts b/packages/core/src/extensions/TableHandles/TableHandlesPlugin.ts index 57f1533773..b52fd03e54 100644 --- a/packages/core/src/extensions/TableHandles/TableHandlesPlugin.ts +++ b/packages/core/src/extensions/TableHandles/TableHandlesPlugin.ts @@ -36,7 +36,7 @@ export type TableHandlesState< | undefined; }; -function setHiddenDragImage() { +function setHiddenDragImage(rootEl: Document | ShadowRoot) { if (dragImageElement) { return; } @@ -46,12 +46,21 @@ function setHiddenDragImage() { dragImageElement.style.opacity = "0"; dragImageElement.style.height = "1px"; dragImageElement.style.width = "1px"; - document.body.appendChild(dragImageElement); + // document.body.appendChild(dragImageElement); + if (rootEl instanceof Document) { + rootEl.body.appendChild(dragImageElement); + } else { + rootEl.appendChild(dragImageElement); + } } -function unsetHiddenDragImage() { +function unsetHiddenDragImage(rootEl: Document | ShadowRoot) { if (dragImageElement) { - document.body.removeChild(dragImageElement); + if (rootEl instanceof Document) { + rootEl.body.removeChild(dragImageElement); + } else { + rootEl.removeChild(dragImageElement); + } dragImageElement = undefined; } } @@ -116,13 +125,19 @@ export class TableHandlesView< pmView.dom.addEventListener("mousemove", this.mouseMoveHandler); - document.addEventListener("dragover", this.dragOverHandler); - document.addEventListener("drop", this.dropHandler); + // document.addEventListener("dragover", this.dragOverHandler); + // document.addEventListener("drop", this.dropHandler); + pmView.root.addEventListener( + "dragover", + this.dragOverHandler as EventListener + ); + pmView.root.addEventListener("drop", this.dropHandler as EventListener); // Setting capture=true ensures that any parent container of the editor that // gets scrolled will trigger the scroll event. Scroll events do not bubble // and so won't propagate to the document by default. - document.addEventListener("scroll", this.scrollHandler, true); + // document.addEventListener("scroll", this.scrollHandler, true); + pmView.root.addEventListener("scroll", this.scrollHandler, true); } mouseMoveHandler = (event: MouseEvent) => { @@ -242,7 +257,12 @@ export class TableHandlesView< // Gets the table cell element that the bounded mouse cursor coordinates lie // in. - const tableCellElements = document + // const tableCellElements = document + // .elementsFromPoint(boundedMouseCoords.left, boundedMouseCoords.top) + // .filter( + // (element) => element.tagName === "TD" || element.tagName === "TH" + // ); + const tableCellElements = this.pmView.root .elementsFromPoint(boundedMouseCoords.left, boundedMouseCoords.top) .filter( (element) => element.tagName === "TD" || element.tagName === "TH" @@ -343,7 +363,10 @@ export class TableHandlesView< scrollHandler = () => { if (this.state?.show) { - const tableElement = document.querySelector( + // const tableElement = document.querySelector( + // `[data-node-type="blockContainer"][data-id="${this.tableId}"] table` + // )!; + const tableElement = this.pmView.root.querySelector( `[data-node-type="blockContainer"][data-id="${this.tableId}"] table` )!; const cellElement = tableElement.querySelector( @@ -361,10 +384,18 @@ export class TableHandlesView< destroy() { this.pmView.dom.removeEventListener("mousemove", this.mouseMoveHandler); - document.removeEventListener("dragover", this.dragOverHandler); - document.removeEventListener("drop", this.dropHandler); - - document.removeEventListener("scroll", this.scrollHandler, true); + // document.removeEventListener("dragover", this.dragOverHandler); + // document.removeEventListener("drop", this.dropHandler); + // document.removeEventListener("scroll", this.scrollHandler, true); + this.pmView.root.removeEventListener( + "dragover", + this.dragOverHandler as EventListener + ); + this.pmView.root.removeEventListener( + "drop", + this.dropHandler as EventListener + ); + this.pmView.root.removeEventListener("scroll", this.scrollHandler, true); } } @@ -559,7 +590,7 @@ export class TableHandlesProsemirrorPlugin< }) ); - setHiddenDragImage(); + setHiddenDragImage(this.editor._tiptapEditor.view.root); event.dataTransfer!.setDragImage(dragImageElement!, 0, 0); event.dataTransfer!.effectAllowed = "move"; }; @@ -595,7 +626,7 @@ export class TableHandlesProsemirrorPlugin< }) ); - setHiddenDragImage(); + setHiddenDragImage(this.editor._tiptapEditor.view.root); event.dataTransfer!.setDragImage(dragImageElement!, 0, 0); event.dataTransfer!.effectAllowed = "copyMove"; }; @@ -618,7 +649,7 @@ export class TableHandlesProsemirrorPlugin< this.editor._tiptapEditor.state.tr.setMeta(tableHandlesPluginKey, null) ); - unsetHiddenDragImage(); + unsetHiddenDragImage(this.editor._tiptapEditor.view.root); }; /** diff --git a/packages/core/src/i18n/locales/ar.ts b/packages/core/src/i18n/locales/ar.ts index 4dbae5fdbf..525d56b2a1 100644 --- a/packages/core/src/i18n/locales/ar.ts +++ b/packages/core/src/i18n/locales/ar.ts @@ -3,182 +3,141 @@ import type { Dictionary } from "../dictionary"; export const ar: Dictionary = { slash_menu: { heading: { - title: "العنوان 1", - subtext: "يستخدم للعنوان الرئيسي", - aliases: ["h", "heading1", "h1", "عنوان رئيسي", "عنوان 1"], + title: "عنوان 1", + subtext: "يستخدم لعناوين المستوى الأعلى", + aliases: ["ع", "عنوان1", "ع1"], group: "العناوين", }, heading_2: { - title: "العنوان 2", + title: "عنوان 2", subtext: "يستخدم للأقسام الرئيسية", - aliases: ["h2", "heading2", "subheading", "عنوان 2", "عنوان فرعي"], + aliases: ["ع2", "عنوان2", "عنوان فرعي"], group: "العناوين", }, heading_3: { - title: "العنوان 3", - subtext: "يستخدم للأقسام الفرعية وعناوين المجموعات", - aliases: ["h3", "heading3", "subheading", "عنوان 3", "عنوان فرعي"], + title: "عنوان 3", + subtext: "يستخدم للأقسام الفرعية والعناوين المجموعة", + aliases: ["ع3", "عنوان3", "عنوان فرعي"], group: "العناوين", }, numbered_list: { title: "قائمة مرقمة", - subtext: "يستخدم لعرض قائمة مرقمة", - aliases: [ - "ol", - "li", - "list", - "numberedlist", - "numbered list", - "قائمة", - "قائمة مرقمة", - ], + subtext: "تستخدم لعرض قائمة مرقمة", + aliases: ["ق", "عناصر قائمة", "قائمة", "قائمة مرقمة"], group: "الكتل الأساسية", }, bullet_list: { - title: "قائمة نقاط", - subtext: "يستخدم لعرض قائمة غير مرتبة", - aliases: [ - "ul", - "li", - "list", - "bulletlist", - "bullet list", - "قائمة", - "قائمة نقاط", - ], + title: "قائمة نقطية", + subtext: "تستخدم لعرض قائمة غير مرتبة", + aliases: ["ق", "عناصر قائمة", "قائمة", "قائمة نقطية"], group: "الكتل الأساسية", }, check_list: { - title: "قائمة الاختيار", - subtext: "يستخدم لعرض قائمة مع مربعات الاختيار", + title: "قائمة تحقق", + subtext: "تستخدم لعرض قائمة بمربعات التحقق", aliases: [ - "ul", - "li", - "list", - "checklist", - "check list", - "checked list", - "checkbox", + "قوائم غير مرتبة", + "عناصر قائمة", "قائمة", - "قائمة الاختيار", - "قائمة مربعات الاختيار", + "قائمة تحقق", + "قائمة التحقق", + "قائمة مشطوبة", + "مربع التحقق", ], group: "الكتل الأساسية", }, paragraph: { title: "فقرة", - subtext: "يستخدم لجسم المستند الخاص بك", - aliases: ["p", "paragraph", "فقرة", "نص"], + subtext: "تستخدم لنص الوثيقة الأساسي", + aliases: ["ف", "فقرة"], group: "الكتل الأساسية", }, table: { title: "جدول", subtext: "يستخدم للجداول", - aliases: ["table", "جدول", "جداول"], + aliases: ["جدول"], group: "متقدم", }, image: { title: "صورة", - subtext: "أدرج صورة", - aliases: [ - "صورة", - "رفع الصورة", - "رفع", - "image", - "upload", - "img", - "picture", - "media", - "url", - ], - group: "الوسائط", + subtext: "إدراج صورة", + aliases: ["صورة", "رفع صورة", "تحميل", "صورة", "صورة", "وسائط", "رابط"], + group: "وسائط", }, video: { title: "فيديو", - subtext: "أدرج فيديو", + subtext: "إدراج فيديو", aliases: [ "فيديو", - "رفع الفيديو", - "رفع", - "video", - "upload", - "mp4", - "film", - "media", - "url", + "رفع فيديو", + "تحميل", + "فيديو", + "فيلم", + "وسائط", + "رابط", ], - group: "الوسائط", + group: "وسائط", }, audio: { title: "صوت", - subtext: "أدرج صوت", - aliases: [ - "صوت", - "رفع الصوت", - "رفع", - "audio", - "upload", - "mp3", - "sound", - "media", - "url", - ], - group: "الوسائط", + subtext: "إدراج صوت", + aliases: ["صوت", "رفع صوت", "تحميل", "صوت", "صوت", "وسائط", "رابط"], + group: "وسائط", }, file: { title: "ملف", - subtext: "أدرج ملف", - aliases: ["file", "upload", "embed", "media", "url", "ملف", "رفع"], - group: "الوسائط", + subtext: "إدراج ملف", + aliases: ["ملف", "تحميل", "تضمين", "وسائط", "رابط"], + group: "وسائط", }, }, placeholders: { - default: "أدخل النص أو اكتب '/' للأوامر", - heading: "العنوان", + default: "أدخل نصًا أو اكتب '/' للأوامر", + heading: "عنوان", bulletListItem: "قائمة", numberedListItem: "قائمة", checkListItem: "قائمة", }, file_blocks: { image: { - add_button_text: "أضف صورة", + add_button_text: "إضافة صورة", }, video: { - add_button_text: "أضف فيديو", + add_button_text: "إضافة فيديو", }, audio: { - add_button_text: "أضف صوت", + add_button_text: "إضافة صوت", }, file: { - add_button_text: "أضف ملف", + add_button_text: "إضافة ملف", }, }, // from react package: side_menu: { - add_block_label: "أضف كتلة", - drag_handle_label: "افتح قائمة الكتل", + add_block_label: "إضافة محتوي", + drag_handle_label: "فتح قائمة المحتويات", }, drag_handle: { delete_menuitem: "حذف", - colors_menuitem: "الألوان", + colors_menuitem: "ألوان", }, table_handle: { - delete_column_menuitem: "حذف العمود", - delete_row_menuitem: "حذف الصف", - add_left_menuitem: "أضف عموداً على اليسار", - add_right_menuitem: "أضف عموداً على اليمين", - add_above_menuitem: "أضف صفاً أعلى", - add_below_menuitem: "أضف صفاً أسفل", + delete_column_menuitem: "حذف عمود", + delete_row_menuitem: "حذف صف", + add_left_menuitem: "إضافة عمود إلى اليسار", + add_right_menuitem: "إضافة عمود إلى اليمين", + add_above_menuitem: "إضافة صف أعلى", + add_below_menuitem: "إضافة صف أسفل", }, suggestion_menu: { no_items_title: "لم يتم العثور على عناصر", - loading: "جار التحميل...", + loading: "جارٍ التحميل…", }, color_picker: { - text_title: "النص", - background_title: "الخلفية", + text_title: "نص", + background_title: "خلفية", colors: { - default: "الافتراضي", + default: "افتراضي", gray: "رمادي", brown: "بني", red: "أحمر", @@ -186,7 +145,7 @@ export const ar: Dictionary = { yellow: "أصفر", green: "أخضر", blue: "أزرق", - purple: "بنفسجي", + purple: "أرجواني", pink: "وردي", }, }, @@ -201,11 +160,11 @@ export const ar: Dictionary = { secondary_tooltip: "Mod+I", }, underline: { - tooltip: "تسطير", + tooltip: "تحته خط", secondary_tooltip: "Mod+U", }, strike: { - tooltip: "شطب", + tooltip: "مشطوب", secondary_tooltip: "Mod+Shift+X", }, code: { @@ -213,15 +172,15 @@ export const ar: Dictionary = { secondary_tooltip: "", }, colors: { - tooltip: "الألوان", + tooltip: "ألوان", }, link: { tooltip: "إنشاء رابط", secondary_tooltip: "Mod+K", }, file_caption: { - tooltip: "تعديل التسمية التوضيحية", - input_placeholder: "تعديل التسمية التوضيحية", + tooltip: "تحرير التسمية التوضيحية", + input_placeholder: "تحرير التسمية التوضيحية", }, file_replace: { tooltip: { @@ -247,10 +206,10 @@ export const ar: Dictionary = { }, file_download: { tooltip: { - image: "تحميل الصورة", - video: "تحميل الفيديو", - audio: "تحميل الصوت", - file: "تحميل الملف", + image: "تنزيل الصورة", + video: "تنزيل الفيديو", + audio: "تنزيل الصوت", + file: "تنزيل الملف", } as Record, }, file_delete: { @@ -262,21 +221,21 @@ export const ar: Dictionary = { } as Record, }, file_preview_toggle: { - tooltip: "تبديل العرض", + tooltip: "تبديل المعاينة", }, nest: { - tooltip: "تداخل الكتل", + tooltip: "محتويات متداخلة", secondary_tooltip: "Tab", }, unnest: { - tooltip: "إلغاء تداخل الكتل", + tooltip: "إلغاء التداخل", secondary_tooltip: "Shift+Tab", }, align_left: { tooltip: "محاذاة النص إلى اليسار", }, align_center: { - tooltip: "محاذاة النص إلى الوسط", + tooltip: "محاذاة النص في المنتصف", }, align_right: { tooltip: "محاذاة النص إلى اليمين", @@ -289,20 +248,20 @@ export const ar: Dictionary = { upload: { title: "تحميل", file_placeholder: { - image: "تحميل الصورة", - video: "تحميل الفيديو", - audio: "تحميل الصوت", - file: "تحميل الملف", + image: "تحميل صورة", + video: "تحميل فيديو", + audio: "تحميل صوت", + file: "تحميل ملف", } as Record, upload_error: "خطأ: فشل التحميل", }, embed: { title: "تضمين", embed_button: { - image: "تضمين الصورة", - video: "تضمين الفيديو", - audio: "تضمين الصوت", - file: "تضمين الملف", + image: "تضمين صورة", + video: "تضمين فيديو", + audio: "تضمين صوت", + file: "تضمين ملف", } as Record, url_placeholder: "أدخل الرابط", }, @@ -312,15 +271,15 @@ export const ar: Dictionary = { tooltip: "إزالة الرابط", }, edit: { - text: "تعديل الرابط", - tooltip: "تعديل", + text: "تحرير الرابط", + tooltip: "تحرير", }, open: { - tooltip: "افتح في علامة تبويب جديدة", + tooltip: "فتح في تبويب جديد", }, form: { - title_placeholder: "تعديل العنوان", - url_placeholder: "تعديل الرابط", + title_placeholder: "تحرير العنوان", + url_placeholder: "تحرير الرابط", }, }, generic: { From 19e1167a2aace62e0259a1af20906a69bf0aa716 Mon Sep 17 00:00:00 2001 From: Diogo Cadavez Date: Wed, 19 Jun 2024 12:07:29 +0200 Subject: [PATCH 2/7] removed updates to pasteExtension --- .../core/src/api/parsers/pasteExtension.ts | 37 ------------------- 1 file changed, 37 deletions(-) diff --git a/packages/core/src/api/parsers/pasteExtension.ts b/packages/core/src/api/parsers/pasteExtension.ts index 466873dced..c9648e0878 100644 --- a/packages/core/src/api/parsers/pasteExtension.ts +++ b/packages/core/src/api/parsers/pasteExtension.ts @@ -4,14 +4,11 @@ import { Plugin } from "prosemirror-state"; import type { BlockNoteEditor } from "../../editor/BlockNoteEditor"; import { BlockSchema, InlineContentSchema, StyleSchema } from "../../schema"; import { nestedListsToBlockNoteStructure } from "./html/util/nestedLists"; -import { PartialBlock } from "../../blocks/defaultBlocks"; -import { createBlobFromFile } from "./utils"; const acceptedMIMETypes = [ "blocknote/html", "text/html", "text/plain", - "Files", ] as const; export const createPasteFromClipboardExtension = < @@ -52,40 +49,6 @@ export const createPasteFromClipboardExtension = < ); data = htmlNode.innerHTML; - } else if (format === "Files") { - const items = event.clipboardData!.items; - if (items) { - for (let i = 0; i < items.length; i++) { - //Img pasted - if (items[i].type.indexOf("image") !== -1) { - event.preventDefault(); - const file = items[i].getAsFile(); - if (file) { - createBlobFromFile(file).then((imageBlob) => { - if (imageBlob) { - const currentBlock = - editor.getTextCursorPosition().block; - const imgBlock = { - type: "image", - props: { - url: URL.createObjectURL(imageBlob), - caption: "", - width: 100, - }, - } as PartialBlock; - editor.insertBlocks( - [imgBlock], - currentBlock, - "after" - ); - } - }); - } - break; - } - } - } - return true; } editor._tiptapEditor.view.pasteHTML(data); } From cc4d306b17aa60e6ac14f1b9cda6fc677c2c392b Mon Sep 17 00:00:00 2001 From: Diogo Cadavez Date: Wed, 19 Jun 2024 12:12:38 +0200 Subject: [PATCH 3/7] removed arabic updates --- packages/core/src/i18n/locales/ar.ts | 215 ++++++++++++++++----------- 1 file changed, 128 insertions(+), 87 deletions(-) diff --git a/packages/core/src/i18n/locales/ar.ts b/packages/core/src/i18n/locales/ar.ts index 525d56b2a1..4dbae5fdbf 100644 --- a/packages/core/src/i18n/locales/ar.ts +++ b/packages/core/src/i18n/locales/ar.ts @@ -3,141 +3,182 @@ import type { Dictionary } from "../dictionary"; export const ar: Dictionary = { slash_menu: { heading: { - title: "عنوان 1", - subtext: "يستخدم لعناوين المستوى الأعلى", - aliases: ["ع", "عنوان1", "ع1"], + title: "العنوان 1", + subtext: "يستخدم للعنوان الرئيسي", + aliases: ["h", "heading1", "h1", "عنوان رئيسي", "عنوان 1"], group: "العناوين", }, heading_2: { - title: "عنوان 2", + title: "العنوان 2", subtext: "يستخدم للأقسام الرئيسية", - aliases: ["ع2", "عنوان2", "عنوان فرعي"], + aliases: ["h2", "heading2", "subheading", "عنوان 2", "عنوان فرعي"], group: "العناوين", }, heading_3: { - title: "عنوان 3", - subtext: "يستخدم للأقسام الفرعية والعناوين المجموعة", - aliases: ["ع3", "عنوان3", "عنوان فرعي"], + title: "العنوان 3", + subtext: "يستخدم للأقسام الفرعية وعناوين المجموعات", + aliases: ["h3", "heading3", "subheading", "عنوان 3", "عنوان فرعي"], group: "العناوين", }, numbered_list: { title: "قائمة مرقمة", - subtext: "تستخدم لعرض قائمة مرقمة", - aliases: ["ق", "عناصر قائمة", "قائمة", "قائمة مرقمة"], + subtext: "يستخدم لعرض قائمة مرقمة", + aliases: [ + "ol", + "li", + "list", + "numberedlist", + "numbered list", + "قائمة", + "قائمة مرقمة", + ], group: "الكتل الأساسية", }, bullet_list: { - title: "قائمة نقطية", - subtext: "تستخدم لعرض قائمة غير مرتبة", - aliases: ["ق", "عناصر قائمة", "قائمة", "قائمة نقطية"], + title: "قائمة نقاط", + subtext: "يستخدم لعرض قائمة غير مرتبة", + aliases: [ + "ul", + "li", + "list", + "bulletlist", + "bullet list", + "قائمة", + "قائمة نقاط", + ], group: "الكتل الأساسية", }, check_list: { - title: "قائمة تحقق", - subtext: "تستخدم لعرض قائمة بمربعات التحقق", + title: "قائمة الاختيار", + subtext: "يستخدم لعرض قائمة مع مربعات الاختيار", aliases: [ - "قوائم غير مرتبة", - "عناصر قائمة", + "ul", + "li", + "list", + "checklist", + "check list", + "checked list", + "checkbox", "قائمة", - "قائمة تحقق", - "قائمة التحقق", - "قائمة مشطوبة", - "مربع التحقق", + "قائمة الاختيار", + "قائمة مربعات الاختيار", ], group: "الكتل الأساسية", }, paragraph: { title: "فقرة", - subtext: "تستخدم لنص الوثيقة الأساسي", - aliases: ["ف", "فقرة"], + subtext: "يستخدم لجسم المستند الخاص بك", + aliases: ["p", "paragraph", "فقرة", "نص"], group: "الكتل الأساسية", }, table: { title: "جدول", subtext: "يستخدم للجداول", - aliases: ["جدول"], + aliases: ["table", "جدول", "جداول"], group: "متقدم", }, image: { title: "صورة", - subtext: "إدراج صورة", - aliases: ["صورة", "رفع صورة", "تحميل", "صورة", "صورة", "وسائط", "رابط"], - group: "وسائط", + subtext: "أدرج صورة", + aliases: [ + "صورة", + "رفع الصورة", + "رفع", + "image", + "upload", + "img", + "picture", + "media", + "url", + ], + group: "الوسائط", }, video: { title: "فيديو", - subtext: "إدراج فيديو", + subtext: "أدرج فيديو", aliases: [ "فيديو", - "رفع فيديو", - "تحميل", - "فيديو", - "فيلم", - "وسائط", - "رابط", + "رفع الفيديو", + "رفع", + "video", + "upload", + "mp4", + "film", + "media", + "url", ], - group: "وسائط", + group: "الوسائط", }, audio: { title: "صوت", - subtext: "إدراج صوت", - aliases: ["صوت", "رفع صوت", "تحميل", "صوت", "صوت", "وسائط", "رابط"], - group: "وسائط", + subtext: "أدرج صوت", + aliases: [ + "صوت", + "رفع الصوت", + "رفع", + "audio", + "upload", + "mp3", + "sound", + "media", + "url", + ], + group: "الوسائط", }, file: { title: "ملف", - subtext: "إدراج ملف", - aliases: ["ملف", "تحميل", "تضمين", "وسائط", "رابط"], - group: "وسائط", + subtext: "أدرج ملف", + aliases: ["file", "upload", "embed", "media", "url", "ملف", "رفع"], + group: "الوسائط", }, }, placeholders: { - default: "أدخل نصًا أو اكتب '/' للأوامر", - heading: "عنوان", + default: "أدخل النص أو اكتب '/' للأوامر", + heading: "العنوان", bulletListItem: "قائمة", numberedListItem: "قائمة", checkListItem: "قائمة", }, file_blocks: { image: { - add_button_text: "إضافة صورة", + add_button_text: "أضف صورة", }, video: { - add_button_text: "إضافة فيديو", + add_button_text: "أضف فيديو", }, audio: { - add_button_text: "إضافة صوت", + add_button_text: "أضف صوت", }, file: { - add_button_text: "إضافة ملف", + add_button_text: "أضف ملف", }, }, // from react package: side_menu: { - add_block_label: "إضافة محتوي", - drag_handle_label: "فتح قائمة المحتويات", + add_block_label: "أضف كتلة", + drag_handle_label: "افتح قائمة الكتل", }, drag_handle: { delete_menuitem: "حذف", - colors_menuitem: "ألوان", + colors_menuitem: "الألوان", }, table_handle: { - delete_column_menuitem: "حذف عمود", - delete_row_menuitem: "حذف صف", - add_left_menuitem: "إضافة عمود إلى اليسار", - add_right_menuitem: "إضافة عمود إلى اليمين", - add_above_menuitem: "إضافة صف أعلى", - add_below_menuitem: "إضافة صف أسفل", + delete_column_menuitem: "حذف العمود", + delete_row_menuitem: "حذف الصف", + add_left_menuitem: "أضف عموداً على اليسار", + add_right_menuitem: "أضف عموداً على اليمين", + add_above_menuitem: "أضف صفاً أعلى", + add_below_menuitem: "أضف صفاً أسفل", }, suggestion_menu: { no_items_title: "لم يتم العثور على عناصر", - loading: "جارٍ التحميل…", + loading: "جار التحميل...", }, color_picker: { - text_title: "نص", - background_title: "خلفية", + text_title: "النص", + background_title: "الخلفية", colors: { - default: "افتراضي", + default: "الافتراضي", gray: "رمادي", brown: "بني", red: "أحمر", @@ -145,7 +186,7 @@ export const ar: Dictionary = { yellow: "أصفر", green: "أخضر", blue: "أزرق", - purple: "أرجواني", + purple: "بنفسجي", pink: "وردي", }, }, @@ -160,11 +201,11 @@ export const ar: Dictionary = { secondary_tooltip: "Mod+I", }, underline: { - tooltip: "تحته خط", + tooltip: "تسطير", secondary_tooltip: "Mod+U", }, strike: { - tooltip: "مشطوب", + tooltip: "شطب", secondary_tooltip: "Mod+Shift+X", }, code: { @@ -172,15 +213,15 @@ export const ar: Dictionary = { secondary_tooltip: "", }, colors: { - tooltip: "ألوان", + tooltip: "الألوان", }, link: { tooltip: "إنشاء رابط", secondary_tooltip: "Mod+K", }, file_caption: { - tooltip: "تحرير التسمية التوضيحية", - input_placeholder: "تحرير التسمية التوضيحية", + tooltip: "تعديل التسمية التوضيحية", + input_placeholder: "تعديل التسمية التوضيحية", }, file_replace: { tooltip: { @@ -206,10 +247,10 @@ export const ar: Dictionary = { }, file_download: { tooltip: { - image: "تنزيل الصورة", - video: "تنزيل الفيديو", - audio: "تنزيل الصوت", - file: "تنزيل الملف", + image: "تحميل الصورة", + video: "تحميل الفيديو", + audio: "تحميل الصوت", + file: "تحميل الملف", } as Record, }, file_delete: { @@ -221,21 +262,21 @@ export const ar: Dictionary = { } as Record, }, file_preview_toggle: { - tooltip: "تبديل المعاينة", + tooltip: "تبديل العرض", }, nest: { - tooltip: "محتويات متداخلة", + tooltip: "تداخل الكتل", secondary_tooltip: "Tab", }, unnest: { - tooltip: "إلغاء التداخل", + tooltip: "إلغاء تداخل الكتل", secondary_tooltip: "Shift+Tab", }, align_left: { tooltip: "محاذاة النص إلى اليسار", }, align_center: { - tooltip: "محاذاة النص في المنتصف", + tooltip: "محاذاة النص إلى الوسط", }, align_right: { tooltip: "محاذاة النص إلى اليمين", @@ -248,20 +289,20 @@ export const ar: Dictionary = { upload: { title: "تحميل", file_placeholder: { - image: "تحميل صورة", - video: "تحميل فيديو", - audio: "تحميل صوت", - file: "تحميل ملف", + image: "تحميل الصورة", + video: "تحميل الفيديو", + audio: "تحميل الصوت", + file: "تحميل الملف", } as Record, upload_error: "خطأ: فشل التحميل", }, embed: { title: "تضمين", embed_button: { - image: "تضمين صورة", - video: "تضمين فيديو", - audio: "تضمين صوت", - file: "تضمين ملف", + image: "تضمين الصورة", + video: "تضمين الفيديو", + audio: "تضمين الصوت", + file: "تضمين الملف", } as Record, url_placeholder: "أدخل الرابط", }, @@ -271,15 +312,15 @@ export const ar: Dictionary = { tooltip: "إزالة الرابط", }, edit: { - text: "تحرير الرابط", - tooltip: "تحرير", + text: "تعديل الرابط", + tooltip: "تعديل", }, open: { - tooltip: "فتح في تبويب جديد", + tooltip: "افتح في علامة تبويب جديدة", }, form: { - title_placeholder: "تحرير العنوان", - url_placeholder: "تحرير الرابط", + title_placeholder: "تعديل العنوان", + url_placeholder: "تعديل الرابط", }, }, generic: { From 069b5a1a30eeaf870acd6a3e057d145f50b62502 Mon Sep 17 00:00:00 2001 From: Diogo Cadavez Date: Wed, 19 Jun 2024 12:50:31 +0200 Subject: [PATCH 4/7] removed comments --- .../extensions/FilePanel/FilePanelPlugin.ts | 8 ---- .../FormattingToolbarPlugin.ts | 2 - .../LinkToolbar/LinkToolbarPlugin.ts | 4 -- .../Placeholder/PlaceholderPlugin.ts | 2 - .../src/extensions/SideMenu/SideMenuPlugin.ts | 14 ------- .../SuggestionMenu/SuggestionPlugin.ts | 1 - .../TableHandles/TableHandlesPlugin.ts | 37 +++++++------------ 7 files changed, 14 insertions(+), 54 deletions(-) diff --git a/packages/core/src/extensions/FilePanel/FilePanelPlugin.ts b/packages/core/src/extensions/FilePanel/FilePanelPlugin.ts index b738467dc9..1bdbea01ea 100644 --- a/packages/core/src/extensions/FilePanel/FilePanelPlugin.ts +++ b/packages/core/src/extensions/FilePanel/FilePanelPlugin.ts @@ -49,7 +49,6 @@ export class FilePanelView // Setting capture=true ensures that any parent container of the editor that // gets scrolled will trigger the scroll event. Scroll events do not bubble // and so won't propagate to the document by default. - // document.addEventListener("scroll", this.scrollHandler, true); pmView.root.addEventListener("scroll", this.scrollHandler, true); } @@ -70,9 +69,6 @@ export class FilePanelView scrollHandler = () => { if (this.state?.show) { - // const blockElement = document.querySelector( - // `[data-node-type="blockContainer"][data-id="${this.state.block.id}"]` - // )!; const blockElement = this.pmView.root.querySelector( `[data-node-type="blockContainer"][data-id="${this.state.block.id}"]` )!; @@ -88,9 +84,6 @@ export class FilePanelView } = this.pluginKey.getState(view.state); if (!this.state?.show && pluginState.block && this.editor.isEditable) { - // const blockElement = document.querySelector( - // `[data-node-type="blockContainer"][data-id="${pluginState.block.id}"]` - // )!; const blockElement = this.pmView.root.querySelector( `[data-node-type="blockContainer"][data-id="${pluginState.block.id}"]` )!; @@ -131,7 +124,6 @@ export class FilePanelView this.pmView.dom.removeEventListener("dragstart", this.dragstartHandler); - // document.removeEventListener("scroll", this.scrollHandler, true); this.pmView.root.removeEventListener("scroll", this.scrollHandler, true); } } diff --git a/packages/core/src/extensions/FormattingToolbar/FormattingToolbarPlugin.ts b/packages/core/src/extensions/FormattingToolbar/FormattingToolbarPlugin.ts index 05567a42cb..0db0daa6bc 100644 --- a/packages/core/src/extensions/FormattingToolbar/FormattingToolbarPlugin.ts +++ b/packages/core/src/extensions/FormattingToolbar/FormattingToolbarPlugin.ts @@ -62,7 +62,6 @@ export class FormattingToolbarView implements PluginView { // Setting capture=true ensures that any parent container of the editor that // gets scrolled will trigger the scroll event. Scroll events do not bubble // and so won't propagate to the document by default. - // document.addEventListener("scroll", this.scrollHandler, true); pmView.root.addEventListener("scroll", this.scrollHandler, true); } @@ -148,7 +147,6 @@ export class FormattingToolbarView implements PluginView { this.pmView.dom.removeEventListener("dragstart", this.dragHandler); this.pmView.dom.removeEventListener("dragover", this.dragHandler); - // document.removeEventListener("scroll", this.scrollHandler, true); this.pmView.root.removeEventListener("scroll", this.scrollHandler, true); } diff --git a/packages/core/src/extensions/LinkToolbar/LinkToolbarPlugin.ts b/packages/core/src/extensions/LinkToolbar/LinkToolbarPlugin.ts index 13d8eb954c..258a4d9978 100644 --- a/packages/core/src/extensions/LinkToolbar/LinkToolbarPlugin.ts +++ b/packages/core/src/extensions/LinkToolbar/LinkToolbarPlugin.ts @@ -61,7 +61,6 @@ class LinkToolbarView implements PluginView { }; this.pmView.dom.addEventListener("mouseover", this.mouseOverHandler); - // document.addEventListener("click", this.clickHandler, true); this.pmView.root.addEventListener( "click", this.clickHandler as EventListener, @@ -71,7 +70,6 @@ class LinkToolbarView implements PluginView { // Setting capture=true ensures that any parent container of the editor that // gets scrolled will trigger the scroll event. Scroll events do not bubble // and so won't propagate to the document by default. - // document.addEventListener("scroll", this.scrollHandler, true); this.pmView.root.addEventListener("scroll", this.scrollHandler, true); } @@ -277,8 +275,6 @@ class LinkToolbarView implements PluginView { destroy() { this.pmView.dom.removeEventListener("mouseover", this.mouseOverHandler); - // document.removeEventListener("scroll", this.scrollHandler, true); - // document.removeEventListener("click", this.clickHandler, true); this.pmView.root.removeEventListener("scroll", this.scrollHandler, true); this.pmView.root.removeEventListener( "click", diff --git a/packages/core/src/extensions/Placeholder/PlaceholderPlugin.ts b/packages/core/src/extensions/Placeholder/PlaceholderPlugin.ts index 2979d879ca..9783a6e2ae 100644 --- a/packages/core/src/extensions/Placeholder/PlaceholderPlugin.ts +++ b/packages/core/src/extensions/Placeholder/PlaceholderPlugin.ts @@ -12,12 +12,10 @@ export const PlaceholderPlugin = ( key: PLUGIN_KEY, view: () => { const styleEl = document.createElement("style"); - // editor.view.root.append(styleEl); const nonce = editor._tiptapEditor.options.injectNonce; if (nonce) { styleEl.setAttribute("nonce", nonce); } - // document.head.appendChild(styleEl); if (editor._tiptapEditor.view.root instanceof ShadowRoot) { editor._tiptapEditor.view.root.append(styleEl); } else if (editor._tiptapEditor.view.root instanceof Document) { diff --git a/packages/core/src/extensions/SideMenu/SideMenuPlugin.ts b/packages/core/src/extensions/SideMenu/SideMenuPlugin.ts index 488c7872e3..c518b6908a 100644 --- a/packages/core/src/extensions/SideMenu/SideMenuPlugin.ts +++ b/packages/core/src/extensions/SideMenu/SideMenuPlugin.ts @@ -146,13 +146,11 @@ function setDragImage(view: EditorView, from: number, to = from) { dragImageElement.className = dragImageElement.className + " bn-drag-preview " + inheritedClasses; - // document.body.appendChild(dragImageElement); view.root.appendChild(dragImageElement); } function unsetDragImage(rootEl: Document | ShadowRoot) { if (dragImageElement !== undefined) { - // document.body.removeChild(dragImageElement); rootEl.removeChild(dragImageElement); dragImageElement = undefined; } @@ -179,7 +177,6 @@ function dragStart< top: e.clientY, }; - // const elements = document.elementsFromPoint(coords.left, coords.top); const elements = view.root.elementsFromPoint(coords.left, coords.top); let blockEl = undefined; @@ -286,13 +283,11 @@ export class SideMenuView< this.pmView.dom.firstChild! as HTMLElement ).getBoundingClientRect().x; - // document.body.addEventListener("drop", this.onDrop, true); this.pmView.root.addEventListener( "drop", this.onDrop as EventListener, true ); - // document.body.addEventListener("dragover", this.onDragOver); this.pmView.root.addEventListener( "dragover", this.onDragOver as EventListener @@ -300,7 +295,6 @@ export class SideMenuView< this.pmView.dom.addEventListener("dragstart", this.onDragStart); // Shows or updates menu position whenever the cursor moves, if the menu isn't frozen. - // document.body.addEventListener("mousemove", this.onMouseMove, true); this.pmView.root.addEventListener( "mousemove", this.onMouseMove as EventListener, @@ -310,7 +304,6 @@ export class SideMenuView< // Unfreezes the menu whenever the user clicks. this.pmView.dom.addEventListener("mousedown", this.onMouseDown); // Hides and unfreezes the menu whenever the user presses a key. - // document.body.addEventListener("keydown", this.onKeyDown, true); this.pmView.root.addEventListener( "keydown", this.onKeyDown as EventListener, @@ -320,7 +313,6 @@ export class SideMenuView< // Setting capture=true ensures that any parent container of the editor that // gets scrolled will trigger the scroll event. Scroll events do not bubble // and so won't propagate to the document by default. - // document.addEventListener("scroll", this.onScroll, true); this.pmView.root.addEventListener("scroll", this.onScroll, true); } @@ -345,7 +337,6 @@ export class SideMenuView< top: this.mousePos.y, }; - // const elements = document.elementsFromPoint(coords.left, coords.top); const elements = this.pmView.root.elementsFromPoint( coords.left, coords.top @@ -580,28 +571,23 @@ export class SideMenuView< this.state.show = false; this.emitUpdate(this.state); } - // document.body.removeEventListener("mousemove", this.onMouseMove, true); this.pmView.root.removeEventListener( "mousemove", this.onMouseMove as EventListener, true ); - // document.body.removeEventListener("dragover", this.onDragOver); this.pmView.root.removeEventListener( "dragover", this.onDragOver as EventListener ); this.pmView.dom.removeEventListener("dragstart", this.onDragStart); - // document.body.removeEventListener("drop", this.onDrop, true); this.pmView.root.removeEventListener( "drop", this.onDrop as EventListener, true ); - // document.removeEventListener("scroll", this.onScroll, true); this.pmView.root.removeEventListener("scroll", this.onScroll, true); this.pmView.dom.removeEventListener("mousedown", this.onMouseDown); - // document.body.removeEventListener("keydown", this.onKeyDown, true); this.pmView.root.removeEventListener( "keydown", this.onKeyDown as EventListener, diff --git a/packages/core/src/extensions/SuggestionMenu/SuggestionPlugin.ts b/packages/core/src/extensions/SuggestionMenu/SuggestionPlugin.ts index 85eb76c24e..d64bd83984 100644 --- a/packages/core/src/extensions/SuggestionMenu/SuggestionPlugin.ts +++ b/packages/core/src/extensions/SuggestionMenu/SuggestionPlugin.ts @@ -42,7 +42,6 @@ class SuggestionMenuView< // Setting capture=true ensures that any parent container of the editor that // gets scrolled will trigger the scroll event. Scroll events do not bubble // and so won't propagate to the document by default. - // document.addEventListener("scroll", this.handleScroll, true); this.rootEl.addEventListener("scroll", this.handleScroll, true); } diff --git a/packages/core/src/extensions/TableHandles/TableHandlesPlugin.ts b/packages/core/src/extensions/TableHandles/TableHandlesPlugin.ts index b52fd03e54..b30f45a92d 100644 --- a/packages/core/src/extensions/TableHandles/TableHandlesPlugin.ts +++ b/packages/core/src/extensions/TableHandles/TableHandlesPlugin.ts @@ -46,7 +46,6 @@ function setHiddenDragImage(rootEl: Document | ShadowRoot) { dragImageElement.style.opacity = "0"; dragImageElement.style.height = "1px"; dragImageElement.style.width = "1px"; - // document.body.appendChild(dragImageElement); if (rootEl instanceof Document) { rootEl.body.appendChild(dragImageElement); } else { @@ -82,9 +81,13 @@ function domCellAround(target: Element | null): Element | null { } // Hides elements in the DOMwith the provided class names. -function hideElementsWithClassNames(classNames: string[]) { +function hideElementsWithClassNames( + classNames: string[], + rootEl: Document | ShadowRoot +) { classNames.forEach((className) => { - const elementsToHide = document.getElementsByClassName(className); + const elementsToHide = rootEl.querySelectorAll(className); + for (let i = 0; i < elementsToHide.length; i++) { (elementsToHide[i] as HTMLElement).style.visibility = "hidden"; } @@ -125,8 +128,6 @@ export class TableHandlesView< pmView.dom.addEventListener("mousemove", this.mouseMoveHandler); - // document.addEventListener("dragover", this.dragOverHandler); - // document.addEventListener("drop", this.dropHandler); pmView.root.addEventListener( "dragover", this.dragOverHandler as EventListener @@ -136,7 +137,6 @@ export class TableHandlesView< // Setting capture=true ensures that any parent container of the editor that // gets scrolled will trigger the scroll event. Scroll events do not bubble // and so won't propagate to the document by default. - // document.addEventListener("scroll", this.scrollHandler, true); pmView.root.addEventListener("scroll", this.scrollHandler, true); } @@ -235,11 +235,14 @@ export class TableHandlesView< event.preventDefault(); event.dataTransfer!.dropEffect = "move"; - hideElementsWithClassNames([ - "column-resize-handle", - "prosemirror-dropcursor-block", - "prosemirror-dropcursor-inline", - ]); + hideElementsWithClassNames( + [ + "column-resize-handle", + "prosemirror-dropcursor-block", + "prosemirror-dropcursor-inline", + ], + this.pmView.root + ); // The mouse cursor coordinates, bounded to the table's bounding box. The // bounding box is shrunk by 1px on each side to ensure that the bounded @@ -257,11 +260,6 @@ export class TableHandlesView< // Gets the table cell element that the bounded mouse cursor coordinates lie // in. - // const tableCellElements = document - // .elementsFromPoint(boundedMouseCoords.left, boundedMouseCoords.top) - // .filter( - // (element) => element.tagName === "TD" || element.tagName === "TH" - // ); const tableCellElements = this.pmView.root .elementsFromPoint(boundedMouseCoords.left, boundedMouseCoords.top) .filter( @@ -363,9 +361,6 @@ export class TableHandlesView< scrollHandler = () => { if (this.state?.show) { - // const tableElement = document.querySelector( - // `[data-node-type="blockContainer"][data-id="${this.tableId}"] table` - // )!; const tableElement = this.pmView.root.querySelector( `[data-node-type="blockContainer"][data-id="${this.tableId}"] table` )!; @@ -383,10 +378,6 @@ export class TableHandlesView< destroy() { this.pmView.dom.removeEventListener("mousemove", this.mouseMoveHandler); - - // document.removeEventListener("dragover", this.dragOverHandler); - // document.removeEventListener("drop", this.dropHandler); - // document.removeEventListener("scroll", this.scrollHandler, true); this.pmView.root.removeEventListener( "dragover", this.dragOverHandler as EventListener From 2cb57b3313ae937ad1008ebe12d98848b5a636b1 Mon Sep 17 00:00:00 2001 From: Matthew Lipski Date: Mon, 24 Jun 2024 20:14:15 +0200 Subject: [PATCH 5/7] Implemented PR feedback --- packages/core/src/api/parsers/utils.ts | 27 ------------------- .../Placeholder/PlaceholderPlugin.ts | 4 +-- .../src/extensions/SideMenu/SideMenuPlugin.ts | 6 ++++- 3 files changed, 7 insertions(+), 30 deletions(-) delete mode 100644 packages/core/src/api/parsers/utils.ts diff --git a/packages/core/src/api/parsers/utils.ts b/packages/core/src/api/parsers/utils.ts deleted file mode 100644 index 7a16f3e1eb..0000000000 --- a/packages/core/src/api/parsers/utils.ts +++ /dev/null @@ -1,27 +0,0 @@ -/** - * Create a Blob from a File object - * @param file - * @returns Blob or null - */ -export function createBlobFromFile(file: File): Promise { - return new Promise((resolve) => { - if (!file) { - resolve(null); - } - - const reader = new FileReader(); - reader.onload = () => { - const result = reader.result as string; - fetch(result) - .then((res) => res.blob()) - .then((blob) => { - resolve(blob); - }) - .catch(() => { - resolve(null); - }); - }; - - reader.readAsDataURL(file); - }); -} diff --git a/packages/core/src/extensions/Placeholder/PlaceholderPlugin.ts b/packages/core/src/extensions/Placeholder/PlaceholderPlugin.ts index 9783a6e2ae..35259d4322 100644 --- a/packages/core/src/extensions/Placeholder/PlaceholderPlugin.ts +++ b/packages/core/src/extensions/Placeholder/PlaceholderPlugin.ts @@ -18,7 +18,7 @@ export const PlaceholderPlugin = ( } if (editor._tiptapEditor.view.root instanceof ShadowRoot) { editor._tiptapEditor.view.root.append(styleEl); - } else if (editor._tiptapEditor.view.root instanceof Document) { + } else { editor._tiptapEditor.view.root.head.appendChild(styleEl); } @@ -69,7 +69,7 @@ export const PlaceholderPlugin = ( destroy: () => { if (editor._tiptapEditor.view.root instanceof ShadowRoot) { editor._tiptapEditor.view.root.removeChild(styleEl); - } else if (editor._tiptapEditor.view.root instanceof Document) { + } else { editor._tiptapEditor.view.root.head.removeChild(styleEl); } }, diff --git a/packages/core/src/extensions/SideMenu/SideMenuPlugin.ts b/packages/core/src/extensions/SideMenu/SideMenuPlugin.ts index c518b6908a..28bca37eb2 100644 --- a/packages/core/src/extensions/SideMenu/SideMenuPlugin.ts +++ b/packages/core/src/extensions/SideMenu/SideMenuPlugin.ts @@ -146,7 +146,11 @@ function setDragImage(view: EditorView, from: number, to = from) { dragImageElement.className = dragImageElement.className + " bn-drag-preview " + inheritedClasses; - view.root.appendChild(dragImageElement); + if (view.root instanceof ShadowRoot) { + view.root.appendChild(dragImageElement); + } else { + view.root.body.appendChild(dragImageElement); + } } function unsetDragImage(rootEl: Document | ShadowRoot) { From 4c8c708aa9e67c40411707fa26a7cca4f95b20f2 Mon Sep 17 00:00:00 2001 From: Matthew Lipski Date: Mon, 24 Jun 2024 20:30:02 +0200 Subject: [PATCH 6/7] Fixed drop error --- packages/core/src/extensions/SideMenu/SideMenuPlugin.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/core/src/extensions/SideMenu/SideMenuPlugin.ts b/packages/core/src/extensions/SideMenu/SideMenuPlugin.ts index 28bca37eb2..3f5e02075c 100644 --- a/packages/core/src/extensions/SideMenu/SideMenuPlugin.ts +++ b/packages/core/src/extensions/SideMenu/SideMenuPlugin.ts @@ -155,7 +155,12 @@ function setDragImage(view: EditorView, from: number, to = from) { function unsetDragImage(rootEl: Document | ShadowRoot) { if (dragImageElement !== undefined) { - rootEl.removeChild(dragImageElement); + if (rootEl instanceof ShadowRoot) { + rootEl.removeChild(dragImageElement); + } else { + rootEl.body.appendChild(dragImageElement); + } + dragImageElement = undefined; } } From c762180a2133b56e0f1f0ef6b612ba39d2db9121 Mon Sep 17 00:00:00 2001 From: Matthew Lipski Date: Mon, 24 Jun 2024 20:54:19 +0200 Subject: [PATCH 7/7] Small test fix --- tests/src/end-to-end/dragdrop/dragdrop.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/src/end-to-end/dragdrop/dragdrop.test.ts b/tests/src/end-to-end/dragdrop/dragdrop.test.ts index f51fd953f1..62f11f4324 100644 --- a/tests/src/end-to-end/dragdrop/dragdrop.test.ts +++ b/tests/src/end-to-end/dragdrop/dragdrop.test.ts @@ -1,10 +1,10 @@ import { test } from "../../setup/setupScript"; import { BASE_URL, - BLOCK_CONTAINER_SELECTOR, H_ONE_BLOCK_SELECTOR, H_THREE_BLOCK_SELECTOR, H_TWO_BLOCK_SELECTOR, + PARAGRAPH_SELECTOR, } from "../../utils/const"; import { compareDocToSnapshot, focusOnEditor } from "../../utils/editor"; import { insertHeading, insertParagraph } from "../../utils/copypaste"; @@ -75,7 +75,7 @@ test.describe("Check Block Dragging Functionality", () => { // Dragging third heading into outside nesting. dragTarget = await page.locator(H_THREE_BLOCK_SELECTOR); - dropTarget = await page.locator(BLOCK_CONTAINER_SELECTOR).last(); + dropTarget = await page.locator(PARAGRAPH_SELECTOR).last(); await dragAndDropBlock(page, dragTarget, dropTarget, true); await compareDocToSnapshot(page, "dragdropnested");