mirror of
https://github.com/laurent22/joplin.git
synced 2024-12-24 10:27:10 +02:00
53 lines
1.2 KiB
TypeScript
53 lines
1.2 KiB
TypeScript
import { syntaxTree } from '@codemirror/language';
|
|
import { EditorSelection, EditorState, SelectionRange } from '@codemirror/state';
|
|
|
|
// Expands and returns a copy of [sel] to the smallest container node with name in [nodeNames].
|
|
const growSelectionToNode = (
|
|
state: EditorState, sel: SelectionRange, nodeNames: string|string[]|null,
|
|
): SelectionRange => {
|
|
if (!nodeNames) {
|
|
return sel;
|
|
}
|
|
|
|
const isAcceptableNode = (name: string): boolean => {
|
|
if (typeof nodeNames === 'string') {
|
|
return name === nodeNames;
|
|
}
|
|
|
|
for (const otherName of nodeNames) {
|
|
if (otherName === name) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
};
|
|
|
|
let newFrom = null;
|
|
let newTo = null;
|
|
let smallestLen = Infinity;
|
|
|
|
// Find the smallest range.
|
|
syntaxTree(state).iterate({
|
|
from: sel.from, to: sel.to,
|
|
enter: node => {
|
|
if (isAcceptableNode(node.name)) {
|
|
if (node.to - node.from < smallestLen) {
|
|
newFrom = node.from;
|
|
newTo = node.to;
|
|
smallestLen = newTo - newFrom;
|
|
}
|
|
}
|
|
},
|
|
});
|
|
|
|
// If it's in such a node,
|
|
if (newFrom !== null && newTo !== null) {
|
|
return EditorSelection.range(newFrom, newTo);
|
|
} else {
|
|
return sel;
|
|
}
|
|
};
|
|
|
|
export default growSelectionToNode;
|