Skip to content

Commit

Permalink
Snapshot: Fix mispositioned popups when zoomed in client
Browse files Browse the repository at this point in the history
  • Loading branch information
AbeJellinek committed Jun 26, 2024
1 parent d90650c commit 2cf11de
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 6 deletions.
27 changes: 21 additions & 6 deletions src/dom/common/dom-view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ abstract class DOMView<State extends DOMViewState, Data> {

protected _handledPointerIDs = new Set<number>();

protected _iframeCoordScaleFactor = 1;

protected _previewAnnotation: NewAnnotation<WADMAnnotation> | null = null;

protected _touchAnnotationStartPosition: CaretPosition | null = null;
Expand Down Expand Up @@ -247,6 +249,15 @@ abstract class DOMView<State extends DOMViewState, Data> {
);
}

protected _scaleDOMRect(rect: DOMRect): DOMRect {
return new DOMRect(
rect.x * this._iframeCoordScaleFactor,
rect.y * this._iframeCoordScaleFactor,
rect.width * this._iframeCoordScaleFactor,
rect.height * this._iframeCoordScaleFactor
);
}

protected _getAnnotationFromTextSelection(type: AnnotationType, color?: string): NewAnnotation<WADMAnnotation> | null {
let selection = this._iframeDocument.getSelection();
if (!selection || selection.isCollapsed) {
Expand Down Expand Up @@ -395,7 +406,7 @@ abstract class DOMView<State extends DOMViewState, Data> {
return;
}
let range = moveRangeEndsIntoTextNodes(makeRangeSpanning(...getSelectionRanges(selection)));
let domRect = this._getViewportBoundingRect(range);
let domRect = this._scaleDOMRect(this._getViewportBoundingRect(range));
let rect: ArrayRect = [domRect.left, domRect.top, domRect.right, domRect.bottom];
let annotation = this._getAnnotationFromRange(range, 'highlight');
if (annotation) {
Expand All @@ -420,6 +431,7 @@ abstract class DOMView<State extends DOMViewState, Data> {
}
domRect = this._getViewportBoundingRect(range);
}
domRect = this._scaleDOMRect(domRect);
let rect: ArrayRect = [domRect.left, domRect.top, domRect.right, domRect.bottom];
this._options.onSetAnnotationPopup({ rect, annotation });
}
Expand Down Expand Up @@ -714,7 +726,10 @@ abstract class DOMView<State extends DOMViewState, Data> {
// Prevent native context menu
event.preventDefault();
let br = this._iframe.getBoundingClientRect();
this._options.onOpenViewContextMenu({ x: br.x + event.clientX, y: br.y + event.clientY });
this._options.onOpenViewContextMenu({
x: br.x + event.clientX * this._iframeCoordScaleFactor,
y: br.y + event.clientY * this._iframeCoordScaleFactor,
});
}

private _handleAnnotationContextMenu = (id: string, event: React.MouseEvent) => {
Expand All @@ -729,17 +744,17 @@ abstract class DOMView<State extends DOMViewState, Data> {
if (this._selectedAnnotationIDs.includes(id)) {
this._options.onOpenAnnotationContextMenu({
ids: this._selectedAnnotationIDs,
x: br.x + event.clientX,
y: br.y + event.clientY,
x: br.x + event.clientX * this._iframeCoordScaleFactor,
y: br.y + event.clientY * this._iframeCoordScaleFactor,
view: true,
});
}
else {
this._options.onSelectAnnotations([id], event.nativeEvent);
this._options.onOpenAnnotationContextMenu({
ids: [id],
x: br.x + event.clientX,
y: br.y + event.clientY,
x: br.x + event.clientX * this._iframeCoordScaleFactor,
y: br.y + event.clientY * this._iframeCoordScaleFactor,
view: true,
});
}
Expand Down
3 changes: 3 additions & 0 deletions src/dom/snapshot/snapshot-view.ts
Original file line number Diff line number Diff line change
Expand Up @@ -481,6 +481,9 @@ class SnapshotView extends DOMView<SnapshotViewState, SnapshotViewData> {

if (this._options.onSetZoom) {
this._options.onSetZoom(this._iframe, scale);
// Store the scale factor so we can adjust clientX/clientY coordinates when opening popups
// TODO: Use CSS zoom instead of onSetZoom() when Zotero is on fx>=126
this._iframeCoordScaleFactor = scale;
}
else {
if (scale == 1) {
Expand Down

0 comments on commit 2cf11de

Please sign in to comment.