aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/nodes/formattedText/RichTextMenu.tsx
diff options
context:
space:
mode:
authorgeireann <geireann.lindfield@gmail.com>2024-07-25 15:06:01 -0400
committergeireann <geireann.lindfield@gmail.com>2024-07-25 15:06:01 -0400
commite1db06d59d580aa640212a0d3a6aeecb9122bdf0 (patch)
tree26e61dd0fc7ed4ae6e4eabe00551ff3d9883e7ba /src/client/views/nodes/formattedText/RichTextMenu.tsx
parent6b5455503c9a63648e9d8b475a41fdeef06352ce (diff)
lots more 'any' cleanup and more.
Diffstat (limited to 'src/client/views/nodes/formattedText/RichTextMenu.tsx')
-rw-r--r--src/client/views/nodes/formattedText/RichTextMenu.tsx91
1 files changed, 44 insertions, 47 deletions
diff --git a/src/client/views/nodes/formattedText/RichTextMenu.tsx b/src/client/views/nodes/formattedText/RichTextMenu.tsx
index a612f3c65..247b7c097 100644
--- a/src/client/views/nodes/formattedText/RichTextMenu.tsx
+++ b/src/client/views/nodes/formattedText/RichTextMenu.tsx
@@ -5,7 +5,7 @@ import { observer } from 'mobx-react';
import { lift, wrapIn } from 'prosemirror-commands';
import { Mark, MarkType } from 'prosemirror-model';
import { wrapInList } from 'prosemirror-schema-list';
-import { EditorState, NodeSelection, TextSelection } from 'prosemirror-state';
+import { EditorState, NodeSelection, TextSelection, Transaction } from 'prosemirror-state';
import { EditorView } from 'prosemirror-view';
import * as React from 'react';
import { Doc } from '../../../../fields/Doc';
@@ -17,7 +17,7 @@ import { ObservableReactComponent } from '../../ObservableReactComponent';
import { DocumentView } from '../DocumentView';
import { EquationBox } from '../EquationBox';
import { FieldViewProps } from '../FieldView';
-import { FormattedTextBox } from './FormattedTextBox';
+import { FormattedTextBox, FormattedTextBoxProps } from './FormattedTextBox';
import { updateBullets } from './ProsemirrorExampleTransfer';
import './RichTextMenu.scss';
import { schema } from './schema_rts';
@@ -35,8 +35,8 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
private _linkToRef = React.createRef<HTMLInputElement>();
layoutDoc: Doc | undefined;
- @observable public view?: EditorView = undefined;
- public editorProps: FieldViewProps | undefined;
+ @observable public view?: EditorView & { TextView ?: FormattedTextBox } = undefined;
+ public editorProps: FieldViewProps | AntimodeMenuProps |undefined;
public _brushMap: Map<string, Set<Mark>> = new Map();
@@ -114,17 +114,17 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
}
_disposer: IReactionDisposer | undefined;
componentDidMount() {
- this._disposer = reaction(
- () => DocumentView.Selected().slice(),
- () => this.updateMenu(undefined, undefined, undefined, undefined)
- );
+ // this._disposer = reaction(
+ // () => DocumentView.Selected().slice(),
+ // () => this.updateMenu(undefined, undefined, undefined, undefined)
+ // );
}
componentWillUnmount() {
this._disposer?.();
}
@action
- public updateMenu(view: EditorView | undefined, lastState: EditorState | undefined, props: any, layoutDoc: Doc | undefined) {
+ public updateMenu(view: EditorView | undefined, lastState: EditorState | undefined, props: FormattedTextBoxProps|AntimodeMenuProps|undefined, layoutDoc: Doc | undefined) {
if (this._linkToRef.current?.getBoundingClientRect().width) {
return;
}
@@ -158,7 +158,7 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
this.getTextLinkTargetTitle().then(targetTitle => this.setCurrentLink(targetTitle));
}
- setMark = (mark: Mark, state: EditorState, dispatch: any, dontToggle: boolean = false) => {
+ setMark = (mark: Mark, state: EditorState, dispatch: (tr:Transaction) => void, dontToggle: boolean = false) => {
if (mark) {
const newPos = state.selection.$anchor.node()?.type === schema.nodes.ordered_list ? state.selection.from : state.selection.from;
const node = (state.selection as NodeSelection).node ?? (newPos >= 0 ? state.doc.nodeAt(newPos) : undefined);
@@ -177,17 +177,18 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
toggleMark(mark.type, mark.attrs)(state, dispatch);
}
}
- this.updateMenu(this.view, undefined, undefined, this.layoutDoc);
+ // this.updateMenu(this.view, undefined, undefined, this.layoutDoc);
}
};
// finds font sizes and families in selection
- getActiveAlignment() {
+ getActiveAlignment = () => {
if (this.view && this.TextView?._props.rootSelected?.()) {
- const { path } = this.view.state.selection.$from as any;
- for (let i = path.length - 3; i < path.length && i >= 0; i -= 3) {
- if (path[i]?.type === this.view.state.schema.nodes.paragraph || path[i]?.type === this.view.state.schema.nodes.heading) {
- return path[i].attrs.align || 'left';
+ const from = this.view.state.selection.$from;
+ for (let i = from.depth; i >= 0; i--) {
+ const node = from.node(i);
+ if (node.type === this.view.state.schema.nodes.paragraph || node.type === this.view.state.schema.nodes.heading) {
+ return node.attrs.align || 'left';
}
}
}
@@ -195,7 +196,7 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
}
// finds font sizes and families in selection
- getActiveListStyle() {
+ getActiveListStyle = () => {
const state = this.view?.state;
if (state) {
const pos = state.selection.$anchor;
@@ -321,7 +322,7 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
if (this.view) {
const mark = this.view.state.schema.mark(this.view.state.schema.marks.noAutoLinkAnchor);
this.setMark(mark, this.view.state, this.view.dispatch, false);
- this.TextView.autoLink();
+ this.TextView?.autoLink();
this.view.focus();
}
};
@@ -350,7 +351,7 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
};
setFontField = (value: string, fontField: 'fontSize' | 'fontFamily' | 'fontColor' | 'fontHighlight') => {
- if (this.view) {
+ if (this.TextView && this.view) {
const { text, paragraph } = this.view.state.schema.nodes;
const selNode = this.view.state.selection.$anchor.node();
if (this.view.state.selection.from === 1 && this.view.state.selection.empty && [undefined, text, paragraph].includes(selNode?.type)) {
@@ -360,11 +361,11 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
const attrs: { [key: string]: string } = {};
attrs[fontField] = value;
const fmark = this.view?.state.schema.marks['pF' + fontField.substring(1)].create(attrs);
- this.setMark(fmark, this.view.state, (tx: any) => this.view!.dispatch(tx.addStoredMark(fmark)), true);
+ this.setMark(fmark, this.view.state, (tx: Transaction) => this.view!.dispatch(tx.addStoredMark(fmark)), true);
this.view.focus();
} else {
Doc.UserDoc()[fontField] = value;
- this.updateMenu(this.view, undefined, this.props, this.layoutDoc);
+ // this.updateMenu(this.view, undefined, this.props, this.layoutDoc);
}
};
@@ -383,17 +384,17 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
marks && tx2.setStoredMarks([...marks]);
this.view.dispatch(tx2);
} else
- !wrapInList(schema.nodes.ordered_list)(this.view.state, (tx2: any) => {
+ !wrapInList(schema.nodes.ordered_list)(this.view.state, (tx2: Transaction) => {
const tx3 = updateBullets(tx2, schema, newMapStyle, this.view!.state.selection.from - 1, this.view!.state.selection.to + 1);
marks && tx3.ensureMarks([...marks]);
marks && tx3.setStoredMarks([...marks]);
this.view!.dispatch(tx3);
});
this.view.focus();
- this.updateMenu(this.view, undefined, this.props, this.layoutDoc);
+ // this.updateMenu(this.view, undefined, this.props, this.layoutDoc);
};
- insertSummarizer(state: EditorState, dispatch: any) {
+ insertSummarizer(state: EditorState, dispatch: (tr:Transaction) => void) {
if (state.selection.empty) return false;
const mark = state.schema.marks.summarize.create();
const { tr } = state;
@@ -407,7 +408,7 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
vcenterToggle = () => {
this.layoutDoc && (this.layoutDoc._layout_centered = !this.layoutDoc._layout_centered);
};
- align = (view: EditorView, dispatch: any, alignment: 'left' | 'right' | 'center') => {
+ align = (view: EditorView, dispatch: (tr:Transaction) => void, alignment: 'left' | 'right' | 'center') => {
if (this.TextView?._props.rootSelected?.()) {
let { tr } = view.state;
view.state.doc.nodesBetween(view.state.selection.from, view.state.selection.to, (node, pos) => {
@@ -423,7 +424,7 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
}
};
- paragraphSetup(state: EditorState, dispatch: any, field: 'inset' | 'indent', value?: 0 | 10 | -10) {
+ paragraphSetup(state: EditorState, dispatch: (tr:Transaction) => void, field: 'inset' | 'indent', value?: 0 | 10 | -10) {
let { tr } = state;
state.doc.nodesBetween(state.selection.from, state.selection.to, (node, pos) => {
if (node.type === schema.nodes.paragraph || node.type === schema.nodes.heading) {
@@ -439,9 +440,9 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
return true;
}
- insertBlockquote(state: EditorState, dispatch: any) {
- const { path } = state.selection.$from as any;
- if (path.length > 6 && path[path.length - 6].type === schema.nodes.blockquote) {
+ insertBlockquote(state: EditorState, dispatch: (tr:Transaction) => void) {
+ const node = state.selection.$from.depth ? state.selection.$from.node(state.selection.$from.depth-1): undefined;
+ if (node?.type === schema.nodes.blockquote) {
lift(state, dispatch);
} else {
wrapIn(schema.nodes.blockquote)(state, dispatch);
@@ -449,7 +450,7 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
return true;
}
- insertHorizontalRule(state: EditorState, dispatch: any) {
+ insertHorizontalRule(state: EditorState, dispatch: (tr:Transaction) => void) {
dispatch(state.tr.replaceSelectionWith(state.schema.nodes.horizontal_rule.create()).scrollIntoView());
return true;
}
@@ -497,7 +498,7 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
}
get TextView() {
- return (this.view as any)?.TextView as FormattedTextBox;
+ return this.view?.TextView;
}
get TextViewFieldKey() {
return this.TextView?._props.fieldKey;
@@ -512,11 +513,9 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
}
createLinkButton() {
- const self = this;
-
- function onLinkChange(e: React.ChangeEvent<HTMLInputElement>) {
- self.TextView?.endUndoTypingBatch();
- UndoManager.RunInBatch(() => self.setCurrentLink(e.target.value), 'link change');
+ const onLinkChange = (e: React.ChangeEvent<HTMLInputElement>) => {
+ this.TextView?.endUndoTypingBatch();
+ UndoManager.RunInBatch(() => this.setCurrentLink(e.target.value), 'link change');
}
const link = this.currentLink ? this.currentLink : '';
@@ -524,7 +523,6 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
const button = (
<Tooltip title={<div className="dash-tooltip">set hyperlink</div>} placement="bottom">
{
- // eslint-disable-next-line jsx-a11y/control-has-associated-label
<button type="button" className="antimodeMenu-button color-preview-button">
<FontAwesomeIcon icon="link" size="lg" />
</button>
@@ -589,7 +587,7 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
// TODO: should check for valid URL
@undoBatch
makeLinkToURL = (target: string) => {
- ((this.view as any)?.TextView as FormattedTextBox).makeLinkAnchor(undefined, 'onRadd:rightight', target, target);
+ this.TextView?.makeLinkAnchor(undefined, 'onRadd:rightight', target, target);
};
@undoBatch
@@ -597,12 +595,12 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
if (this.view) {
const linkAnchor = this.view.state.selection.$from.nodeAfter?.marks.find(m => m.type === this.view!.state.schema.marks.linkAnchor);
if (linkAnchor) {
- const allAnchors = linkAnchor.attrs.allAnchors.slice();
- this.TextView.RemoveAnchorFromSelection(allAnchors);
+ const allAnchors = (linkAnchor.attrs.allAnchors as { href: string; title: string; linkId: string; targetId: string; }[]).slice();
+ this.TextView?.RemoveAnchorFromSelection(allAnchors);
// bcz: Argh ... this will remove the link from the document even it's anchored somewhere else in the text which happens if only part of the anchor text was selected.
allAnchors
- .filter((aref: any) => aref?.href.indexOf(Doc.localServerPath()) === 0)
- .forEach((aref: any) => {
+ .filter(aref => aref?.href.indexOf(Doc.localServerPath()) === 0)
+ .forEach(aref => {
const anchorId = aref.href.replace(Doc.localServerPath(), '').split('?')[0];
anchorId && DocServer.GetRefField(anchorId).then(linkDoc => Doc.DeleteLink?.(linkDoc as Doc));
});
@@ -629,7 +627,7 @@ export class ButtonDropdown extends ObservableReactComponent<ButtonDropdownProps
@observable private showDropdown: boolean = false;
private ref: HTMLDivElement | null = null;
- constructor(props: any) {
+ constructor(props: ButtonDropdownProps) {
super(props);
makeObservable(this);
}
@@ -683,7 +681,6 @@ export class ButtonDropdown extends ObservableReactComponent<ButtonDropdownProps
<>
{this._props.button}
{
- // eslint-disable-next-line jsx-a11y/control-has-associated-label
<button type="button" className="dropdown-button antimodeMenu-button" key="antimodebutton" onPointerDown={this.onDropdownClick}>
<FontAwesomeIcon icon="caret-down" size="sm" />
</button>
@@ -697,12 +694,12 @@ export class ButtonDropdown extends ObservableReactComponent<ButtonDropdownProps
}
interface RichTextMenuPluginProps {
- editorProps: any;
+ editorProps: FormattedTextBoxProps;
}
export class RichTextMenuPlugin extends React.Component<RichTextMenuPluginProps> {
// eslint-disable-next-line react/no-unused-class-component-methods
- update(view: EditorView, lastState: EditorState | undefined) {
- RichTextMenu.Instance?.updateMenu(view, lastState, this.props.editorProps, (view as any).TextView?.layoutDoc);
+ update(view: EditorView & {TextView ?: FormattedTextBox}, lastState: EditorState | undefined) {
+ RichTextMenu.Instance?.updateMenu(view, lastState, this.props.editorProps, view.TextView?.layoutDoc);
}
render() {
return null;