In some cases, I want to use a custom way to control the behavior of arrow key pressing, but when there is an image node in a paragraph node, view.endOfTextblock("up")
does not work as I expected. Is there any other way to deal with it?
Can you be a bit more specific about the circumstances in which this happens and the way it doesn’t do what you expect? Preferably with a minimal example script. When I try this out in a simple line-wrapped paragraph with an image I don’t see anything unexpected.
Here is an example in codesandbox.
In this case it cannot judge the boundary conditions well, is there any alternative method?(I want to know when the caret is leaving current paragraph node)
It’s returning true
there for me (Chrome or Firefox Linux). Which browser and platform are you seeing this on?
Chrome for Windows(Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36)
I tested on firefox(Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:139.0) Gecko/20100101 Firefox/139.0), it is also false.
I tried on those browsers on Windows. Still getting true
when I press up on the line above the image.
How’s it possible?
You can check the code link above, I recorded a video.
Hi, sorry to bother you again, is the above situation a feature or a bug? If it is the former, is there a suitable alternative under this condition?
Finally I found a way to deal with this situation. In order to prevent someone from encountering the same problem as me, I put my solution here. This may not be the best solution. Any comments are welcome.
const isCaretAtFirstLine = (selection: Selection, view?: EditorView) => {
if (!view) return false;
const { to } = selection;
const { target, start, before } = findSelectionNode(
selection,
(node) => node.isBlock
);
if (!target) return false; // target should exist
if (selection instanceof TextSelection) {
return view.coordsAtPos(start).top === view.coordsAtPos(to).top;
}
// node selection
const dom = view.nodeDOM(selection.from) as HTMLElement;
const parentDom = view.nodeDOM(before) as HTMLElement;
return (
dom.getBoundingClientRect().top ===
parentDom.getBoundingClientRect().top
);
};
function findSelectionNode(
selection: Selection,
f: (node: Node) => boolean
) {
const { $from, to } = selection;
let target: Node | null = null;
let before = -1;
let after = -1;
let start = -1;
let end = -1;
for (let i = $from.sharedDepth(to); i > 0; i--) {
if (f($from.node(i))) {
target = $from.node(i);
before = $from.before(i);
after = $from.after(i);
start = $from.start(i);
end = $from.end(i);
break;
}
}
return { target, before, after, start, end };
}
If you’re at the top of a textblock, endOfTextblock("up")
should be returning true. However, until I can reproduce the issue, I won’t be able to do much about it.