From caaf9578dc8676833b45a98d7e448c1c754ae9ae Mon Sep 17 00:00:00 2001 From: Safae Merigh Date: Tue, 26 May 2020 20:36:12 +0000 Subject: Modifications to DashDocCommentView (class from RichTextSchema) --- .../nodes/formattedText/DashDocCommentView.tsx | 139 ++++++++++++--------- 1 file changed, 80 insertions(+), 59 deletions(-) (limited to 'src/client/views/nodes/formattedText/DashDocCommentView.tsx') diff --git a/src/client/views/nodes/formattedText/DashDocCommentView.tsx b/src/client/views/nodes/formattedText/DashDocCommentView.tsx index d56b87ae5..2d4e360a8 100644 --- a/src/client/views/nodes/formattedText/DashDocCommentView.tsx +++ b/src/client/views/nodes/formattedText/DashDocCommentView.tsx @@ -1,56 +1,75 @@ -import { IReactionDisposer, observable, reaction, runInAction } from "mobx"; -import { baseKeymap, toggleMark } from "prosemirror-commands"; -import { redo, undo } from "prosemirror-history"; -import { keymap } from "prosemirror-keymap"; -import { DOMOutputSpecArray, Fragment, MarkSpec, Node, NodeSpec, Schema, Slice } from "prosemirror-model"; -import { bulletList, listItem, orderedList } from 'prosemirror-schema-list'; -import { EditorState, NodeSelection, Plugin, TextSelection } from "prosemirror-state"; -import { StepMap } from "prosemirror-transform"; -import { EditorView } from "prosemirror-view"; +import { TextSelection } from "prosemirror-state"; import * as ReactDOM from 'react-dom'; -import { Doc, DocListCast, Field, HeightSym, WidthSym } from "../../../../fields/Doc"; -import { Id } from "../../../../fields/FieldSymbols"; -import { List } from "../../../../fields/List"; -import { ObjectField } from "../../../../fields/ObjectField"; -import { listSpec } from "../../../../fields/Schema"; -import { SchemaHeaderField } from "../../../../fields/SchemaHeaderField"; -import { ComputedField } from "../../../../fields/ScriptField"; -import { BoolCast, Cast, NumCast, StrCast } from "../../../../fields/Types"; -import { emptyFunction, returnEmptyString, returnFalse, returnOne, Utils, returnZero } from "../../../../Utils"; +import { Doc } from "../../../../fields/Doc"; import { DocServer } from "../../../DocServer"; - import React = require("react"); -import { schema } from "./schema_rts"; +export class DashDocCommentView { + _fieldWrapper: HTMLDivElement; // container for label and value + + constructor(node: any, view: any, getPos: any) { + this._fieldWrapper = document.createElement("div"); + this._fieldWrapper.style.width = node.attrs.width; + this._fieldWrapper.style.height = node.attrs.height; + this._fieldWrapper.style.fontWeight = "bold"; + this._fieldWrapper.style.position = "relative"; + this._fieldWrapper.style.display = "inline-block"; + this._fieldWrapper.onkeypress = function (e: any) { e.stopPropagation(); }; + this._fieldWrapper.onkeydown = function (e: any) { e.stopPropagation(); }; + this._fieldWrapper.onkeyup = function (e: any) { e.stopPropagation(); }; + this._fieldWrapper.onmousedown = function (e: any) { e.stopPropagation(); }; + + ReactDOM.render(, this._fieldWrapper); + (this as any).dom = this._fieldWrapper; + } + + destroy() { + ReactDOM.unmountComponentAtNode(this._fieldWrapper); + } + + selectNode() { } +} -interface IDashDocCommentView { +interface IDashDocCommentViewInternal { node: any; view: any; getPos: any; } -export class DashDocCommentView extends React.Component{ - constructor(props: IDashDocCommentView) { - super(props); + +export class DashDocCommentViewInternal extends React.Component{ + + constructor(props: IDashDocCommentViewInternal) { + super(props) + this.onPointerLeaveCollapsed = this.onPointerLeaveCollapsed.bind(this) + this.onPointerEnterCollapsed = this.onPointerEnterCollapsed.bind(this) + this.onPointerUpCollapsed = this.onPointerUpCollapsed.bind(this) + this.onPointerDownCollapsed = this.onPointerDownCollapsed.bind(this) } - targetNode = () => { // search forward in the prosemirror doc for the attached dashDocNode that is the target of the comment anchor - for (let i = this.props.getPos() + 1; i < this.props.view.state.doc.content.size; i++) { - const m = this.props.view.state.doc.nodeAt(i); - if (m && m.type === this.props.view.state.schema.nodes.dashDoc && m.attrs.docid === this.props.node.attrs.docid) { - return { node: m, pos: i, hidden: m.attrs.hidden } as { node: any, pos: number, hidden: boolean }; - } - } - const dashDoc = this.props.view.state.schema.nodes.dashDoc.create({ width: 75, height: 35, title: "dashDoc", docid: this.props.node.attrs.docid, float: "right" }); - this.props.view.dispatch(this.props.view.state.tr.insert(this.props.getPos() + 1, dashDoc)); - setTimeout(() => { try { this.props.view.dispatch(this.props.view.state.tr.setSelection(TextSelection.create(this.props.view.state.tr.doc, this.props.getPos() + 2))); } catch (e) { } }, 0); - return undefined; + getId() { + return this.props.node.attrs.docid } - onPointerDownCollapse = (e: any) => e.stopPropagation(); + onPointerLeaveCollapsed(e: any) { + DocServer.GetRefField(this.props.node.attrs.docid).then(async dashDoc => dashDoc instanceof Doc && Doc.linkFollowUnhighlight()); + e.preventDefault(); + e.stopPropagation(); + }; - onPointerUpCollapse = (e: any) => { + onPointerEnterCollapsed(e: any) { + DocServer.GetRefField(this.props.node.attrs.docid).then(async dashDoc => dashDoc instanceof Doc && Doc.linkFollowHighlight(dashDoc, false)); + e.preventDefault(); + e.stopPropagation(); + }; + + onPointerUpCollapsed(e: any) { const target = this.targetNode(); + if (target) { const expand = target.hidden; const tr = this.props.view.state.tr.setNodeMarkup(target.pos, undefined, { ...target.node.attrs, hidden: target.node.attrs.hidden ? false : true }); @@ -61,35 +80,37 @@ export class DashDocCommentView extends React.Component{ }, 0); } e.stopPropagation(); - } + }; - onPointerEnterCollapse = (e: any) => { - DocServer.GetRefField(this.props.node.attrs.docid).then(async dashDoc => dashDoc instanceof Doc && Doc.linkFollowHighlight(dashDoc, false)); - e.preventDefault(); + onPointerDownCollapsed(e: any) { e.stopPropagation(); - } + }; - onPointerLeaveCollapse = (e: any) => { - DocServer.GetRefField(this.props.node.attrs.docid).then(async dashDoc => dashDoc instanceof Doc && Doc.linkFollowUnhighlight()); - e.preventDefault(); - e.stopPropagation(); - } - - render() { + targetNode = () => { // search forward in the prosemirror doc for the attached dashDocNode that is the target of the comment anchor + for (let i = this.props.getPos() + 1; i < this.props.view.state.doc.content.size; i++) { + const m = this.props.view.state.doc.nodeAt(i); + if (m && m.type === this.props.view.state.schema.nodes.dashDoc && m.attrs.docid === this.props.node.attrs.docid) { + return { node: m, pos: i, hidden: m.attrs.hidden } as { node: any, pos: number, hidden: boolean }; + } + } - const collapsedId = "DashDocCommentView-" + this.props.node.attrs.docid; + const dashDoc = this.props.view.state.schema.nodes.dashDoc.create({ width: 75, height: 35, title: "dashDoc", docid: this.props.node.attrs.docid, float: "right" }); + this.props.view.dispatch(this.props.view.state.tr.insert(this.props.getPos() + 1, dashDoc)); + setTimeout(() => { try { this.props.view.dispatch(this.props.view.state.tr.setSelection(TextSelection.create(this.props.view.state.tr.doc, this.props.getPos() + 2))); } catch (e) { } }, 0); + return undefined; + }; + render() { return ( - - - ); + + ) } -} \ No newline at end of file +} -- cgit v1.2.3-70-g09d2 From 997035dfaf78ec0bcb4ec1b85e2e3f7dae410ca0 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Tue, 16 Jun 2020 12:40:21 -0400 Subject: cleaned up some of the prosemirror plugin views. --- .../nodes/formattedText/DashDocCommentView.tsx | 38 +++--- .../views/nodes/formattedText/DashFieldView.tsx | 7 +- .../views/nodes/formattedText/FootnoteView.tsx | 17 +-- .../views/nodes/formattedText/FormattedTextBox.tsx | 8 +- .../formattedText/FormattedTextBoxComment.tsx | 7 +- .../views/nodes/formattedText/RichTextSchema.tsx | 96 +------------- .../views/nodes/formattedText/SummaryView.tsx | 144 +++++++-------------- 7 files changed, 86 insertions(+), 231 deletions(-) (limited to 'src/client/views/nodes/formattedText/DashDocCommentView.tsx') diff --git a/src/client/views/nodes/formattedText/DashDocCommentView.tsx b/src/client/views/nodes/formattedText/DashDocCommentView.tsx index 2d4e360a8..ad204f3df 100644 --- a/src/client/views/nodes/formattedText/DashDocCommentView.tsx +++ b/src/client/views/nodes/formattedText/DashDocCommentView.tsx @@ -4,6 +4,10 @@ import { Doc } from "../../../../fields/Doc"; import { DocServer } from "../../../DocServer"; import React = require("react"); + +// creates an inline comment in a note when '>>' is typed. +// the comment sits on the right side of the note and vertically aligns with its anchor in the text. +// the comment can be toggled on/off with the '<-' text anchor. export class DashDocCommentView { _fieldWrapper: HTMLDivElement; // container for label and value @@ -19,11 +23,7 @@ export class DashDocCommentView { this._fieldWrapper.onkeyup = function (e: any) { e.stopPropagation(); }; this._fieldWrapper.onmousedown = function (e: any) { e.stopPropagation(); }; - ReactDOM.render(, this._fieldWrapper); + ReactDOM.render(, this._fieldWrapper); (this as any).dom = this._fieldWrapper; } @@ -35,12 +35,11 @@ export class DashDocCommentView { } interface IDashDocCommentViewInternal { - node: any; + docid: string; view: any; getPos: any; } - export class DashDocCommentViewInternal extends React.Component{ constructor(props: IDashDocCommentViewInternal) { @@ -51,18 +50,14 @@ export class DashDocCommentViewInternal extends React.Component dashDoc instanceof Doc && Doc.linkFollowUnhighlight()); + DocServer.GetRefField(this.props.docid).then(async dashDoc => dashDoc instanceof Doc && Doc.linkFollowUnhighlight()); e.preventDefault(); e.stopPropagation(); }; onPointerEnterCollapsed(e: any) { - DocServer.GetRefField(this.props.node.attrs.docid).then(async dashDoc => dashDoc instanceof Doc && Doc.linkFollowHighlight(dashDoc, false)); + DocServer.GetRefField(this.props.docid).then(async dashDoc => dashDoc instanceof Doc && Doc.linkFollowHighlight(dashDoc, false)); e.preventDefault(); e.stopPropagation(); }; @@ -75,7 +70,7 @@ export class DashDocCommentViewInternal extends React.Component { - expand && DocServer.GetRefField(this.props.node.attrs.docid).then(async dashDoc => dashDoc instanceof Doc && Doc.linkFollowHighlight(dashDoc)); + expand && DocServer.GetRefField(this.props.docid).then(async dashDoc => dashDoc instanceof Doc && Doc.linkFollowHighlight(dashDoc)); try { this.props.view.dispatch(this.props.view.state.tr.setSelection(TextSelection.create(this.props.view.state.tr.doc, this.props.getPos() + (expand ? 2 : 1)))); } catch (e) { } }, 0); } @@ -87,16 +82,17 @@ export class DashDocCommentViewInternal extends React.Component { // search forward in the prosemirror doc for the attached dashDocNode that is the target of the comment anchor - for (let i = this.props.getPos() + 1; i < this.props.view.state.doc.content.size; i++) { - const m = this.props.view.state.doc.nodeAt(i); - if (m && m.type === this.props.view.state.schema.nodes.dashDoc && m.attrs.docid === this.props.node.attrs.docid) { + const state = this.props.view.state; + for (let i = this.props.getPos() + 1; i < state.doc.content.size; i++) { + const m = state.doc.nodeAt(i); + if (m && m.type === state.schema.nodes.dashDoc && m.attrs.docid === this.props.docid) { return { node: m, pos: i, hidden: m.attrs.hidden } as { node: any, pos: number, hidden: boolean }; } } - const dashDoc = this.props.view.state.schema.nodes.dashDoc.create({ width: 75, height: 35, title: "dashDoc", docid: this.props.node.attrs.docid, float: "right" }); - this.props.view.dispatch(this.props.view.state.tr.insert(this.props.getPos() + 1, dashDoc)); - setTimeout(() => { try { this.props.view.dispatch(this.props.view.state.tr.setSelection(TextSelection.create(this.props.view.state.tr.doc, this.props.getPos() + 2))); } catch (e) { } }, 0); + const dashDoc = state.schema.nodes.dashDoc.create({ width: 75, height: 35, title: "dashDoc", docid: this.props.docid, float: "right" }); + this.props.view.dispatch(state.tr.insert(this.props.getPos() + 1, dashDoc)); + setTimeout(() => { try { this.props.view.dispatch(state.tr.setSelection(TextSelection.create(state.tr.doc, this.props.getPos() + 2))); } catch (e) { } }, 0); return undefined; }; @@ -104,7 +100,7 @@ export class DashDocCommentViewInternal extends React.Component, this._fieldWrapper); (this as any).dom = this._fieldWrapper; } - destroy() { - ReactDOM.unmountComponentAtNode(this._fieldWrapper); - } + destroy() { ReactDOM.unmountComponentAtNode(this._fieldWrapper); } selectNode() { } - } + interface IDashFieldViewInternal { fieldKey: string; docid: string; diff --git a/src/client/views/nodes/formattedText/FootnoteView.tsx b/src/client/views/nodes/formattedText/FootnoteView.tsx index 1d21f2ae9..1683cc972 100644 --- a/src/client/views/nodes/formattedText/FootnoteView.tsx +++ b/src/client/views/nodes/formattedText/FootnoteView.tsx @@ -28,15 +28,11 @@ export class FootnoteView { } selectNode() { - const attrs = { ...this.node.attrs }; - attrs.visibility = true; this.dom.classList.add("ProseMirror-selectednode"); if (!this.innerView) this.open(); } deselectNode() { - const attrs = { ...this.node.attrs }; - attrs.visibility = false; this.dom.classList.remove("ProseMirror-selectednode"); if (this.innerView) this.close(); } @@ -78,7 +74,7 @@ export class FootnoteView { }) as any } }); - setTimeout(() => this.innerView && this.innerView.docView.setSelection(0, 0, this.innerView.root, true), 0); + setTimeout(() => this.innerView?.docView.setSelection(0, 0, this.innerView.root, true), 0); } ignore = (e: PointerEvent) => { @@ -88,13 +84,11 @@ export class FootnoteView { toggle = () => { if (this.innerView) this.close(); - else { - this.open(); - } + else this.open(); } close() { - this.innerView && this.innerView.destroy(); + this.innerView?.destroy(); this.innerView = null; this.dom.textContent = ""; } @@ -106,8 +100,7 @@ export class FootnoteView { if (!tr.getMeta("fromOutside")) { const outerTr = this.outerView.state.tr, offsetMap = StepMap.offset(this.getPos() + 1); for (const transaction of transactions) { - const steps = transaction.steps; - for (const step of steps) { + for (const step of transaction.steps) { outerTr.step(step.map(offsetMap)); } } @@ -139,7 +132,7 @@ export class FootnoteView { } stopEvent(event: any) { - return this.innerView && this.innerView.dom.contains(event.target); + return this.innerView?.dom.contains(event.target); } ignoreMutation() { diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index 99cd503ec..ba36a1618 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -35,8 +35,8 @@ import buildKeymap from "./ProsemirrorExampleTransfer"; import RichTextMenu from './RichTextMenu'; import { RichTextRules } from "./RichTextRules"; -import { DashDocView } from "./DashDocView"; -// import { DashDocView } from "./RichTextSchema"; +//import { DashDocView } from "./DashDocView"; +import { DashDocView } from "./RichTextSchema"; import { DashDocCommentView } from "./DashDocCommentView"; import { DashFieldView } from "./DashFieldView"; @@ -903,9 +903,9 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp }, dispatchTransaction: this.dispatchTransaction, nodeViews: { - dashComment(node, view, getPos) { console.log("rendering dashComment"); return new DashDocCommentView(node, view, getPos); }, - dashField(node, view, getPos) { return new DashFieldView(node, view, getPos, self); }, + dashComment(node, view, getPos) { return new DashDocCommentView(node, view, getPos); }, dashDoc(node, view, getPos) { return new DashDocView(node, view, getPos, self); }, + dashField(node, view, getPos) { return new DashFieldView(node, view, getPos, self); }, summary(node, view, getPos) { return new SummaryView(node, view, getPos); }, ordered_list(node, view, getPos) { return new OrderedListView(); }, footnote(node, view, getPos) { return new FootnoteView(node, view, getPos); } diff --git a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx index 5ac173602..000b3c2e5 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx @@ -50,7 +50,9 @@ export function findEndOfMark(rpos: ResolvedPos, view: EditorView, finder: (mark return after; } - +// this view appears when clicking on text that has a hyperlink which is configured to show a preview of its target. +// this will also display metadata information about text when the view is configured to display things like other people who authored text. +// export class FormattedTextBoxComment { static tooltip: HTMLElement; static tooltipText: HTMLElement; @@ -235,9 +237,6 @@ export class FormattedTextBoxComment { FormattedTextBoxComment.tooltip.style.width = NumCast(target._width) ? `${NumCast(target._width)}` : "100%"; FormattedTextBoxComment.tooltip.style.height = NumCast(target._height) ? `${NumCast(target._height)}` : "100%"; } - // let ext = (target && target.type !== DocumentType.PDFANNO && Doc.fieldExtensionDoc(target, "data")) || target; // try guessing that the target doc's data is in the 'data' field. probably need an 'overviewLayout' and then just display the target Document .... - // let text = ext && StrCast(ext.text); - // ext && (FormattedTextBoxComment.tooltipText.textContent = (target && target.type === DocumentType.PDFANNO ? "Quoted from " : "") + "=> " + (text || StrCast(ext.title))); } }); } diff --git a/src/client/views/nodes/formattedText/RichTextSchema.tsx b/src/client/views/nodes/formattedText/RichTextSchema.tsx index 79abfa995..05557e22a 100644 --- a/src/client/views/nodes/formattedText/RichTextSchema.tsx +++ b/src/client/views/nodes/formattedText/RichTextSchema.tsx @@ -1,95 +1,20 @@ -import { IReactionDisposer, observable, reaction, runInAction } from "mobx"; -import { baseKeymap, toggleMark } from "prosemirror-commands"; -import { redo, undo } from "prosemirror-history"; -import { keymap } from "prosemirror-keymap"; -import { DOMOutputSpecArray, Fragment, MarkSpec, Node, NodeSpec, Schema, Slice } from "prosemirror-model"; -import { bulletList, listItem, orderedList } from 'prosemirror-schema-list'; -import { EditorState, NodeSelection, Plugin, TextSelection } from "prosemirror-state"; -import { StepMap } from "prosemirror-transform"; -import { EditorView } from "prosemirror-view"; +import { IReactionDisposer, reaction } from "mobx"; +import { NodeSelection } from "prosemirror-state"; import * as ReactDOM from 'react-dom'; -import { Doc, DocListCast, Field, HeightSym, WidthSym } from "../../../../fields/Doc"; +import { Doc, HeightSym, WidthSym } from "../../../../fields/Doc"; import { Id } from "../../../../fields/FieldSymbols"; -import { List } from "../../../../fields/List"; import { ObjectField } from "../../../../fields/ObjectField"; -import { listSpec } from "../../../../fields/Schema"; -import { SchemaHeaderField } from "../../../../fields/SchemaHeaderField"; import { ComputedField } from "../../../../fields/ScriptField"; -import { BoolCast, Cast, NumCast, StrCast, FieldValue } from "../../../../fields/Types"; -import { emptyFunction, returnEmptyString, returnFalse, returnOne, Utils, returnZero } from "../../../../Utils"; +import { BoolCast, Cast, NumCast, StrCast } from "../../../../fields/Types"; +import { emptyFunction, returnEmptyString, returnFalse, returnZero, Utils } from "../../../../Utils"; import { DocServer } from "../../../DocServer"; import { Docs, DocUtils } from "../../../documents/Documents"; -import { CollectionViewType } from "../../collections/CollectionView"; +import { Transform } from "../../../util/Transform"; import { DocumentView } from "../DocumentView"; import { FormattedTextBox } from "./FormattedTextBox"; -import { DocumentManager } from "../../../util/DocumentManager"; -import { Transform } from "../../../util/Transform"; import React = require("react"); - -// export class DashDocCommentView { -// _collapsed: HTMLElement; -// _view: any; -// constructor(node: any, view: any, getPos: any) { - -// console.log("DashDocCommentView constructor"); - -// //moved -// this._collapsed = document.createElement("span"); -// this._collapsed.className = "formattedTextBox-inlineComment"; -// this._collapsed.id = "DashDocCommentView-" + node.attrs.docid; -// this._view = view; -// //moved -// const targetNode = () => { // search forward in the prosemirror doc for the attached dashDocNode that is the target of the comment anchor -// for (let i = getPos() + 1; i < view.state.doc.content.size; i++) { -// const m = view.state.doc.nodeAt(i); -// if (m && m.type === view.state.schema.nodes.dashDoc && m.attrs.docid === node.attrs.docid) { -// return { node: m, pos: i, hidden: m.attrs.hidden } as { node: any, pos: number, hidden: boolean }; -// } -// } -// const dashDoc = view.state.schema.nodes.dashDoc.create({ width: 75, height: 35, title: "dashDoc", docid: node.attrs.docid, float: "right" }); -// view.dispatch(view.state.tr.insert(getPos() + 1, dashDoc)); -// setTimeout(() => { try { view.dispatch(view.state.tr.setSelection(TextSelection.create(view.state.tr.doc, getPos() + 2))); } catch (e) { } }, 0); -// return undefined; -// }; -// //moved -// this._collapsed.onpointerdown = (e: any) => { -// e.stopPropagation(); -// }; -// //moved -// this._collapsed.onpointerup = (e: any) => { -// const target = targetNode(); -// if (target) { -// const expand = target.hidden; -// const tr = view.state.tr.setNodeMarkup(target.pos, undefined, { ...target.node.attrs, hidden: target.node.attrs.hidden ? false : true }); -// view.dispatch(tr.setSelection(TextSelection.create(tr.doc, getPos() + (expand ? 2 : 1)))); // update the attrs -// setTimeout(() => { -// expand && DocServer.GetRefField(node.attrs.docid).then(async dashDoc => dashDoc instanceof Doc && Doc.linkFollowHighlight(dashDoc)); -// try { view.dispatch(view.state.tr.setSelection(TextSelection.create(view.state.tr.doc, getPos() + (expand ? 2 : 1)))); } catch (e) { } -// }, 0); -// } -// e.stopPropagation(); -// }; -// //moved -// this._collapsed.onpointerenter = (e: any) => { -// DocServer.GetRefField(node.attrs.docid).then(async dashDoc => dashDoc instanceof Doc && Doc.linkFollowHighlight(dashDoc, false)); -// e.preventDefault(); -// e.stopPropagation(); -// }; -// //moved -// this._collapsed.onpointerleave = (e: any) => { -// DocServer.GetRefField(node.attrs.docid).then(async dashDoc => dashDoc instanceof Doc && Doc.linkFollowUnhighlight()); -// e.preventDefault(); -// e.stopPropagation(); -// }; - -// (this as any).dom = this._collapsed; -// } -// //moved -// selectNode() { } -// } - export class DashDocView { _dashSpan: HTMLDivElement; _outer: HTMLElement; @@ -132,10 +57,6 @@ export class DashDocView { this._dashSpan.style.whiteSpace = "normal"; this._dashSpan.onpointerleave = () => { - - console.log("DashDocView_dashSpan.onpointerleave"); // SMM - console.log("DashDocCommentView-id=", node.attrs.docid); // SMM - const ele = document.getElementById("DashDocCommentView-" + node.attrs.docid); if (ele) { (ele as HTMLDivElement).style.backgroundColor = ""; @@ -143,9 +64,6 @@ export class DashDocView { }; this._dashSpan.onpointerenter = () => { - console.log("DashDocView_dashSpan.onpointerenter"); // SMM - console.log("DashDocCommentView-id=", node.attrs.docid); // SMM - const ele = document.getElementById("DashDocCommentView-" + node.attrs.docid); if (ele) { (ele as HTMLDivElement).style.backgroundColor = "orange"; @@ -208,7 +126,7 @@ export class DashDocView { this._dashSpan.style.height = this._outer.style.height = Math.max(20, dim[1]) + "px"; this._outer.style.border = "1px solid " + StrCast(finalLayout.color, (Cast(Doc.UserDoc().activeWorkspace, Doc, null).darkScheme ? "dimGray" : "lightGray")); }, { fireImmediately: true }); - + const doReactRender = (finalLayout: Doc, resolvedDataDoc: Doc) => { ReactDOM.unmountComponentAtNode(this._dashSpan); diff --git a/src/client/views/nodes/formattedText/SummaryView.tsx b/src/client/views/nodes/formattedText/SummaryView.tsx index e5328496c..922285bd0 100644 --- a/src/client/views/nodes/formattedText/SummaryView.tsx +++ b/src/client/views/nodes/formattedText/SummaryView.tsx @@ -1,108 +1,45 @@ -import { IReactionDisposer, observable, computed, action } from "mobx"; -import { Fragment, Node, Slice } from "prosemirror-model"; import { TextSelection } from "prosemirror-state"; +import { Fragment, Node, Slice } from "prosemirror-model"; import * as ReactDOM from 'react-dom'; import React = require("react"); -// import { dom } from "@fortawesome/fontawesome-svg-core"; -// import { observer } from "mobx-react"; +// an elidable textblock that collapses when its '<-' is clicked and expands when its '...' anchor is clicked. +// this node actively edits prosemirror (as opposed to just changing how things are rendered) and thus doesn't +// really need a react view. However, it would be cleaner to figure out how to do this just as a react rendering +// method instead of changing prosemirror's text when the expand/elide buttons are clicked. export class SummaryView { - - _fieldWrapper: HTMLDivElement; // container for label + _fieldWrapper: HTMLSpanElement; // container for label and value constructor(node: any, view: any, getPos: any) { - console.log("You are here") - this._fieldWrapper = document.createElement("div"); - this._fieldWrapper.style.fontWeight = "bold"; - this._fieldWrapper.style.position = "relative"; - this._fieldWrapper.style.display = "inline-block"; + const self = this; + this._fieldWrapper = document.createElement("span"); + this._fieldWrapper.className = this.className(node.attrs.visibility); + this._fieldWrapper.onpointerdown = function (e: any) { self.onPointerDown(e, node, view, getPos); } + this._fieldWrapper.onkeypress = function (e: any) { e.stopPropagation(); }; + this._fieldWrapper.onkeydown = function (e: any) { e.stopPropagation(); }; + this._fieldWrapper.onkeyup = function (e: any) { e.stopPropagation(); }; + this._fieldWrapper.onmousedown = function (e: any) { e.stopPropagation(); }; const js = node.toJSON; - node.toJSON = function () { - return js.apply(this, arguments); - }; + node.toJSON = function () { return js.apply(this, arguments); }; - console.log("rendering new SummaryViewInternal") - ReactDOM.render(, this._fieldWrapper); + ReactDOM.render(, this._fieldWrapper); (this as any).dom = this._fieldWrapper; } + className = (visible: boolean) => "formattedTextBox-summarizer" + (visible ? "" : "-collapsed"); + destroy() { ReactDOM.unmountComponentAtNode(this._fieldWrapper); } selectNode() { } - deselectNode() { } - - destroy() { - ReactDOM.unmountComponentAtNode(this._fieldWrapper); - } -} - -interface ISummaryViewInternal { - node: any; - view: any; - getPos: any; -} - -export class SummaryViewInternal extends React.Component{ - _className: any; - _view: any; - _reactionDisposer: IReactionDisposer | undefined; - - constructor(props: ISummaryViewInternal) { - super(props); - - this._className = this.className(this.props.node.attrs.visibility); - this._view = this.props.view; - this.onPointerDownCollapsed = this.onPointerDownCollapsed.bind(this); - this.updateSummarizedText = this.updateSummarizedText.bind(this); - } - - componentWillUnmount() { - this._reactionDisposer?.(); - } - - - className(visible: boolean) { - return "formattedTextBox-summarizer" + (visible ? "" : "-collapsed"); - } - - onPointerDownCollapsed(e: any) { - const visible = !this.props.node.attrs.visibility; - const attrs = { ...this.props.node.attrs, visibility: visible }; - let textSelection = TextSelection.create(this.props.view.state.doc, this.props.getPos() + 1); - - - if (!visible) { // update summarized text and save in attrs - textSelection = this.updateSummarizedText(this.props.getPos() + 1); - attrs.text = textSelection.content(); - attrs.textslice = attrs.text.toJSON(); - } - - this.props.view.dispatch(this.props.view.state.tr. - setSelection(textSelection). // select the current summarized text (or where it will be if its collapsed) - replaceSelection(!visible ? new Slice(Fragment.fromArray([]), 0, 0) : this.props.node.attrs.text). // collapse/expand it - setNodeMarkup(this.props.getPos(), undefined, attrs)); // update the attrs - - e.preventDefault(); - e.stopPropagation(); - - this._className = this.className(visible); - - } - - updateSummarizedText(start?: any) { - const mtype = this.props.view.state.schema.marks.summarize; - const mtypeInc = this.props.view.state.schema.marks.summarizeInclusive; + updateSummarizedText(start: any, view: any) { + const mtype = view.state.schema.marks.summarize; + const mtypeInc = view.state.schema.marks.summarizeInclusive; let endPos = start; const visited = new Set(); - for (let i: number = start + 1; i < this.props.view.state.doc.nodeSize - 1; i++) { + for (let i: number = start + 1; i < view.state.doc.nodeSize - 1; i++) { let skip = false; - this.props.view.state.doc.nodesBetween(start, i, (node: Node, pos: number, parent: Node, index: number) => { + view.state.doc.nodesBetween(start, i, (node: Node, pos: number, parent: Node, index: number) => { if (node.isLeaf && !visited.has(node) && !skip) { if (node.marks.find((m: any) => m.type === mtype || m.type === mtypeInc)) { visited.add(node); @@ -112,18 +49,33 @@ export class SummaryViewInternal extends React.Component{ } }); } - return TextSelection.create(this.props.view.state.doc, start, endPos); + return TextSelection.create(view.state.doc, start, endPos); } - render() { - return ( - - - - ); - + onPointerDown = (e: any, node: any, view: any, getPos: any) => { + const visible = !node.attrs.visibility; + const attrs = { ...node.attrs, visibility: visible }; + let textSelection = TextSelection.create(view.state.doc, getPos() + 1); + if (!visible) { // update summarized text and save in attrs + textSelection = this.updateSummarizedText(getPos() + 1, view); + attrs.text = textSelection.content(); + attrs.textslice = attrs.text.toJSON(); + } + view.dispatch(view.state.tr. + setSelection(textSelection). // select the current summarized text (or where it will be if its collapsed) + replaceSelection(!visible ? new Slice(Fragment.fromArray([]), 0, 0) : node.attrs.text). // collapse/expand it + setNodeMarkup(getPos(), undefined, attrs)); // update the attrs + e.preventDefault(); + e.stopPropagation(); + this._fieldWrapper.className = this.className(visible); } +} +interface ISummaryView { } +// currently nothing needs to be rendered for the internal view of a summary. +export class SummaryViewInternal extends React.Component { + render() { + return <> ; + } +} \ No newline at end of file -- cgit v1.2.3-70-g09d2 From 3afdfa11e35bcb73dd4a871e5e4489b0dd3a3c95 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Tue, 16 Jun 2020 21:16:54 -0400 Subject: fixed problems with scriptingBox types & cleaned up code. --- src/client/views/nodes/ScriptingBox.scss | 25 ++- src/client/views/nodes/ScriptingBox.tsx | 224 +++++---------------- .../nodes/formattedText/DashDocCommentView.tsx | 22 +- 3 files changed, 84 insertions(+), 187 deletions(-) (limited to 'src/client/views/nodes/formattedText/DashDocCommentView.tsx') diff --git a/src/client/views/nodes/ScriptingBox.scss b/src/client/views/nodes/ScriptingBox.scss index d7fb7ca88..a937364a8 100644 --- a/src/client/views/nodes/ScriptingBox.scss +++ b/src/client/views/nodes/ScriptingBox.scss @@ -35,14 +35,14 @@ max-height: calc(100%-30px); display: flex; flex-direction: row; - overflow: scroll; + overflow: auto; justify-content: center; .descriptor { overflow: hidden; } - .scriptingBox-textArea { + .scriptingBox-textArea, .scriptingBox-textArea-inputs { flex: 70; height: 100%; max-width: 95%; @@ -50,7 +50,7 @@ box-sizing: border-box; resize: none; padding: 7px; - overflow-y: scroll; + overflow-y: auto; overflow-x: hidden; body { @@ -63,7 +63,7 @@ width: 100%; height: 100%; margin-bottom: 60px !important; - overflow-y: scroll; + overflow-y: auto; overflow-x: hidden; overflow: hidden; } @@ -94,7 +94,7 @@ border-radius: 3px; box-shadow: 0 0 5px rgba(27, 31, 35, 0.1); list-style: none; - overflow-y: scroll; + overflow-y: auto; overflow-x: hidden; } @@ -103,7 +103,7 @@ width: 100%; text-align: left; outline: none; - overflow-y: scroll; + overflow-y: auto; } .rta__entity:hover { @@ -122,6 +122,17 @@ } } + .scriptingBox-textArea-inputs { + max-width: 100%; + height: 40%; + width: 100%; + resize: none; + } + .scriptingBox-textArea-script { + resize: none; + height: 100%; + } + .scriptingBox-plist { flex: 30; width: 30%; @@ -129,7 +140,7 @@ box-sizing: border-box; resize: none; padding: 2px; - overflow-y: scroll; + overflow-y: auto; .scriptingBox-pborder { background-color: rgb(241, 239, 235); diff --git a/src/client/views/nodes/ScriptingBox.tsx b/src/client/views/nodes/ScriptingBox.tsx index 0ae57ca52..8912b113c 100644 --- a/src/client/views/nodes/ScriptingBox.tsx +++ b/src/client/views/nodes/ScriptingBox.tsx @@ -8,7 +8,7 @@ import { documentSchema } from "../../../fields/documentSchemas"; import { List } from "../../../fields/List"; import { createSchema, listSpec, makeInterface } from "../../../fields/Schema"; import { ScriptField } from "../../../fields/ScriptField"; -import { Cast, NumCast, ScriptCast, StrCast } from "../../../fields/Types"; +import { Cast, NumCast, ScriptCast, StrCast, BoolCast } from "../../../fields/Types"; import { returnEmptyString } from "../../../Utils"; import { DragManager } from "../../util/DragManager"; import { InteractionUtils } from "../../util/InteractionUtils"; @@ -21,6 +21,7 @@ import { FieldView, FieldViewProps } from "../nodes/FieldView"; import { OverlayView } from "../OverlayView"; import { DocumentIconContainer } from "./DocumentIcon"; import "./ScriptingBox.scss"; +import { TraceMobx } from "../../../fields/util"; const _global = (window /* browser */ || global /* node */) as any; const ScriptingSchema = createSchema({}); @@ -34,15 +35,14 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent void; + private _caretPos = 0; @observable private _errorMessage: string = ""; @observable private _applied: boolean = false; @observable private _function: boolean = false; - @observable private _hovered: boolean = false; @observable private _spaced: boolean = false; @observable private _scriptKeys: any = Scripting.getGlobals(); - @observable private _scriptGlobals: any = Scripting.getGlobalObj(); @observable private _scriptingDescriptions: any = Scripting.getDescriptions(); @observable private _scriptingParams: any = Scripting.getParameters(); @@ -57,7 +57,6 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent(value); } getValue(result: any, descrip: boolean) { - let value = ""; if (typeof result === "object") { - let text = ""; - if (descrip) { - text = result[1]; - } else { - text = result[2]; - } - if (text !== undefined) { - value = text; - } else { - value = ""; - } + const text = descrip ? result[1] : result[2]; + return text !== undefined ? text : ""; } else { - value = ""; + return ""; } - return value; } @action @@ -118,21 +106,18 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent (x + scriptWidth)) { const diff = (left + suggestionWidth) - (x + scriptWidth); left = left - diff; } - runInAction(() => { - this._suggestionBoxX = left; - this._suggestionBoxY = top; - }); + this._suggestionBoxX = left; + this._suggestionBoxY = top; } componentWillUnmount() { @@ -176,11 +161,7 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent { - this._errorMessage = ""; if (this.functionName.length === 0) { @@ -246,7 +226,6 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent { //@ts-ignore - this.dataDoc[name] = e.target.selectedOptions[0].value; + const val = e.target.selectedOptions[0].value; + this.dataDoc[name] = val[0] === "S" ? val.substring(1) : val[0] === "N" ? parseInt(val.substring(1)) : val.substring(1) === "true"; } // creates a copy of the script document @@ -297,19 +277,17 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent this.functionDescription = e.target.value} placeholder="enter description here" value={this.functionDescription} - style={{ maxWidth: "100%", height: "40%", width: "100%", resize: "none" }} />; const nameInput =