diff options
author | bobzel <zzzman@gmail.com> | 2024-09-02 09:26:37 -0400 |
---|---|---|
committer | bobzel <zzzman@gmail.com> | 2024-09-02 09:26:37 -0400 |
commit | cda69e48361fce8d71a4dc66edd9dd976a27f52d (patch) | |
tree | 82b9a1a5967ae88a9534f89f7eaed3aeb289652f /src/client/views/nodes/formattedText/RichTextRules.ts | |
parent | c01828308714874589d1f60c33ca59df4c656c0c (diff) | |
parent | a958577d4c27b276aa37484e3f895e196138b17c (diff) |
Merge branch 'master' into alyssa-starter
Diffstat (limited to 'src/client/views/nodes/formattedText/RichTextRules.ts')
-rw-r--r-- | src/client/views/nodes/formattedText/RichTextRules.ts | 59 |
1 files changed, 27 insertions, 32 deletions
diff --git a/src/client/views/nodes/formattedText/RichTextRules.ts b/src/client/views/nodes/formattedText/RichTextRules.ts index bf11dfe62..e0d6c7c05 100644 --- a/src/client/views/nodes/formattedText/RichTextRules.ts +++ b/src/client/views/nodes/formattedText/RichTextRules.ts @@ -1,4 +1,5 @@ import { ellipsis, emDash, InputRule, smartQuotes, textblockTypeInputRule } from 'prosemirror-inputrules'; +import { NodeType } from 'prosemirror-model'; import { NodeSelection, TextSelection } from 'prosemirror-state'; import { ClientUtils } from '../../../../ClientUtils'; import { Doc, DocListCast, FieldResult, StrListCast } from '../../../../fields/Doc'; @@ -6,7 +7,7 @@ import { DocData } from '../../../../fields/DocSymbols'; import { Id } from '../../../../fields/FieldSymbols'; import { List } from '../../../../fields/List'; import { NumCast, StrCast } from '../../../../fields/Types'; -import { Utils } from '../../../../Utils'; +import { emptyFunction, Utils } from '../../../../Utils'; import { Docs } from '../../../documents/Documents'; import { CollectionViewType } from '../../../documents/DocumentTypes'; import { DocUtils } from '../../../documents/DocUtils'; @@ -35,13 +36,7 @@ export class RichTextRules { wrappingInputRule(/%>$/, schema.nodes.blockquote), // 1. create numerical ordered list - wrappingInputRule( - /^1\.\s$/, - schema.nodes.ordered_list, - () => ({ mapStyle: 'decimal', bulletStyle: 1 }), - (match: any, node: any) => node.childCount + node.attrs.order === +match[1], - ((type: any) => ({ type: type, attrs: { mapStyle: 'decimal', bulletStyle: 1 } })) as any - ), + wrappingInputRule(/^1\.\s$/, schema.nodes.ordered_list, () => ({ mapStyle: 'decimal', bulletStyle: 1 }), emptyFunction, ((type: unknown) => ({ type, attrs: { mapStyle: 'decimal', bulletStyle: 1 } })) as unknown as null), // A. create alphabetical ordered list wrappingInputRule( @@ -49,9 +44,8 @@ export class RichTextRules { schema.nodes.ordered_list, // match => { () => ({ mapStyle: 'multi', bulletStyle: 1 }), - // return ({ order: +match[1] }) - (match: any, node: any) => node.childCount + node.attrs.order === +match[1], - ((type: any) => ({ type: type, attrs: { mapStyle: 'multi', bulletStyle: 1 } })) as any + emptyFunction, + ((type: NodeType) => ({ type, attrs: { mapStyle: 'multi', bulletStyle: 1 } })) as unknown as null ), // * + - create bullet list @@ -60,8 +54,8 @@ export class RichTextRules { schema.nodes.ordered_list, // match => { () => ({ mapStyle: 'bullet' }), // ({ order: +match[1] }) - (match: any, node: any) => node.childCount + node.attrs.order === +match[1], - ((type: any) => ({ type: type, attrs: { mapStyle: 'bullet' } })) as any + emptyFunction, + ((type: NodeType) => ({ type: type, attrs: { mapStyle: 'bullet' } })) as unknown as null ), // ``` create code block @@ -93,7 +87,7 @@ export class RichTextRules { const textDoc = this.Document[DocData]; const numInlines = NumCast(textDoc.inlineTextCount); textDoc.inlineTextCount = numInlines + 1; - const node = (state.doc.resolve(start) as any).nodeAfter; + const node = state.doc.resolve(start).nodeAfter; const newNode = schema.nodes.dashComment.create({ docId: doc[Id], reflow: false }); const dashDoc = schema.nodes.dashDoc.create({ width: 75, height: 35, title: 'dashDoc', docId: doc[Id], float: 'right' }); const sm = state.storedMarks || undefined; @@ -137,7 +131,7 @@ export class RichTextRules { textDocInline.proto = textDoc; // make the annotation inherit from the outer text doc so that it can resolve any nested field references, e.g., [[field]] textDoc[inlineLayoutKey] = FormattedTextBox.LayoutString(inlineFieldKey); // create a layout string for the layout key that will render the annotation text textDoc[inlineFieldKey] = ''; // set a default value for the annotation - const node = (state.doc.resolve(start) as any).nodeAfter; + const node = state.doc.resolve(start).nodeAfter; const newNode = schema.nodes.dashComment.create({ docId: textDocInline[Id], reflow: true }); const dashDoc = schema.nodes.dashDoc.create({ width: 75, height: 35, title: 'dashDoc', docId: textDocInline[Id], float: 'right' }); const sm = state.storedMarks || undefined; @@ -154,8 +148,8 @@ export class RichTextRules { // set the First-line indent node type for the selection's paragraph (assumes % was used to initiate an EnteringStyle mode) new InputRule(/(%d|d)$/, (state, match, start, end) => { if (!match[0].startsWith('%') && !this.EnteringStyle) return null; - const pos = state.doc.resolve(start) as any; - for (let depth = pos.path.length / 3 - 1; depth >= 0; depth--) { + const pos = state.doc.resolve(start); + for (let depth = pos.depth; depth >= 0; depth--) { const node = pos.node(depth); if (node.type === schema.nodes.paragraph) { const replaced = state.tr.setNodeMarkup(pos.pos - pos.parentOffset - 1, node.type, { ...node.attrs, indent: node.attrs.indent === 25 ? undefined : 25 }); @@ -169,8 +163,8 @@ export class RichTextRules { // set the Hanging indent node type for the current selection's paragraph (assumes % was used to initiate an EnteringStyle mode) new InputRule(/(%h|h)$/, (state, match, start, end) => { if (!match[0].startsWith('%') && !this.EnteringStyle) return null; - const pos = state.doc.resolve(start) as any; - for (let depth = pos.path.length / 3 - 1; depth >= 0; depth--) { + const pos = state.doc.resolve(start); + for (let depth = pos.depth; depth >= 0; depth--) { const node = pos.node(depth); if (node.type === schema.nodes.paragraph) { const replaced = state.tr.setNodeMarkup(pos.pos - pos.parentOffset - 1, node.type, { ...node.attrs, indent: node.attrs.indent === -25 ? undefined : -25 }); @@ -184,12 +178,12 @@ export class RichTextRules { // set the Quoted indent node type for the current selection's paragraph (assumes % was used to initiate an EnteringStyle mode) new InputRule(/(%q|q)$/, (state, match, start, end) => { if (!match[0].startsWith('%') && !this.EnteringStyle) return null; - const pos = state.doc.resolve(start) as any; + const pos = state.doc.resolve(start); if (state.selection instanceof NodeSelection && state.selection.node.type === schema.nodes.ordered_list) { const { node } = state.selection; return state.tr.setNodeMarkup(pos.pos, node.type, { ...node.attrs, indent: node.attrs.indent === 30 ? undefined : 30 }); } - for (let depth = pos.path.length / 3 - 1; depth >= 0; depth--) { + for (let depth = pos.depth; depth >= 0; depth--) { const node = pos.node(depth); if (node.type === schema.nodes.paragraph) { const replaced = state.tr.setNodeMarkup(pos.pos - pos.parentOffset - 1, node.type, { ...node.attrs, inset: node.attrs.inset === 30 ? undefined : 30 }); @@ -202,9 +196,9 @@ export class RichTextRules { // center justify text new InputRule(/%\^/, (state, match, start, end) => { - const resolved = state.doc.resolve(start) as any; + const resolved = state.doc.resolve(start); if (resolved?.parent.type.name === 'paragraph') { - return state.tr.deleteRange(start, end).setNodeMarkup(resolved.path[resolved.path.length - 4], schema.nodes.paragraph, { ...resolved.parent.attrs, align: 'center' }, resolved.parent.marks); + return state.tr.deleteRange(start, end).setNodeMarkup(resolved.start() - 1, schema.nodes.paragraph, { ...resolved.parent.attrs, align: 'center' }, resolved.parent.marks); } const node = resolved.nodeAfter; const sm = state.storedMarks || undefined; @@ -214,9 +208,9 @@ export class RichTextRules { // left justify text new InputRule(/%\[/, (state, match, start, end) => { - const resolved = state.doc.resolve(start) as any; + const resolved = state.doc.resolve(start); if (resolved?.parent.type.name === 'paragraph') { - return state.tr.deleteRange(start, end).setNodeMarkup(resolved.path[resolved.path.length - 4], schema.nodes.paragraph, { ...resolved.parent.attrs, align: 'left' }, resolved.parent.marks); + return state.tr.deleteRange(start, end).setNodeMarkup(resolved.start() - 1, schema.nodes.paragraph, { ...resolved.parent.attrs, align: 'left' }, resolved.parent.marks); } const node = resolved.nodeAfter; const sm = state.storedMarks || undefined; @@ -226,9 +220,9 @@ export class RichTextRules { // right justify text new InputRule(/%\]/, (state, match, start, end) => { - const resolved = state.doc.resolve(start) as any; + const resolved = state.doc.resolve(start); if (resolved?.parent.type.name === 'paragraph') { - return state.tr.deleteRange(start, end).setNodeMarkup(resolved.path[resolved.path.length - 4], schema.nodes.paragraph, { ...resolved.parent.attrs, align: 'right' }, resolved.parent.marks); + return state.tr.deleteRange(start, end).setNodeMarkup(resolved.start() - 1, schema.nodes.paragraph, { ...resolved.parent.attrs, align: 'right' }, resolved.parent.marks); } const node = resolved.nodeAfter; const sm = state.storedMarks || undefined; @@ -402,7 +396,7 @@ export class RichTextRules { }), // create an inline view of a tag stored under the '#' field - new InputRule(/#([a-zA-Z_-]+[a-zA-Z_\-0-9]*)\s$/, (state, match, start, end) => { + new InputRule(/#(@?[a-zA-Z_-]+[a-zA-Z_\-0-9]*)\s$/, (state, match, start, end) => { const tag = match[1]; if (!tag) return state.tr; // this.Document[DocData]['#' + tag] = '#' + tag; @@ -410,6 +404,7 @@ export class RichTextRules { if (!tags.includes(tag)) { tags.push(tag); this.Document[DocData].tags = new List<string>(tags); + this.Document[DocData].showTags = true; } const fieldView = state.schema.nodes.dashField.create({ fieldKey: '#' + tag }); return state.tr @@ -426,9 +421,9 @@ export class RichTextRules { if (state.selection.to === state.selection.from || !this.EnteringStyle) return null; const tag = match[0] === 't' ? 'todo' : match[0] === 'i' ? 'ignore' : match[0] === 'x' ? 'disagree' : match[0] === '!' ? 'important' : '??'; - const node = (state.doc.resolve(start) as any).nodeAfter; + const node = state.doc.resolve(start).nodeAfter; - if (node?.marks.findIndex((m: any) => m.type === schema.marks.user_tag) !== -1) return state.tr.removeMark(start, end, schema.marks.user_tag); + if (node?.marks.findIndex(m => m.type === schema.marks.user_tag) !== -1) return state.tr.removeMark(start, end, schema.marks.user_tag); return node ? state.tr .removeMark(start, end, schema.marks.user_mark) @@ -438,7 +433,7 @@ export class RichTextRules { }), new InputRule(/%\(/, (state, match, start, end) => { - const node = (state.doc.resolve(start) as any).nodeAfter; + const node = state.doc.resolve(start).nodeAfter; const sm = state.storedMarks?.slice() || []; const mark = state.schema.marks.summarizeInclusive.create(); @@ -447,7 +442,7 @@ export class RichTextRules { const content = selected.selection.content(); const replaced = node ? selected.replaceRangeWith(start, end, schema.nodes.summary.create({ visibility: true, text: content, textslice: content.toJSON() })) : state.tr; - return replaced.setSelection(new TextSelection(replaced.doc.resolve(end))).setStoredMarks([...node.marks, ...sm]); + return replaced.setSelection(new TextSelection(replaced.doc.resolve(end))).setStoredMarks([...(node?.marks ?? []), ...sm]); }), new InputRule(/%\)/, (state, match, start, end) => state.tr.deleteRange(start, end).removeStoredMark(state.schema.marks.summarizeInclusive.create())), |