aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client/documents/Documents.ts1
-rw-r--r--src/client/goldenLayout.js2
-rw-r--r--src/client/util/RichTextSchema.tsx1
-rw-r--r--src/client/util/TooltipTextMenu.tsx14
-rw-r--r--src/client/views/linking/LinkMenuItem.tsx60
-rw-r--r--src/client/views/nodes/FormattedTextBox.tsx68
6 files changed, 137 insertions, 9 deletions
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index ae65fde1e..e53c72c1c 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -620,7 +620,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 f027a4bf7..379da112f 100644
--- a/src/client/util/RichTextSchema.tsx
+++ b/src/client/util/RichTextSchema.tsx
@@ -253,6 +253,7 @@ export const marks: { [index: string]: MarkSpec } = {
href: {},
location: { default: null },
title: { default: null },
+ guid: { default: null },
docref: { default: false }
},
inclusive: false,
diff --git a/src/client/util/TooltipTextMenu.tsx b/src/client/util/TooltipTextMenu.tsx
index c376b6f86..34025787d 100644
--- a/src/client/util/TooltipTextMenu.tsx
+++ b/src/client/util/TooltipTextMenu.tsx
@@ -309,11 +309,13 @@ export class TooltipTextMenu {
handlers: {
dragComplete: action(() => {
let linkDoc = dragData.linkDocument;
+ let guid = Utils.GenerateGuid();
let proto = Doc.GetProto(linkDoc);
if (proto && 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
@@ -395,13 +397,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/linking/LinkMenuItem.tsx b/src/client/views/linking/LinkMenuItem.tsx
index 19a0023e9..0e951fc38 100644
--- a/src/client/views/linking/LinkMenuItem.tsx
+++ b/src/client/views/linking/LinkMenuItem.tsx
@@ -12,6 +12,18 @@ import { MainView } from '../MainView';
import { LinkFollowBox } from './LinkFollowBox';
import './LinkMenu.scss';
import React = require("react");
+<<<<<<< HEAD:src/client/views/nodes/LinkMenuItem.tsx
+import { Doc, DocListCastAsync } from '../../../new_fields/Doc';
+import { StrCast, Cast, FieldValue, NumCast } from '../../../new_fields/Types';
+import { observable, action } from 'mobx';
+import { LinkManager } from '../../util/LinkManager';
+import { DragLinkAsDocument } from '../../util/DragManager';
+import { CollectionDockingView } from '../collections/CollectionDockingView';
+import { SelectionManager } from '../../util/SelectionManager';
+import { Utils } from '../../../Utils';
+import { Id } from '../../../new_fields/FieldSymbols';
+=======
+>>>>>>> ec62b213439ab49134fa2dbbdf38a6d1ef5737cd:src/client/views/linking/LinkMenuItem.tsx
library.add(faEye, faEdit, faTimes, faArrowRight, faChevronDown, faChevronUp);
@@ -28,8 +40,56 @@ interface LinkMenuItemProps {
export class LinkMenuItem extends React.Component<LinkMenuItemProps> {
private _drag = React.createRef<HTMLDivElement>();
@observable private _showMore: boolean = false;
+<<<<<<< HEAD:src/client/views/nodes/LinkMenuItem.tsx
+ @action toggleShowMore() { this._showMore = !this._showMore; }
+
+ @undoBatch
+ onFollowLink = async (e: React.PointerEvent): Promise<void> => {
+ e.stopPropagation();
+ e.persist();
+ let jumpToDoc = this.props.destinationDoc;
+ let pdfDoc = FieldValue(Cast(this.props.destinationDoc, Doc));
+ if (pdfDoc) {
+ jumpToDoc = pdfDoc;
+ }
+ 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);
+ }
+
+ if (this.props.destinationDoc === self.props.linkDoc.anchor2 && targetContext) {
+ DocumentManager.Instance.jumpToDocument(jumpToDoc, e.altKey, false, async document => dockingFunc(document), undefined, targetContext);
+ }
+ else if (this.props.destinationDoc === self.props.linkDoc.anchor1 && sourceContext) {
+ DocumentManager.Instance.jumpToDocument(jumpToDoc, e.altKey, false, document => dockingFunc(sourceContext!));
+ if (guid) {
+ console.log('wegotthis', StrCast(self.props.linkDoc.anchor2), jumpToDoc[Id]);
+ jumpToDoc.linkHref = Utils.prepend("/doc/" + StrCast(this.props.linkDoc.anchor2));
+ jumpToDoc.guid = guid;
+ } else { // retroactively fixing old in-text links by adding guid
+ console.log('wegotthis', self.props.linkDoc.anchor2, jumpToDoc[Id]);
+ jumpToDoc.linkHref = Utils.prepend("/doc/" + StrCast(this.props.linkDoc.anchor2));
+ let newguid = Utils.GenerateGuid();
+ this.props.linkDoc.guid = newguid;
+ jumpToDoc.guid = newguid;
+ }
+ }
+ else if (DocumentManager.Instance.getDocumentView(jumpToDoc)) {
+ DocumentManager.Instance.jumpToDocument(jumpToDoc, e.altKey, undefined, undefined, NumCast((this.props.destinationDoc === self.props.linkDoc.anchor2 ? self.props.linkDoc.anchor2Page : self.props.linkDoc.anchor1Page)));
+ }
+ else {
+ DocumentManager.Instance.jumpToDocument(jumpToDoc, e.altKey, false, dockingFunc);
+ }
+=======
@action toggleShowMore() {
this._showMore = !this._showMore;
+>>>>>>> ec62b213439ab49134fa2dbbdf38a6d1ef5737cd:src/client/views/linking/LinkMenuItem.tsx
}
onEdit = (e: React.PointerEvent): void => {
diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx
index 0ea36cdc2..985075a52 100644
--- a/src/client/views/nodes/FormattedTextBox.tsx
+++ b/src/client/views/nodes/FormattedTextBox.tsx
@@ -135,6 +135,65 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
if (this.props.isOverlay) {
DragManager.StartDragFunctions.push(() => FormattedTextBox.InputBoxOverlay = undefined);
}
+
+ document.addEventListener("paste", this.paste);
+
+ reaction(
+ () => StrCast(this.props.Document.guid),
+ async (guid) => {
+ let start = -1;
+ let href = this.props.Document.linkHref;
+
+ if (this._editorView && guid) {
+ let editor = this._editorView;
+ let ret = findLinkFrag(editor.state.doc.content, editor);
+
+ if (ret.frag.size > 2) {
+ let tr;
+ if (ret.frag.firstChild) {
+ tr = editor.state.tr.setSelection(TextSelection.between(editor.state.doc.resolve(ret.start + 2), editor.state.doc.resolve(ret.start + ret.frag.firstChild.nodeSize)));
+ } else {
+ tr = editor.state.tr.setSelection(TextSelection.near(editor.state.doc.resolve(ret.start)));
+ }
+ editor.focus();
+ editor.dispatch(tr.scrollIntoView());
+ editor.dispatch(tr.scrollIntoView()); // bcz: sometimes selection doesn't fully scroll into view on smaller text boxes <5 lines visibility -- hopefully avoidable by ppl just not using small boxes...?
+ this.props.Document.guid = "";
+ this.props.Document.linkHref = "";
+ }
+ }
+
+ function findLinkFrag(frag: Fragment, editor: EditorView) {
+ const nodes: Node[] = [];
+ frag.forEach((node, index) => {
+ let examinedNode = findLinkNode(node, editor);
+ if (examinedNode && examinedNode.textContent !== "") {
+ nodes.push(examinedNode);
+ 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) {
+ return node;
+ } else if (href && href === marks[linkIndex].attrs.href) { // retroactively fixing old in-text links by adding guid
+ marks[linkIndex].attrs.guid = guid;
+ return node;
+ }
+ console.log('href was and is ', href, marks[linkIndex].attrs.href);
+ }
+ return undefined;
+ }
+ }
+ );
}
public get CurrentDiv(): HTMLDivElement { return this._ref.current!; }
@@ -598,6 +657,7 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
let frag = addMarkToFrag(slice.content, (node: Node) => addLinkMark(node, StrCast(doc.title)));
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"));
}
});
@@ -724,6 +784,7 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
let ctrlKey = e.ctrlKey;
if (e.button === 0 && ((!this.props.isSelected() && !e.ctrlKey) || (this.props.isSelected() && e.ctrlKey)) && !e.metaKey && e.target) {
let href = (e.target as any).href;
+ let guid = (e.target as any).guid;
let location: string;
if ((e.target as any).attributes.location) {
location = (e.target as any).attributes.location.value;
@@ -747,9 +808,14 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
let proto = Doc.GetProto(linkDoc);
let targetContext = await Cast(proto.targetContext, Doc);
let jumpToDoc = await Cast(linkDoc.anchor2, Doc);
+
if (jumpToDoc) {
if (DocumentManager.Instance.getDocumentView(jumpToDoc)) {
-
+ // if !guid, then generate guid and apply to full doc
+ if (!guid) {
+ console.log('making new guid!'); // hehheehhehehe
+ linkDoc.guid = Utils.GenerateGuid();
+ }
DocumentManager.Instance.jumpToDocument(jumpToDoc, e.altKey, undefined, undefined, NumCast((jumpToDoc === linkDoc.anchor2 ? linkDoc.anchor2Page : linkDoc.anchor1Page)));
return;
}