文件
mynode/packages/editor/ProseMirror/utils/computeSelectionFormatting.ts
chen 301194963b
一些检查失败了
automerge / automerge (push) Has been cancelled
react-native-android-build-apk / AssembleRelease (push) Has been cancelled
Build macOS M1 / Main (push) Has been cancelled
Joplin Continuous Integration / Main (macos-15-intel) (push) Has been cancelled
Joplin Continuous Integration / Main (ubuntu-22.04) (push) Has been cancelled
Joplin Continuous Integration / Main (ubuntu-22.04-arm) (push) Has been cancelled
Joplin Continuous Integration / Main (windows-11-vs2026-arm) (push) Has been cancelled
Joplin Continuous Integration / Main (windows-2025) (push) Has been cancelled
Joplin Continuous Integration / ServerDockerImage (ubuntu-22.04) (push) Has been cancelled
Joplin Continuous Integration / ServerDockerImage (ubuntu-22.04-arm) (push) Has been cancelled
Joplin UI tests / Main (ubuntu-22.04) (push) Has been cancelled
Joplin UI tests / Main (windows-2025) (push) Has been cancelled
Joplin UI tests / Mobile (push) Has been cancelled
Close stale issues / ProcessStaleIssues (push) Has been cancelled
feat: Initial clean release of CHM
2026-11-04 11:29:39 +08:00

77 行
2.5 KiB
TypeScript

import { MarkType } from 'prosemirror-model';
import { EditorState } from 'prosemirror-state';
import SelectionFormatting, { MutableSelectionFormatting, defaultSelectionFormatting } from '../../SelectionFormatting';
import schema from '../schema';
import { EditorSettings } from '../../types';
const computeSelectionFormatting = (state: EditorState, settings: EditorSettings): SelectionFormatting => {
const doc = state.doc;
const selection = state.selection;
const formatting: MutableSelectionFormatting = {
...defaultSelectionFormatting,
selectedText: doc.textBetween(selection.from, selection.to),
spellChecking: settings.spellcheckEnabled,
};
doc.nodesBetween(selection.from, selection.to, (node) => {
if (node.type === schema.nodes.heading) {
formatting.headerLevel = node.attrs.level;
}
if (node.type === schema.nodes.ordered_list) {
formatting.inOrderedList = true;
formatting.listLevel ++;
}
if (node.type === schema.nodes.bullet_list) {
formatting.inUnorderedList = true;
formatting.listLevel ++;
}
if (node.type === schema.nodes.task_list) {
formatting.inChecklist = true;
formatting.listLevel ++;
}
if (node.type === schema.nodes.pre_block) {
formatting.inCode = true;
}
const linkMark = node.marks.find(mark => mark.type === schema.marks.link);
if (linkMark) {
formatting.linkData = {
linkText: node.textContent,
linkURL: linkMark.attrs.href,
};
formatting.inLink = true;
}
});
const hasMark = (type: MarkType) => {
if (!type) {
throw new Error(`Type not found in schema: ${type}`);
}
// See the corresponding logic in prosemirror-example-setup:
// https://github.com/ProseMirror/prosemirror-example-setup/blob/8c11be6850604081dceda8f36e08d2426875e19a/src/menu.ts#L58
//
// Using state.storedMarks with an empty selection is important to accurately reflect changes made
// **by the user** to the current marks associated with the cursor.
if (selection.empty) {
return !!type.isInSet(state.storedMarks ?? selection.$head.marks());
} else {
return doc.rangeHasMark(selection.from, selection.to, type);
}
};
formatting.inCode ||= hasMark(schema.marks.code);
if (formatting.inCode) {
formatting.unspellCheckableRegion = true;
}
formatting.italicized = hasMark(schema.marks.emphasis);
formatting.bolded = hasMark(schema.marks.strong);
if (formatting.unspellCheckableRegion) {
formatting.spellChecking = false;
}
return formatting;
};
export default computeSelectionFormatting;