Skip to content

Commit fc44d00

Browse files
fix: Drag & drop of blocks without inline content opens formatting toolbar (BLO-1116) (#2628)
* fix: move an image doesn't work with drag and drop (#2603) * Removed redundant check in formatting toolbar `shouldShow` * Moved/refactored tests * Implemented PR feedback --------- Co-authored-by: Matthew Lipski <matthewlipski@gmail.com>
1 parent 5edeb54 commit fc44d00

6 files changed

Lines changed: 65 additions & 36 deletions

File tree

packages/core/src/extensions/FormattingToolbar/FormattingToolbar.ts

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { NodeSelection, TextSelection } from "prosemirror-state";
1+
import { TextSelection } from "prosemirror-state";
22

33
import {
44
createExtension,
@@ -16,15 +16,6 @@ export const FormattingToolbarExtension = createExtension(({ editor }) => {
1616
return false;
1717
}
1818

19-
// Don't show if a block with inline content is selected.
20-
if (
21-
tr.selection instanceof NodeSelection &&
22-
(tr.selection.node.type.spec.content === "inline*" ||
23-
tr.selection.node.firstChild?.type.spec.content === "inline*")
24-
) {
25-
return false;
26-
}
27-
2819
// Don't show if the selection is a text selection but contains no text.
2920
if (
3021
tr.selection instanceof TextSelection &&
@@ -61,16 +52,17 @@ export const FormattingToolbarExtension = createExtension(({ editor }) => {
6152
* We want to mimic the Notion behavior of not showing the toolbar while the user is holding down the mouse button (to create a selection)
6253
*/
6354
let preventShowWhileMouseDown = false;
55+
let preventShowWhileDragging = false;
6456

6557
const unsubscribeOnChange = editor.onChange(() => {
66-
if (preventShowWhileMouseDown) {
58+
if (preventShowWhileMouseDown || preventShowWhileDragging) {
6759
return;
6860
}
6961
// re-evaluate whether the toolbar should be shown
7062
store.setState(shouldShow());
7163
});
7264
const unsubscribeOnSelectionChange = editor.onSelectionChange(() => {
73-
if (preventShowWhileMouseDown) {
65+
if (preventShowWhileMouseDown || preventShowWhileDragging) {
7466
return;
7567
}
7668
// re-evaluate whether the toolbar should be shown
@@ -91,6 +83,7 @@ export const FormattingToolbarExtension = createExtension(({ editor }) => {
9183
"pointerup",
9284
() => {
9385
preventShowWhileMouseDown = false;
86+
9487
// We only want to re-show the toolbar if the mouse made the selection
9588
if (editor.isFocused()) {
9689
store.setState(shouldShow());
@@ -102,12 +95,26 @@ export const FormattingToolbarExtension = createExtension(({ editor }) => {
10295
dom.addEventListener(
10396
"pointercancel",
10497
() => {
105-
preventShowWhileMouseDown = false;
98+
preventShowWhileMouseDown = true;
10699
},
107-
{
108-
signal,
109-
capture: true,
100+
{ signal, capture: true },
101+
);
102+
103+
editor.prosemirrorView.root.addEventListener(
104+
"dragstart",
105+
() => {
106+
preventShowWhileDragging = true;
107+
store.setState(false);
108+
},
109+
{ signal },
110+
);
111+
112+
editor.prosemirrorView.root.addEventListener(
113+
"dragend",
114+
() => {
115+
preventShowWhileDragging = false;
110116
},
117+
{ signal },
111118
);
112119

113120
signal.addEventListener("abort", () => {

tests/src/end-to-end/dragdrop/dragdrop.test.ts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
1+
import { expect } from "@playwright/test";
12
import { test } from "../../setup/setupScript.js";
23
import {
34
BASE_URL,
45
H_ONE_BLOCK_SELECTOR,
56
H_THREE_BLOCK_SELECTOR,
67
H_TWO_BLOCK_SELECTOR,
8+
IMAGE_SELECTOR,
79
PARAGRAPH_SELECTOR,
810
} from "../../utils/const.js";
911
import { insertHeading, insertParagraph } from "../../utils/copypaste.js";
1012
import { compareDocToSnapshot, focusOnEditor } from "../../utils/editor.js";
1113
import { dragAndDropBlock } from "../../utils/mouse.js";
14+
import { executeSlashCommand } from "../../utils/slashmenu.js";
1215

1316
test.describe.configure({ mode: "serial" });
1417

@@ -80,4 +83,42 @@ test.describe("Check Block Dragging Functionality", () => {
8083

8184
await compareDocToSnapshot(page, "dragdropnested");
8285
});
86+
87+
test("Should be able to drag image", async ({ page, browserName }) => {
88+
test.skip(
89+
browserName === "firefox",
90+
"Playwright doesn't correctly simulate drag events in Firefox.",
91+
);
92+
await focusOnEditor(page);
93+
await executeSlashCommand(page, "image");
94+
95+
await insertHeading(page, 1);
96+
97+
const dragTarget = await page.locator(IMAGE_SELECTOR);
98+
const dropTarget = await page.locator(H_ONE_BLOCK_SELECTOR);
99+
await page.pause();
100+
await dragAndDropBlock(page, dragTarget, dropTarget, false);
101+
102+
await compareDocToSnapshot(page, "dragImage");
103+
});
104+
105+
test("Formatting toolbar should not appear when dragging image block", async ({
106+
page,
107+
browserName,
108+
}) => {
109+
test.skip(
110+
browserName === "firefox",
111+
"Playwright doesn't correctly simulate drag events in Firefox.",
112+
);
113+
await focusOnEditor(page);
114+
await executeSlashCommand(page, "image");
115+
await insertHeading(page, 1);
116+
117+
const dragTarget = page.locator(IMAGE_SELECTOR);
118+
const dropTarget = page.locator(H_ONE_BLOCK_SELECTOR);
119+
await dragAndDropBlock(page, dragTarget, dropTarget, false);
120+
121+
const toolbar = page.locator(".bn-formatting-toolbar");
122+
await expect(toolbar).not.toBeVisible();
123+
});
83124
});

tests/src/end-to-end/images/images.test.ts-snapshots/dragImage-chromium-linux.json renamed to tests/src/end-to-end/dragdrop/dragdrop.test.ts-snapshots/dragImage-chromium-linux.json

File renamed without changes.

tests/src/end-to-end/images/images.test.ts-snapshots/dragImage-firefox-linux.json renamed to tests/src/end-to-end/dragdrop/dragdrop.test.ts-snapshots/dragImage-firefox-linux.json

File renamed without changes.

tests/src/end-to-end/images/images.test.ts-snapshots/dragImage-webkit-linux.json renamed to tests/src/end-to-end/dragdrop/dragdrop.test.ts-snapshots/dragImage-webkit-linux.json

File renamed without changes.

tests/src/end-to-end/images/images.test.ts

Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,7 @@
11
import { FileChooser, expect } from "@playwright/test";
22
import { test } from "../../setup/setupScript.js";
3-
import {
4-
BASE_URL,
5-
H_ONE_BLOCK_SELECTOR,
6-
IMAGE_SELECTOR,
7-
} from "../../utils/const.js";
8-
import { insertHeading } from "../../utils/copypaste.js";
3+
import { BASE_URL } from "../../utils/const.js";
94
import { compareDocToSnapshot, focusOnEditor } from "../../utils/editor.js";
10-
import { dragAndDropBlock } from "../../utils/mouse.js";
115
import { executeSlashCommand } from "../../utils/slashmenu.js";
126

137
const IMAGE_UPLOAD_PATH = "src/end-to-end/images/placeholder.png";
@@ -115,17 +109,4 @@ test.describe("Check Image Block and Toolbar functionality", () => {
115109

116110
await compareDocToSnapshot(page, "deleteImage");
117111
});
118-
test("Should be able to drag image", async ({ page }) => {
119-
await focusOnEditor(page);
120-
await executeSlashCommand(page, "image");
121-
122-
await insertHeading(page, 1);
123-
124-
const dragTarget = await page.locator(IMAGE_SELECTOR);
125-
const dropTarget = await page.locator(H_ONE_BLOCK_SELECTOR);
126-
await page.pause();
127-
await dragAndDropBlock(page, dragTarget, dropTarget, false);
128-
129-
await compareDocToSnapshot(page, "dragImage");
130-
});
131112
});

0 commit comments

Comments
 (0)