aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/nodes/LinkAnchorBox.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/nodes/LinkAnchorBox.tsx')
-rw-r--r--src/client/views/nodes/LinkAnchorBox.tsx167
1 files changed, 91 insertions, 76 deletions
diff --git a/src/client/views/nodes/LinkAnchorBox.tsx b/src/client/views/nodes/LinkAnchorBox.tsx
index 7fd289a97..85a8622ec 100644
--- a/src/client/views/nodes/LinkAnchorBox.tsx
+++ b/src/client/views/nodes/LinkAnchorBox.tsx
@@ -1,30 +1,31 @@
-import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
-import { action, observable } from "mobx";
-import { observer } from "mobx-react";
-import { Doc } from "../../../fields/Doc";
-import { Cast, NumCast, StrCast } from "../../../fields/Types";
-import { TraceMobx } from "../../../fields/util";
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { action, observable } from 'mobx';
+import { observer } from 'mobx-react';
+import { Doc } from '../../../fields/Doc';
+import { Cast, NumCast, StrCast } from '../../../fields/Types';
+import { TraceMobx } from '../../../fields/util';
import { emptyFunction, setupMoveUpEvents, Utils } from '../../../Utils';
-import { DragManager } from "../../util/DragManager";
-import { LinkManager } from "../../util/LinkManager";
-import { SelectionManager } from "../../util/SelectionManager";
-import { ContextMenu } from "../ContextMenu";
-import { ContextMenuProps } from "../ContextMenuItem";
-import { ViewBoxBaseComponent } from "../DocComponent";
-import { LinkEditor } from "../linking/LinkEditor";
-import { StyleProp } from "../StyleProvider";
-import { FieldView, FieldViewProps } from "./FieldView";
-import "./LinkAnchorBox.scss";
-import { LinkDocPreview } from "./LinkDocPreview";
-import React = require("react");
-const higflyout = require("@hig/flyout");
+import { DragManager } from '../../util/DragManager';
+import { LinkFollower } from '../../util/LinkFollower';
+import { SelectionManager } from '../../util/SelectionManager';
+import { ContextMenu } from '../ContextMenu';
+import { ContextMenuProps } from '../ContextMenuItem';
+import { ViewBoxBaseComponent } from '../DocComponent';
+import { LinkEditor } from '../linking/LinkEditor';
+import { StyleProp } from '../StyleProvider';
+import { FieldView, FieldViewProps } from './FieldView';
+import './LinkAnchorBox.scss';
+import { LinkDocPreview } from './LinkDocPreview';
+import React = require('react');
+const higflyout = require('@hig/flyout');
export const { anchorPoints } = higflyout;
export const Flyout = higflyout.default;
-
@observer
export class LinkAnchorBox extends ViewBoxBaseComponent<FieldViewProps>() {
- public static LayoutString(fieldKey: string) { return FieldView.LayoutString(LinkAnchorBox, fieldKey); }
+ public static LayoutString(fieldKey: string) {
+ return FieldView.LayoutString(LinkAnchorBox, fieldKey);
+ }
_doubleTap = false;
_lastTap: number = 0;
_ref = React.createRef<HTMLDivElement>();
@@ -38,7 +39,7 @@ export class LinkAnchorBox extends ViewBoxBaseComponent<FieldViewProps>() {
onPointerDown = (e: React.PointerEvent) => {
setupMoveUpEvents(this, e, this.onPointerMove, emptyFunction, emptyFunction, false);
- }
+ };
onPointerMove = action((e: PointerEvent, down: number[], delta: number[]) => {
const cdiv = this._ref && this._ref.current && this._ref.current.parentElement;
if (!this._isOpen && cdiv) {
@@ -47,20 +48,20 @@ export class LinkAnchorBox extends ViewBoxBaseComponent<FieldViewProps>() {
const separation = Math.sqrt((pt[0] - e.clientX) * (pt[0] - e.clientX) + (pt[1] - e.clientY) * (pt[1] - e.clientY));
if (separation > 100) {
const dragData = new DragManager.DocumentDragData([this.rootDoc]);
- dragData.dropAction = "alias";
- dragData.removeDropProperties = ["anchor1_x", "anchor1_y", "anchor2_x", "anchor2_y", "isLinkButton"];
+ dragData.dropAction = 'alias';
+ dragData.removeDropProperties = ['anchor1_x', 'anchor1_y', 'anchor2_x', 'anchor2_y', 'isLinkButton'];
DragManager.StartDocumentDrag([this._ref.current!], dragData, pt[0], pt[1]);
return true;
} else {
- this.rootDoc[this.fieldKey + "_x"] = (pt[0] - bounds.left) / bounds.width * 100;
- this.rootDoc[this.fieldKey + "_y"] = (pt[1] - bounds.top) / bounds.height * 100;
+ this.rootDoc[this.fieldKey + '_x'] = ((pt[0] - bounds.left) / bounds.width) * 100;
+ this.rootDoc[this.fieldKey + '_y'] = ((pt[1] - bounds.top) / bounds.height) * 100;
}
}
return false;
});
@action
onClick = (e: React.MouseEvent) => {
- if ((e.button === 2 || e.ctrlKey || !this.layoutDoc.isLinkButton)) {
+ if (e.button === 2 || e.ctrlKey || !this.layoutDoc.isLinkButton) {
this.props.select(false);
}
if (!this._doubleTap && !e.ctrlKey && e.button < 2) {
@@ -68,10 +69,13 @@ export class LinkAnchorBox extends ViewBoxBaseComponent<FieldViewProps>() {
this._editing = true;
anchorContainerDoc && this.props.bringToFront(anchorContainerDoc, false);
if (anchorContainerDoc && !this.layoutDoc.onClick && !this._isOpen) {
- this._timeout = setTimeout(action(() => {
- LinkManager.FollowLink(this.rootDoc, anchorContainerDoc, this.props, false);
- this._editing = false;
- }), 300 - (Date.now() - this._lastTap));
+ this._timeout = setTimeout(
+ action(() => {
+ LinkFollower.FollowLink(this.rootDoc, anchorContainerDoc, this.props, false);
+ this._editing = false;
+ }),
+ 300 - (Date.now() - this._lastTap)
+ );
e.stopPropagation();
}
} else {
@@ -81,17 +85,17 @@ export class LinkAnchorBox extends ViewBoxBaseComponent<FieldViewProps>() {
this.openLinkEditor(e);
e.stopPropagation();
}
- }
+ };
openLinkDocOnRight = (e: React.MouseEvent) => {
- this.props.addDocTab(this.rootDoc, "add:right");
- }
+ this.props.addDocTab(this.rootDoc, 'add:right');
+ };
openLinkTargetOnRight = (e: React.MouseEvent) => {
const alias = Doc.MakeAlias(Cast(this.layoutDoc[this.fieldKey], Doc, null));
alias._isLinkButton = undefined;
- alias.layoutKey = "layout";
- this.props.addDocTab(alias, "add:right");
- }
+ alias.layoutKey = 'layout';
+ this.props.addDocTab(alias, 'add:right');
+ };
@action
openLinkEditor = action((e: React.MouseEvent) => {
SelectionManager.DeselectAll();
@@ -100,56 +104,67 @@ export class LinkAnchorBox extends ViewBoxBaseComponent<FieldViewProps>() {
specificContextMenu = (e: React.MouseEvent): void => {
const funcs: ContextMenuProps[] = [];
- funcs.push({ description: "Open Link Target on Right", event: () => this.openLinkTargetOnRight(e), icon: "eye" });
- funcs.push({ description: "Open Link on Right", event: () => this.openLinkDocOnRight(e), icon: "eye" });
- funcs.push({ description: "Open Link Editor", event: () => this.openLinkEditor(e), icon: "eye" });
- funcs.push({ description: "Toggle Always Show Link", event: () => this.props.Document.linkDisplay = !this.props.Document.linkDisplay, icon: "eye" });
+ funcs.push({ description: 'Open Link Target on Right', event: () => this.openLinkTargetOnRight(e), icon: 'eye' });
+ funcs.push({ description: 'Open Link on Right', event: () => this.openLinkDocOnRight(e), icon: 'eye' });
+ funcs.push({ description: 'Open Link Editor', event: () => this.openLinkEditor(e), icon: 'eye' });
+ funcs.push({ description: 'Toggle Always Show Link', event: () => (this.props.Document.linkDisplay = !this.props.Document.linkDisplay), icon: 'eye' });
- ContextMenu.Instance.addItem({ description: "Options...", subitems: funcs, icon: "asterisk" });
- }
+ ContextMenu.Instance.addItem({ description: 'Options...', subitems: funcs, icon: 'asterisk' });
+ };
render() {
TraceMobx();
const small = this.props.PanelWidth() <= 1; // this happens when rendered in a treeView
- const x = NumCast(this.rootDoc[this.fieldKey + "_x"], 100);
- const y = NumCast(this.rootDoc[this.fieldKey + "_y"], 100);
+ const x = NumCast(this.rootDoc[this.fieldKey + '_x'], 100);
+ const y = NumCast(this.rootDoc[this.fieldKey + '_y'], 100);
const linkSource = this.props.styleProvider?.(this.dataDoc, this.props, StyleProp.LinkSource);
- const background = this.props.styleProvider?.(this.dataDoc, this.props, StyleProp.BackgroundColor + ":anchor");
- const anchor = this.fieldKey === "anchor1" ? "anchor2" : "anchor1";
- const anchorScale = !this.dataDoc[this.fieldKey + "-useLinkSmallAnchor"] && (x === 0 || x === 100 || y === 0 || y === 100) ? 1 : .25;
+ const background = this.props.styleProvider?.(this.dataDoc, this.props, StyleProp.BackgroundColor + ':anchor');
+ const anchor = this.fieldKey === 'anchor1' ? 'anchor2' : 'anchor1';
+ const anchorScale = !this.dataDoc[this.fieldKey + '-useLinkSmallAnchor'] && (x === 0 || x === 100 || y === 0 || y === 100) ? 1 : 0.25;
const targetTitle = StrCast((this.dataDoc[anchor] as Doc)?.title);
const flyout = (
<div className="linkAnchorBoxBox-flyout" title=" " onPointerOver={() => Doc.UnBrushDoc(this.rootDoc)}>
- <LinkEditor sourceDoc={Cast(this.dataDoc[this.fieldKey], Doc, null)} hideback={true} linkDoc={this.rootDoc} showLinks={action(() => { })} />
- {!this._forceOpen ? (null) : <div className="linkAnchorBox-linkCloser" onPointerDown={action(() => this._isOpen = this._editing = this._forceOpen = false)}>
- <FontAwesomeIcon color="dimgray" icon={"times"} size={"sm"} />
- </div>}
+ <LinkEditor sourceDoc={Cast(this.dataDoc[this.fieldKey], Doc, null)} hideback={true} linkDoc={this.rootDoc} showLinks={action(() => {})} />
+ {!this._forceOpen ? null : (
+ <div className="linkAnchorBox-linkCloser" onPointerDown={action(() => (this._isOpen = this._editing = this._forceOpen = false))}>
+ <FontAwesomeIcon color="dimgray" icon={'times'} size={'sm'} />
+ </div>
+ )}
+ </div>
+ );
+ return (
+ <div
+ className={`linkAnchorBox-cont${small ? '-small' : ''}`}
+ onPointerLeave={LinkDocPreview.Clear}
+ onPointerEnter={e =>
+ LinkDocPreview.SetLinkInfo({
+ docProps: this.props,
+ linkSrc: linkSource,
+ linkDoc: this.rootDoc,
+ showHeader: true,
+ location: [e.clientX, e.clientY + 20],
+ })
+ }
+ onPointerDown={this.onPointerDown}
+ onClick={this.onClick}
+ title={targetTitle}
+ onContextMenu={this.specificContextMenu}
+ ref={this._ref}
+ style={{
+ background,
+ left: `calc(${x}% - ${small ? 2.5 : 7.5}px)`,
+ top: `calc(${y}% - ${small ? 2.5 : 7.5}px)`,
+ transform: `scale(${anchorScale})`,
+ }}>
+ {!this._editing && !this._forceOpen ? null : (
+ <Flyout anchorPoint={anchorPoints.LEFT_TOP} content={flyout} open={this._forceOpen ? true : undefined} onOpen={() => (this._isOpen = true)} onClose={action(() => (this._isOpen = this._forceOpen = this._editing = false))}>
+ <span className="linkAnchorBox-button">
+ <FontAwesomeIcon icon={'eye'} size={'lg'} />
+ </span>
+ </Flyout>
+ )}
</div>
);
- return <div className={`linkAnchorBox-cont${small ? "-small" : ""}`}
- onPointerLeave={LinkDocPreview.Clear}
- onPointerEnter={e => LinkDocPreview.SetLinkInfo({
- docProps: this.props,
- linkSrc: linkSource,
- linkDoc: this.rootDoc,
- showHeader: true,
- location: [e.clientX, e.clientY + 20]
- })}
- onPointerDown={this.onPointerDown} onClick={this.onClick} title={targetTitle} onContextMenu={this.specificContextMenu}
- ref={this._ref}
- style={{
- background,
- left: `calc(${x}% - ${small ? 2.5 : 7.5}px)`,
- top: `calc(${y}% - ${small ? 2.5 : 7.5}px)`,
- transform: `scale(${anchorScale})`
- }} >
- {!this._editing && !this._forceOpen ? (null) :
- <Flyout anchorPoint={anchorPoints.LEFT_TOP} content={flyout} open={this._forceOpen ? true : undefined} onOpen={() => this._isOpen = true} onClose={action(() => this._isOpen = this._forceOpen = this._editing = false)}>
- <span className="linkAnchorBox-button" >
- <FontAwesomeIcon icon={"eye"} size={"lg"} />
- </span>
- </Flyout>}
- </div>;
}
}