diff options
-rw-r--r-- | src/client/documents/Documents.ts | 1 | ||||
-rw-r--r-- | src/client/goldenLayout.js | 2 | ||||
-rw-r--r-- | src/client/util/RichTextSchema.tsx | 3 | ||||
-rw-r--r-- | src/client/util/TooltipTextMenu.tsx | 14 | ||||
-rw-r--r-- | src/client/views/nodes/FormattedTextBox.tsx | 91 | ||||
-rw-r--r-- | src/client/views/nodes/LinkMenuItem.tsx | 3 | ||||
-rw-r--r-- | src/client/views/pdf/Page.tsx | 2 |
7 files changed, 101 insertions, 15 deletions
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 9c8b6c129..1777174ef 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -621,7 +621,6 @@ export namespace DocUtils { linkDocProto.sourceContext = sourceContext; linkDocProto.title = title === "" ? source.title + " to " + target.title : title; linkDocProto.linkDescription = description; - linkDocProto.type = DocumentType.LINK; linkDocProto.anchor1 = source; linkDocProto.anchor1Page = source.curPage; diff --git a/src/client/goldenLayout.js b/src/client/goldenLayout.js index ad78139c1..29b750720 100644 --- a/src/client/goldenLayout.js +++ b/src/client/goldenLayout.js @@ -377,7 +377,7 @@ this._nOriginalY = coordinates.y; this._oDocument.on('mousemove touchmove', this._fMove); - this._oDocument.one('mouseup touchend', this._fUp); + this._oDocument.on('mouseup touchend', this._fUp); this._timeout = setTimeout(lm.utils.fnBind(this._startDrag, this), this._nDelay); } diff --git a/src/client/util/RichTextSchema.tsx b/src/client/util/RichTextSchema.tsx index 6d2abfaa2..44ebc05d4 100644 --- a/src/client/util/RichTextSchema.tsx +++ b/src/client/util/RichTextSchema.tsx @@ -214,7 +214,8 @@ export const marks: { [index: string]: MarkSpec } = { attrs: { href: {}, location: { default: null }, - title: { default: null } + title: { default: null }, + guid: { default: null } }, inclusive: false, parseDOM: [{ diff --git a/src/client/util/TooltipTextMenu.tsx b/src/client/util/TooltipTextMenu.tsx index 4672dd246..5304f4cc6 100644 --- a/src/client/util/TooltipTextMenu.tsx +++ b/src/client/util/TooltipTextMenu.tsx @@ -302,11 +302,13 @@ export class TooltipTextMenu { dragComplete: action(() => { // let m = dragData.droppedDocuments; let linkDoc = dragData.linkDocument; + let guid = Utils.GenerateGuid(); let proto = Doc.GetProto(linkDoc); if (docView && docView.props.ContainingCollectionView) { proto.sourceContext = docView.props.ContainingCollectionView.props.Document; } - linkDoc instanceof Doc && this.makeLink(Utils.prepend("/doc/" + linkDoc[Id]), ctrlKey ? "onRight" : "inTab"); + linkDoc.guid = guid; + linkDoc instanceof Doc && this.makeLink(Utils.prepend("/doc/" + linkDoc[Id]), ctrlKey ? "onRight" : "inTab", guid); }), }, hideSource: false @@ -390,13 +392,13 @@ export class TooltipTextMenu { } } - makeLinkWithState = (state: EditorState, target: string, location: string) => { - let link = state.schema.mark(state.schema.marks.link, { href: target, location: location }); - } + // makeLinkWithState = (state: EditorState, target: string, location: string) => { + // let link = state.schema.mark(state.schema.marks.link, { href: target, location: location }); + // } - makeLink = (target: string, location: string) => { + makeLink = (target: string, location: string, guid?: string) => { let node = this.view.state.selection.$from.nodeAfter; - let link = this.view.state.schema.mark(this.view.state.schema.marks.link, { href: target, location: location }); + let link = this.view.state.schema.mark(this.view.state.schema.marks.link, { href: target, location: location, guid: guid }); this.view.dispatch(this.view.state.tr.removeMark(this.view.state.selection.from, this.view.state.selection.to, this.view.state.schema.marks.link)); this.view.dispatch(this.view.state.tr.addMark(this.view.state.selection.from, this.view.state.selection.to, link)); node = this.view.state.selection.$from.nodeAfter; diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index f7890e5a6..0266364e9 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -6,7 +6,7 @@ import { baseKeymap } from "prosemirror-commands"; import { history } from "prosemirror-history"; import { keymap } from "prosemirror-keymap"; import { Fragment, Node, Node as ProsNode, NodeType, Slice } from "prosemirror-model"; -import { EditorState, Plugin, Transaction } from "prosemirror-state"; +import { EditorState, Plugin, Transaction, TextSelection } from "prosemirror-state"; import { EditorView } from "prosemirror-view"; import { DateField } from '../../../new_fields/DateField'; import { Doc, DocListCast, Opt, WidthSym } from "../../../new_fields/Doc"; @@ -126,6 +126,84 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe } document.addEventListener("paste", this.paste); + reaction( + () => StrCast(this.props.Document.guid), // this refers to source guid + (guid) => { + let linkNode; + let start = -1; + + // go thru marks and look for guid + if (this._editorView && guid) { + let editor = this._editorView; + + console.log(guid); + + // find index of where mark === 'link' AND guid of text is matching that of the source of the followed link + // linkNode = editor.state.doc.content.firstChild; + // editor.state.tr.selection.content. + + let ret = findLinkFrag(editor.state.doc.content, editor); + + if (ret.frag.size > 2) { // fragment is not empty + console.log('here is frag', ret.frag); + console.log('here is node', linkNode); + console.log(editor.state.tr.selection); + // 1. get pos of start of frag in doc + // get from frag to slice to selection + let slice = new Slice(ret.frag, 1, 1); // significance of open depth??? + // let tr = editor.state.tr.setSelection(TextSelection.create(slice, )); + // editor.dispatch(tr.scrollIntoView()); + } + + // this._editorView.state.tr.setSelection(editor.state.doc, start of node, end of node); + // slice = new Slice(frag, slice.openStart, slice.openEnd); + // var tr = view.state.tr.replaceSelection(slice); + // view.dispatch(tr.scrollIntoView() + + // this._editorView.dispatch( /** pass in transaction */); + } + /** + * todo + * 1. recurse through fragment/node content until we find text nodes + * 2. once we find text nodes, find the specific one that matches guid (which we can do?????) + * 3. transport that back into main + * PROBLEM: this reaction is called 4 times for some reason + */ + + function findLinkFrag(frag: Fragment, editor: EditorView) { + const nodes: Node[] = []; + frag.forEach((node, index) => { + let examinedNode = findLinkNode(node, editor); + if (examinedNode) { + // here -- add information about 'for each' index? + nodes.push(examinedNode); + if (index > start) { + start = index; + } + } + }); + return { frag: Fragment.fromArray(nodes), start: start }; + } + function findLinkNode(node: Node, editor: EditorView) { + if (!node.isText) { + const content = findLinkFrag(node.content, editor); + return node.copy(content.frag); + } + const marks = [...node.marks]; + const linkIndex = marks.findIndex(mark => mark.type.name === "link"); + if (linkIndex !== -1) { + if (guid === marks[linkIndex].attrs.guid) { + console.log('linkindex is not -1,', linkIndex); + console.log('found match,', node); + linkNode = node; + return node; + } + } else { + return undefined; + } + } + } + ); } @computed get extensionDoc() { return Doc.resolvedFieldDataDoc(this.dataDoc, this.props.fieldKey, "dummy"); } @@ -167,7 +245,6 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe FormattedTextBox._toolTipTextMenu && (FormattedTextBox._toolTipTextMenu.HackToFixTextSelectionGlitch = false); if (state.selection.empty && FormattedTextBox._toolTipTextMenu) { const marks = tx.storedMarks; - console.log(marks); if (marks) { FormattedTextBox._toolTipTextMenu.mark_key_pressed(marks); } } this._applyingChange = true; @@ -292,8 +369,11 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe const field = this.dataDoc ? Cast(this.dataDoc[this.props.fieldKey], RichTextField) : undefined; return field ? field.Data : `{"doc":{"type":"doc","content":[]},"selection":{"type":"text","anchor":0,"head":0}}`; }, - field2 => this._editorView && !this._applyingChange && - this._editorView.updateState(EditorState.fromJSON(config, JSON.parse(field2))) + field2 => { + let ff2 = JSON.parse(field2); + this._editorView && !this._applyingChange && + this._editorView.updateState(EditorState.fromJSON(config, ff2)); + } ); this.props.isOverlay && (this._heightReactionDisposer = reaction( @@ -384,9 +464,12 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe if (link) { cbe.clipboardData!.setData("dash/linkDoc", link[Id]); linkId = link[Id]; + let guid = StrCast(link.guid); + link.guid = guid; let frag = addMarkToFrag(slice.content); slice = new Slice(frag, slice.openStart, slice.openEnd); var tr = view.state.tr.replaceSelection(slice); + view.dispatch(tr.scrollIntoView().setMeta("paste", true).setMeta("uiEvent", "paste")); } }); diff --git a/src/client/views/nodes/LinkMenuItem.tsx b/src/client/views/nodes/LinkMenuItem.tsx index a119eb39b..1ce60ac88 100644 --- a/src/client/views/nodes/LinkMenuItem.tsx +++ b/src/client/views/nodes/LinkMenuItem.tsx @@ -43,9 +43,9 @@ export class LinkMenuItem extends React.Component<LinkMenuItemProps> { let proto = Doc.GetProto(this.props.linkDoc); let targetContext = await Cast(proto.targetContext, Doc); let sourceContext = await Cast(proto.sourceContext, Doc); + let guid = StrCast(this.props.linkDoc.guid); let self = this; - let dockingFunc = (document: Doc) => { this.props.addDocTab(document, undefined, "inTab"); SelectionManager.DeselectAll(); }; if (e.ctrlKey) { dockingFunc = (document: Doc) => CollectionDockingView.Instance.AddRightSplit(document, undefined); @@ -55,6 +55,7 @@ export class LinkMenuItem extends React.Component<LinkMenuItemProps> { DocumentManager.Instance.jumpToDocument(jumpToDoc, e.altKey, false, async document => dockingFunc(document), undefined, targetContext!); } else if (this.props.destinationDoc === self.props.linkDoc.anchor1 && sourceContext) { + jumpToDoc.guid = guid; DocumentManager.Instance.jumpToDocument(jumpToDoc, e.altKey, false, document => dockingFunc(sourceContext!)); } else if (DocumentManager.Instance.getDocumentView(jumpToDoc)) { diff --git a/src/client/views/pdf/Page.tsx b/src/client/views/pdf/Page.tsx index 7ca9d2d7d..09bdd8043 100644 --- a/src/client/views/pdf/Page.tsx +++ b/src/client/views/pdf/Page.tsx @@ -112,7 +112,7 @@ export default class Page extends React.Component<IPageProps> { if (!BoolCast(annotationDoc.linkedToDoc)) { let annotations = await DocListCastAsync(annotationDoc.annotations); annotations && annotations.forEach(anno => anno.target = targetDoc); - DocUtils.MakeLink(annotationDoc, targetDoc, dragData.targetContext, `Annotation from ${StrCast(this.props.Document.title)}`) + DocUtils.MakeLink(annotationDoc, targetDoc, dragData.targetContext, `Annotation from ${StrCast(this.props.Document.title)}`); } } }, |