2021-11-09 03:53:39 +01:00
|
|
|
// Copyright: Ankitects Pty Ltd and contributors
|
|
|
|
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|
|
|
|
2022-02-04 09:36:34 +01:00
|
|
|
import { getRange, getSelection } from "../../lib/cross-browser";
|
2021-11-09 03:53:39 +01:00
|
|
|
import type { CaretLocation } from "./location";
|
2021-11-18 10:18:39 +01:00
|
|
|
import { compareLocations, Position } from "./location";
|
2022-02-04 09:36:34 +01:00
|
|
|
import { getNodeCoordinates } from "./node";
|
2021-11-09 03:53:39 +01:00
|
|
|
|
|
|
|
export interface SelectionLocationCollapsed {
|
|
|
|
readonly anchor: CaretLocation;
|
|
|
|
readonly collapsed: true;
|
|
|
|
}
|
|
|
|
|
|
|
|
export interface SelectionLocationContent {
|
|
|
|
readonly anchor: CaretLocation;
|
|
|
|
readonly focus: CaretLocation;
|
|
|
|
readonly collapsed: false;
|
|
|
|
readonly direction: "forward" | "backward";
|
|
|
|
}
|
|
|
|
|
|
|
|
export type SelectionLocation = SelectionLocationCollapsed | SelectionLocationContent;
|
|
|
|
|
|
|
|
export function getSelectionLocation(base: Node): SelectionLocation | null {
|
|
|
|
const selection = getSelection(base)!;
|
2022-01-08 02:46:01 +01:00
|
|
|
const range = getRange(selection);
|
2021-11-09 03:53:39 +01:00
|
|
|
|
2022-01-08 02:46:01 +01:00
|
|
|
if (!range) {
|
2021-11-09 03:53:39 +01:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2022-01-08 02:46:01 +01:00
|
|
|
const collapsed = range.collapsed;
|
2021-11-09 03:53:39 +01:00
|
|
|
const anchorCoordinates = getNodeCoordinates(selection.anchorNode!, base);
|
|
|
|
const anchor = { coordinates: anchorCoordinates, offset: selection.anchorOffset };
|
|
|
|
|
|
|
|
if (collapsed) {
|
|
|
|
return { anchor, collapsed };
|
|
|
|
}
|
|
|
|
|
|
|
|
const focusCoordinates = getNodeCoordinates(selection.focusNode!, base);
|
|
|
|
const focus = { coordinates: focusCoordinates, offset: selection.focusOffset };
|
|
|
|
const order = compareLocations(anchor, focus);
|
|
|
|
|
2021-11-18 10:18:39 +01:00
|
|
|
const direction = order === Position.After ? "backward" : "forward";
|
2021-11-09 03:53:39 +01:00
|
|
|
|
|
|
|
return {
|
|
|
|
anchor,
|
|
|
|
focus,
|
|
|
|
collapsed,
|
|
|
|
direction,
|
|
|
|
};
|
|
|
|
}
|