diff options
Diffstat (limited to 'src/client/views/nodes/formattedText/FormattedTextBox.tsx')
-rw-r--r-- | src/client/views/nodes/formattedText/FormattedTextBox.tsx | 87 |
1 files changed, 32 insertions, 55 deletions
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index 63435eea8..fc8d2b7dd 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -1,7 +1,7 @@ import { IconProp } from '@fortawesome/fontawesome-svg-core'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { isEqual } from 'lodash'; -import { action, computed, IReactionDisposer, observable, reaction, runInAction } from 'mobx'; +import { action, computed, IReactionDisposer, observable, reaction, runInAction, trace } from 'mobx'; import { observer } from 'mobx-react'; import { baseKeymap, selectAll } from 'prosemirror-commands'; import { history } from 'prosemirror-history'; @@ -87,7 +87,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps private _ref: React.RefObject<HTMLDivElement> = React.createRef(); private _scrollRef: React.RefObject<HTMLDivElement> = React.createRef(); private _editorView: Opt<EditorView>; - private _applyingChange: string = ''; + public _applyingChange: string = ''; private _searchIndex = 0; private _lastTimedMark: Mark | undefined = undefined; private _cachedLinks: Doc[] = []; @@ -499,12 +499,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps const end = this._editorView.state.doc.nodeSize - 2; this._editorView.dispatch(this._editorView.state.tr.removeMark(0, end, mark).removeMark(0, end, activeMark)); } - if (FormattedTextBox.PasteOnLoad) { - const pdfDocId = FormattedTextBox.PasteOnLoad.clipboardData?.getData('dash/pdfOrigin'); - const pdfRegionId = FormattedTextBox.PasteOnLoad.clipboardData?.getData('dash/pdfRegion'); - FormattedTextBox.PasteOnLoad = undefined; - setTimeout(() => pdfDocId && pdfRegionId && this.addPdfReference(pdfDocId, pdfRegionId, undefined), 10); - } }; adoptAnnotation = (start: number, end: number, mark: Mark) => { const view = this._editorView!; @@ -1235,61 +1229,38 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps }; handlePaste = (view: EditorView, event: Event, slice: Slice): boolean => { - const cbe = event as ClipboardEvent; - const pdfDocId = cbe.clipboardData?.getData('dash/pdfOrigin'); - const pdfRegionId = cbe.clipboardData?.getData('dash/pdfRegion'); - return pdfDocId && pdfRegionId && this.addPdfReference(pdfDocId, pdfRegionId, slice) ? true : false; + const pdfAnchorId = (event as ClipboardEvent).clipboardData?.getData('dash/pdfAnchor'); + return pdfAnchorId && this.addPdfReference(pdfAnchorId) ? true : false; }; - addPdfReference = (pdfDocId: string, pdfRegionId: string, slice?: Slice) => { + addPdfReference = (pdfAnchorId: string) => { const view = this._editorView!; - if (pdfDocId && pdfRegionId) { - DocServer.GetRefField(pdfDocId).then(pdfDoc => { - DocServer.GetRefField(pdfRegionId).then(pdfRegion => { - if (pdfDoc instanceof Doc && pdfRegion instanceof Doc) { - setTimeout(async () => { - const targetField = Doc.LayoutFieldKey(pdfDoc); - const targetAnnotations = await DocListCastAsync(pdfDoc[DataSym][targetField + '-annotations']); // bcz: better to have the PDF's view handle updating its own annotations - if (targetAnnotations) targetAnnotations.push(pdfRegion); - else Doc.AddDocToList(pdfDoc[DataSym], targetField + '-annotations', pdfRegion); - }); - - const link = DocUtils.MakeLink({ doc: this.rootDoc }, { doc: pdfRegion }, 'PDF pasted'); - if (link) { - const linkId = link[Id]; - const quote = view.state.schema.nodes.blockquote.create({ content: addMarkToFrag(slice?.content || view.state.doc.content, (node: Node) => addLinkMark(node, StrCast(pdfDoc.title), linkId)) }); - const newSlice = new Slice(Fragment.from(quote), slice?.openStart || 0, slice?.openEnd || 0); - if (slice) { - view.dispatch(view.state.tr.replaceSelection(newSlice).scrollIntoView().setMeta('paste', true).setMeta('uiEvent', 'paste')); - } else { - selectAll(view.state, (tx: Transaction) => view.dispatch(tx.replaceSelection(newSlice).scrollIntoView())); - } - } + if (pdfAnchorId) { + DocServer.GetRefField(pdfAnchorId).then(pdfAnchor => { + if (pdfAnchor instanceof Doc) { + const dashField = view.state.schema.nodes.paragraph.create({}, [ + view.state.schema.nodes.dashField.create({ fieldKey: 'text', docid: pdfAnchor[Id], hideKey: true, editable: false }, undefined, [ + view.state.schema.marks.linkAnchor.create({ + allAnchors: [{ href: `/doc/${this.rootDoc[Id]}`, title: this.rootDoc.title, anchorId: `${this.rootDoc[Id]}` }], + location: 'add:right', + title: `from: ${DocCast(pdfAnchor.context).title}`, + noPreview: true, + docref: false, + }), + view.state.schema.marks.pFontSize.create({ fontSize: '8px' }), + view.state.schema.marks.em.create({}), + ]), + ]); + + const link = DocUtils.MakeLink({ doc: pdfAnchor }, { doc: this.rootDoc }, 'PDF pasted'); + if (link) { + view.dispatch(view.state.tr.replaceSelectionWith(dashField, false).scrollIntoView().setMeta('paste', true).setMeta('uiEvent', 'paste')); } - }); + } }); return true; } return false; - - function addMarkToFrag(frag: Fragment, marker: (node: Node) => Node) { - const nodes: Node[] = []; - frag.forEach(node => nodes.push(marker(node))); - return Fragment.fromArray(nodes); - } - - function addLinkMark(node: Node, title: string, linkId: string) { - if (!node.isText) { - const content = addMarkToFrag(node.content, (node: Node) => addLinkMark(node, title, linkId)); - return node.copy(content); - } - const marks = [...node.marks]; - const linkIndex = marks.findIndex(mark => mark.type.name === 'link'); - const allLinks = [{ href: Doc.globalServerPath(linkId), title, linkId }]; - const link = view.state.schema.mark(view.state.schema.marks.linkAnchor, { allLinks, location: 'add:right', title, docref: true }); - marks.splice(linkIndex === -1 ? 0 : linkIndex, 1, link); - return node.mark(marks); - } }; isActiveTab(el: Element | null | undefined) { @@ -1417,6 +1388,11 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps ...(Doc.UserDoc().fontSize ? [schema.mark(schema.marks.pFontSize, { fontSize: this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.FontSize) })] : []), ...(Doc.UserDoc().fontWeight === 'bold' ? [schema.mark(schema.marks.strong)] : []), ]; + if (FormattedTextBox.PasteOnLoad) { + const pdfAnchorId = FormattedTextBox.PasteOnLoad.clipboardData?.getData('dash/pdfAnchor'); + FormattedTextBox.PasteOnLoad = undefined; + pdfAnchorId && this.addPdfReference(pdfAnchorId); + } } FormattedTextBox.DontSelectInitialText = false; } @@ -1530,6 +1506,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps //applyDevTools.applyDevTools(this._editorView); FormattedTextBox.Focused = this; this.ProseRef?.children[0] === e.nativeEvent.target && this._editorView && RichTextMenu.Instance?.updateMenu(this._editorView, undefined, this.props); + this.startUndoTypingBatch(); }; @observable public static Focused: FormattedTextBox | undefined; |