diff options
-rw-r--r-- | src/client/util/RichTextRules.ts | 12 | ||||
-rw-r--r-- | src/client/util/RichTextSchema.tsx | 64 | ||||
-rw-r--r-- | src/client/views/nodes/FormattedTextBox.scss | 12 | ||||
-rw-r--r-- | src/client/views/nodes/FormattedTextBox.tsx | 5 |
4 files changed, 81 insertions, 12 deletions
diff --git a/src/client/util/RichTextRules.ts b/src/client/util/RichTextRules.ts index ebb9bda8a..f4c44e5ce 100644 --- a/src/client/util/RichTextRules.ts +++ b/src/client/util/RichTextRules.ts @@ -147,16 +147,14 @@ export const inpRules = { new InputRule( new RegExp(/##\s$/), (state, match, start, end) => { + let target = Docs.Create.TextDocument({ width: 75, height: 35, autoHeight: true, fontSize: 9, title: "inline comment" }); let node = (state.doc.resolve(start) as any).nodeAfter; + let newNode = schema.nodes.dashComment.create({ docid: target[Id] }); + let dashDoc = schema.nodes.dashDoc.create({ width: 75, height: 35, title: "dashDoc", docid: target[Id], float: "right" }); let sm = state.storedMarks || undefined; - let target = Docs.Create.TextDocument({ width: 75, height: 35, autoHeight: true, fontSize: 9, title: "inline comment" }); - let replaced = node ? state.tr.insertText("←", start).replaceRangeWith(start + 1, end + 1, schema.nodes.dashDoc.create({ - width: 75, height: 35, - title: "dashDoc", docid: target[Id], - float: "right" - })).setStoredMarks([...node.marks, ...(sm ? sm : [])]) : + let replaced = node ? state.tr.insert(start, newNode).replaceRangeWith(start + 1, end + 1, dashDoc).setStoredMarks([...node.marks, ...(sm ? sm : [])]) : state.tr; - return replaced.setSelection(new TextSelection(replaced.doc.resolve(end - 1))); + return replaced;//.setSelection(new NodeSelection(replaced.doc.resolve(end))); }), new InputRule( new RegExp(/\(\(/), diff --git a/src/client/util/RichTextSchema.tsx b/src/client/util/RichTextSchema.tsx index 506c9767f..522232e9f 100644 --- a/src/client/util/RichTextSchema.tsx +++ b/src/client/util/RichTextSchema.tsx @@ -107,6 +107,18 @@ export const nodes: { [index: string]: NodeSpec } = { group: "inline" }, + dashComment: { + attrs: { + docid: { default: "" }, + }, + inline: true, + group: "inline", + toDOM(node) { + const attrs = { style: `width: 40px` }; + return ["span", { ...node.attrs, ...attrs }, "←"]; + }, + }, + star: { inline: true, attrs: { @@ -171,7 +183,8 @@ export const nodes: { [index: string]: NodeSpec } = { title: { default: null }, float: { default: "right" }, location: { default: "onRight" }, - docid: { default: "" } + hidden: { default: false }, + docid: { default: "" }, }, group: "inline", draggable: true, @@ -648,6 +661,38 @@ export class ImageResizeView { } } + +export class DashDocCommentView { + _collapsed: HTMLElement; + _view: any; + constructor(node: any, view: any, getPos: any) { + this._collapsed = document.createElement("span"); + this._collapsed.className = "formattedTextBox-inlineComment"; + this._collapsed.id = "DashDocCommentView-" + node.attrs.docid; + this._view = view; + this._collapsed.onpointerdown = (e: any) => { + let node = view.state.doc.nodeAt(getPos() + 1); + view.dispatch(view.state.tr. + setNodeMarkup(getPos() + 1, undefined, { ...node.attrs, hidden: node.attrs.hidden ? false : true })); // update the attrs + setTimeout(() => node.attrs.hidden && DocServer.GetRefField(node.attrs.docid).then(async dashDoc => dashDoc instanceof Doc && Doc.linkFollowHighlight(dashDoc)), 100); + } + this._collapsed.onpointerenter = (e: any) => { + let node = view.state.doc.nodeAt(getPos() + 1); + DocServer.GetRefField(node.attrs.docid).then(async dashDoc => dashDoc instanceof Doc && Doc.linkFollowHighlight(dashDoc)); + e.preventDefault(); + e.stopPropagation(); + }; + this._collapsed.onpointerleave = (e: any) => { + let node = view.state.doc.nodeAt(getPos() + 1); + DocServer.GetRefField(node.attrs.docid).then(async dashDoc => dashDoc instanceof Doc && Doc.linkFollowUnhighlight()); + e.preventDefault(); + e.stopPropagation(); + }; + (this as any).dom = this._collapsed; + } + selectNode() { } +} + export class DashDocView { _dashSpan: HTMLDivElement; _outer: HTMLElement; @@ -667,20 +712,33 @@ export class DashDocView { this._outer.style.position = "relative"; this._outer.style.width = node.attrs.width; this._outer.style.height = node.attrs.height; - this._outer.style.display = "inline-block"; - this._outer.style.overflow = "hidden"; + this._outer.style.display = node.attrs.hidden ? "none" : "inline-block"; + // this._outer.style.overflow = "hidden"; // bcz: not sure if this is needed. if it's used, then the doc doesn't highlight when you hover over a docComment (this._outer.style as any).float = node.attrs.float; this._dashSpan.style.width = node.attrs.width; this._dashSpan.style.height = node.attrs.height; this._dashSpan.style.position = "absolute"; this._dashSpan.style.display = "inline-block"; + this._dashSpan.style.borderWidth = "4"; let removeDoc = () => { let pos = getPos(); let ns = new NodeSelection(view.state.doc.resolve(pos)); view.dispatch(view.state.tr.setSelection(ns).deleteSelection()); return true; }; + this._dashSpan.onpointerleave = () => { + let ele = document.getElementById("DashDocCommentView-" + node.attrs.docid); + if (ele) { + (ele as HTMLDivElement).style.backgroundColor = ""; + } + } + this._dashSpan.onpointerenter = () => { + let ele = document.getElementById("DashDocCommentView-" + node.attrs.docid); + if (ele) { + (ele as HTMLDivElement).style.backgroundColor = "orange"; + } + } DocServer.GetRefField(node.attrs.docid).then(async dashDoc => { if (dashDoc instanceof Doc) { self._dashDoc = dashDoc; diff --git a/src/client/views/nodes/FormattedTextBox.scss b/src/client/views/nodes/FormattedTextBox.scss index 984d51791..4f72bb679 100644 --- a/src/client/views/nodes/FormattedTextBox.scss +++ b/src/client/views/nodes/FormattedTextBox.scss @@ -189,6 +189,17 @@ footnote::after { width: 0; } + +.formattedTextBox-inlineComment { + position: relative; + width: 40px; + height: 20px; +} + +.formattedTextBox-inlineComment::after { + content: "←"; +} + .formattedTextBox-summarizer { opacity: 0.5; position: relative; @@ -198,6 +209,7 @@ footnote::after { .formattedTextBox-summarizer::after { content: "←"; + font-weight: bold; } .formattedTextBox-summarizer-collapsed { diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index c8a629984..a5530f32d 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -27,7 +27,7 @@ import { DictationManager } from '../../util/DictationManager'; import { DragManager } from "../../util/DragManager"; import buildKeymap from "../../util/ProsemirrorExampleTransfer"; import { inpRules } from "../../util/RichTextRules"; -import { FootnoteView, ImageResizeView, DashDocView, OrderedListView, schema, SummarizedView } from "../../util/RichTextSchema"; +import { DashDocCommentView, FootnoteView, ImageResizeView, DashDocView, OrderedListView, schema, SummarizedView } from "../../util/RichTextSchema"; import { SelectionManager } from "../../util/SelectionManager"; import { TooltipLinkingMenu } from "../../util/TooltipLinkingMenu"; import { TooltipTextMenu } from "../../util/TooltipTextMenu"; @@ -787,6 +787,7 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps & }, dispatchTransaction: this.dispatchTransaction, nodeViews: { + dashComment(node, view, getPos) { return new DashDocCommentView(node, view, getPos); }, dashDoc(node, view, getPos) { return new DashDocView(node, view, getPos, self); }, image(node, view, getPos) { return new ImageResizeView(node, view, getPos, self.props.addDocTab); }, star(node, view, getPos) { return new SummarizedView(node, view, getPos); }, @@ -1081,7 +1082,7 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps & whenActiveChanged={this.whenActiveChanged} removeDocument={this.removeDocument} moveDocument={this.moveDocument} - addDocument={(doc:Doc) => { doc.hideSidebar = true; return this.addDocument(doc); }} + addDocument={(doc: Doc) => { doc.hideSidebar = true; return this.addDocument(doc); }} CollectionView={undefined} ScreenToLocalTransform={() => this.props.ScreenToLocalTransform().translate(-(this.props.PanelWidth() - this.sidebarWidth), 0)} ruleProvider={undefined} |