Files
Tom Moor bf45e97641 chore: Enforce type import consistency (#10968)
* Update types

* fix circular dep

* type imports

* lint type imports and --fix
2025-12-19 23:07:02 -05:00

81 lines
2.2 KiB
TypeScript

import type { MarkType } from "prosemirror-model";
import type { EditorState } from "prosemirror-state";
import { NodeSelection } from "prosemirror-state";
import type { Primitive } from "utility-types";
import { getMarksBetween } from "./getMarksBetween";
import { getMarkRangeNodeSelection } from "./getMarkRange";
type Options = {
/** Only return match if the range and attrs is exact */
exact?: boolean;
/** If true then mark must contain entire selection */
inclusive?: boolean;
};
const isNodeMarkActive =
(type: MarkType) =>
(state: EditorState): boolean => {
if (!type) {
return false;
}
const { selection } = state;
if (!(selection instanceof NodeSelection)) {
return false;
}
const mark = getMarkRangeNodeSelection(selection, type);
if (!mark) {
return false;
}
return true;
};
const isInlineMarkActive =
(type: MarkType, attrs?: Record<string, Primitive>, options?: Options) =>
(state: EditorState): boolean => {
if (!type) {
return false;
}
const { from, $from, to, empty } = state.selection;
const hasMark = !!(empty
? type.isInSet(state.storedMarks || $from.marks())
: state.doc.rangeHasMark(from, to, type));
if (!hasMark) {
return false;
}
if (attrs || options) {
const results = getMarksBetween(from, to, state);
return results.some(
({ mark, start, end }) =>
mark.type === type &&
(!attrs ||
Object.keys(attrs).every(
(key) => mark.attrs[key] === attrs[key]
)) &&
(!options?.exact || (start === from && end === to)) &&
(!options?.inclusive || (start <= from && end >= to))
);
}
return true;
};
/**
* Checks if a mark is active in the current selection or not.
*
* @param type The mark type to check.
* @param attrs The attributes to check.
* @param options The options to use.
* @returns A function that checks if a mark is active in the current selection or not.
*/
export const isMarkActive =
(type: MarkType, attrs?: Record<string, Primitive>, options?: Options) =>
(state: EditorState) =>
isInlineMarkActive(type, attrs, options)(state) ||
isNodeMarkActive(type)(state);