610ef8f043
* Add utility functions for saving and restoring the caret location * Implement cross-browser.getSelection * Save and restore location on ContentEditable * Fix refocus by clicking on a field that had a non-collapsed selection
54 lines
1.8 KiB
TypeScript
54 lines
1.8 KiB
TypeScript
// Copyright: Ankitects Pty Ltd and contributors
|
|
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|
|
|
import { getNodeCoordinates } from "./node";
|
|
import type { CaretLocation } from "./location";
|
|
import { compareLocations, Order } from "./location";
|
|
import { getSelection } from "../../lib/cross-browser";
|
|
|
|
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;
|
|
|
|
/* Gecko can have multiple ranges in the selection
|
|
/* this function will get the coordinates of the latest one created */
|
|
export function getSelectionLocation(base: Node): SelectionLocation | null {
|
|
const selection = getSelection(base)!;
|
|
|
|
if (selection.rangeCount === 0) {
|
|
return null;
|
|
}
|
|
|
|
const anchorCoordinates = getNodeCoordinates(selection.anchorNode!, base);
|
|
const anchor = { coordinates: anchorCoordinates, offset: selection.anchorOffset };
|
|
/* selection.isCollapsed will always return true in shadow root in Gecko */
|
|
const collapsed = selection.getRangeAt(selection.rangeCount - 1).collapsed;
|
|
|
|
if (collapsed) {
|
|
return { anchor, collapsed };
|
|
}
|
|
|
|
const focusCoordinates = getNodeCoordinates(selection.focusNode!, base);
|
|
const focus = { coordinates: focusCoordinates, offset: selection.focusOffset };
|
|
const order = compareLocations(anchor, focus);
|
|
|
|
const direction = order === Order.GreaterThan ? "backward" : "forward";
|
|
|
|
return {
|
|
anchor,
|
|
focus,
|
|
collapsed,
|
|
direction,
|
|
};
|
|
}
|