aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/nodes/FormattedTextBox.tsx
diff options
context:
space:
mode:
authorab <abdullah_ahmed@brown.edu>2019-07-23 11:38:10 -0400
committerab <abdullah_ahmed@brown.edu>2019-07-23 11:38:10 -0400
commit13c016d7f7765acda7f6ce2d69c14597469f55d7 (patch)
tree6fcf409ee4f0035443aa4fb67a05d24aae09689d /src/client/views/nodes/FormattedTextBox.tsx
parentbd841fe56540e1a9177d2872310b10fefcb4acd1 (diff)
parentd880e4b2fcb4e7bab3ee25d63209b173efcf37c0 (diff)
merged
Diffstat (limited to 'src/client/views/nodes/FormattedTextBox.tsx')
-rw-r--r--src/client/views/nodes/FormattedTextBox.tsx87
1 files changed, 61 insertions, 26 deletions
diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx
index 8db7a9327..524500f35 100644
--- a/src/client/views/nodes/FormattedTextBox.tsx
+++ b/src/client/views/nodes/FormattedTextBox.tsx
@@ -1,6 +1,6 @@
import { library } from '@fortawesome/fontawesome-svg-core';
import { faEdit, faSmile } from '@fortawesome/free-solid-svg-icons';
-import { action, IReactionDisposer, observable, reaction, runInAction, computed, Lambda } from "mobx";
+import { action, IReactionDisposer, observable, reaction, runInAction, computed, Lambda, trace } from "mobx";
import { observer } from "mobx-react";
import { baseKeymap } from "prosemirror-commands";
import { history } from "prosemirror-history";
@@ -10,11 +10,11 @@ import { Node as ProsNode } from "prosemirror-model";
import { EditorState, Plugin, Transaction } from "prosemirror-state";
import { EditorView } from "prosemirror-view";
import { Doc, Opt } from "../../../new_fields/Doc";
-import { Id } from '../../../new_fields/FieldSymbols';
+import { Id, Copy } from '../../../new_fields/FieldSymbols';
import { List } from '../../../new_fields/List';
import { RichTextField } from "../../../new_fields/RichTextField";
import { createSchema, listSpec, makeInterface } from "../../../new_fields/Schema";
-import { BoolCast, Cast, NumCast, StrCast } from "../../../new_fields/Types";
+import { BoolCast, Cast, NumCast, StrCast, DateCast } from "../../../new_fields/Types";
import { DocServer } from "../../DocServer";
import { Docs } from '../../documents/Documents';
import { DocumentManager } from '../../util/DocumentManager';
@@ -35,6 +35,9 @@ import { FieldView, FieldViewProps } from "./FieldView";
import "./FormattedTextBox.scss";
import React = require("react");
import { For } from 'babel-types';
+import { DateField } from '../../../new_fields/DateField';
+import { thisExpression } from 'babel-types';
+import { Utils } from '../../../Utils';
library.add(faEdit);
library.add(faSmile);
@@ -73,6 +76,7 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
private _linkClicked = "";
private _reactionDisposer: Opt<IReactionDisposer>;
private _searchReactionDisposer?: Lambda;
+ private _textReactionDisposer: Opt<IReactionDisposer>;
private _proxyReactionDisposer: Opt<IReactionDisposer>;
private dropDisposer?: DragManager.DragDropDisposer;
public get CurrentDiv(): HTMLDivElement { return this._ref.current!; }
@@ -133,7 +137,9 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
}
}
- @computed get dataDoc() { return BoolCast(this.props.Document.isTemplate) && this.props.DataDoc ? this.props.DataDoc : this.props.Document; }
+ @computed get extensionDoc() { return Doc.resolvedFieldDataDoc(this.dataDoc, this.props.fieldKey, "dummy"); }
+
+ @computed get dataDoc() { return BoolCast(this.props.Document.isTemplate) && this.props.DataDoc ? this.props.DataDoc : Doc.GetProto(this.props.Document); }
dispatchTransaction = (tx: Transaction) => {
if (this._editorView) {
@@ -149,13 +155,15 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
Doc.GetProto(this.dataDoc)[this.props.fieldKey] = new RichTextField(JSON.stringify(state.toJSON()));
Doc.GetProto(this.dataDoc)[this.props.fieldKey + "_text"] = state.doc.textBetween(0, state.doc.content.size, "\n\n");
}
+ if (this.extensionDoc) this.extensionDoc.text = state.doc.textBetween(0, state.doc.content.size, "\n\n");
+ if (this.extensionDoc) this.extensionDoc.lastModified = new DateField(new Date(Date.now()));
+ this.dataDoc[this.props.fieldKey] = new RichTextField(JSON.stringify(state.toJSON()));
this._applyingChange = false;
let title = StrCast(this.dataDoc.title);
if (title && title.startsWith("-") && this._editorView) {
let str = this._editorView.state.doc.textContent;
let titlestr = str.substr(0, Math.min(40, str.length));
- let target = this.dataDoc.proto ? this.dataDoc.proto : this.dataDoc;
- target.title = "-" + titlestr + (str.length > 40 ? "..." : "");
+ this.dataDoc.title = "-" + titlestr + (str.length > 40 ? "..." : "");
}
}
}
@@ -289,10 +297,22 @@ 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}}`;
},
- field => this._editorView && !this._applyingChange &&
- this._editorView.updateState(EditorState.fromJSON(config, JSON.parse(field)))
+ field2 => {
+ this._editorView && !this._applyingChange &&
+ this._editorView.updateState(EditorState.fromJSON(config, JSON.parse(field2)));
+ }
);
+ this._textReactionDisposer = reaction(
+ () => this.extensionDoc,
+ () => {
+ if (this.dataDoc.text || this.dataDoc.lastModified) {
+ this.extensionDoc.text = this.dataDoc.text;
+ this.extensionDoc.lastModified = DateCast(this.dataDoc.lastModified)[Copy]();
+ this.dataDoc.text = undefined;
+ this.dataDoc.lastModified = undefined;
+ }
+ }, { fireImmediately: true });
this.setupEditor(config, this.dataDoc, this.props.fieldKey);
this._searchReactionDisposer = reaction(() => {
@@ -347,15 +367,10 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
}
componentWillUnmount() {
- if (this._editorView) {
- this._editorView.destroy();
- }
- if (this._reactionDisposer) {
- this._reactionDisposer();
- }
- if (this._proxyReactionDisposer) {
- this._proxyReactionDisposer();
- }
+ this._editorView && this._editorView.destroy();
+ this._reactionDisposer && this._reactionDisposer();
+ this._proxyReactionDisposer && this._proxyReactionDisposer();
+ this._textReactionDisposer && this._textReactionDisposer();
}
onPointerDown = (e: React.PointerEvent): void => {
@@ -368,21 +383,39 @@ 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 location: string;
+ if ((e.target as any).attributes.location) {
+ location = (e.target as any).attributes.location.value;
+ }
for (let parent = (e.target as any).parentNode; !href && parent; parent = parent.parentNode) {
href = parent.childNodes[0].href ? parent.childNodes[0].href : parent.href;
}
if (href) {
- if (href.indexOf(DocServer.prepend("/doc/")) === 0) {
- this._linkClicked = href.replace(DocServer.prepend("/doc/"), "").split("?")[0];
+ if (href.indexOf(Utils.prepend("/doc/")) === 0) {
+ this._linkClicked = href.replace(Utils.prepend("/doc/"), "").split("?")[0];
if (this._linkClicked) {
- DocServer.GetRefField(this._linkClicked).then(f => {
- (f instanceof Doc) && DocumentManager.Instance.jumpToDocument(f, ctrlKey, false, document => this.props.addDocTab(document, undefined, "inTab"));
+ DocServer.GetRefField(this._linkClicked).then(async linkDoc => {
+ if (linkDoc instanceof Doc) {
+ 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)) {
+
+ DocumentManager.Instance.jumpToDocument(jumpToDoc, e.altKey, undefined, undefined, NumCast((jumpToDoc === linkDoc.anchor2 ? linkDoc.anchor2Page : linkDoc.anchor1Page)));
+ return;
+ }
+ }
+ if (targetContext) {
+ DocumentManager.Instance.jumpToDocument(targetContext, ctrlKey, false, document => this.props.addDocTab(document, undefined, location ? location : "inTab"));
+ }
+ }
});
e.stopPropagation();
e.preventDefault();
}
} 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) });
+ let webDoc = Docs.Create.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];
}
@@ -415,7 +448,8 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
}
}
onPointerWheel = (e: React.WheelEvent): void => {
- if (this.props.isSelected()) {
+ // if a text note is not selected and scrollable, this prevents us from being able to scroll and zoom out at the same time
+ if (this.props.isSelected() || e.currentTarget.scrollHeight > e.currentTarget.clientHeight) {
e.stopPropagation();
}
}
@@ -472,8 +506,7 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
if (StrCast(this.dataDoc.title).startsWith("-") && this._editorView) {
let str = this._editorView.state.doc.textContent;
let titlestr = str.substr(0, Math.min(40, str.length));
- let target = this.dataDoc.proto ? this.dataDoc.proto : this.dataDoc;
- target.title = "-" + titlestr + (str.length > 40 ? "..." : "");
+ this.dataDoc.title = "-" + titlestr + (str.length > 40 ? "..." : "");
}
if (!this._undoTyping) {
this._undoTyping = UndoManager.StartBatch("undoTyping");
@@ -484,13 +517,14 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
@action
tryUpdateHeight() {
if (this.props.isOverlay && this.props.Document.autoHeight) {
+ let self = this;
let xf = this._ref.current!.getBoundingClientRect();
let scrBounds = this.props.ScreenToLocalTransform().transformBounds(0, 0, xf.width, xf.height);
let nh = NumCast(this.dataDoc.nativeHeight, 0);
let dh = NumCast(this.props.Document.height, 0);
let sh = scrBounds.height;
this.props.Document.height = nh ? dh / nh * sh : sh;
- this.dataDoc.proto!.nativeHeight = nh ? sh : undefined;
+ this.dataDoc.nativeHeight = nh ? sh : undefined;
}
}
@@ -516,6 +550,7 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
let style = this.props.isOverlay ? "scroll" : "hidden";
let rounded = StrCast(this.props.Document.borderRounding) === "100%" ? "-rounded" : "";
let interactive = InkingControl.Instance.selectedTool ? "" : "interactive";
+ Doc.UpdateDocumentExtensionForField(this.dataDoc, this.props.fieldKey);
return (
<div className={`formattedTextBox-cont-${style}`} ref={this._ref}
style={{