Skip to content

Commit

Permalink
[lexical-table] Bug Fix: Resolve table selection issue when the mouse…
Browse files Browse the repository at this point in the history
… crosses over a portal (#6834)
  • Loading branch information
etrepum authored Nov 24, 2024
1 parent d9014f3 commit fcb7666
Show file tree
Hide file tree
Showing 28 changed files with 1,252 additions and 637 deletions.
61 changes: 60 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 1 addition & 4 deletions packages/lexical-clipboard/src/clipboard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,16 @@ import {
BaseSelection,
COMMAND_PRIORITY_CRITICAL,
COPY_COMMAND,
getDOMSelection,
isSelectionWithinEditor,
LexicalEditor,
LexicalNode,
SELECTION_INSERT_CLIPBOARD_NODES_COMMAND,
SerializedElementNode,
SerializedTextNode,
} from 'lexical';
import {CAN_USE_DOM} from 'shared/canUseDOM';
import invariant from 'shared/invariant';

const getDOMSelection = (targetWindow: Window | null): Selection | null =>
CAN_USE_DOM ? (targetWindow || window).getSelection() : null;

export interface LexicalClipboardData {
'text/html'?: string | undefined;
'application/x-lexical-editor'?: string | undefined;
Expand Down
5 changes: 0 additions & 5 deletions packages/lexical-playground/__tests__/e2e/Tables.spec.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -2274,7 +2274,6 @@ test.describe.parallel('Tables', () => {
<p class="PlaygroundEditorTheme__paragraph"><br /></p>
`,
);

await unmergeTableCell(page);
await assertHTML(
page,
Expand Down Expand Up @@ -3447,8 +3446,6 @@ test.describe.parallel('Tables', () => {
</div>`,
});

await page.pause();

await assertHTML(
page,
html`
Expand Down Expand Up @@ -3537,8 +3534,6 @@ test.describe.parallel('Tables', () => {
</div>`,
});

await page.pause();

await assertHTML(
page,
html`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ test.describe('Regression test #4697', () => {
false,
false,
);
await page.pause();

await selectCellsFromTableCords(
page,
Expand All @@ -46,6 +47,7 @@ test.describe('Regression test #4697', () => {
false,
false,
);
await page.pause();

await assertTableSelectionCoordinates(page, {
anchor: {x: 2, y: 1},
Expand Down
56 changes: 26 additions & 30 deletions packages/lexical-playground/__tests__/utils/index.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -396,7 +396,7 @@ async function assertSelectionOnPageOrFrame(page, expected) {
focusOffset: fixOffset(focusNode, focusOffset),
focusPath: getPathFromNode(focusNode),
};
}, expected);
});
expect(selection.anchorPath).toEqual(expected.anchorPath);
expect(selection.focusPath).toEqual(expected.focusPath);
if (Array.isArray(expected.anchorOffset)) {
Expand Down Expand Up @@ -738,9 +738,6 @@ export async function dragMouse(
fromX += fromBoundingBox.width;
fromY += fromBoundingBox.height;
}
await page.mouse.move(fromX, fromY);
await page.mouse.down();

let toX = toBoundingBox.x;
let toY = toBoundingBox.y;
if (positionEnd === 'middle') {
Expand All @@ -751,13 +748,9 @@ export async function dragMouse(
toY += toBoundingBox.height;
}

if (slow) {
//simulate more than 1 mouse move event to replicate human slow dragging
await page.mouse.move((fromX + toX) / 2, (fromY + toY) / 2);
}

await page.mouse.move(toX, toY);

await page.mouse.move(fromX, fromY);
await page.mouse.down();
await page.mouse.move(toX, toY, slow ? 10 : 1);
if (mouseUp) {
await page.mouse.up();
}
Expand Down Expand Up @@ -907,72 +900,75 @@ export async function selectCellsFromTableCords(
}:nth-child(${secondCords.x + 1})`,
);

// Focus on inside the iFrame or the boundingBox() below returns null.
await firstRowFirstColumnCell.click();
await page.keyboard.down('Shift');
await secondRowSecondCell.click();
await page.keyboard.up('Shift');

await dragMouse(
// const firstBox = await firstRowFirstColumnCell.boundingBox();
// const secondBox = await secondRowSecondCell.boundingBox();
// await dragMouse(page, firstBox, secondBox, 'middle', 'middle', true, true);
}

export async function clickTableCellActiveButton(page) {
await click(
page,
await firstRowFirstColumnCell.boundingBox(),
await secondRowSecondCell.boundingBox(),
'middle',
'middle',
true,
true,
'.table-cell-action-button-container--active > .table-cell-action-button',
);
}

export async function insertTableRowAbove(page) {
await click(page, '.table-cell-action-button-container');
await clickTableCellActiveButton(page);
await click(page, '.item[data-test-id="table-insert-row-above"]');
}

export async function insertTableRowBelow(page) {
await click(page, '.table-cell-action-button-container');
await clickTableCellActiveButton(page);
await click(page, '.item[data-test-id="table-insert-row-below"]');
}

export async function insertTableColumnBefore(page) {
await click(page, '.table-cell-action-button-container');
await clickTableCellActiveButton(page);
await click(page, '.item[data-test-id="table-insert-column-before"]');
}

export async function insertTableColumnAfter(page) {
await click(page, '.table-cell-action-button-container');
await clickTableCellActiveButton(page);
await click(page, '.item[data-test-id="table-insert-column-after"]');
}

export async function mergeTableCells(page) {
await click(page, '.table-cell-action-button-container');
await clickTableCellActiveButton(page);
await click(page, '.item[data-test-id="table-merge-cells"]');
}

export async function unmergeTableCell(page) {
await click(page, '.table-cell-action-button-container');
await clickTableCellActiveButton(page);
await click(page, '.item[data-test-id="table-unmerge-cells"]');
}

export async function toggleColumnHeader(page) {
await click(page, '.table-cell-action-button-container');
await clickTableCellActiveButton(page);
await click(page, '.item[data-test-id="table-column-header"]');
}

export async function deleteTableRows(page) {
await click(page, '.table-cell-action-button-container');
await clickTableCellActiveButton(page);
await click(page, '.item[data-test-id="table-delete-rows"]');
}

export async function deleteTableColumns(page) {
await click(page, '.table-cell-action-button-container');
await clickTableCellActiveButton(page);
await click(page, '.item[data-test-id="table-delete-columns"]');
}

export async function deleteTable(page) {
await click(page, '.table-cell-action-button-container');
await clickTableCellActiveButton(page);
await click(page, '.item[data-test-id="table-delete"]');
}

export async function setBackgroundColor(page) {
await click(page, '.table-cell-action-button-container');
await clickTableCellActiveButton(page);
await click(page, '.item[data-test-id="table-background-color"]');
}

Expand Down
3 changes: 2 additions & 1 deletion packages/lexical-playground/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@
"@vitejs/plugin-react": "^4.2.1",
"rollup-plugin-copy": "^3.5.0",
"vite": "^5.2.11",
"vite-plugin-replace": "^0.1.1"
"vite-plugin-replace": "^0.1.1",
"vite-plugin-static-copy": "^2.1.0"
},
"sideEffects": false
}
13 changes: 11 additions & 2 deletions packages/lexical-playground/src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -1307,14 +1307,23 @@ i.page-break,
left: 0;
will-change: transform;
}
.table-cell-action-button-container.table-cell-action-button-container--active {
pointer-events: auto;
opacity: 1;
}
.table-cell-action-button-container.table-cell-action-button-container--inactive {
pointer-events: none;
opacity: 0;
}

.table-cell-action-button {
background-color: none;
display: flex;
justify-content: center;
align-items: center;
border: 0;
position: relative;
position: absolute;
top: 10px;
right: 10px;
border-radius: 15px;
color: #222;
display: inline-block;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ import {
CLEAR_EDITOR_COMMAND,
COMMAND_PRIORITY_EDITOR,
createCommand,
getDOMSelection,
KEY_ESCAPE_COMMAND,
} from 'lexical';
import {useCallback, useEffect, useMemo, useRef, useState} from 'react';
Expand Down Expand Up @@ -923,7 +924,7 @@ export default function CommentPlugin({
editor.registerCommand(
INSERT_INLINE_COMMAND,
() => {
const domSelection = window.getSelection();
const domSelection = getDOMSelection(editor._window);
if (domSelection !== null) {
domSelection.removeAllRanges();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {
COMMAND_PRIORITY_CRITICAL,
COMMAND_PRIORITY_HIGH,
COMMAND_PRIORITY_LOW,
getDOMSelection,
KEY_ESCAPE_COMMAND,
LexicalEditor,
SELECTION_CHANGE_COMMAND,
Expand Down Expand Up @@ -77,7 +78,7 @@ function FloatingLinkEditor({
}
}
const editorElem = editorRef.current;
const nativeSelection = window.getSelection();
const nativeSelection = getDOMSelection(editor._window);
const activeElement = document.activeElement;

if (editorElem === null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
$isTextNode,
COMMAND_PRIORITY_LOW,
FORMAT_TEXT_COMMAND,
getDOMSelection,
LexicalEditor,
SELECTION_CHANGE_COMMAND,
} from 'lexical';
Expand Down Expand Up @@ -113,7 +114,7 @@ function TextFormatFloatingToolbar({
const selection = $getSelection();

const popupCharStylesEditorElem = popupCharStylesEditorRef.current;
const nativeSelection = window.getSelection();
const nativeSelection = getDOMSelection(editor._window);

if (popupCharStylesEditorElem === null) {
return;
Expand Down Expand Up @@ -293,7 +294,7 @@ function useFloatingTextFormatToolbar(
return;
}
const selection = $getSelection();
const nativeSelection = window.getSelection();
const nativeSelection = getDOMSelection(editor._window);
const rootElement = editor.getRootElement();

if (
Expand Down
Loading

0 comments on commit fcb7666

Please sign in to comment.