Skip to content

Commit

Permalink
[WEB-1118] fix: table selections using drag handle fixed (#4429)
Browse files Browse the repository at this point in the history
* fix: table selections in using drag handle fixed

* fix: not show drag handles for empty p tags
  • Loading branch information
Palanikannan1437 committed May 10, 2024
1 parent 88ebda4 commit 0ad8bf7
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 47 deletions.
3 changes: 3 additions & 0 deletions packages/editor/core/src/lib/editor-commands.ts
Expand Up @@ -97,6 +97,9 @@ const replaceCodeBlockWithContent = (editor: Editor) => {
const startPos = pos;
const endPos = pos + node.nodeSize;
const textContent = node.textContent;
if (textContent.length === 0) {
editor.chain().focus().toggleCodeBlock().run();
}
replaceCodeBlock(startPos, endPos, textContent);
return false;
}
Expand Down
20 changes: 13 additions & 7 deletions packages/editor/core/src/ui/extensions/table/table/table.ts
Expand Up @@ -218,15 +218,21 @@ export const Table = Node.create({
addKeyboardShortcuts() {
return {
Tab: () => {
if (this.editor.commands.goToNextCell()) {
return true;
}
if (this.editor.isActive("table")) {
if (this.editor.isActive("listItem") || this.editor.isActive("taskItem")) {
return false;
}
if (this.editor.commands.goToNextCell()) {
return true;
}

if (!this.editor.can().addRowAfter()) {
return false;
}
if (!this.editor.can().addRowAfter()) {
return false;
}

return this.editor.chain().addRowAfter().goToNextCell().run();
return this.editor.chain().addRowAfter().goToNextCell().run();
}
return false;
},
"Shift-Tab": () => this.editor.commands.goToPreviousCell(),
Backspace: deleteTableWhenAllCellsSelected,
Expand Down
1 change: 0 additions & 1 deletion packages/editor/core/src/ui/props.tsx
Expand Up @@ -15,7 +15,6 @@ export function CoreEditorProps(editorClassName: string): EditorProps {
if (["ArrowUp", "ArrowDown", "Enter"].includes(event.key)) {
const slashCommand = document.querySelector("#slash-command");
if (slashCommand) {
console.log("registered");
return true;
}
}
Expand Down
105 changes: 66 additions & 39 deletions packages/editor/extensions/src/extensions/drag-drop.tsx
Expand Up @@ -14,6 +14,21 @@ export interface DragHandleOptions {
};
}

export const DragAndDrop = (setHideDragHandle?: (hideDragHandlerFromDragDrop: () => void) => void) =>
Extension.create({
name: "dragAndDrop",

addProseMirrorPlugins() {
return [
DragHandle({
dragHandleWidth: 24,
scrollThreshold: { up: 300, down: 100 },
setHideDragHandle,
}),
];
},
});

function createDragHandleElement(): HTMLElement {
const dragHandleElement = document.createElement("div");
dragHandleElement.draggable = true;
Expand Down Expand Up @@ -49,23 +64,31 @@ function absoluteRect(node: Element) {
}

function nodeDOMAtCoords(coords: { x: number; y: number }) {
return document
.elementsFromPoint(coords.x, coords.y)
.find(
(elem: Element) =>
elem.parentElement?.matches?.(".ProseMirror") ||
elem.matches(
[
"li",
"p:not(:first-child)",
".code-block",
"blockquote",
"h1, h2, h3",
"table",
"[data-type=horizontalRule]",
].join(", ")
)
);
const elements = document.elementsFromPoint(coords.x, coords.y);
const generalSelectors = [
"li",
"p:not(:first-child)",
".code-block",
"blockquote",
"h1, h2, h3",
".table-wrapper",
"[data-type=horizontalRule]",
].join(", ");

for (const elem of elements) {
// 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")) &&
elem?.textContent?.trim() !== ""
) {
return elem; // Return only if p tag is not empty
}
// apply general selector
if (elem.matches(generalSelectors)) {
return elem;
}
}
return null;
}

function nodePosAtDOM(node: Element, view: EditorView, options: DragHandleOptions) {
Expand All @@ -86,15 +109,19 @@ function nodePosAtDOMForBlockquotes(node: Element, view: EditorView) {
})?.inside;
}

function calcNodePos(pos: number, view: EditorView) {
function calcNodePos(pos: number, view: EditorView, node: Element) {
const maxPos = view.state.doc.content.size;
const safePos = Math.max(0, Math.min(pos, maxPos));
const $pos = view.state.doc.resolve(safePos);

if ($pos.depth > 1) {
const newPos = $pos.before($pos.depth);
return Math.max(0, Math.min(newPos, maxPos));
if (node.matches("ul:not([data-type=taskList]) li, ol li")) {
// only for nested lists
const newPos = $pos.before($pos.depth);
return Math.max(0, Math.min(newPos, maxPos));
}
}

return safePos;
}

Expand All @@ -114,12 +141,12 @@ function DragHandle(options: DragHandleOptions) {

let draggedNodePos = nodePosAtDOM(node, view, options);
if (draggedNodePos == null || draggedNodePos < 0) return;
draggedNodePos = calcNodePos(draggedNodePos, view);
draggedNodePos = calcNodePos(draggedNodePos, view, node);

const { from, to } = view.state.selection;
const diff = from - to;

const fromSelectionPos = calcNodePos(from, view);
const fromSelectionPos = calcNodePos(from, view, node);
let differentNodeSelected = false;

const nodePos = view.state.doc.resolve(fromSelectionPos);
Expand Down Expand Up @@ -148,6 +175,19 @@ function DragHandle(options: DragHandleOptions) {
listType = node.parentElement!.tagName;
}

if (node.matches("blockquote")) {
let nodePosForBlockquotes = nodePosAtDOMForBlockquotes(node, view);
if (nodePosForBlockquotes === null || nodePosForBlockquotes === undefined) return;

const docSize = view.state.doc.content.size;
nodePosForBlockquotes = Math.max(0, Math.min(nodePosForBlockquotes, docSize));

if (nodePosForBlockquotes >= 0 && nodePosForBlockquotes <= docSize) {
const nodeSelection = NodeSelection.create(view.state.doc, nodePosForBlockquotes);
view.dispatch(view.state.tr.setSelection(nodeSelection));
}
}

const slice = view.state.selection.content();
const { dom, text } = __serializeForClipboard(view, slice);

Expand Down Expand Up @@ -190,7 +230,7 @@ function DragHandle(options: DragHandleOptions) {
if (nodePos === null || nodePos === undefined) return;

// Adjust the nodePos to point to the start of the node, ensuring NodeSelection can be applied
nodePos = calcNodePos(nodePos, view);
nodePos = calcNodePos(nodePos, view, node);

// Use NodeSelection to select the node at the calculated position
const nodeSelection = NodeSelection.create(view.state.doc, nodePos);
Expand Down Expand Up @@ -279,9 +319,11 @@ function DragHandle(options: DragHandleOptions) {

// Li markers
if (node.matches("ul:not([data-type=taskList]) li, ol li")) {
rect.top += 4;
rect.left -= 18;
}
if (node.matches(".table-wrapper")) {
rect.top += 8;
}

rect.width = options.dragHandleWidth;

Expand Down Expand Up @@ -352,18 +394,3 @@ function DragHandle(options: DragHandleOptions) {
},
});
}

export const DragAndDrop = (setHideDragHandle?: (hideDragHandlerFromDragDrop: () => void) => void) =>
Extension.create({
name: "dragAndDrop",

addProseMirrorPlugins() {
return [
DragHandle({
dragHandleWidth: 24,
scrollThreshold: { up: 300, down: 100 },
setHideDragHandle,
}),
];
},
});

0 comments on commit 0ad8bf7

Please sign in to comment.