Add more highlighter color choices (#7012)

* Add more highlighter color choices, closes #7011

* docs
This commit is contained in:
Tom Moor
2024-06-09 13:54:31 -04:00
committed by GitHub
parent 808415b906
commit ed59b3e350
10 changed files with 167 additions and 34 deletions

View File

@@ -0,0 +1,31 @@
import { Mark } from "prosemirror-model";
import { EditorState } from "prosemirror-state";
/**
* Get all marks that are applied to text between two positions.
*
* @param start The start position
* @param end The end position
* @param state The editor state
* @returns A list of marks
*/
export function getMarksBetween(
start: number,
end: number,
state: EditorState
) {
let marks: { start: number; end: number; mark: Mark }[] = [];
state.doc.nodesBetween(start, end, (node, pos) => {
marks = [
...marks,
...node.marks.map((mark) => ({
start: pos,
end: pos + node.nodeSize,
mark,
})),
];
});
return marks;
}

View File

@@ -1,5 +1,12 @@
import { Node, Schema } from "prosemirror-model";
/**
* Check if a node is a list node.
*
* @param node The node to check
* @param schema The schema to check against
* @returns True if the node is a list node, false otherwise
*/
export function isList(node: Node, schema: Schema) {
return (
node.type === schema.nodes.bullet_list ||

View File

@@ -1,16 +1,38 @@
import { MarkType } from "prosemirror-model";
import { EditorState } from "prosemirror-state";
import { Primitive } from "utility-types";
import { getMarksBetween } from "./getMarksBetween";
/**
* 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.
* @returns A function that checks if a mark is active in the current selection or not.
*/
export const isMarkActive =
(type: MarkType) =>
(type: MarkType, attrs?: Record<string, Primitive>) =>
(state: EditorState): boolean => {
if (!type) {
return false;
}
const { from, $from, to, empty } = state.selection;
return !!(empty
const hasMark = !!(empty
? type.isInSet(state.storedMarks || $from.marks())
: state.doc.rangeHasMark(from, to, type));
if (!hasMark) {
return false;
}
if (attrs) {
const results = getMarksBetween(from, to, state);
return results.some(
({ mark }) =>
mark.type === type &&
Object.keys(attrs).every((key) => mark.attrs[key] === attrs[key])
);
}
return true;
};

View File

@@ -3,6 +3,13 @@ import { EditorState } from "prosemirror-state";
import { Primitive } from "utility-types";
import { findParentNode } from "./findParentNode";
/**
* Checks if a node is active in the current selection or not.
*
* @param type The node type to check.
* @param attrs The attributes to check.
* @returns A function that checks if a node is active in the current selection or not.
*/
export const isNodeActive =
(type: NodeType, attrs: Record<string, Primitive> = {}) =>
(state: EditorState) => {
@@ -14,9 +21,7 @@ export const isNodeActive =
let node = nodeAfter?.type === type ? nodeAfter : undefined;
if (!node) {
const parent = findParentNode((node) => node.type === type)(
state.selection
);
const parent = findParentNode((n) => n.type === type)(state.selection);
node = parent?.node;
}