mirror of
https://github.com/TriliumNext/Notes.git
synced 2025-07-27 18:12:29 +08:00
fix: moving tables/blockQuote
This commit is contained in:
parent
e6c2f729f4
commit
3a56a16a58
@ -2,8 +2,7 @@
|
|||||||
* https://github.com/TriliumNext/Notes/issues/1002
|
* https://github.com/TriliumNext/Notes/issues/1002
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Command, DocumentSelection, Element, Node, Plugin } from 'ckeditor5';
|
import { Command, DocumentSelection, Element, Node, Plugin, Range } from 'ckeditor5';
|
||||||
|
|
||||||
export default class MoveBlockUpDownPlugin extends Plugin {
|
export default class MoveBlockUpDownPlugin extends Plugin {
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
@ -81,36 +80,54 @@ abstract class MoveBlockUpDownCommand extends Command {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Restore selection to all items if many have been moved
|
// Restore selection
|
||||||
if (
|
let range: Range;
|
||||||
startOffset <= (firstBlock.maxOffset ?? Infinity) &&
|
const maxStart = firstBlock.maxOffset ?? startOffset;
|
||||||
endOffset <= (lastBlock.maxOffset ?? Infinity)
|
const maxEnd = lastBlock.maxOffset ?? endOffset;
|
||||||
) {
|
// If original offsets valid within bounds, restore partial selection
|
||||||
writer.setSelection(
|
if (startOffset <= maxStart && endOffset <= maxEnd) {
|
||||||
writer.createRange(
|
const clampedStart = Math.min(startOffset, maxStart);
|
||||||
writer.createPositionAt(firstBlock, startOffset),
|
const clampedEnd = Math.min(endOffset, maxEnd);
|
||||||
writer.createPositionAt(lastBlock, endOffset)
|
range = writer.createRange(
|
||||||
)
|
writer.createPositionAt(firstBlock, clampedStart),
|
||||||
|
writer.createPositionAt(lastBlock, clampedEnd)
|
||||||
|
);
|
||||||
|
} else { // Fallback: select entire moved blocks (handles tables)
|
||||||
|
range = writer.createRange(
|
||||||
|
writer.createPositionBefore(firstBlock),
|
||||||
|
writer.createPositionAfter(lastBlock)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
writer.setSelection(range);
|
||||||
|
this.editor.editing.view.focus();
|
||||||
|
|
||||||
this.scrollToSelection();
|
this.scrollToSelection();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getSelectedBlocks(selection: DocumentSelection) {
|
getSelectedBlocks(selection: DocumentSelection) {
|
||||||
const blocks = [...selection.getSelectedBlocks()];
|
const blocks = [...selection.getSelectedBlocks()];
|
||||||
|
const resolved: Element[] = [];
|
||||||
|
|
||||||
// If the selected block is an object, such as a block quote or admonition, return the entire block.
|
// Selects elements (such as Mermaid) when there are no blocks
|
||||||
if (blocks.length === 1) {
|
if (!blocks.length) {
|
||||||
const block = blocks[0];
|
const selectedObj = selection.getSelectedElement();
|
||||||
const parent = block.parent;
|
if (selectedObj) {
|
||||||
if (!parent?.name?.startsWith('$')) {
|
return [selectedObj];
|
||||||
return [parent as Element];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return blocks;
|
for (const block of blocks) {
|
||||||
|
let el: Element = block;
|
||||||
|
// Traverse up until the parent is the root ($root) or there is no parent
|
||||||
|
while (el.parent && el.parent.name !== '$root') {
|
||||||
|
el = el.parent as Element;
|
||||||
|
}
|
||||||
|
resolved.push(el);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deduplicate adjacent duplicates (e.g., nested selections resolving to same block)
|
||||||
|
return resolved.filter((blk, idx) => idx === 0 || blk !== resolved[idx - 1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
scrollToSelection() {
|
scrollToSelection() {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user