diff options
-rw-r--r-- | src/Utils.ts | 10 | ||||
-rw-r--r-- | src/client/views/ContextMenu.tsx | 15 | ||||
-rw-r--r-- | src/client/views/nodes/DocumentView.tsx | 15 | ||||
-rw-r--r-- | src/client/views/nodes/ImageBox.tsx | 2 | ||||
-rw-r--r-- | src/client/views/nodes/PDFBox.tsx | 5 |
5 files changed, 28 insertions, 19 deletions
diff --git a/src/Utils.ts b/src/Utils.ts index 3fffadb6d..ddc16dceb 100644 --- a/src/Utils.ts +++ b/src/Utils.ts @@ -82,15 +82,7 @@ export namespace Utils { } export function CopyText(text: string) { - const textArea = document.createElement("textarea"); - textArea.value = text; - document.body.appendChild(textArea); - textArea.focus(); - textArea.select(); - - try { document.execCommand('copy'); } catch (err) { } - - document.body.removeChild(textArea); + navigator.clipboard.writeText(text); } export function decimalToHexString(number: number) { diff --git a/src/client/views/ContextMenu.tsx b/src/client/views/ContextMenu.tsx index c4fabbf99..78564a11b 100644 --- a/src/client/views/ContextMenu.tsx +++ b/src/client/views/ContextMenu.tsx @@ -47,11 +47,17 @@ export class ContextMenu extends React.Component { this._mouseDown = false; const curX = e.clientX; const curY = e.clientY; - if (this._mouseX !== curX || this._mouseY !== curY) { + if (Math.abs(this._mouseX - curX) > 1 || Math.abs(this._mouseY - curY) > 1) { this._shouldDisplay = false; } - this._shouldDisplay && (this._display = true); + if (this._shouldDisplay) { + if (this._onDisplay) { + this._onDisplay(); + } else { + this._display = true; + } + } } componentWillUnmount() { document.removeEventListener("pointerdown", this.onPointerDown); @@ -138,9 +144,9 @@ export class ContextMenu extends React.Component { return y; } - + _onDisplay?: () => void = undefined; @action - displayMenu = (x: number, y: number, initSearch = "", showSearch = false) => { + displayMenu = (x: number, y: number, initSearch = "", showSearch = false, onDisplay?: () => void) => { //maxX and maxY will change if the UI/font size changes, but will work for any amount //of items added to the menu @@ -149,6 +155,7 @@ export class ContextMenu extends React.Component { this._pageY = y; this._searchString = initSearch; this._shouldDisplay = true; + this._onDisplay = onDisplay; } @action diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 1fcbffadd..193befa5d 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -13,7 +13,7 @@ import { BoolCast, Cast, NumCast, ScriptCast, StrCast } from "../../../fields/Ty import { AudioField } from "../../../fields/URLField"; import { GetEffectiveAcl, SharingPermissions, TraceMobx } from '../../../fields/util'; import { MobileInterface } from '../../../mobile/MobileInterface'; -import { emptyFunction, hasDescendantTarget, OmitKeys, returnTrue, returnVal, Utils, lightOrDark } from "../../../Utils"; +import { emptyFunction, hasDescendantTarget, OmitKeys, returnTrue, returnVal, Utils, lightOrDark, simulateMouseClick } from "../../../Utils"; import { GooglePhotos } from '../../apis/google_docs/GooglePhotosClientUtils'; import { Docs, DocUtils } from "../../documents/Documents"; import { DocumentType } from '../../documents/DocumentTypes'; @@ -671,6 +671,18 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps const cm = ContextMenu.Instance; if (!cm || (e as any)?.nativeEvent?.SchemaHandled) return; + if (e?.buttons === 2) { + const onDisplay = () => setTimeout(() => { + DocumentViewInternal.SelectAfterContextMenu && !this.props.isSelected(true) && SelectionManager.SelectView(this.props.DocumentView(), false); // on a mac, the context menu is triggered on mouse down, but a YouTube video becaomes interactive when selected which means that the context menu won't show up. by delaying the selection until hopefully after the pointer up, the context menu will appear. + setTimeout(() => { + const ele = document.elementFromPoint(e.clientX, e.clientY); + simulateMouseClick(ele, e.clientX, e.clientY, e.screenX, e.screenY); + }); + }); + cm.displayMenu((e?.pageX || pageX || 0) - 15, (e?.pageY || pageY || 0) - 15, undefined, undefined, onDisplay); + return; + } + const customScripts = Cast(this.props.Document.contextMenuScripts, listSpec(ScriptField), []); StrListCast(this.Document.contextMenuLabels).forEach((label, i) => cm.addItem({ description: label, event: () => customScripts[i]?.script.run({ documentView: this, this: this.layoutDoc, scriptContext: this.props.scriptContext, self: this.rootDoc }), icon: "sticky-note" })); @@ -777,7 +789,6 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps if (!this.topMost) e?.stopPropagation(); // DocumentViews should stop propagation of this event cm.displayMenu((e?.pageX || pageX || 0) - 15, (e?.pageY || pageY || 0) - 15); - DocumentViewInternal.SelectAfterContextMenu && !this.props.isSelected(true) && setTimeout(() => SelectionManager.SelectView(this.props.DocumentView(), false), 300); // on a mac, the context menu is triggered on mouse down, but a YouTube video becaomes interactive when selected which means that the context menu won't show up. by delaying the selection until hopefully after the pointer up, the context menu will appear. } rootSelected = (outsideReaction?: boolean) => this.props.isSelected(outsideReaction) || (this.props.Document.rootDocument && this.props.rootSelected?.(outsideReaction)) || false; diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index 38deb4a73..b41bfd3ea 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -144,9 +144,9 @@ export class ImageBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp const funcs: ContextMenuProps[] = []; funcs.push({ description: "Rotate Clockwise 90", event: this.rotate, icon: "expand-arrows-alt" }); funcs.push({ description: `Show ${this.layoutDoc._showFullRes ? "Dynamic Res" : "Full Res"}`, event: this.resolution, icon: "expand-arrows-alt" }); + funcs.push({ description: "Copy path", event: () => Utils.CopyText(this.choosePath(field.url)), icon: "expand-arrows-alt" }); if (!Doc.UserDoc().noviceMode) { funcs.push({ description: "Export to Google Photos", event: () => GooglePhotos.Transactions.UploadImages([this.props.Document]), icon: "caret-square-right" }); - funcs.push({ description: "Copy path", event: () => Utils.CopyText(field.url.href), icon: "expand-arrows-alt" }); const existingAnalyze = ContextMenu.Instance?.findByDescription("Analyzers..."); const modes: ContextMenuProps[] = existingAnalyze && "subitems" in existingAnalyze ? existingAnalyze.subitems : []; diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx index 88fb2ed13..ce851b830 100644 --- a/src/client/views/nodes/PDFBox.tsx +++ b/src/client/views/nodes/PDFBox.tsx @@ -226,9 +226,8 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps specificContextMenu = (e: React.MouseEvent): void => { const funcs: ContextMenuProps[] = []; - funcs.push({ description: "Copy path", event: () => this.pdfUrl && Utils.CopyText(this.pdfUrl.url.pathname), icon: "expand-arrows-alt" }); - funcs.push({ description: "Toggle Fit Width " + (this.Document._fitWidth ? "Off" : "On"), event: () => this.Document._fitWidth = !this.Document._fitWidth, icon: "expand-arrows-alt" }); - funcs.push({ description: "Toggle Sidebar ", event: () => this.toggleSidebar(), icon: "expand-arrows-alt" }); + funcs.push({ description: "Copy path", event: () => this.pdfUrl && Utils.CopyText(Utils.prepend("") + this.pdfUrl.url.pathname), icon: "expand-arrows-alt" }); + //funcs.push({ description: "Toggle Sidebar ", event: () => this.toggleSidebar(), icon: "expand-arrows-alt" }); ContextMenu.Instance.addItem({ description: "Options...", subitems: funcs, icon: "asterisk" }); } |