diff options
| author | bobzel <zzzman@gmail.com> | 2024-04-24 18:12:30 -0400 |
|---|---|---|
| committer | bobzel <zzzman@gmail.com> | 2024-04-24 18:12:30 -0400 |
| commit | b1376d401e709515cee078cc08b05fd3fb89caeb (patch) | |
| tree | d9ed253a539d506589a6c4251b9598dd5d0111f7 /src/client/views/nodes/formattedText | |
| parent | aa4f7b37483c516b92181d3374d3151972b98383 (diff) | |
completing eslint pass
Diffstat (limited to 'src/client/views/nodes/formattedText')
10 files changed, 282 insertions, 277 deletions
diff --git a/src/client/views/nodes/formattedText/DashDocCommentView.tsx b/src/client/views/nodes/formattedText/DashDocCommentView.tsx index a72ed1813..3ec49fa27 100644 --- a/src/client/views/nodes/formattedText/DashDocCommentView.tsx +++ b/src/client/views/nodes/formattedText/DashDocCommentView.tsx @@ -1,60 +1,11 @@ import { TextSelection } from 'prosemirror-state'; import * as ReactDOM from 'react-dom/client'; -import { Doc } from '../../../../fields/Doc'; -import { DocServer } from '../../../DocServer'; import * as React from 'react'; import { IReactionDisposer, computed, reaction } from 'mobx'; +import { Doc } from '../../../../fields/Doc'; +import { DocServer } from '../../../DocServer'; import { NumCast } from '../../../../fields/Types'; -// creates an inline comment in a note when '>>' is typed. -// the comment sits on the right side of the note and vertically aligns with its anchor in the text. -// the comment can be toggled on/off with the '<-' text anchor. -export class DashDocCommentView { - dom: HTMLDivElement; // container for label and value - root: any; - node: any; - - constructor(node: any, view: any, getPos: any) { - this.node = node; - this.dom = document.createElement('div'); - this.dom.style.width = node.attrs.width; - this.dom.style.height = node.attrs.height; - this.dom.style.fontWeight = 'bold'; - this.dom.style.position = 'relative'; - this.dom.style.display = 'inline-block'; - this.dom.onkeypress = function (e: any) { - e.stopPropagation(); - }; - this.dom.onkeydown = function (e: any) { - e.stopPropagation(); - }; - this.dom.onkeyup = function (e: any) { - e.stopPropagation(); - }; - this.dom.onmousedown = function (e: any) { - e.stopPropagation(); - }; - - this.root = ReactDOM.createRoot(this.dom); - this.root.render(<DashDocCommentViewInternal view={view} getPos={getPos} setHeight={this.setHeight} docId={node.attrs.docId} />); - (this as any).dom = this.dom; - } - - setHeight = (hgt: number) => { - !this.node.attrs.reflow && DocServer.GetRefField(this.node.attrs.docId).then(doc => doc instanceof Doc && (this.dom.style.height = hgt + '')); - }; - - destroy() { - this.root.unmount(); - } - deselectNode() { - this.dom.classList.remove('ProseMirror-selectednode'); - } - selectNode() { - this.dom.classList.add('ProseMirror-selectednode'); - } -} - interface IDashDocCommentViewInternal { docId: string; view: any; @@ -65,9 +16,6 @@ interface IDashDocCommentViewInternal { export class DashDocCommentViewInternal extends React.Component<IDashDocCommentViewInternal> { _reactionDisposer: IReactionDisposer | undefined; - @computed get _dashDoc() { - return DocServer.GetRefField(this.props.docId); - } constructor(props: any) { super(props); this.onPointerLeaveCollapsed = this.onPointerLeaveCollapsed.bind(this); @@ -77,58 +25,62 @@ export class DashDocCommentViewInternal extends React.Component<IDashDocCommentV } componentDidMount(): void { this._reactionDisposer?.(); - this._dashDoc.then( - doc => - doc instanceof Doc && - (this._reactionDisposer = reaction( + this._dashDoc.then(doc => { + if (doc instanceof Doc) { + this._reactionDisposer = reaction( () => NumCast((doc as Doc)._height), hgt => this.props.setHeight(hgt), - { - fireImmediately: true, - } - )) - ); + { fireImmediately: true } + ); + } + }); } componentWillUnmount(): void { this._reactionDisposer?.(); } - onPointerLeaveCollapsed(e: any) { + @computed get _dashDoc() { + return DocServer.GetRefField(this.props.docId); + } + + onPointerLeaveCollapsed = (e: any) => { this._dashDoc.then(async dashDoc => dashDoc instanceof Doc && Doc.linkFollowUnhighlight()); e.preventDefault(); e.stopPropagation(); - } + }; - onPointerEnterCollapsed(e: any) { + onPointerEnterCollapsed = (e: any) => { this._dashDoc.then(async dashDoc => dashDoc instanceof Doc && Doc.linkFollowHighlight(dashDoc, false)); e.preventDefault(); e.stopPropagation(); - } + }; - onPointerUpCollapsed(e: any) { + onPointerUpCollapsed = (e: any) => { const target = this.targetNode(); if (target) { const expand = target.hidden; - const tr = this.props.view.state.tr.setNodeMarkup(target.pos, undefined, { ...target.node.attrs, hidden: target.node.attrs.hidden ? false : true }); + const tr = this.props.view.state.tr.setNodeMarkup(target.pos, undefined, { ...target.node.attrs, hidden: !target.node.attrs.hidden }); this.props.view.dispatch(tr.setSelection(TextSelection.create(tr.doc, this.props.getPos() + (expand ? 2 : 1)))); // update the attrs setTimeout(() => { expand && this._dashDoc.then(async dashDoc => dashDoc instanceof Doc && Doc.linkFollowHighlight(dashDoc)); try { this.props.view.dispatch(this.props.view.state.tr.setSelection(TextSelection.create(this.props.view.state.tr.doc, this.props.getPos() + (expand ? 2 : 1)))); - } catch (e) {} + } catch (err) { + /* empty */ + } }, 0); } e.stopPropagation(); - } + }; - onPointerDownCollapsed(e: any) { + onPointerDownCollapsed = (e: any) => { e.stopPropagation(); - } + }; targetNode = () => { // search forward in the prosemirror doc for the attached dashDocNode that is the target of the comment anchor - const state = this.props.view.state; + const { state } = this.props.view; for (let i = this.props.getPos() + 1; i < state.doc.content.size; i++) { const m = state.doc.nodeAt(i); if (m && m.type === state.schema.nodes.dashDoc && m.attrs.docId === this.props.docId) { @@ -141,7 +93,9 @@ export class DashDocCommentViewInternal extends React.Component<IDashDocCommentV setTimeout(() => { try { this.props.view.dispatch(state.tr.setSelection(TextSelection.create(state.tr.doc, this.props.getPos() + 2))); - } catch (e) {} + } catch (err) { + /* empty */ + } }, 0); return undefined; }; @@ -154,7 +108,60 @@ export class DashDocCommentViewInternal extends React.Component<IDashDocCommentV onPointerLeave={this.onPointerLeaveCollapsed} onPointerEnter={this.onPointerEnterCollapsed} onPointerUp={this.onPointerUpCollapsed} - onPointerDown={this.onPointerDownCollapsed}></span> + onPointerDown={this.onPointerDownCollapsed} + /> ); } } + +// creates an inline comment in a note when '>>' is typed. +// the comment sits on the right side of the note and vertically aligns with its anchor in the text. +// the comment can be toggled on/off with the '<-' text anchor. +export class DashDocCommentView { + dom: HTMLDivElement; // container for label and value + root: any; + node: any; + + constructor(node: any, view: any, getPos: any) { + this.node = node; + this.dom = document.createElement('div'); + this.dom.style.width = node.attrs.width; + this.dom.style.height = node.attrs.height; + this.dom.style.fontWeight = 'bold'; + this.dom.style.position = 'relative'; + this.dom.style.display = 'inline-block'; + this.dom.onkeypress = function (e: any) { + e.stopPropagation(); + }; + this.dom.onkeydown = function (e: any) { + e.stopPropagation(); + }; + this.dom.onkeyup = function (e: any) { + e.stopPropagation(); + }; + this.dom.onmousedown = function (e: any) { + e.stopPropagation(); + }; + + this.root = ReactDOM.createRoot(this.dom); + this.root.render(<DashDocCommentViewInternal view={view} getPos={getPos} setHeight={this.setHeight} docId={node.attrs.docId} />); + (this as any).dom = this.dom; + } + + setHeight = (hgt: number) => { + !this.node.attrs.reflow && + DocServer.GetRefField(this.node.attrs.docId).then(doc => { + doc instanceof Doc && (this.dom.style.height = hgt + ''); + }); + }; + + destroy() { + this.root.unmount(); + } + deselectNode() { + this.dom.classList.remove('ProseMirror-selectednode'); + } + selectNode() { + this.dom.classList.add('ProseMirror-selectednode'); + } +} diff --git a/src/client/views/nodes/formattedText/DashDocView.tsx b/src/client/views/nodes/formattedText/DashDocView.tsx index dee7d70bb..f311b3cdd 100644 --- a/src/client/views/nodes/formattedText/DashDocView.tsx +++ b/src/client/views/nodes/formattedText/DashDocView.tsx @@ -1,10 +1,10 @@ +/* eslint-disable jsx-a11y/no-static-element-interactions */ import { action, computed, IReactionDisposer, makeObservable, observable, reaction } from 'mobx'; import { observer } from 'mobx-react'; import { NodeSelection } from 'prosemirror-state'; import * as React from 'react'; import * as ReactDOM from 'react-dom/client'; -import { Utils } from '../../../../Utils'; -import { returnFalse } from '../../../../ClientUtils'; +import { ClientUtils, returnFalse } from '../../../../ClientUtils'; import { Doc } from '../../../../fields/Doc'; import { Height, Width } from '../../../../fields/DocSymbols'; import { NumCast } from '../../../../fields/Types'; @@ -16,63 +16,7 @@ import { DocumentView } from '../DocumentView'; import { FocusViewOptions } from '../FieldView'; import { FormattedTextBox } from './FormattedTextBox'; -var horizPadding = 3; // horizontal padding to container to allow cursor to show up on either side. -export class DashDocView { - dom: HTMLSpanElement; // container for label and value - root: any; - - constructor(node: any, view: any, getPos: any, tbox: FormattedTextBox) { - this.dom = document.createElement('span'); - this.dom.style.position = 'relative'; - this.dom.style.textIndent = '0'; - this.dom.style.width = (+node.attrs.width.toString().replace('px', '') + horizPadding).toString(); - this.dom.style.height = node.attrs.height; - this.dom.style.display = node.attrs.hidden ? 'none' : 'inline-block'; - (this.dom.style as any).float = node.attrs.float; - this.dom.onkeypress = function (e: any) { - e.stopPropagation(); - }; - this.dom.onkeydown = function (e: any) { - e.stopPropagation(); - }; - this.dom.onkeyup = function (e: any) { - e.stopPropagation(); - }; - this.dom.onmousedown = function (e: any) { - e.stopPropagation(); - }; - - this.root = ReactDOM.createRoot(this.dom); - this.root.render( - <DashDocViewInternal - docId={node.attrs.docId} - embedding={node.attrs.embedding} - width={node.attrs.width} - height={node.attrs.height} - hidden={node.attrs.hidden} - fieldKey={node.attrs.fieldKey} - tbox={tbox} - view={view} - node={node} - getPos={getPos} - /> - ); - } - destroy() { - setTimeout(() => { - try { - this.root.unmount(); - } catch {} - }); - } - deselectNode() { - this.dom.style.backgroundColor = ''; - } - selectNode() { - this.dom.style.backgroundColor = 'rgb(141, 182, 247)'; - } -} - +const horizPadding = 3; // horizontal padding to container to allow cursor to show up on either side. interface IDashDocViewInternal { docId: string; embedding: string; @@ -85,6 +29,7 @@ interface IDashDocViewInternal { node: any; getPos: any; } + @observer export class DashDocViewInternal extends ObservableReactComponent<IDashDocViewInternal> { _spanRef = React.createRef<HTMLDivElement>(); @@ -158,7 +103,7 @@ export class DashDocViewInternal extends ObservableReactComponent<IDashDocViewIn getDocTransform = () => { if (!this._spanRef.current) return Transform.Identity(); - const { scale, translateX, translateY } = Utils.GetScreenTransform(this._spanRef.current); + const { scale, translateX, translateY } = ClientUtils.GetScreenTransform(this._spanRef.current); return new Transform(-translateX, -translateY, 1).scale(1 / scale); }; outerFocus = (target: Doc, options: FocusViewOptions) => this._textBox.focus(target, options); // ideally, this would scroll to show the focus target @@ -227,3 +172,61 @@ export class DashDocViewInternal extends ObservableReactComponent<IDashDocViewIn ); } } + +export class DashDocView { + dom: HTMLSpanElement; // container for label and value + root: any; + + constructor(node: any, view: any, getPos: any, tbox: FormattedTextBox) { + this.dom = document.createElement('span'); + this.dom.style.position = 'relative'; + this.dom.style.textIndent = '0'; + this.dom.style.width = (+node.attrs.width.toString().replace('px', '') + horizPadding).toString(); + this.dom.style.height = node.attrs.height; + this.dom.style.display = node.attrs.hidden ? 'none' : 'inline-block'; + (this.dom.style as any).float = node.attrs.float; + this.dom.onkeypress = function (e: any) { + e.stopPropagation(); + }; + this.dom.onkeydown = function (e: any) { + e.stopPropagation(); + }; + this.dom.onkeyup = function (e: any) { + e.stopPropagation(); + }; + this.dom.onmousedown = function (e: any) { + e.stopPropagation(); + }; + + this.root = ReactDOM.createRoot(this.dom); + this.root.render( + <DashDocViewInternal + docId={node.attrs.docId} + embedding={node.attrs.embedding} + width={node.attrs.width} + height={node.attrs.height} + hidden={node.attrs.hidden} + fieldKey={node.attrs.fieldKey} + tbox={tbox} + view={view} + node={node} + getPos={getPos} + /> + ); + } + destroy() { + setTimeout(() => { + try { + this.root.unmount(); + } catch { + /* empty */ + } + }); + } + deselectNode() { + this.dom.style.backgroundColor = ''; + } + selectNode() { + this.dom.style.backgroundColor = 'rgb(141, 182, 247)'; + } +} diff --git a/src/client/views/nodes/formattedText/EquationEditor.tsx b/src/client/views/nodes/formattedText/EquationEditor.tsx index b4102e08e..d9b1a2cf8 100644 --- a/src/client/views/nodes/formattedText/EquationEditor.tsx +++ b/src/client/views/nodes/formattedText/EquationEditor.tsx @@ -1,3 +1,4 @@ +/* eslint-disable react/require-default-props */ import React, { Component, createRef } from 'react'; // Import JQuery, required for the functioning of the equation editor @@ -5,11 +6,9 @@ import $ from 'jquery'; import './EquationEditor.scss'; -// eslint-disable-next-line @typescript-eslint/ban-ts-ignore // @ts-ignore window.jQuery = $; -// eslint-disable-next-line @typescript-eslint/ban-ts-ignore // @ts-ignore require('mathquill/build/mathquill'); diff --git a/src/client/views/nodes/formattedText/EquationView.tsx b/src/client/views/nodes/formattedText/EquationView.tsx index b90653acc..5167c8f2a 100644 --- a/src/client/views/nodes/formattedText/EquationView.tsx +++ b/src/client/views/nodes/formattedText/EquationView.tsx @@ -1,3 +1,4 @@ +/* eslint-disable jsx-a11y/no-static-element-interactions */ import { IReactionDisposer } from 'mobx'; import { observer } from 'mobx-react'; import { TextSelection } from 'prosemirror-state'; @@ -10,44 +11,6 @@ import EquationEditor from './EquationEditor'; import { FormattedTextBox } from './FormattedTextBox'; import { DocData } from '../../../../fields/DocSymbols'; -export class EquationView { - dom: HTMLDivElement; // container for label and value - root: any; - tbox: FormattedTextBox; - view: any; - constructor(node: any, view: any, getPos: any, tbox: FormattedTextBox) { - this.tbox = tbox; - this.view = view; - this.dom = document.createElement('div'); - this.dom.style.width = node.attrs.width; - this.dom.style.height = node.attrs.height; - this.dom.style.position = 'relative'; - this.dom.style.display = 'inline-block'; - this.dom.onmousedown = function (e: any) { - e.stopPropagation(); - }; - - this.root = ReactDOM.createRoot(this.dom); - this.root.render(<EquationViewInternal fieldKey={node.attrs.fieldKey} width={node.attrs.width} height={node.attrs.height} getPos={getPos} setEditor={this.setEditor} tbox={tbox} />); - } - _editor: EquationEditor | undefined; - setEditor = (editor?: EquationEditor) => (this._editor = editor); - destroy() { - this.root.unmount(); - } - setSelection() { - this._editor?.mathField.focus(); - } - selectNode() { - this.tbox._applyingChange = this.tbox.fieldKey; // setting focus will make prosemirror lose focus, which will cause it to change its selection to a text selection, which causes this view to get rebuilt but it's no longer node selected, so the equationview won't have focus - setTimeout(() => { - this._editor?.mathField.focus(); - setTimeout(() => (this.tbox._applyingChange = '')); - }); - } - deselectNode() {} -} - interface IEquationViewInternal { fieldKey: string; tbox: FormattedTextBox; @@ -70,12 +33,12 @@ export class EquationViewInternal extends React.Component<IEquationViewInternal> this._textBoxDoc = props.tbox.Document; } - componentWillUnmount() { - this._reactionDisposer?.(); - } componentDidMount() { this.props.setEditor(this._ref.current ?? undefined); } + componentWillUnmount() { + this._reactionDisposer?.(); + } render() { return ( @@ -100,12 +63,56 @@ export class EquationViewInternal extends React.Component<IEquationViewInternal> <EquationEditor ref={this._ref} value={StrCast(this._textBoxDoc[DocData][this._fieldKey])} - onChange={(str: any) => (this._textBoxDoc[DocData][this._fieldKey] = str)} + onChange={(str: any) => { + this._textBoxDoc[DocData][this._fieldKey] = str; + }} autoCommands="pi theta sqrt sum prod alpha beta gamma rho" autoOperatorNames="sin cos tan" - spaceBehavesLikeTab={true} + spaceBehavesLikeTab /> </div> ); } } + +export class EquationView { + dom: HTMLDivElement; // container for label and value + root: any; + tbox: FormattedTextBox; + view: any; + constructor(node: any, view: any, getPos: any, tbox: FormattedTextBox) { + this.tbox = tbox; + this.view = view; + this.dom = document.createElement('div'); + this.dom.style.width = node.attrs.width; + this.dom.style.height = node.attrs.height; + this.dom.style.position = 'relative'; + this.dom.style.display = 'inline-block'; + this.dom.onmousedown = function (e: any) { + e.stopPropagation(); + }; + + this.root = ReactDOM.createRoot(this.dom); + this.root.render(<EquationViewInternal fieldKey={node.attrs.fieldKey} width={node.attrs.width} height={node.attrs.height} getPos={getPos} setEditor={this.setEditor} tbox={tbox} />); + } + _editor: EquationEditor | undefined; + setEditor = (editor?: EquationEditor) => { + this._editor = editor; + }; + destroy() { + this.root.unmount(); + } + setSelection() { + this._editor?.mathField.focus(); + } + selectNode() { + this.tbox._applyingChange = this.tbox.fieldKey; // setting focus will make prosemirror lose focus, which will cause it to change its selection to a text selection, which causes this view to get rebuilt but it's no longer node selected, so the equationview won't have focus + setTimeout(() => { + this._editor?.mathField.focus(); + setTimeout(() => { + this.tbox._applyingChange = ''; + }); + }); + } + deselectNode() {} +} diff --git a/src/client/views/nodes/formattedText/FootnoteView.tsx b/src/client/views/nodes/formattedText/FootnoteView.tsx index b327e5137..4641da2e9 100644 --- a/src/client/views/nodes/formattedText/FootnoteView.tsx +++ b/src/client/views/nodes/formattedText/FootnoteView.tsx @@ -2,9 +2,9 @@ import { EditorView } from 'prosemirror-view'; import { EditorState } from 'prosemirror-state'; import { keymap } from 'prosemirror-keymap'; import { baseKeymap, toggleMark } from 'prosemirror-commands'; -import { schema } from './schema_rts'; import { redo, undo } from 'prosemirror-history'; import { StepMap } from 'prosemirror-transform'; +import { schema } from './schema_rts'; export class FootnoteView { innerView: any; @@ -100,8 +100,8 @@ export class FootnoteView { this.innerView.updateState(state); if (!tr.getMeta('fromOutside')) { - const outerTr = this.outerView.state.tr, - offsetMap = StepMap.offset(this.getPos() + 1); + const outerTr = this.outerView.state.tr; + const offsetMap = StepMap.offset(this.getPos() + 1); for (const transaction of transactions) { for (const step of transaction.steps) { outerTr.step(step.map(offsetMap)); @@ -115,7 +115,7 @@ export class FootnoteView { if (!node.sameMarkup(this.node)) return false; this.node = node; if (this.innerView) { - const state = this.innerView.state; + const { state } = this.innerView; const start = node.content.findDiffStart(state.doc.content); if (start !== null) { let { a: endA, b: endB } = node.content.findDiffEnd(state.doc.content); diff --git a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx index 52d93ec38..01c46edeb 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx @@ -19,20 +19,22 @@ export function findLinkMark(marks: readonly Mark[]): Mark | undefined { return marks.find(m => m.type === schema.marks.autoLinkAnchor || m.type === schema.marks.linkAnchor); } export function findStartOfMark(rpos: ResolvedPos, view: EditorView, finder: (marks: readonly Mark[]) => Mark | undefined) { - let before = 0, - nbef = rpos.nodeBefore; + let before = 0; + let nbef = rpos.nodeBefore; while (nbef && finder(nbef.marks)) { before += nbef.nodeSize; + // eslint-disable-next-line no-param-reassign rpos = view.state.doc.resolve(rpos.pos - nbef.nodeSize); rpos && (nbef = rpos.nodeBefore); } return before; } export function findEndOfMark(rpos: ResolvedPos, view: EditorView, finder: (marks: readonly Mark[]) => Mark | undefined) { - let after = 0, - naft = rpos.nodeAfter; + let after = 0; + let naft = rpos.nodeAfter; while (naft && finder(naft.marks)) { after += naft.nodeSize; + // eslint-disable-next-line no-param-reassign rpos = view.state.doc.resolve(rpos.pos + naft.nodeSize); rpos && (naft = rpos.nodeAfter); } @@ -80,10 +82,10 @@ export class FormattedTextBoxComment { } static showCommentbox(view: EditorView, nbef: number) { - const state = view.state; + const { state } = view; // These are in screen coordinates - const start = view.coordsAtPos(state.selection.from - nbef), - end = view.coordsAtPos(state.selection.from - nbef); + const start = view.coordsAtPos(state.selection.from - nbef); + const end = view.coordsAtPos(state.selection.from - nbef); // The box in which the tooltip is positioned, to use as base const box = (document.getElementsByClassName('mainView-container') as any)[0].getBoundingClientRect(); // Find a center-ish x position from the selection endpoints (when crossing lines, end may be more to the left) @@ -110,14 +112,16 @@ export class FormattedTextBoxComment { } static setupPreview(view: EditorView, textBox: FormattedTextBox, hrefs?: string[], linkDoc?: string, noPreview?: boolean) { - const state = view.state; + const { state } = view; // this section checks to see if the insertion point is over text entered by a different user. If so, it sets ths comment text to indicate the user and the modification date if (state.selection.$from) { const nbef = findStartOfMark(state.selection.$from, view, findOtherUserMark); const naft = findEndOfMark(state.selection.$from, view, findOtherUserMark); const noselection = state.selection.$from === state.selection.$to; let child: any = null; - state.doc.nodesBetween(state.selection.from, state.selection.to, (node: any, pos: number, parent: any) => !child && node.marks.length && (child = node)); + state.doc.nodesBetween(state.selection.from, state.selection.to, (node: any /* , pos: number, parent: any */) => { + !child && node.marks.length && (child = node); + }); const mark = child && findOtherUserMark(child.marks); if (mark && child && (nbef || naft) && (!mark.attrs.opened || noselection)) { FormattedTextBoxComment.saveMarkRegion(textBox, state.selection.$from.pos - nbef, state.selection.$from.pos + naft, mark); @@ -132,7 +136,7 @@ export class FormattedTextBoxComment { if (state.selection.$from && hrefs?.length) { const nbef = findStartOfMark(state.selection.$from, view, findLinkMark); const naft = findEndOfMark(state.selection.$from, view, findLinkMark) || nbef; - //nbef && + // nbef && naft && LinkInfo.SetLinkInfo({ DocumentView: textBox.DocumentView, diff --git a/src/client/views/nodes/formattedText/OrderedListView.tsx b/src/client/views/nodes/formattedText/OrderedListView.tsx index c3595e59b..dbc60f7bf 100644 --- a/src/client/views/nodes/formattedText/OrderedListView.tsx +++ b/src/client/views/nodes/formattedText/OrderedListView.tsx @@ -1,8 +1,7 @@ export class OrderedListView { - - update(node: any) { - // if attr's of an ordered_list (e.g., bulletStyle) change, + update() { + // if attr's of an ordered_list (e.g., bulletStyle) change, // return false forces the dom node to be recreated which is necessary for the bullet labels to update - return false; + return false; } -}
\ No newline at end of file +} diff --git a/src/client/views/nodes/formattedText/ParagraphNodeSpec.ts b/src/client/views/nodes/formattedText/ParagraphNodeSpec.ts index 30da91710..6c88a0d29 100644 --- a/src/client/views/nodes/formattedText/ParagraphNodeSpec.ts +++ b/src/client/views/nodes/formattedText/ParagraphNodeSpec.ts @@ -1,18 +1,19 @@ +/* eslint-disable import/extensions */ +import { Node, DOMOutputSpec } from 'prosemirror-model'; import clamp from '../../../util/clamp'; import convertToCSSPTValue from '../../../util/convertToCSSPTValue'; import toCSSLineSpacing from '../../../util/toCSSLineSpacing'; -import { Node, DOMOutputSpec } from 'prosemirror-model'; -//import type { NodeSpec } from './Types'; +// import type { NodeSpec } from './Types'; type NodeSpec = { - attrs?: { [key: string]: any }, - content?: string, - draggable?: boolean, - group?: string, - inline?: boolean, - name?: string, - parseDOM?: Array<any>, - toDOM?: (node: any) => DOMOutputSpec, + attrs?: { [key: string]: any }; + content?: string; + draggable?: boolean; + group?: string; + inline?: boolean; + name?: string; + parseDOM?: Array<any>; + toDOM?: (node: any) => DOMOutputSpec; }; // This assumes that every 36pt maps to one indent level. @@ -25,41 +26,18 @@ export const EMPTY_CSS_VALUE = new Set(['', '0%', '0pt', '0px']); const ALIGN_PATTERN = /(left|right|center|justify)/; -// https://github.com/ProseMirror/prosemirror-schema-basic/blob/master/src/schema-basic.js -// :: NodeSpec A plain paragraph textblock. Represented in the DOM -// as a `<p>` element. -export const ParagraphNodeSpec: NodeSpec = { - attrs: { - align: { default: null }, - color: { default: null }, - id: { default: null }, - indent: { default: null }, - inset: { default: null }, - lineSpacing: { default: null }, - // TODO: Add UI to let user edit / clear padding. - paddingBottom: { default: null }, - // TODO: Add UI to let user edit / clear padding. - paddingTop: { default: null }, - }, - content: 'inline*', - group: 'block', - parseDOM: [{ tag: 'p', getAttrs }], - toDOM, -}; +function convertMarginLeftToIndentValue(marginLeft: string): number { + const ptValue = convertToCSSPTValue(marginLeft); + return clamp(MIN_INDENT_LEVEL, Math.floor(ptValue / INDENT_MARGIN_PT_SIZE), MAX_INDENT_LEVEL); +} function getAttrs(dom: HTMLElement): Object { - const { - lineHeight, - textAlign, - marginLeft, - paddingTop, - paddingBottom, - } = dom.style; + const { lineHeight, textAlign, marginLeft, paddingTop, paddingBottom } = dom.style; let align = dom.getAttribute('align') || textAlign || ''; - align = ALIGN_PATTERN.test(align) ? align : ""; + align = ALIGN_PATTERN.test(align) ? align : ''; - let indent = parseInt(dom.getAttribute(ATTRIBUTE_INDENT) || "", 10); + let indent = parseInt(dom.getAttribute(ATTRIBUTE_INDENT) || '', 10); if (!indent && marginLeft) { indent = convertMarginLeftToIndentValue(marginLeft); @@ -74,15 +52,7 @@ function getAttrs(dom: HTMLElement): Object { } function toDOM(node: Node): DOMOutputSpec { - const { - align, - indent, - inset, - lineSpacing, - paddingTop, - paddingBottom, - id, - } = node.attrs; + const { align, indent, inset, lineSpacing, paddingTop, paddingBottom, id } = node.attrs; const attrs: { [key: string]: any } | null = {}; let style = ''; @@ -128,16 +98,29 @@ function toDOM(node: Node): DOMOutputSpec { return ['p', attrs, 0]; } +// https://github.com/ProseMirror/prosemirror-schema-basic/blob/master/src/schema-basic.js +// :: NodeSpec A plain paragraph textblock. Represented in the DOM +// as a `<p>` element. +export const ParagraphNodeSpec: NodeSpec = { + attrs: { + align: { default: null }, + color: { default: null }, + id: { default: null }, + indent: { default: null }, + inset: { default: null }, + lineSpacing: { default: null }, + // TODO: Add UI to let user edit / clear padding. + paddingBottom: { default: null }, + // TODO: Add UI to let user edit / clear padding. + paddingTop: { default: null }, + }, + content: 'inline*', + group: 'block', + parseDOM: [{ tag: 'p', getAttrs }], + toDOM, +}; + export const toParagraphDOM = toDOM; export const getParagraphNodeAttrs = getAttrs; -export function convertMarginLeftToIndentValue(marginLeft: string): number { - const ptValue = convertToCSSPTValue(marginLeft); - return clamp( - MIN_INDENT_LEVEL, - Math.floor(ptValue / INDENT_MARGIN_PT_SIZE), - MAX_INDENT_LEVEL - ); -} - -export default ParagraphNodeSpec;
\ No newline at end of file +export default ParagraphNodeSpec; diff --git a/src/client/views/nodes/formattedText/RichTextRules.ts b/src/client/views/nodes/formattedText/RichTextRules.ts index 88adab66e..c107a6724 100644 --- a/src/client/views/nodes/formattedText/RichTextRules.ts +++ b/src/client/views/nodes/formattedText/RichTextRules.ts @@ -14,6 +14,7 @@ import { CollectionView } from '../../collections/CollectionView'; import { ContextMenu } from '../../ContextMenu'; import { KeyValueBox } from '../KeyValueBox'; import { FormattedTextBox } from './FormattedTextBox'; +// eslint-disable-next-line import/extensions import { wrappingInputRule } from './prosemirrorPatches'; import { RichTextMenu } from './RichTextMenu'; import { schema } from './schema_rts'; @@ -253,7 +254,7 @@ export class RichTextRules { } if (marks) { const tr = state.tr.deleteRange(start, end); - return marks ? Array.from(marks).reduce((tr, m) => tr.addStoredMark(m), tr) : tr; + return marks ? Array.from(marks).reduce((tr2, m) => tr2.addStoredMark(m), tr) : tr; } const isValidColor = (strColor: string) => { @@ -283,7 +284,7 @@ export class RichTextRules { return marks ? Array.from(marks) .filter(m => m.type !== state.schema.marks.user_mark) - .reduce((tr, m) => tr.removeStoredMark(m), tr) + .reduce((tr2, m) => tr2.removeStoredMark(m), tr) : tr; }), @@ -309,11 +310,11 @@ export class RichTextRules { teditor.dispatch(tstate.tr.setSelection(new TextSelection(tstate.doc.resolve(selection)))); } }; - const getTitledDoc = (docTitle: string) => { - if (!DocServer.FindDocByTitle(docTitle)) { - Docs.Create.TextDocument('', { title: docTitle, _width: 400, _layout_fitWidth: true, _layout_autoHeight: true }); + const getTitledDoc = (title: string) => { + if (!DocServer.FindDocByTitle(title)) { + Docs.Create.TextDocument('', { title: title, _width: 400, _layout_fitWidth: true, _layout_autoHeight: true }); } - const titledDoc = DocServer.FindDocByTitle(docTitle); + const titledDoc = DocServer.FindDocByTitle(title); return titledDoc ? Doc.BestEmbedding(titledDoc) : titledDoc; }; const target = getTitledDoc(docTitle); @@ -336,7 +337,7 @@ export class RichTextRules { const assign = match[4] === ':' ? (match[4] = '') : match[4]; const value = match[5]; const dataDoc = value === undefined ? !fieldKey.startsWith('_') : !assign?.startsWith('='); - const getTitledDoc = (docTitle: string) => DocServer.FindDocByTitle(docTitle); + const getTitledDoc = (title: string) => DocServer.FindDocByTitle(title); // if the value has commas assume its an array (unless it's part of a chat gpt call indicated by '((' ) if (value?.includes(',') && !value.startsWith('((')) { const values = value.split(','); diff --git a/src/client/views/nodes/formattedText/SummaryView.tsx b/src/client/views/nodes/formattedText/SummaryView.tsx index 7ec296ed2..2c366b49b 100644 --- a/src/client/views/nodes/formattedText/SummaryView.tsx +++ b/src/client/views/nodes/formattedText/SummaryView.tsx @@ -3,6 +3,15 @@ import { Fragment, Node, Slice } from 'prosemirror-model'; import * as ReactDOM from 'react-dom/client'; import * as React from 'react'; +interface ISummaryView {} +// currently nothing needs to be rendered for the internal view of a summary. +// eslint-disable-next-line react/prefer-stateless-function +export class SummaryViewInternal extends React.Component<ISummaryView> { + render() { + return null; + } +} + // an elidable textblock that collapses when its '<-' is clicked and expands when its '...' anchor is clicked. // this node actively edits prosemirror (as opposed to just changing how things are rendered) and thus doesn't // really need a react view. However, it would be cleaner to figure out how to do this just as a react rendering @@ -32,8 +41,8 @@ export class SummaryView { }; const js = node.toJSON; - node.toJSON = function () { - return js.apply(this, arguments); + node.toJSON = function (...args: any[]) { + return js.apply(this, args); }; this.root = ReactDOM.createRoot(this.dom); @@ -54,7 +63,8 @@ export class SummaryView { const visited = new Set(); for (let i: number = start + 1; i < view.state.doc.nodeSize - 1; i++) { let skip = false; - view.state.doc.nodesBetween(start, i, (node: Node, pos: number, parent: Node, index: number) => { + // eslint-disable-next-line no-loop-func + view.state.doc.nodesBetween(start, i, (node: Node /* , pos: number, parent: Node, index: number */) => { if (node.isLeaf && !visited.has(node) && !skip) { if (node.marks.find((m: any) => m.type === mtype || m.type === mtypeInc)) { visited.add(node); @@ -87,11 +97,3 @@ export class SummaryView { this.dom.className = this.className(visible); }; } - -interface ISummaryView {} -// currently nothing needs to be rendered for the internal view of a summary. -export class SummaryViewInternal extends React.Component<ISummaryView> { - render() { - return <> </>; - } -} |
