|
@@ -213,6 +213,7 @@ import {
|
|
tupleToCoors,
|
|
tupleToCoors,
|
|
viewportCoordsToSceneCoords,
|
|
viewportCoordsToSceneCoords,
|
|
withBatchedUpdates,
|
|
withBatchedUpdates,
|
|
|
|
+ wrapEvent,
|
|
withBatchedUpdatesThrottled,
|
|
withBatchedUpdatesThrottled,
|
|
} from "../utils";
|
|
} from "../utils";
|
|
import ContextMenu, { ContextMenuOption } from "./ContextMenu";
|
|
import ContextMenu, { ContextMenuOption } from "./ContextMenu";
|
|
@@ -526,6 +527,7 @@ class App extends React.Component<AppProps, AppState> {
|
|
element={selectedElement[0]}
|
|
element={selectedElement[0]}
|
|
appState={this.state}
|
|
appState={this.state}
|
|
setAppState={this.setAppState}
|
|
setAppState={this.setAppState}
|
|
|
|
+ onLinkOpen={this.props.onLinkOpen}
|
|
/>
|
|
/>
|
|
)}
|
|
)}
|
|
{this.state.showStats && (
|
|
{this.state.showStats && (
|
|
@@ -2384,8 +2386,9 @@ class App extends React.Component<AppProps, AppState> {
|
|
});
|
|
});
|
|
};
|
|
};
|
|
|
|
|
|
- private redirectToLink = () => {
|
|
|
|
|
|
+ private redirectToLink = (event: React.PointerEvent<HTMLCanvasElement>) => {
|
|
if (
|
|
if (
|
|
|
|
+ !this.hitLinkElement ||
|
|
this.lastPointerDown!.clientX !== this.lastPointerUp!.clientX ||
|
|
this.lastPointerDown!.clientX !== this.lastPointerUp!.clientX ||
|
|
this.lastPointerDown!.clientY !== this.lastPointerUp!.clientY
|
|
this.lastPointerDown!.clientY !== this.lastPointerUp!.clientY
|
|
) {
|
|
) {
|
|
@@ -2412,14 +2415,21 @@ class App extends React.Component<AppProps, AppState> {
|
|
this.isMobile,
|
|
this.isMobile,
|
|
);
|
|
);
|
|
if (lastPointerDownHittingLinkIcon && LastPointerUpHittingLinkIcon) {
|
|
if (lastPointerDownHittingLinkIcon && LastPointerUpHittingLinkIcon) {
|
|
- const url = this.hitLinkElement?.link;
|
|
|
|
|
|
+ const url = this.hitLinkElement.link;
|
|
if (url) {
|
|
if (url) {
|
|
- const target = isLocalLink(url) ? "_self" : "_blank";
|
|
|
|
- const newWindow = window.open(undefined, target);
|
|
|
|
- // https://mathiasbynens.github.io/rel-noopener/
|
|
|
|
- if (newWindow) {
|
|
|
|
- newWindow.opener = null;
|
|
|
|
- newWindow.location = normalizeLink(url);
|
|
|
|
|
|
+ let customEvent;
|
|
|
|
+ if (this.props.onLinkOpen) {
|
|
|
|
+ customEvent = wrapEvent(EVENT.EXCALIDRAW_LINK, event.nativeEvent);
|
|
|
|
+ this.props.onLinkOpen(this.hitLinkElement, customEvent);
|
|
|
|
+ }
|
|
|
|
+ if (!customEvent?.defaultPrevented) {
|
|
|
|
+ const target = isLocalLink(url) ? "_self" : "_blank";
|
|
|
|
+ const newWindow = window.open(undefined, target);
|
|
|
|
+ // https://mathiasbynens.github.io/rel-noopener/
|
|
|
|
+ if (newWindow) {
|
|
|
|
+ newWindow.opener = null;
|
|
|
|
+ newWindow.location = normalizeLink(url);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -2896,7 +2906,7 @@ class App extends React.Component<AppProps, AppState> {
|
|
this.hitLinkElement &&
|
|
this.hitLinkElement &&
|
|
!this.state.selectedElementIds[this.hitLinkElement.id]
|
|
!this.state.selectedElementIds[this.hitLinkElement.id]
|
|
) {
|
|
) {
|
|
- this.redirectToLink();
|
|
|
|
|
|
+ this.redirectToLink(event);
|
|
}
|
|
}
|
|
|
|
|
|
this.removePointer(event);
|
|
this.removePointer(event);
|