Skip to content

Commit

Permalink
Fix #4135: Plot outputs incorrectly sized inside scaled outputs
Browse files Browse the repository at this point in the history
CSS zoom property affects el.getBoundingClientRect() but not
el.offsetWidth/Height. When reporting sizes of outputs from
client to server, we need to back out the CSS zoom because
those sizes are used as CSS width/height, which will be
affected by zoom.

(Note that something similar happens with CSS transforms but
we don't have a good way to deal with them)
  • Loading branch information
jcheng5 committed Oct 1, 2024
1 parent 2e2114f commit 83e6c2f
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 3 deletions.
5 changes: 3 additions & 2 deletions srcts/src/shiny/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { debounce, Debouncer } from "../time";
import {
$escape,
compareVersion,
getBoundingClientSizeBeforeZoom,
getComputedLinkColor,
getStyle,
hasDefinedProperty,
Expand Down Expand Up @@ -289,7 +290,7 @@ class ShinyClass {
$(".shiny-image-output, .shiny-plot-output, .shiny-report-size").each(
function () {
const id = getIdFromEl(this),
rect = this.getBoundingClientRect();
rect = getBoundingClientSizeBeforeZoom(this);

if (rect.width !== 0 || rect.height !== 0) {
initialValues[".clientdata_output_" + id + "_width"] = rect.width;
Expand Down Expand Up @@ -425,7 +426,7 @@ class ShinyClass {
$(".shiny-image-output, .shiny-plot-output, .shiny-report-size").each(
function () {
const id = getIdFromEl(this),
rect = this.getBoundingClientRect();
rect = getBoundingClientSizeBeforeZoom(this);

if (rect.width !== 0 || rect.height !== 0) {
inputs.setInput(".clientdata_output_" + id + "_width", rect.width);
Expand Down
13 changes: 13 additions & 0 deletions srcts/src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,18 @@ function pixelRatio(): number {
}
}

function getBoundingClientSizeBeforeZoom(el: HTMLElement): {
width: number;
height: number;
} {
const rect = el.getBoundingClientRect();
const zoom = el.currentCSSZoom || 1;

Check failure on line 152 in srcts/src/utils/index.ts

View workflow job for this annotation

GitHub Actions / routine / routine

Property 'currentCSSZoom' does not exist on type 'HTMLElement'.
return {
width: rect.width / zoom,
height: rect.height / zoom,
};
}

// Takes a string expression and returns a function that takes an argument.
//
// When the function is executed, it will evaluate that expression using
Expand Down Expand Up @@ -398,6 +410,7 @@ export {
formatDateUTC,
makeResizeFilter,
pixelRatio,
getBoundingClientSizeBeforeZoom,
scopeExprToFunc,
asArray,
mergeSort,
Expand Down
6 changes: 5 additions & 1 deletion srcts/types/src/utils/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ declare function parseDate(dateString: string): Date;
declare function formatDateUTC(x: Date): string;
declare function makeResizeFilter(el: HTMLElement, func: (width: HTMLElement["offsetWidth"], height: HTMLElement["offsetHeight"]) => void): () => void;
declare function pixelRatio(): number;
declare function getBoundingClientSizeBeforeZoom(el: HTMLElement): {
width: number;
height: number;
};
declare function scopeExprToFunc(expr: string): (scope: unknown) => unknown;
declare function asArray<T>(value: T | T[] | null | undefined): T[];
declare function mergeSort<Item>(list: Item[], sortfunc: (a: Item, b: Item) => boolean | number): Item[];
Expand All @@ -26,4 +30,4 @@ declare function updateLabel(labelTxt: string | undefined, labelNode: JQuery<HTM
declare function getComputedLinkColor(el: HTMLElement): string;
declare function isBS3(): boolean;
declare function toLowerCase<T extends string>(str: T): Lowercase<T>;
export { escapeHTML, randomId, strToBool, getStyle, padZeros, roundSignif, parseDate, formatDateUTC, makeResizeFilter, pixelRatio, scopeExprToFunc, asArray, mergeSort, $escape, mapValues, isnan, _equal, equal, compareVersion, updateLabel, getComputedLinkColor, hasOwnProperty, hasDefinedProperty, isBS3, toLowerCase, };
export { escapeHTML, randomId, strToBool, getStyle, padZeros, roundSignif, parseDate, formatDateUTC, makeResizeFilter, pixelRatio, getBoundingClientSizeBeforeZoom, scopeExprToFunc, asArray, mergeSort, $escape, mapValues, isnan, _equal, equal, compareVersion, updateLabel, getComputedLinkColor, hasOwnProperty, hasDefinedProperty, isBS3, toLowerCase, };

0 comments on commit 83e6c2f

Please sign in to comment.