fix: Indent/outdent list controls, closes #6974
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { Command, TextSelection } from "prosemirror-state";
|
||||
import isInCode from "../queries/isInCode";
|
||||
import { isInCode } from "../queries/isInCode";
|
||||
|
||||
/**
|
||||
* Moves the current selection to the previous newline, this is used inside
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Command } from "prosemirror-state";
|
||||
import isNodeActive from "../queries/isNodeActive";
|
||||
import { isNodeActive } from "../queries/isNodeActive";
|
||||
|
||||
/**
|
||||
* Deletes the first paragraph node if it is empty and the cursor is at the
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { NodeType } from "prosemirror-model";
|
||||
import { Command, TextSelection } from "prosemirror-state";
|
||||
import { findBlockNodes } from "../queries/findChildren";
|
||||
import findCollapsedNodes from "../queries/findCollapsedNodes";
|
||||
import { findCollapsedNodes } from "../queries/findCollapsedNodes";
|
||||
|
||||
export default function splitHeading(type: NodeType): Command {
|
||||
return (state, dispatch): boolean => {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { setBlockType } from "prosemirror-commands";
|
||||
import { NodeType } from "prosemirror-model";
|
||||
import { Command } from "prosemirror-state";
|
||||
import isNodeActive from "../queries/isNodeActive";
|
||||
import { isNodeActive } from "../queries/isNodeActive";
|
||||
|
||||
/**
|
||||
* Toggles the block type of the current selection between the given type and the toggle type.
|
||||
|
||||
@@ -3,7 +3,7 @@ import { wrapInList, liftListItem } from "prosemirror-schema-list";
|
||||
import { Command } from "prosemirror-state";
|
||||
import { chainTransactions } from "../lib/chainTransactions";
|
||||
import { findParentNode } from "../queries/findParentNode";
|
||||
import isList from "../queries/isList";
|
||||
import { isList } from "../queries/isList";
|
||||
import clearNodes from "./clearNodes";
|
||||
|
||||
export default function toggleList(
|
||||
|
||||
@@ -2,7 +2,7 @@ import { wrapIn, lift } from "prosemirror-commands";
|
||||
import { NodeType } from "prosemirror-model";
|
||||
import { Command } from "prosemirror-state";
|
||||
import { Primitive } from "utility-types";
|
||||
import isNodeActive from "../queries/isNodeActive";
|
||||
import { isNodeActive } from "../queries/isNodeActive";
|
||||
|
||||
export default function toggleWrap(
|
||||
type: NodeType,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { InputRule as ProsemirrorInputRule } from "prosemirror-inputrules";
|
||||
import { EditorState } from "prosemirror-state";
|
||||
import isInCode from "../queries/isInCode";
|
||||
import { isInCode } from "../queries/isInCode";
|
||||
|
||||
/**
|
||||
* A factory function for creating Prosemirror input rules that automatically insert text
|
||||
|
||||
@@ -4,7 +4,7 @@ import { Command, Plugin } from "prosemirror-state";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
import collapseSelection from "../commands/collapseSelection";
|
||||
import { chainTransactions } from "../lib/chainTransactions";
|
||||
import isMarkActive from "../queries/isMarkActive";
|
||||
import { isMarkActive } from "../queries/isMarkActive";
|
||||
import Mark from "./Mark";
|
||||
|
||||
export default class Comment extends Mark {
|
||||
|
||||
@@ -12,8 +12,8 @@ import { Command, EditorState, Plugin, TextSelection } from "prosemirror-state";
|
||||
import { EditorView } from "prosemirror-view";
|
||||
import { toast } from "sonner";
|
||||
import { sanitizeUrl } from "../../utils/urls";
|
||||
import getMarkRange from "../queries/getMarkRange";
|
||||
import isMarkActive from "../queries/isMarkActive";
|
||||
import { getMarkRange } from "../queries/getMarkRange";
|
||||
import { isMarkActive } from "../queries/isMarkActive";
|
||||
import { EventType } from "../types";
|
||||
import Mark from "./Mark";
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { MarkSpec } from "prosemirror-model";
|
||||
import { Plugin, TextSelection } from "prosemirror-state";
|
||||
import getMarkRange from "../queries/getMarkRange";
|
||||
import { getMarkRange } from "../queries/getMarkRange";
|
||||
import markRule from "../rules/mark";
|
||||
import Mark from "./Mark";
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import { NodeSpec, Node as ProsemirrorNode, NodeType } from "prosemirror-model";
|
||||
import { Command } from "prosemirror-state";
|
||||
import toggleWrap from "../commands/toggleWrap";
|
||||
import { MarkdownSerializerState } from "../lib/markdown/serializer";
|
||||
import isNodeActive from "../queries/isNodeActive";
|
||||
import { isNodeActive } from "../queries/isNodeActive";
|
||||
import Node from "./Node";
|
||||
|
||||
export default class Blockquote extends Node {
|
||||
|
||||
@@ -88,6 +88,13 @@ export default class CheckboxItem extends Node {
|
||||
}
|
||||
};
|
||||
|
||||
commands({ type }: { type: NodeType }) {
|
||||
return {
|
||||
indentCheckboxList: () => sinkListItem(type),
|
||||
outdentCheckboxList: () => liftListItem(type),
|
||||
};
|
||||
}
|
||||
|
||||
keys({ type }: { type: NodeType }) {
|
||||
return {
|
||||
Enter: splitListItem(type, {
|
||||
|
||||
@@ -76,8 +76,8 @@ import Prism from "../extensions/Prism";
|
||||
import { isCode } from "../lib/isCode";
|
||||
import { MarkdownSerializerState } from "../lib/markdown/serializer";
|
||||
import { findParentNode } from "../queries/findParentNode";
|
||||
import getMarkRange from "../queries/getMarkRange";
|
||||
import isInCode from "../queries/isInCode";
|
||||
import { getMarkRange } from "../queries/getMarkRange";
|
||||
import { isInCode } from "../queries/isInCode";
|
||||
import Node from "./Node";
|
||||
|
||||
const PERSISTENCE_KEY = "rme-code-language";
|
||||
|
||||
@@ -2,8 +2,8 @@ import { NodeSpec, NodeType } from "prosemirror-model";
|
||||
import { Command } from "prosemirror-state";
|
||||
import { isInTable } from "prosemirror-tables";
|
||||
import { MarkdownSerializerState } from "../lib/markdown/serializer";
|
||||
import isInCode from "../queries/isInCode";
|
||||
import isNodeActive from "../queries/isNodeActive";
|
||||
import { isInCode } from "../queries/isInCode";
|
||||
import { isNodeActive } from "../queries/isNodeActive";
|
||||
import breakRule from "../rules/breaks";
|
||||
import Node from "./Node";
|
||||
|
||||
|
||||
@@ -14,9 +14,9 @@ import {
|
||||
import { DecorationSet, Decoration } from "prosemirror-view";
|
||||
import { MarkdownSerializerState } from "../lib/markdown/serializer";
|
||||
import { findParentNodeClosestToPos } from "../queries/findParentNode";
|
||||
import getParentListItem from "../queries/getParentListItem";
|
||||
import isInList from "../queries/isInList";
|
||||
import isList from "../queries/isList";
|
||||
import { getParentListItem } from "../queries/getParentListItem";
|
||||
import { isInList } from "../queries/isInList";
|
||||
import { isList } from "../queries/isList";
|
||||
import Node from "./Node";
|
||||
|
||||
export default class ListItem extends Node {
|
||||
|
||||
@@ -3,7 +3,7 @@ import { Decoration, DecorationSet } from "prosemirror-view";
|
||||
import Storage from "../../utils/Storage";
|
||||
import { headingToPersistenceKey } from "../lib/headingToSlug";
|
||||
import { findBlockNodes } from "../queries/findChildren";
|
||||
import findCollapsedNodes from "../queries/findCollapsedNodes";
|
||||
import { findCollapsedNodes } from "../queries/findCollapsedNodes";
|
||||
|
||||
export class FoldingHeadersPlugin extends Plugin {
|
||||
constructor(documentId: string | undefined) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Node } from "prosemirror-model";
|
||||
import { findBlockNodes, NodeWithPos } from "./findChildren";
|
||||
|
||||
export default function findCollapsedNodes(doc: Node): NodeWithPos[] {
|
||||
export function findCollapsedNodes(doc: Node): NodeWithPos[] {
|
||||
const blocks = findBlockNodes(doc);
|
||||
const nodes: NodeWithPos[] = [];
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { ResolvedPos, MarkType } from "prosemirror-model";
|
||||
|
||||
export default function getMarkRange($pos?: ResolvedPos, type?: MarkType) {
|
||||
export function getMarkRange($pos?: ResolvedPos, type?: MarkType) {
|
||||
if (!$pos || !type) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
import { Node } from "prosemirror-model";
|
||||
import { EditorState } from "prosemirror-state";
|
||||
|
||||
export default function getParentListItem(
|
||||
state: EditorState
|
||||
): [Node, number] | void {
|
||||
export function getParentListItem(state: EditorState): [Node, number] | void {
|
||||
const $head = state.selection.$head;
|
||||
for (let d = $head.depth; d > 0; d--) {
|
||||
const node = $head.node(d);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { EditorState } from "prosemirror-state";
|
||||
import isMarkActive from "./isMarkActive";
|
||||
import isNodeActive from "./isNodeActive";
|
||||
import { isMarkActive } from "./isMarkActive";
|
||||
import { isNodeActive } from "./isNodeActive";
|
||||
|
||||
type Options = {
|
||||
/** Only check if the selection is inside a code block. */
|
||||
@@ -16,10 +16,7 @@ type Options = {
|
||||
* @param options The options.
|
||||
* @returns True if the selection is inside a code block or code mark.
|
||||
*/
|
||||
export default function isInCode(
|
||||
state: EditorState,
|
||||
options?: Options
|
||||
): boolean {
|
||||
export function isInCode(state: EditorState, options?: Options): boolean {
|
||||
const { nodes, marks } = state.schema;
|
||||
|
||||
if (!options?.onlyMark) {
|
||||
|
||||
@@ -1,12 +1,19 @@
|
||||
import { EditorState } from "prosemirror-state";
|
||||
|
||||
export default function isInList(state: EditorState) {
|
||||
/**
|
||||
* Check if the current selection is in a list
|
||||
*
|
||||
* @param state - The current editor state
|
||||
* @param options - Optionally check for specific list types
|
||||
*/
|
||||
export function isInList(state: EditorState, options?: { types: string[] }) {
|
||||
const $head = state.selection.$head;
|
||||
for (let d = $head.depth; d > 0; d--) {
|
||||
if (
|
||||
["ordered_list", "bullet_list", "checkbox_list"].includes(
|
||||
$head.node(d).type.name
|
||||
)
|
||||
(options?.types
|
||||
? options.types
|
||||
: ["ordered_list", "bullet_list", "checkbox_list"]
|
||||
).includes($head.node(d).type.name)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Node, Schema } from "prosemirror-model";
|
||||
|
||||
export default function isList(node: Node, schema: Schema) {
|
||||
export function isList(node: Node, schema: Schema) {
|
||||
return (
|
||||
node.type === schema.nodes.bullet_list ||
|
||||
node.type === schema.nodes.ordered_list ||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { MarkType } from "prosemirror-model";
|
||||
import { EditorState } from "prosemirror-state";
|
||||
|
||||
const isMarkActive =
|
||||
export const isMarkActive =
|
||||
(type: MarkType) =>
|
||||
(state: EditorState): boolean => {
|
||||
if (!type) {
|
||||
@@ -14,5 +14,3 @@ const isMarkActive =
|
||||
? type.isInSet(state.storedMarks || $from.marks())
|
||||
: state.doc.rangeHasMark(from, to, type));
|
||||
};
|
||||
|
||||
export default isMarkActive;
|
||||
|
||||
@@ -3,7 +3,7 @@ import { EditorState } from "prosemirror-state";
|
||||
import { Primitive } from "utility-types";
|
||||
import { findParentNode } from "./findParentNode";
|
||||
|
||||
const isNodeActive =
|
||||
export const isNodeActive =
|
||||
(type: NodeType, attrs: Record<string, Primitive> = {}) =>
|
||||
(state: EditorState) => {
|
||||
if (!type) {
|
||||
@@ -26,5 +26,3 @@ const isNodeActive =
|
||||
|
||||
return node.hasMarkup(type, { ...node.attrs, ...attrs });
|
||||
};
|
||||
|
||||
export default isNodeActive;
|
||||
|
||||
Reference in New Issue
Block a user