aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/nodes/FormattedTextBox.tsx
diff options
context:
space:
mode:
authormadelinegr <laura_wilson@brown.edu>2019-06-05 13:22:43 -0400
committermadelinegr <laura_wilson@brown.edu>2019-06-05 13:22:43 -0400
commit51986eb8483237de11120c04ffb4bacb72b2a603 (patch)
tree447e25c575de2092bd68560f5ed6fb48dfb65892 /src/client/views/nodes/FormattedTextBox.tsx
parent1b3089350c807a52a2acd98c25330e315313b19e (diff)
parente24bf03dd4edab2e5be2d73a6dc7f9c01fc5da85 (diff)
pulled from master
Diffstat (limited to 'src/client/views/nodes/FormattedTextBox.tsx')
-rw-r--r--src/client/views/nodes/FormattedTextBox.tsx65
1 files changed, 47 insertions, 18 deletions
diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx
index 5c635cc0c..478e7ce93 100644
--- a/src/client/views/nodes/FormattedTextBox.tsx
+++ b/src/client/views/nodes/FormattedTextBox.tsx
@@ -7,11 +7,12 @@ import { history } from "prosemirror-history";
import { keymap } from "prosemirror-keymap";
import { EditorState, Plugin, Transaction } from "prosemirror-state";
import { EditorView } from "prosemirror-view";
-import { Doc, Field, Opt, WidthSym, HeightSym } from "../../../new_fields/Doc";
+import { Doc, Opt } from "../../../new_fields/Doc";
import { RichTextField } from "../../../new_fields/RichTextField";
import { createSchema, makeInterface } from "../../../new_fields/Schema";
import { Cast, NumCast, StrCast } from "../../../new_fields/Types";
import { DocServer } from "../../DocServer";
+import { DocUtils, Docs } from '../../documents/Documents';
import { DocumentManager } from "../../util/DocumentManager";
import { DragManager } from "../../util/DragManager";
import buildKeymap from "../../util/ProsemirrorKeymap";
@@ -21,14 +22,12 @@ import { SelectionManager } from "../../util/SelectionManager";
import { TooltipLinkingMenu } from "../../util/TooltipLinkingMenu";
import { TooltipTextMenu } from "../../util/TooltipTextMenu";
import { undoBatch, UndoManager } from "../../util/UndoManager";
-import { ContextMenu } from "../../views/ContextMenu";
-import { CollectionDockingView } from "../collections/CollectionDockingView";
import { DocComponent } from "../DocComponent";
import { InkingControl } from "../InkingControl";
import { FieldView, FieldViewProps } from "./FieldView";
import "./FormattedTextBox.scss";
import React = require("react");
-import { DocUtils } from '../../documents/Documents';
+import { Id } from '../../../new_fields/FieldSymbols';
library.add(faEdit);
library.add(faSmile);
@@ -70,15 +69,40 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
private _ref: React.RefObject<HTMLDivElement>;
private _proseRef: React.RefObject<HTMLDivElement>;
private _editorView: Opt<EditorView>;
- private _gotDown: boolean = false;
+ private _toolTipTextMenu: TooltipTextMenu | undefined = undefined;
+ private _lastState: any = undefined;
+ private _applyingChange: boolean = false;
private _dropDisposer?: DragManager.DragDropDisposer;
+ private _linkClicked = "";
private _reactionDisposer: Opt<IReactionDisposer>;
private _inputReactionDisposer: Opt<IReactionDisposer>;
private _proxyReactionDisposer: Opt<IReactionDisposer>;
public get CurrentDiv(): HTMLDivElement { return this._ref.current!; }
+ @observable _entered = false;
@observable public static InputBoxOverlay?: FormattedTextBox = undefined;
public static InputBoxOverlayScroll: number = 0;
+ public static IsFragment(html: string) {
+ return html.indexOf("data-pm-slice") !== -1;
+ }
+ public static GetHref(html: string): string {
+ let parser = new DOMParser();
+ let parsedHtml = parser.parseFromString(html, 'text/html');
+ if (parsedHtml.body.childNodes.length === 1 && parsedHtml.body.childNodes[0].childNodes.length === 1 &&
+ (parsedHtml.body.childNodes[0].childNodes[0] as any).href) {
+ return (parsedHtml.body.childNodes[0].childNodes[0] as any).href;
+ }
+ return "";
+ }
+ public static GetDocFromUrl(url: string) {
+ if (url.startsWith(document.location.origin)) {
+ let start = url.indexOf(window.location.origin);
+ let path = url.substr(start, url.length - start);
+ let docid = path.replace(DocServer.prepend("/doc/"), "").split("?")[0];
+ return docid;
+ }
+ return "";
+ }
constructor(props: FieldViewProps) {
super(props);
@@ -90,9 +114,7 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
}
}
- _applyingChange: boolean = false;
- _lastState: any = undefined;
dispatchTransaction = (tx: Transaction) => {
if (this._editorView) {
const state = this._lastState = this._editorView.state.apply(tx);
@@ -230,7 +252,7 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
this._toolTipTextMenu.tooltip.style.opacity = "0";
}
}
- let ctrlKey = e.ctrlKey;
+ this._linkClicked = "";
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;
for (let parent = (e.target as any).parentNode; !href && parent; parent = parent.parentNode) {
@@ -238,18 +260,17 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
}
if (href) {
if (href.indexOf(DocServer.prepend("/doc/")) === 0) {
- let docid = href.replace(DocServer.prepend("/doc/"), "").split("?")[0];
- DocServer.GetRefField(docid).then(f => {
- (f instanceof Doc) && DocumentManager.Instance.jumpToDocument(f, ctrlKey, document => this.props.addDocTab(document, "inTab"))
- });
+ this._linkClicked = href.replace(DocServer.prepend("/doc/"), "").split("?")[0];
+ } else {
+ let webDoc = Docs.WebDocument(href, { x: NumCast(this.props.Document.x, 0) + NumCast(this.props.Document.width, 0), y: NumCast(this.props.Document.y) });
+ this.props.addDocument && this.props.addDocument(webDoc);
+ this._linkClicked = webDoc[Id];
}
e.stopPropagation();
e.preventDefault();
}
-
}
if (e.button === 2 || (e.button === 0 && e.ctrlKey)) {
- this._gotDown = true;
e.preventDefault();
}
}
@@ -257,6 +278,14 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
if (this._toolTipTextMenu && this._toolTipTextMenu.tooltip) {
this._toolTipTextMenu.tooltip.style.opacity = "1";
}
+ let ctrlKey = e.ctrlKey;
+ if (this._linkClicked) {
+ DocServer.GetRefField(this._linkClicked).then(f => {
+ (f instanceof Doc) && DocumentManager.Instance.jumpToDocument(f, ctrlKey, document => this.props.addDocTab(document, "inTab"));
+ });
+ e.stopPropagation();
+ e.preventDefault();
+ }
if (e.buttons === 1 && this.props.isSelected() && !e.altKey) {
e.stopPropagation();
}
@@ -280,6 +309,10 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
onClick = (e: React.MouseEvent): void => {
this._proseRef.current!.focus();
+ if (this._linkClicked) {
+ e.preventDefault();
+ e.stopPropagation();
+ }
}
onMouseDown = (e: React.MouseEvent): void => {
if (!this.props.isSelected()) { // preventing default allows the onClick to be generated instead of being swallowed by the text box itself
@@ -297,7 +330,6 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
});
}
- _toolTipTextMenu: TooltipTextMenu | undefined = undefined;
tooltipLinkingMenuPlugin() {
let myprops = this.props;
return new Plugin({
@@ -333,8 +365,6 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
}
}
- @observable
- _entered = false;
@action
onPointerEnter = (e: React.PointerEvent) => {
this._entered = true;
@@ -363,7 +393,6 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
onPointerUp={this.onPointerUp}
onPointerDown={this.onPointerDown}
onMouseDown={this.onMouseDown}
- onContextMenu={this.specificContextMenu}
// tfs: do we need this event handler
onWheel={this.onPointerWheel}
onPointerEnter={this.onPointerEnter}