mirror of
https://github.com/TriliumNext/Notes.git
synced 2025-07-27 18:12:29 +08:00
fix(move_block): Make the object movable
This commit is contained in:
parent
be447b4139
commit
a23b0c5ec9
@ -8,23 +8,40 @@ export default class MoveBlockUpDownPlugin extends Plugin {
|
|||||||
|
|
||||||
init() {
|
init() {
|
||||||
const editor = this.editor;
|
const editor = this.editor;
|
||||||
editor.config.define('moveBlockUp', {
|
|
||||||
keystroke: ['ctrl+arrowup', 'alt+arrowup'],
|
|
||||||
});
|
|
||||||
editor.config.define('moveBlockDown', {
|
|
||||||
keystroke: ['ctrl+arrowdown', 'alt+arrowdown'],
|
|
||||||
});
|
|
||||||
|
|
||||||
editor.commands.add('moveBlockUp', new MoveBlockUpCommand(editor));
|
editor.commands.add('moveBlockUp', new MoveBlockUpCommand(editor));
|
||||||
editor.commands.add('moveBlockDown', new MoveBlockDownCommand(editor));
|
editor.commands.add('moveBlockDown', new MoveBlockDownCommand(editor));
|
||||||
|
|
||||||
for (const keystroke of editor.config.get('moveBlockUp.keystroke') ?? []) {
|
// Use native DOM capturing to intercept Ctrl/Alt + ↑/↓,
|
||||||
editor.keystrokes.set(keystroke, 'moveBlockUp');
|
// as plugin-level keystroke handling may fail when the selection is near an object.
|
||||||
}
|
this.bindMoveBlockShortcuts(editor);
|
||||||
for (const keystroke of editor.config.get('moveBlockDown.keystroke') ?? []) {
|
|
||||||
editor.keystrokes.set(keystroke, 'moveBlockDown');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bindMoveBlockShortcuts(editor: any) {
|
||||||
|
editor.editing.view.once('render', () => {
|
||||||
|
const domRoot = editor.editing.view.getDomRoot();
|
||||||
|
if (!domRoot) return;
|
||||||
|
|
||||||
|
const handleKeydown = (e: KeyboardEvent) => {
|
||||||
|
const keyMap = {
|
||||||
|
ArrowUp: 'moveBlockUp',
|
||||||
|
ArrowDown: 'moveBlockDown'
|
||||||
|
};
|
||||||
|
|
||||||
|
const command = keyMap[e.key];
|
||||||
|
const isCtrl = e.ctrlKey || e.metaKey;
|
||||||
|
const hasModifier = (isCtrl || e.altKey) && !(isCtrl && e.altKey);
|
||||||
|
|
||||||
|
if (command && hasModifier) {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopImmediatePropagation();
|
||||||
|
editor.execute(command);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
domRoot.addEventListener('keydown', handleKeydown, { capture: true });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,10 +66,10 @@ abstract class MoveBlockUpDownCommand extends Command {
|
|||||||
: [...selectedBlocks].reverse();
|
: [...selectedBlocks].reverse();
|
||||||
|
|
||||||
// Store selection offsets
|
// Store selection offsets
|
||||||
const offsets = [
|
const firstBlock = selectedBlocks[0];
|
||||||
model.document.selection.getFirstPosition()?.offset,
|
const lastBlock = selectedBlocks[selectedBlocks.length - 1];
|
||||||
model.document.selection.getLastPosition()?.offset
|
const startOffset = model.document.selection.getFirstPosition()?.offset ?? 0;
|
||||||
];
|
const endOffset = model.document.selection.getLastPosition()?.offset ?? 0;
|
||||||
|
|
||||||
model.change((writer) => {
|
model.change((writer) => {
|
||||||
// Move blocks
|
// Move blocks
|
||||||
@ -65,19 +82,36 @@ abstract class MoveBlockUpDownCommand extends Command {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Restore selection to all items if many have been moved
|
// Restore selection to all items if many have been moved
|
||||||
const range = writer.createRange(
|
if (
|
||||||
writer.createPositionAt(selectedBlocks[0], offsets[0]),
|
startOffset <= (firstBlock.maxOffset ?? Infinity) &&
|
||||||
writer.createPositionAt(
|
endOffset <= (lastBlock.maxOffset ?? Infinity)
|
||||||
selectedBlocks[selectedBlocks.length - 1], offsets[1]));
|
) {
|
||||||
writer.setSelection(range);
|
writer.setSelection(
|
||||||
|
writer.createRange(
|
||||||
|
writer.createPositionAt(firstBlock, startOffset),
|
||||||
|
writer.createPositionAt(lastBlock, endOffset)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
this.scrollToSelection();
|
this.scrollToSelection();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getSelectedBlocks(selection: DocumentSelection) {
|
getSelectedBlocks(selection: DocumentSelection) {
|
||||||
return [...selection.getSelectedBlocks()];
|
const blocks = [...selection.getSelectedBlocks()];
|
||||||
}
|
|
||||||
|
// If the selected block is an object, such as a block quote or admonition, return the entire block.
|
||||||
|
if (blocks.length === 1) {
|
||||||
|
const block = blocks[0];
|
||||||
|
const parent = block.parent;
|
||||||
|
if (!parent?.name?.startsWith('$')) {
|
||||||
|
return [parent as Element];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return blocks;
|
||||||
|
}
|
||||||
|
|
||||||
scrollToSelection() {
|
scrollToSelection() {
|
||||||
// Ensure scroll happens in sync with DOM updates
|
// Ensure scroll happens in sync with DOM updates
|
||||||
|
Loading…
x
Reference in New Issue
Block a user