aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/nodes/formattedText/RichTextRules.ts
diff options
context:
space:
mode:
authorbobzel <zzzman@gmail.com>2023-05-10 10:08:50 -0400
committerbobzel <zzzman@gmail.com>2023-05-10 10:08:50 -0400
commitebb846116af9c7e65a9d674c765c71c0bf0a7d29 (patch)
treed8278e7c27f7577eb5b4706604144940d12a718e /src/client/views/nodes/formattedText/RichTextRules.ts
parentf912a233a89c8772b22b71d34830ff4b0ba82310 (diff)
parent719da9462f02fd3afda9b0b65de19de9405ab4fc (diff)
Merge branch 'master' into UI_Update_Eric_Ma
Diffstat (limited to 'src/client/views/nodes/formattedText/RichTextRules.ts')
-rw-r--r--src/client/views/nodes/formattedText/RichTextRules.ts95
1 files changed, 46 insertions, 49 deletions
diff --git a/src/client/views/nodes/formattedText/RichTextRules.ts b/src/client/views/nodes/formattedText/RichTextRules.ts
index 5675776fb..cad56b14b 100644
--- a/src/client/views/nodes/formattedText/RichTextRules.ts
+++ b/src/client/views/nodes/formattedText/RichTextRules.ts
@@ -1,11 +1,12 @@
import { ellipsis, emDash, InputRule, smartQuotes, textblockTypeInputRule } from 'prosemirror-inputrules';
import { NodeSelection, TextSelection } from 'prosemirror-state';
-import { DataSym, Doc } from '../../../../fields/Doc';
+import { DataSym, Doc, StrListCast } from '../../../../fields/Doc';
import { Id } from '../../../../fields/FieldSymbols';
+import { List } from '../../../../fields/List';
import { ComputedField } from '../../../../fields/ScriptField';
import { NumCast, StrCast } from '../../../../fields/Types';
import { normalizeEmail } from '../../../../fields/util';
-import { returnFalse, Utils } from '../../../../Utils';
+import { Utils } from '../../../../Utils';
import { DocServer } from '../../../DocServer';
import { Docs, DocUtils } from '../../../documents/Documents';
import { FormattedTextBox } from './FormattedTextBox';
@@ -28,7 +29,7 @@ export class RichTextRules {
emDash,
// > blockquote
- wrappingInputRule(/^\s*>\s$/, schema.nodes.blockquote),
+ wrappingInputRule(/%>$/, schema.nodes.blockquote),
// 1. create numerical ordered list
wrappingInputRule(
@@ -89,8 +90,8 @@ export class RichTextRules {
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 newNode = schema.nodes.dashComment.create({ docid: textDocInline[Id] });
- const dashDoc = schema.nodes.dashDoc.create({ width: 75, height: 35, title: 'dashDoc', docid: textDocInline[Id], float: 'right' });
+ const newNode = schema.nodes.dashComment.create({ docId: textDocInline[Id] });
+ const dashDoc = schema.nodes.dashDoc.create({ width: 75, height: 35, title: 'dashDoc', docId: textDocInline[Id], float: 'right' });
const sm = state.storedMarks || undefined;
const replaced = node
? state.tr
@@ -190,21 +191,6 @@ export class RichTextRules {
}
}),
- // %f create footnote
- new InputRule(new RegExp(/%f$/), (state, match, start, end) => {
- const newNode = schema.nodes.footnote.create({});
- const tr = state.tr;
- tr.deleteRange(start, end).replaceSelectionWith(newNode); // replace insertion with a footnote.
- return tr.setSelection(
- new NodeSelection( // select the footnote node to open its display
- tr.doc.resolve(
- // get the location of the footnote node by subtracting the nodesize of the footnote from the current insertion point anchor (which will be immediately after the footnote node)
- tr.selection.anchor - (tr.selection.$anchor.nodeBefore?.nodeSize || 0)
- )
- )
- );
- }),
-
// activate a style by name using prefix '%<color name>'
new InputRule(new RegExp(/%[a-z]+$/), (state, match, start, end) => {
const color = match[0].substring(1, match[0].length);
@@ -229,6 +215,12 @@ export class RichTextRules {
}),
// stop using active style
+ new InputRule(new RegExp(/%\//), (state, match, start, end) => {
+ setTimeout(this.TextBox.cycleAlternateText);
+ return state.tr.deleteRange(start, end);
+ }),
+
+ // stop using active style
new InputRule(new RegExp(/%%$/), (state, match, start, end) => {
const tr = state.tr.deleteRange(start, end);
const marks = state.tr.selection.$anchor.nodeBefore?.marks;
@@ -248,24 +240,28 @@ export class RichTextRules {
// [[fieldKey:Doc]] => show field of doc
new InputRule(new RegExp(/\[\[([a-zA-Z_\? \-0-9]*)(=[a-zA-Z_@\? /\-0-9]*)?(:[a-zA-Z_@:\.\? \-0-9]+)?\]\]$/), (state, match, start, end) => {
const fieldKey = match[1];
- const docid = match[3]?.replace(':', '');
+ const docId = match[3]?.replace(':', '');
const value = match[2]?.substring(1);
+ const linkToDoc = (target: Doc) => {
+ const rstate = this.TextBox.EditorView?.state;
+ const selection = rstate?.selection.$from.pos;
+ if (rstate) {
+ this.TextBox.EditorView?.dispatch(rstate.tr.setSelection(new TextSelection(rstate.doc.resolve(start), rstate.doc.resolve(end - 3))));
+ }
+
+ DocUtils.MakeLink(this.TextBox.getAnchor(true), target, { linkRelationship: 'portal to:portal from' });
+
+ const fstate = this.TextBox.EditorView?.state;
+ if (fstate && selection) {
+ this.TextBox.EditorView?.dispatch(fstate.tr.setSelection(new TextSelection(fstate.doc.resolve(selection))));
+ }
+ };
if (!fieldKey) {
- if (docid) {
- DocServer.GetRefField(docid).then(docx => {
- const rstate = this.TextBox.EditorView?.state;
- const selection = rstate?.selection.$from.pos;
- if (rstate) {
- this.TextBox.EditorView?.dispatch(rstate.tr.setSelection(new TextSelection(rstate.doc.resolve(start), rstate.doc.resolve(end - 3))));
- }
- const target = (docx instanceof Doc && docx) || Docs.Create.FreeformDocument([], { title: docid, _width: 500, _height: 500 }, docid);
- DocUtils.MakeLink({ doc: this.TextBox.getAnchor(true) }, { doc: target }, 'portal to:portal from', undefined);
-
- const fstate = this.TextBox.EditorView?.state;
- if (fstate && selection) {
- this.TextBox.EditorView?.dispatch(fstate.tr.setSelection(new TextSelection(fstate.doc.resolve(selection))));
- }
- });
+ if (docId) {
+ const target = DocServer.QUERY_SERVER_CACHE(docId);
+ if (target) setTimeout(() => linkToDoc(target));
+ else DocServer.GetRefField(docId).then(docx => linkToDoc((docx instanceof Doc && docx) || Docs.Create.FreeformDocument([], { title: docId + '(auto)', _width: 500, _height: 500 }, docId)));
+
return state.tr.deleteRange(end - 1, end).deleteRange(start, start + 3);
}
return state.tr;
@@ -274,7 +270,7 @@ export class RichTextRules {
const num = value.match(/^[0-9.]$/);
this.Document[DataSym][fieldKey] = value === 'true' ? true : value === 'false' ? false : num ? Number(value) : value;
}
- const fieldView = state.schema.nodes.dashField.create({ fieldKey, docid, hideKey: false });
+ const fieldView = state.schema.nodes.dashField.create({ fieldKey, docId, hideKey: false });
return state.tr.setSelection(new TextSelection(state.doc.resolve(start), state.doc.resolve(end))).replaceSelectionWith(fieldView, true);
}),
@@ -296,7 +292,7 @@ export class RichTextRules {
// create an inline equation node
// eq:<equation>>
- new InputRule(new RegExp(/:eq([a-zA-Z-0-9\(\)]*)$/), (state, match, start, end) => {
+ new InputRule(new RegExp(/%eq([a-zA-Z-0-9\(\)]*)$/), (state, match, start, end) => {
const fieldKey = 'math' + Utils.GenerateGuid();
this.TextBox.dataDoc[fieldKey] = match[1];
const tr = state.tr.setSelection(new TextSelection(state.tr.doc.resolve(end - 3), state.tr.doc.resolve(end))).replaceSelectionWith(schema.nodes.equation.create({ fieldKey }));
@@ -311,16 +307,16 @@ export class RichTextRules {
const fieldKey = match[1] || '';
const fieldParam = match[2]?.replace('…', '...') || '';
const rawdocid = match[3]?.substring(1);
- const docid = rawdocid ? (!rawdocid.includes('@') ? normalizeEmail(Doc.CurrentUserEmail) + '@' + rawdocid : rawdocid) : undefined;
- if (!fieldKey && !docid) return state.tr;
- docid &&
- DocServer.GetRefField(docid).then(docx => {
+ const docId = rawdocid ? (!rawdocid.includes('@') ? normalizeEmail(Doc.CurrentUserEmail) + '@' + rawdocid : rawdocid) : undefined;
+ if (!fieldKey && !docId) return state.tr;
+ docId &&
+ DocServer.GetRefField(docId).then(docx => {
if (!(docx instanceof Doc && docx)) {
- Docs.Create.FreeformDocument([], { title: rawdocid, _width: 500, _height: 500 }, docid);
+ Docs.Create.FreeformDocument([], { title: rawdocid, _width: 500, _height: 500 }, docId);
}
});
const node = (state.doc.resolve(start) as any).nodeAfter;
- const dashDoc = schema.nodes.dashDoc.create({ width: 75, height: 75, title: 'dashDoc', docid, fieldKey: fieldKey + fieldParam, float: 'unset', alias: Utils.GenerateGuid() });
+ const dashDoc = schema.nodes.dashDoc.create({ width: 75, height: 75, title: 'dashDoc', docId, fieldKey: fieldKey + fieldParam, float: 'unset', alias: Utils.GenerateGuid() });
const sm = state.storedMarks || undefined;
return node ? state.tr.replaceRangeWith(start, end, dashDoc).setStoredMarks([...node.marks, ...(sm ? sm : [])]) : state.tr;
}),
@@ -329,10 +325,11 @@ export class RichTextRules {
new InputRule(new RegExp(/#([a-zA-Z_\-]+[a-zA-Z_\-0-9]*)\s$/), (state, match, start, end) => {
const tag = match[1];
if (!tag) return state.tr;
- this.Document[DataSym]['#' + tag] = '#' + tag;
- const tags = StrCast(this.Document[DataSym].tags, ':');
- if (!tags.includes(`#${tag}:`)) {
- this.Document[DataSym].tags = `${tags + '#' + tag + ':'}`;
+ //this.Document[DataSym]['#' + tag] = '#' + tag;
+ const tags = StrListCast(this.Document[DataSym].tags);
+ if (!tags.includes(tag)) {
+ tags.push(tag);
+ this.Document[DataSym].tags = new List<string>(tags);
}
const fieldView = state.schema.nodes.dashField.create({ fieldKey: '#' + tag });
return state.tr
@@ -374,7 +371,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 + 1))).setStoredMarks([...node.marks, ...sm]);
+ return replaced.setSelection(new TextSelection(replaced.doc.resolve(end))).setStoredMarks([...node.marks, ...sm]);
}),
new InputRule(new RegExp(/%\)/), (state, match, start, end) => {