diff --git a/package-lock.json b/package-lock.json index da683e8ad..fdc5d69ec 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1826,12 +1826,13 @@ } }, "@editorjs/editorjs": { - "version": "2.20.0", - "resolved": "https://registry.npmjs.org/@editorjs/editorjs/-/editorjs-2.20.0.tgz", - "integrity": "sha512-e6DWi8bMypFhovq9R6cefaDWVfrlVU++Q7ABp79+MxZIuC/SKAW5EtxBbKPL22H/Mc3bJIhZCxOqEl70HBh2yw==", + "version": "2.22.2", + "resolved": "https://registry.npmjs.org/@editorjs/editorjs/-/editorjs-2.22.2.tgz", + "integrity": "sha512-rPCv7Z5LZebreQaaL4DZuWzoVGEqwB+P7BF1dsefGQNBmLyeLF412topeW2b6e+g4l1oQ7t75kCOACNTEyYYIA==", "requires": { "codex-notifier": "^1.1.2", - "codex-tooltip": "^1.0.1" + "codex-tooltip": "^1.0.2", + "nanoid": "^3.1.22" } }, "@editorjs/embed": { @@ -11530,9 +11531,9 @@ "integrity": "sha512-DCp6xe/LGueJ1N5sXEwcBc3r3PyVkEEDNWCVigfvywAkeXcZMk9K41a31tkEFBW0Ptlwji6/JlAb49E3Yrxbtg==" }, "codex-tooltip": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/codex-tooltip/-/codex-tooltip-1.0.2.tgz", - "integrity": "sha512-oC+Bu5X/zyhbPydgMSLWKoM/+vkJMqaLWu3Dt/jZgXS3MWK23INwC5DMBrVXZSufAFk0i0SUni38k9rLMyZn/w==" + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/codex-tooltip/-/codex-tooltip-1.0.4.tgz", + "integrity": "sha512-Ud+N+y8PMIa9xGyKuo2j3q8QlfTzkMWQ5KeRrbCDerwVn7xq45nqPKQCFBXEMV0YI42/OqSMnsxP8MyVAyVhnA==" }, "collapse-white-space": { "version": "1.0.6", @@ -21820,6 +21821,11 @@ "integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==", "optional": true }, + "nanoid": { + "version": "3.1.30", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.30.tgz", + "integrity": "sha512-zJpuPDwOv8D2zq2WRoMe1HsfZthVewpel9CAvTfc/2mBD1uUT/agc5f7GHGWXlYkFvi1mVxe4IjvP2HNrop7nQ==" + }, "nanomatch": { "version": "1.2.13", "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", diff --git a/package.json b/package.json index fa20deaa8..006c381bd 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ }, "dependencies": { "@apollo/client": "^3.4.15", - "@editorjs/editorjs": "^2.19.3", + "@editorjs/editorjs": "^2.22.2", "@editorjs/header": "^2.6.1", "@editorjs/image": "^2.6.0", "@editorjs/list": "^1.6.1", diff --git a/src/components/RichTextEditor/RichTextEditor.tsx b/src/components/RichTextEditor/RichTextEditor.tsx index 83f52608f..51ff957b3 100644 --- a/src/components/RichTextEditor/RichTextEditor.tsx +++ b/src/components/RichTextEditor/RichTextEditor.tsx @@ -1,5 +1,6 @@ import EditorJS, { LogLevels, OutputData } from "@editorjs/editorjs"; import { FormControl, FormHelperText, InputLabel } from "@material-ui/core"; +import { PromiseQueue } from "@saleor/misc"; import classNames from "classnames"; import React from "react"; @@ -31,7 +32,7 @@ const RichTextEditor: React.FC = ({ const [isFocused, setFocus] = React.useState(false); const editor = React.useRef(); const editorContainer = React.useRef(); - const prevTogglePromise = React.useRef>(); // used to await subsequent toggle invocations + const togglePromiseQueue = React.useRef(PromiseQueue()); // used to await subsequent toggle invocations const initialMount = React.useRef(true); React.useEffect( @@ -75,15 +76,14 @@ const RichTextEditor: React.FC = ({ if (editor.current?.readOnly) { // readOnly.toggle() by itself does not enqueue the events and will result in a broken output if invocations overlap // Remove this logic when this is fixed in EditorJS - if (prevTogglePromise.current instanceof Promise) { - await prevTogglePromise.current; - } - prevTogglePromise.current = editor.current.readOnly.toggle(disabled); + togglePromiseQueue.current.add(() => + editor.current.readOnly.toggle(disabled) + ); // Switching to readOnly with empty blocks present causes the editor to freeze // Remove this logic when this is fixed in EditorJS if (!disabled && !data?.blocks?.length) { - await prevTogglePromise.current; + await togglePromiseQueue.current.queue; editor.current.clear(); } } diff --git a/src/misc.ts b/src/misc.ts index 2ee6df692..e34c5d201 100644 --- a/src/misc.ts +++ b/src/misc.ts @@ -460,3 +460,18 @@ export const flatten = (obj: unknown) => { return result; }; + +export function PromiseQueue() { + let queue = Promise.resolve(); + + function add(operation: (value: T | void) => PromiseLike) { + return new Promise((resolve, reject) => { + queue = queue + .then(operation) + .then(resolve) + .catch(reject); + }); + } + + return { queue, add }; +}