diff options
Diffstat (limited to 'src/client/views/nodes')
| -rw-r--r-- | src/client/views/nodes/ColorBox.tsx | 4 | ||||
| -rw-r--r-- | src/client/views/nodes/ContentFittingDocumentView.tsx | 2 | ||||
| -rw-r--r-- | src/client/views/nodes/DocumentView.tsx | 2 | ||||
| -rw-r--r-- | src/client/views/nodes/PresBox.tsx | 27 | ||||
| -rw-r--r-- | src/client/views/nodes/VideoBox.tsx | 15 | ||||
| -rw-r--r-- | src/client/views/nodes/WebBox.tsx | 98 | ||||
| -rw-r--r-- | src/client/views/nodes/formattedText/FormattedTextBox.scss | 2 | ||||
| -rw-r--r-- | src/client/views/nodes/formattedText/FormattedTextBox.tsx | 6 | ||||
| -rw-r--r-- | src/client/views/nodes/formattedText/RichTextMenu.tsx | 8 |
9 files changed, 103 insertions, 61 deletions
diff --git a/src/client/views/nodes/ColorBox.tsx b/src/client/views/nodes/ColorBox.tsx index fcc9e50f5..4fb350b55 100644 --- a/src/client/views/nodes/ColorBox.tsx +++ b/src/client/views/nodes/ColorBox.tsx @@ -69,11 +69,11 @@ export class ColorBox extends ViewBoxBaseComponent<FieldViewProps, ColorDocument SetActiveInkWidth(e.target.value); SelectionManager.SelectedDocuments().filter(i => StrCast(i.rootDoc.type) === DocumentType.INK).map(i => i.rootDoc.strokeWidth = Number(e.target.value)); }} /> - <div> {ActiveInkBezierApprox() ?? 2}</div> + {/* <div> {ActiveInkBezierApprox() ?? 2}</div> <input type="range" defaultValue={ActiveInkBezierApprox() ?? 2} min={0} max={300} onChange={(e: React.ChangeEvent<HTMLInputElement>) => { SetActiveBezierApprox(e.target.value); SelectionManager.SelectedDocuments().filter(i => StrCast(i.rootDoc.type) === DocumentType.INK).map(i => i.rootDoc.strokeBezier = e.target.value); - }} /> + }} /> */} <br /> <br /> </div> diff --git a/src/client/views/nodes/ContentFittingDocumentView.tsx b/src/client/views/nodes/ContentFittingDocumentView.tsx index bc3ad5bce..0c52b9044 100644 --- a/src/client/views/nodes/ContentFittingDocumentView.tsx +++ b/src/client/views/nodes/ContentFittingDocumentView.tsx @@ -40,7 +40,7 @@ export class ContentFittingDocumentView extends React.Component<DocumentViewProp @computed get panelWidth() { return this.nativeWidth() && !this.props.Document._fitWidth ? this.nativeWidth() * this.contentScaling() : this.props.PanelWidth(); } @computed get panelHeight() { if (this.nativeHeight()) { - if (!this.props.Document._fitWidth) return this.nativeHeight() * this.contentScaling() + if (!this.props.Document._fitWidth) return this.nativeHeight() * this.contentScaling(); else return this.panelWidth / Doc.NativeAspect(this.layoutDoc, this.props.DataDoc, this.freezeDimensions) || 1; } return this.props.PanelHeight(); diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 0b27cd03c..a4da00578 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -839,8 +839,8 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu onClicks.push({ description: "Select on Click", event: () => this.selectOnClick(), icon: "link" }); onClicks.push({ description: "Follow Link on Click", event: () => this.followLinkOnClick(undefined, false), icon: "link" }); onClicks.push({ description: "Toggle Link Target on Click", event: () => this.toggleTargetOnClick(), icon: "map-pin" }); + !existingOnClick && cm.addItem({ description: "OnClick...", addDivider: true, subitems: onClicks, icon: "mouse-pointer" }); } - !existingOnClick && cm.addItem({ description: "OnClick...", addDivider: true, subitems: onClicks, icon: "mouse-pointer" }); } const funcs: ContextMenuProps[] = []; diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx index a31e92807..518d365ed 100644 --- a/src/client/views/nodes/PresBox.tsx +++ b/src/client/views/nodes/PresBox.tsx @@ -91,7 +91,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema> const tagDocs: Doc[] = []; for (const doc of this.childDocs) { const tagDoc = Cast(doc.presentationTargetDoc, Doc, null); - tagDocs.push(tagDoc) + tagDocs.push(tagDoc); } return tagDocs; } @@ -486,7 +486,14 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema> //stops the presentaton. resetPresentation = () => { this.rootDoc._itemIndex = 0; - for (const doc of this.childDocs) Cast(doc.presentationTargetDoc, Doc, null).opacity = 1; + this.childDocs.map(doc => Cast(doc.presentationTargetDoc, Doc, null)).filter(doc => doc instanceof Doc).forEach(doc => { + try { + doc.opacity = 1; + } catch (e) { + console.log("REset presentation error: ", e); + } + }); + ///for (const doc of this.childDocs) Cast(doc.presentationTargetDoc, Doc, null).opacity = 1; } @action togglePath = (srcContext: Doc, off?: boolean) => { @@ -638,9 +645,9 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema> const list = Array.from(this._selectedArray.keys()).map((doc: Doc, index: any) => { const curDoc = Cast(doc, Doc, null); const tagDoc = Cast(curDoc.presentationTargetDoc!, Doc, null); - if (curDoc && curDoc === this.activeItem) return <div className="selectedList-items"><b>{index + 1}. {curDoc.title}</b></div> - else if (tagDoc) return <div className="selectedList-items">{index + 1}. {curDoc.title}</div>; - else if (curDoc) return <div className="selectedList-items">{index + 1}. {curDoc.title}</div>; + if (curDoc && curDoc === this.activeItem) return <div key={index} className="selectedList-items"><b>{index + 1}. {curDoc.title}</b></div>; + else if (tagDoc) return <div key={index} className="selectedList-items">{index + 1}. {curDoc.title}</div>; + else if (curDoc) return <div key={index} className="selectedList-items">{index + 1}. {curDoc.title}</div>; }); return list; } @@ -799,10 +806,10 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema> } getAllIndexes = (arr: Doc[], val: Doc): number[] => { - var indexes = [], i; - for (i = 0; i < arr.length; i++) - if (arr[i] === val) - indexes.push(i); + const indexes = []; + for (let i = 0; i < arr.length; i++) { + arr[i] === val && indexes.push(i); + } return indexes; } @@ -952,7 +959,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema> doc.presMovement = PresMovement.None; break; } - }) + }); }); @undoBatch diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx index 250595db5..190193351 100644 --- a/src/client/views/nodes/VideoBox.tsx +++ b/src/client/views/nodes/VideoBox.tsx @@ -159,7 +159,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps, VideoD @action updateTimecode = () => { this.player && (this.layoutDoc._currentTimecode = this.player.currentTime); - this._youtubePlayer && (this.layoutDoc._currentTimecode = this._youtubePlayer.getCurrentTime()); + this._youtubePlayer && (this.layoutDoc._currentTimecode = this._youtubePlayer.getCurrentTime?.()); } componentDidMount() { @@ -281,13 +281,14 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps, VideoD () => !this.props.Document.isAnnotating && Doc.GetSelectedTool() === InkTool.None && this.props.isSelected(true) && !SnappingManager.GetIsDragging() && !DocumentDecorations.Instance.Interacting, (interactive) => iframe.style.pointerEvents = interactive ? "all" : "none", { fireImmediately: true }); }; - this._youtubePlayer = new YT.Player(`${this.youtubeVideoId + this._youtubeIframeId}-player`, { - events: { - 'onReady': this.props.dontRegisterView ? undefined : onYoutubePlayerReady, - 'onStateChange': this.props.dontRegisterView ? undefined : onYoutubePlayerStateChange, - } + (YT as any)?.ready(() => { + this._youtubePlayer = new YT.Player(`${this.youtubeVideoId + this._youtubeIframeId}-player`, { + events: { + 'onReady': this.props.dontRegisterView ? undefined : onYoutubePlayerReady, + 'onStateChange': this.props.dontRegisterView ? undefined : onYoutubePlayerStateChange, + } + }) }); - } private get uIButtons() { const curTime = (this.layoutDoc._currentTimecode || 0); diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx index de5546fa9..8a8f46963 100644 --- a/src/client/views/nodes/WebBox.tsx +++ b/src/client/views/nodes/WebBox.tsx @@ -1,4 +1,3 @@ -import { faMousePointer, faPen, faStickyNote } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { action, computed, IReactionDisposer, observable, reaction, runInAction } from "mobx"; import { observer } from "mobx-react"; @@ -47,6 +46,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum private _mainCont: React.RefObject<HTMLDivElement> = React.createRef(); private _startX: number = 0; private _startY: number = 0; + private _scrollTarget: any = undefined; @observable private _marqueeX: number = 0; @observable private _marqueeY: number = 0; @observable private _marqueeWidth: number = 0; @@ -61,8 +61,8 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum @observable private _savedAnnotations: Dictionary<number, HTMLDivElement[]> = new Dictionary<number, HTMLDivElement[]>(); private _selectionReactionDisposer?: IReactionDisposer; private _scrollReactionDisposer?: IReactionDisposer; + private _scrollTopReactionDisposer?: IReactionDisposer; private _moveReactionDisposer?: IReactionDisposer; - private _keyInput = React.createRef<HTMLInputElement>(); private _longPressSecondsHack?: NodeJS.Timeout; private _outerRef = React.createRef<HTMLDivElement>(); private _iframeRef = React.createRef<HTMLIFrameElement>(); @@ -83,14 +83,17 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum if (iframe && iframe.contentDocument) { iframe.setAttribute("enable-annotation", "true"); iframe.contentDocument.addEventListener("click", undoBatch(action(e => { - const href = e.target?.href; + let href = ""; + for (let ele = e.target; ele; ele = ele.parentElement) { + href = (typeof (ele.href) === "string" ? ele.href : ele.href?.baseVal) || ele.parentElement?.href || href; + } if (href) { this._url = href.replace(Utils.prepend(""), Cast(this.dataDoc[this.fieldKey], WebField, null)?.url.origin); this.submitURL(); } }))); - iframe.contentDocument.addEventListener('pointerdown', this.iframedown, false); - iframe.contentDocument.addEventListener('scroll', this.iframeScrolled, false); + iframe.contentDocument.addEventListener('wheel', this.iframeWheel, false); + iframe.contentDocument.addEventListener('scroll', this.iframeScroll, false); this.layoutDoc.scrollHeight = iframe.contentDocument.children?.[0].scrollHeight || 1000; iframe.contentDocument.children[0].scrollTop = NumCast(this.layoutDoc._scrollTop); iframe.contentDocument.children[0].scrollLeft = NumCast(this.layoutDoc._scrollLeft); @@ -102,17 +105,30 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum const durationStr = StrCast(this.Document._viewTransition).match(/([0-9]*)ms/); const duration = durationStr ? Number(durationStr[1]) : 1000; if (scrollY !== undefined) { - setTimeout(() => this._outerRef.current && smoothScroll(duration, this._outerRef.current, Math.abs(scrollY || 0)), delay); - setTimeout(() => { this.layoutDoc._scrollTop = scrollY; this.layoutDoc._scrollY = undefined; }, duration + delay); + this._forceSmoothScrollUpdate = true; + this.layoutDoc._scrollY = undefined; + setTimeout(() => this._outerRef.current && smoothScroll(duration, this._outerRef.current, Math.abs(scrollY || 0), () => this.layoutDoc._scrollTop = scrollY), delay); } if (scrollX !== undefined) { - setTimeout(() => this._outerRef.current && smoothScroll(duration, this._outerRef.current, Math.abs(scrollX || 0)), delay); - setTimeout(() => { this.layoutDoc._scrollLeft = scrollX; this.layoutDoc._scrollX = undefined; }, duration + delay); + this._forceSmoothScrollUpdate = true; + this.layoutDoc._scrollX = undefined; + setTimeout(() => this._outerRef.current && smoothScroll(duration, this._outerRef.current, Math.abs(scrollX || 0), () => this.layoutDoc._scrollLeft = scrollX), delay); } }, { fireImmediately: true } ); + this._scrollTopReactionDisposer = reaction(() => this.layoutDoc._scrollTop, + scrollTop => { + const durationStr = StrCast(this.Document._viewTransition).match(/([0-9]*)ms/); + const duration = durationStr ? Number(durationStr[1]) : 1000; + if (scrollTop !== undefined && this._forceSmoothScrollUpdate) { + this._outerRef.current && smoothScroll(duration, this._outerRef.current, Math.abs(scrollTop || 0), () => this._forceSmoothScrollUpdate = true); + } else this._forceSmoothScrollUpdate = true; + }, + { fireImmediately: true } + ); }); + _forceSmoothScrollUpdate = true; updateScroll = (x: Opt<number>, y: Opt<number>) => { if (y !== undefined) { @@ -126,18 +142,28 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum } setPreviewCursor = (func?: (x: number, y: number, drag: boolean) => void) => this._setPreviewCursor = func; - iframedown = (e: PointerEvent) => { - this._setPreviewCursor?.(e.screenX, e.screenY, false); - } - iframeScrolled = (e: any) => { - if (e.target?.children) { - e.target.children[0].scrollLeft = 0; - const scrollTop = e.target.children[0].scrollTop; - const scrollLeft = e.target.children[0].scrollLeft; - this.layoutDoc._scrollTop = this._outerRef.current!.scrollTop = scrollTop; - this.layoutDoc._scrollLeft = this._outerRef.current!.scrollLeft = scrollLeft; + iframeWheel = (e: any) => { + if (this._forceSmoothScrollUpdate && e.target?.children) { + this._scrollTarget && setTimeout(action(() => { + this._scrollTarget.scrollLeft = 0; + const scrollTop = this._scrollTarget.scrollTop; + const scrollLeft = this._scrollTarget.scrollLeft; + this._outerRef.current!.scrollTop = scrollTop; + this._outerRef.current!.scrollLeft = scrollLeft; + if (this.layoutDoc._scrollTop !== scrollTop) { + this._forceSmoothScrollUpdate = false; + this.layoutDoc._scrollTop = scrollTop; + } + if (this.layoutDoc._scrollLeft !== scrollLeft) { + this._forceSmoothScrollUpdate = false; + this.layoutDoc._scrollLeft = scrollLeft; + } + })) } } + iframeScroll = (e: any) => { + this._scrollTarget = e.target.children[0]; + } async componentDidMount() { const urlField = Cast(this.dataDoc[this.props.fieldKey], WebField); runInAction(() => this._url = urlField?.url.toString() || ""); @@ -180,11 +206,12 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum componentWillUnmount() { this._moveReactionDisposer?.(); this._selectionReactionDisposer?.(); + this._scrollTopReactionDisposer?.(); this._scrollReactionDisposer?.(); document.removeEventListener("pointerup", this.onLongPressUp); document.removeEventListener("pointermove", this.onLongPressMove); - this._iframeRef.current?.contentDocument?.removeEventListener('pointerdown', this.iframedown); - this._iframeRef.current?.contentDocument?.removeEventListener('scroll', this.iframeScrolled); + this._iframeRef.current?.contentDocument?.removeEventListener('wheel', this.iframeWheel); + this._iframeRef.current?.contentDocument?.removeEventListener('scroll', this.iframeScroll); } onUrlDragover = (e: React.DragEvent) => { @@ -468,7 +495,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum } @computed get annotationLayer() { TraceMobx(); - return <div className="webBox-annotationLayer" style={{ height: Doc.NativeHeight(this.Document) }} ref={this._annotationLayer}> + return <div className="webBox-annotationLayer" style={{ height: Doc.NativeHeight(this.Document) || undefined }} ref={this._annotationLayer}> {this.nonDocAnnotations.sort((a, b) => NumCast(a.y) - NumCast(b.y)).map(anno => <Annotation {...this.props} showInfo={emptyFunction} focus={this.props.focus} dataDoc={this.dataDoc} fieldKey={this.props.fieldKey} anno={anno} key={`${anno[Id]}-annotation`} />) } @@ -542,10 +569,12 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum } else if (this._mainCont.current) { // set marquee x and y positions to the spatially transformed position + const nheight = Doc.NativeHeight(this.Document) || 1; + const nwidth = Doc.NativeWidth(this.Document) || 1; const boundingRect = this._mainCont.current.getBoundingClientRect(); - const boundingHeight = (Doc.NativeHeight(this.Document) || 1) / (Doc.NativeWidth(this.Document) || 1) * boundingRect.width; - this._startX = (e.clientX - boundingRect.left) / boundingRect.width * (Doc.NativeWidth(this.Document) || 1); - this._startY = (e.clientY - boundingRect.top) / boundingHeight * (Doc.NativeHeight(this.Document) || 1); + const boundingHeight = nheight / nwidth * boundingRect.width; + this._startX = (e.clientX - boundingRect.left) / boundingRect.width * nwidth; + this._startY = (e.clientY - boundingRect.top) / boundingHeight * nheight; this._marqueeHeight = this._marqueeWidth = 0; this._marqueeing = true; } @@ -619,23 +648,24 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum marqueeX = () => this._marqueeX; marqueeY = () => this._marqueeY; marqueeing = () => this._marqueeing; - visibleHeiht = () => { + visibleHeight = () => { if (this._mainCont.current) { const boundingRect = this._mainCont.current.getBoundingClientRect(); - const scalin = (Doc.NativeWidth(this.Document) || 0) / boundingRect.width; - return Math.min(boundingRect.height * scalin, this.props.PanelHeight() * scalin); + const scaling = (Doc.NativeWidth(this.Document) || 0) / boundingRect.width; + return Math.min(boundingRect.height * scaling, this.props.PanelHeight() * scaling); } return this.props.PanelHeight(); } scrollXf = () => this.props.ScreenToLocalTransform().translate(NumCast(this.layoutDoc._scrollLeft), NumCast(this.layoutDoc._scrollTop)); render() { + const scaling = Number.isFinite(this.props.ContentScaling()) ? this.props.ContentScaling() || 1 : 1; return (<div className="webBox" ref={this._mainCont} > <div className={`webBox-container`} style={{ position: undefined, - transform: `scale(${this.props.ContentScaling()})`, - width: Number.isFinite(this.props.ContentScaling()) ? `${100 / this.props.ContentScaling()}% ` : "100%", - height: Number.isFinite(this.props.ContentScaling()) ? `${100 / this.props.ContentScaling()}% ` : "100%", + transform: `scale(${scaling})`, + width: `${100 / scaling}% `, + height: `${100 / scaling}% `, pointerEvents: this.layoutDoc._isBackground ? "none" : undefined }} onContextMenu={this.specificContextMenu}> @@ -643,7 +673,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum {this.content} <div className={"webBox-outerContent"} ref={this._outerRef} style={{ - width: Number.isFinite(this.props.ContentScaling()) ? `${Math.max(100, 100 / this.props.ContentScaling())}% ` : "100%", + width: `${Math.max(100, 100 / scaling)}% `, pointerEvents: this.layoutDoc.isAnnotating && !this.layoutDoc._isBackground ? "all" : "none" }} onWheel={e => e.stopPropagation()} @@ -662,14 +692,14 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum //this._outerRef.current!.scrollTop !== this._scrollTop && (this._outerRef.current!.scrollTop = this._scrollTop) }}> <div className={"webBox-innerContent"} style={{ - height: NumCast(this.layoutDoc.scrollHeight), + height: NumCast(this.layoutDoc.scrollHeight, 50), pointerEvents: this.layoutDoc._isBackground ? "none" : undefined }}> <CollectionFreeFormView {...OmitKeys(this.props, ["NativeWidth", "NativeHeight"]).omit} PanelHeight={this.props.PanelHeight} PanelWidth={this.props.PanelWidth} annotationsKey={this.annotationKey} - VisibleHeight={this.visibleHeiht} + VisibleHeight={this.visibleHeight} focus={this.props.focus} setPreviewCursor={this.setPreviewCursor} isSelected={this.props.isSelected} diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.scss b/src/client/views/nodes/formattedText/FormattedTextBox.scss index 9307f1649..b75cc230f 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.scss +++ b/src/client/views/nodes/formattedText/FormattedTextBox.scss @@ -22,7 +22,7 @@ border-style: solid; overflow-y: auto; overflow-x: hidden; - color: initial; + color: inherit; display: flex; flex-direction: row; transition: opacity 1s; diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index d44f35a96..bc9e8e99d 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -11,7 +11,7 @@ import { EditorState, NodeSelection, Plugin, TextSelection, Transaction } from " import { ReplaceStep } from 'prosemirror-transform'; import { EditorView } from "prosemirror-view"; import { DateField } from '../../../../fields/DateField'; -import { DataSym, Doc, DocListCast, DocListCastAsync, Field, HeightSym, Opt, WidthSym, AclEdit, AclAdmin, UpdatingFromServer } from "../../../../fields/Doc"; +import { DataSym, Doc, DocListCast, DocListCastAsync, Field, HeightSym, Opt, WidthSym, AclEdit, AclAdmin, UpdatingFromServer, ForceServerWrite } from "../../../../fields/Doc"; import { documentSchema } from '../../../../fields/documentSchemas'; import applyDevTools = require("prosemirror-dev-tools"); import { removeMarkWithAttrs } from "./prosemirrorPatches"; @@ -805,9 +805,9 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp tr = tr.addMark(pos, pos + node.nodeSize, link); } }); - this.dataDoc[UpdatingFromServer] = true; // need to allow permissions for adding links to readonly/augment only documents + this.dataDoc[ForceServerWrite] = this.dataDoc[UpdatingFromServer] = true; // need to allow permissions for adding links to readonly/augment only documents this._editorView!.dispatch(tr.removeMark(sel.from, sel.to, splitter)); - this.dataDoc[UpdatingFromServer] = false; + this.dataDoc[UpdatingFromServer] = this.dataDoc[ForceServerWrite] = false; } } componentDidMount() { diff --git a/src/client/views/nodes/formattedText/RichTextMenu.tsx b/src/client/views/nodes/formattedText/RichTextMenu.tsx index 2700c508b..cf9b03308 100644 --- a/src/client/views/nodes/formattedText/RichTextMenu.tsx +++ b/src/client/views/nodes/formattedText/RichTextMenu.tsx @@ -31,6 +31,7 @@ const { toggleMark } = require("prosemirror-commands"); export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> { static Instance: RichTextMenu; public overMenu: boolean = false; // kind of hacky way to prevent selects not being selectable + private _linkToRef = React.createRef<HTMLInputElement>(); @observable public view?: EditorView; public editorProps: FieldViewProps & FormattedTextBoxProps | undefined; @@ -154,6 +155,9 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> { @action public updateMenu(view: EditorView | undefined, lastState: EditorState | undefined, props: any) { + if (this._linkToRef.current?.getBoundingClientRect().width) { + return; + } this.view = view; if (!view || !view.hasFocus()) { return; @@ -792,7 +796,7 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> { const self = this; function onLinkChange(e: React.ChangeEvent<HTMLInputElement>) { - self.TextView.endUndoTypingBatch(); + self.TextView?.endUndoTypingBatch(); UndoManager.RunInBatch(() => self.setCurrentLink(e.target.value), "link change"); } @@ -807,7 +811,7 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> { const dropdownContent = <div className="dropdown link-menu"> <p>Linked to:</p> - <input value={link} placeholder="Enter URL" onChange={onLinkChange} /> + <input value={link} ref={this._linkToRef} placeholder="Enter URL" onChange={onLinkChange} /> <button className="make-button" onPointerDown={e => this.makeLinkToURL(link, "add:right")}>Apply hyperlink</button> <div className="divider"></div> <button className="remove-button" onPointerDown={e => this.deleteLink()}>Remove link</button> |
