Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 70 additions & 19 deletions src/columnresizing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ import { TableMap } from './tablemap';
import { TableView, updateColumnsOnResize } from './tableview';
import type { CellAttrs } from './util';
import { cellAround, pointsAtCell } from './util';

import { getEventCoordinates } from './eventCoor'

/**
* @public
*/
Expand Down Expand Up @@ -95,6 +96,19 @@ export function columnResizing({
mousedown: (view, event) => {
handleMouseDown(view, event, cellMinWidth, defaultCellMinWidth);
},
touchmove: (view, event) => {
console.log('zjzj touchmove', event?.constructor?.name, event)
handleMouseMove(view, event, handleWidth, lastColumnResizable);
},
touchend: (view) => {
handleMouseLeave(view);
},
touchcancel: (view) => {
handleMouseLeave(view);
},
touchstart: (view, event) => {
handleMouseDown(view, event, cellMinWidth, defaultCellMinWidth)
},
},

decorations: (state) => {
Expand Down Expand Up @@ -140,7 +154,7 @@ export class ResizeState {

function handleMouseMove(
view: EditorView,
event: MouseEvent,
event: MouseEvent | TouchEvent,
handleWidth: number,
lastColumnResizable: boolean,
): void {
Expand All @@ -151,12 +165,15 @@ function handleMouseMove(

if (!pluginState.dragging) {
const target = domCellAround(event.target as HTMLElement);
const coords = getEventCoordinates(event);
if (!coords) return;
const { clientX } = coords;
let cell = -1;
if (target) {
const { left, right } = target.getBoundingClientRect();
if (event.clientX - left <= handleWidth)
if (clientX - left <= handleWidth)
cell = edgeCell(view, event, 'left', handleWidth);
else if (right - event.clientX <= handleWidth)
else if (right - clientX <= handleWidth)
cell = edgeCell(view, event, 'right', handleWidth);
}

Expand Down Expand Up @@ -191,7 +208,7 @@ function handleMouseLeave(view: EditorView): void {

function handleMouseDown(
view: EditorView,
event: MouseEvent,
event: MouseEvent | TouchEvent,
cellMinWidth: number,
defaultCellMinWidth: number,
): boolean {
Expand All @@ -205,15 +222,28 @@ function handleMouseDown(

const cell = view.state.doc.nodeAt(pluginState.activeHandle)!;
const width = currentColWidth(view, pluginState.activeHandle, cell.attrs);
const coords = getEventCoordinates(event)
if (!coords) return false;
const { clientX, isMouseEvent, isTouchEvent } = coords;
view.dispatch(
view.state.tr.setMeta(columnResizingPluginKey, {
setDragging: { startX: event.clientX, startWidth: width },
setDragging: { startX: clientX, startWidth: width },
}),
);

function finish(event: MouseEvent) {
win.removeEventListener('mouseup', finish);
win.removeEventListener('mousemove', move);
function finish(event: MouseEvent | TouchEvent) {
const coords = getEventCoordinates(event);
if (!coords) return;
const { isMouseEvent, isTouchEvent } = coords;
if (isMouseEvent) {
win.removeEventListener('mouseup', finish);
win.removeEventListener('mousemove', move);
}
if (isTouchEvent) {
win.removeEventListener('touchend', finish);
win.removeEventListener('touchcancel', finish);
win.removeEventListener('touchmove', move);
}
const pluginState = columnResizingPluginKey.getState(view.state);
if (pluginState?.dragging) {
updateColumnWidth(
Expand All @@ -227,8 +257,15 @@ function handleMouseDown(
}
}

function move(event: MouseEvent): void {
if (!event.which) return finish(event);
function move(event: MouseEvent | TouchEvent): void {
// 对于鼠标事件,检查 which;对于触摸事件,检查是否有有效的触摸点
const coords = getEventCoordinates(event);
if (!coords) return finish(event)
const { isMouseEvent } = coords ?? {};
if (isMouseEvent && !event.which) {
return finish(event);
}

const pluginState = columnResizingPluginKey.getState(view.state);
if (!pluginState) return;
if (pluginState.dragging) {
Expand All @@ -242,15 +279,23 @@ function handleMouseDown(
}
}


displayColumnWidth(
view,
pluginState.activeHandle,
width,
defaultCellMinWidth,
);

win.addEventListener('mouseup', finish);
win.addEventListener('mousemove', move);
if (isMouseEvent) {
win.addEventListener('mouseup', finish);
win.addEventListener('mousemove', move);
}
if (isTouchEvent) {
win.addEventListener('touchend', finish);
win.addEventListener('touchcancel', finish);
win.addEventListener('touchmove', move);
}
event.preventDefault();
return true;
}
Expand Down Expand Up @@ -286,17 +331,20 @@ function domCellAround(target: HTMLElement | null): HTMLElement | null {

function edgeCell(
view: EditorView,
event: MouseEvent,
event: MouseEvent | TouchEvent,
side: 'left' | 'right',
handleWidth: number,
): number {
// posAtCoords returns inconsistent positions when cursor is moving
// across a collapsed table border. Use an offset to adjust the
// target viewport coordinates away from the table border.
const offset = side == 'right' ? -handleWidth : handleWidth;
const coords = getEventCoordinates(event);
if (!coords) return -1;
const { clientX, clientY } = coords;
const found = view.posAtCoords({
left: event.clientX + offset,
top: event.clientY,
left: clientX + offset,
top: clientY,
});
if (!found) return -1;
const { pos } = found;
Expand All @@ -311,12 +359,15 @@ function edgeCell(

function draggedWidth(
dragging: Dragging,
event: MouseEvent,
event: MouseEvent | TouchEvent,
resizeMinWidth: number,
): number {
const offset = event.clientX - dragging.startX;
const coords = getEventCoordinates(event);
if (!coords) return resizeMinWidth;
const { clientX } = coords;
const offset = clientX - dragging.startX;
return Math.max(resizeMinWidth, dragging.startWidth + offset);
}
}

function updateHandle(view: EditorView, value: number): void {
view.dispatch(
Expand Down
14 changes: 14 additions & 0 deletions src/eventCoor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
export const getEventCoordinates = (event: MouseEvent | TouchEvent): { clientX: number; clientY: number; isMouseEvent?: boolean; isTouchEvent?: boolean; } | null => {
// Maybe in micro frontend environment, using `constructor.name` is necessary
if (event?.constructor?.name === 'MouseEvent') {
return { clientX: event.clientX, clientY: event.clientY, isMouseEvent: true };
}
if (event?.constructor?.name === 'TouchEvent') {
const touch = event.touches?.[0] || event.changedTouches?.[0];
console.log('zjzj getEventCoordinates TouchEvent', touch?.clientX, touch)
if (touch) {
return { clientX: touch.clientX, clientY: touch.clientY, isTouchEvent: true };
}
}
return null;
}