diff options
author | Bob Zeleznik <zzzman@gmail.com> | 2020-06-26 00:40:49 -0400 |
---|---|---|
committer | Bob Zeleznik <zzzman@gmail.com> | 2020-06-26 00:40:49 -0400 |
commit | 8d774b6dd81d77294c438bb2951e04cf778dc38e (patch) | |
tree | 7101ee6a7ef3a83c636ec44ba5262a3147e4e325 /src | |
parent | 9d92f68750c943d82baa99dc26c29cdd58417e56 (diff) |
fixed highlighting text anchors in text notes. fixed pasting fragements of PDFs to create back links inside blockquotes.
Diffstat (limited to 'src')
-rw-r--r-- | src/client/util/DocumentManager.ts | 8 | ||||
-rw-r--r-- | src/client/views/PreviewCursor.tsx | 2 | ||||
-rw-r--r-- | src/client/views/nodes/formattedText/FormattedTextBox.tsx | 31 |
3 files changed, 29 insertions, 12 deletions
diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts index 78c05f572..40d6b039a 100644 --- a/src/client/util/DocumentManager.ts +++ b/src/client/util/DocumentManager.ts @@ -130,7 +130,7 @@ export class DocumentManager { willZoom: boolean, // whether to zoom doc to take up most of screen createViewFunc = DocumentManager.addRightSplit, // how to create a view of the doc if it doesn't exist docContext?: Doc, // context to load that should contain the target - linkId?: string, // link that's being followed + linkDoc?: Doc, // link that's being followed closeContextIfNotFound: boolean = false, // after opening a context where the document should be, this determines whether the context should be closed if the Doc isn't actually there originatingDoc: Opt<Doc> = undefined, // doc that initiated the display of the target odoc finished?: () => void @@ -140,7 +140,7 @@ export class DocumentManager { const highlight = () => { const finalDocView = getFirstDocView(targetDoc); if (finalDocView) { - finalDocView.layoutDoc.scrollToLinkID = linkId; + finalDocView.layoutDoc.scrollToLinkID = linkDoc?.[Id]; Doc.linkFollowHighlight(finalDocView.props.Document); } }; @@ -195,7 +195,7 @@ export class DocumentManager { const finalDocView = getFirstDocView(targetDoc); const finalDocContextView = getFirstDocView(targetDocContext); setTimeout(() => // if not, wait a bit to see if the context can be loaded (e.g., a PDF). wait interval heurisitic tries to guess how we're animating based on what's just become visible - this.jumpToDocument(targetDoc, willZoom, createViewFunc, undefined, linkId, true, undefined, finished), // pass true this time for closeContextIfNotFound + this.jumpToDocument(targetDoc, willZoom, createViewFunc, undefined, linkDoc, true, undefined, finished), // pass true this time for closeContextIfNotFound finalDocView ? 0 : finalDocContextView ? 250 : 2000); // so call jump to doc again and if the doc isn't found, it will be created. }, 0); } @@ -224,7 +224,7 @@ export class DocumentManager { containerDoc.currentTimecode = targetTimecode; const targetContext = await target?.context as Doc; const targetNavContext = !Doc.AreProtosEqual(targetContext, currentContext) ? targetContext : undefined; - DocumentManager.Instance.jumpToDocument(target, zoom, (doc, finished) => createViewFunc(doc, StrCast(linkDoc.followLinkLocation, "onRight"), finished), targetNavContext, linkDoc[Id], undefined, doc, finished); + DocumentManager.Instance.jumpToDocument(target, zoom, (doc, finished) => createViewFunc(doc, StrCast(linkDoc.followLinkLocation, "onRight"), finished), targetNavContext, linkDoc, undefined, doc, finished); } else { finished?.(); } diff --git a/src/client/views/PreviewCursor.tsx b/src/client/views/PreviewCursor.tsx index e27f6b95a..1ab99881d 100644 --- a/src/client/views/PreviewCursor.tsx +++ b/src/client/views/PreviewCursor.tsx @@ -9,6 +9,7 @@ import { Transform } from "../util/Transform"; import { DocServer } from '../DocServer'; import { undoBatch } from '../util/UndoManager'; import { NumCast } from '../../fields/Types'; +import { FormattedTextBox } from './nodes/formattedText/FormattedTextBox'; @observer export class PreviewCursor extends React.Component<{}> { @@ -81,6 +82,7 @@ export class PreviewCursor extends React.Component<{}> { e.stopPropagation(); } else { // creates text document + FormattedTextBox.PasteOnLoad = e; undoBatch(() => PreviewCursor._addLiveTextDoc(Docs.Create.TextDocument("", { _width: 500, limitHeight: 400, diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index 25878bda2..f96b165fa 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -4,7 +4,7 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { isEqual } from "lodash"; import { action, computed, IReactionDisposer, Lambda, observable, reaction, runInAction } from "mobx"; import { observer } from "mobx-react"; -import { baseKeymap } from "prosemirror-commands"; +import { baseKeymap, selectAll } from "prosemirror-commands"; import { history } from "prosemirror-history"; import { inputRules } from 'prosemirror-inputrules'; import { keymap } from "prosemirror-keymap"; @@ -102,6 +102,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp public static FocusedBox: FormattedTextBox | undefined; public static SelectOnLoad = ""; + public static PasteOnLoad: ClipboardEvent | undefined; public static SelectOnLoadChar = ""; public static IsFragment(html: string) { return html.indexOf("data-pm-slice") !== -1; @@ -275,6 +276,12 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp 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!; @@ -726,7 +733,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp } const marks = [...node.marks]; const linkIndex = marks.findIndex(mark => mark.type === editor.state.schema.marks.link); - return linkIndex !== -1 && marks[linkIndex].attrs.allRefs.find((item: { href: string }) => scrollToLinkID === item.href.replace(/.*\/doc\//, "")) ? node : undefined; + return linkIndex !== -1 && marks[linkIndex].attrs.allHrefs.find((item: { href: string }) => scrollToLinkID === item.href.replace(/.*\/doc\//, "")) ? node : undefined; }; let start = 0; @@ -859,6 +866,11 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp 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; + } + + addPdfReference = (pdfDocId: string, pdfRegionId: string, slice?: Slice) => { + const view = this._editorView!; if (pdfDocId && pdfRegionId) { DocServer.GetRefField(pdfDocId).then(pdfDoc => { DocServer.GetRefField(pdfRegionId).then(pdfRegion => { @@ -871,13 +883,16 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp const link = DocUtils.MakeLink({ doc: this.rootDoc }, { doc: pdfRegion }, "PDF pasted"); if (link) { - cbe.clipboardData!.setData("dash/linkDoc", link[Id]); const linkId = link[Id]; const quote = view.state.schema.nodes.blockquote.create(); - quote.content = addMarkToFrag(slice.content, (node: Node) => addLinkMark(node, StrCast(pdfDoc.title), linkId)); - slice = new Slice(Fragment.from(quote), slice.openStart, slice.openEnd); - const tr = view.state.tr.replaceSelection(slice) - view.dispatch(tr.scrollIntoView().setMeta("paste", true).setMeta("uiEvent", "paste")); + quote.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())); + + } } } }); @@ -1015,7 +1030,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp const editor = this._editorView!; FormattedTextBoxComment.textBox = this; const pcords = editor.posAtCoords({ left: e.clientX, top: e.clientY }); - const node = pcords && editor.state.doc.resolve(pcords.pos).node();// bcz: changed so that clicking on the attribution of a PDF pasted link will trigger. editor.state.doc.nodeAt(pcords.pos); // get what prosemirror thinks the clicked node is (if it's null, then we didn't click on any text) + const node = pcords && editor.state.doc.nodeAt(pcords.pos); // get what prosemirror thinks the clicked node is (if it's null, then we didn't click on any text) !this.props.isSelected(true) && editor.dispatch(editor.state.tr.setSelection(node && pcords ? new NodeSelection(editor.state.doc.resolve(pcords.pos)) : new TextSelection(editor.state.doc.resolve(pcords?.pos || 0)))); FormattedTextBoxComment.update(editor, undefined, (e.target as any)?.className === "prosemirror-dropdownlink" ? (e.target as any).href : ""); |