mirror of
https://github.com/rstudio/shiny.git
synced 2026-04-29 03:00:45 -04:00
Plot outputs incorrectly sized inside scaled outputs (#4139)
* Fix #4135: Plot outputs incorrectly sized inside scaled outputs 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) * Squelch TS error * `yarn build` (GitHub Actions) * Add TODO Co-authored-by: Garrick Aden-Buie <garrick@adenbuie.com> * Rebuild JS --------- Co-authored-by: jcheng5 <jcheng5@users.noreply.github.com> Co-authored-by: Garrick Aden-Buie <garrick@adenbuie.com>
This commit is contained in:
@@ -6873,6 +6873,14 @@
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
function getBoundingClientSizeBeforeZoom(el) {
|
||||||
|
var rect = el.getBoundingClientRect();
|
||||||
|
var zoom = el.currentCSSZoom || 1;
|
||||||
|
return {
|
||||||
|
width: rect.width / zoom,
|
||||||
|
height: rect.height / zoom
|
||||||
|
};
|
||||||
|
}
|
||||||
function scopeExprToFunc(expr) {
|
function scopeExprToFunc(expr) {
|
||||||
var exprEscaped = expr.replace(/[\\"']/g, "\\$&").replace(/\u0000/g, "\\0").replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/[\b]/g, "\\b");
|
var exprEscaped = expr.replace(/[\\"']/g, "\\$&").replace(/\u0000/g, "\\0").replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/[\b]/g, "\\b");
|
||||||
var func;
|
var func;
|
||||||
@@ -25282,7 +25290,7 @@
|
|||||||
};
|
};
|
||||||
doSendImageSize = function _doSendImageSize() {
|
doSendImageSize = function _doSendImageSize() {
|
||||||
(0, import_jquery39.default)(".shiny-image-output, .shiny-plot-output, .shiny-report-size").each(function() {
|
(0, import_jquery39.default)(".shiny-image-output, .shiny-plot-output, .shiny-report-size").each(function() {
|
||||||
var id = getIdFromEl(this), rect = this.getBoundingClientRect();
|
var id = getIdFromEl(this), rect = getBoundingClientSizeBeforeZoom(this);
|
||||||
if (rect.width !== 0 || rect.height !== 0) {
|
if (rect.width !== 0 || rect.height !== 0) {
|
||||||
inputs.setInput(".clientdata_output_" + id + "_width", rect.width);
|
inputs.setInput(".clientdata_output_" + id + "_width", rect.width);
|
||||||
inputs.setInput(".clientdata_output_" + id + "_height", rect.height);
|
inputs.setInput(".clientdata_output_" + id + "_height", rect.height);
|
||||||
@@ -25464,7 +25472,7 @@
|
|||||||
};
|
};
|
||||||
initialValues = (0, _context3.t0)(_context3.t1, _context3.t2);
|
initialValues = (0, _context3.t0)(_context3.t1, _context3.t2);
|
||||||
(0, import_jquery39.default)(".shiny-image-output, .shiny-plot-output, .shiny-report-size").each(function() {
|
(0, import_jquery39.default)(".shiny-image-output, .shiny-plot-output, .shiny-report-size").each(function() {
|
||||||
var id = getIdFromEl(this), rect = this.getBoundingClientRect();
|
var id = getIdFromEl(this), rect = getBoundingClientSizeBeforeZoom(this);
|
||||||
if (rect.width !== 0 || rect.height !== 0) {
|
if (rect.width !== 0 || rect.height !== 0) {
|
||||||
initialValues[".clientdata_output_" + id + "_width"] = rect.width;
|
initialValues[".clientdata_output_" + id + "_width"] = rect.width;
|
||||||
initialValues[".clientdata_output_" + id + "_height"] = rect.height;
|
initialValues[".clientdata_output_" + id + "_height"] = rect.height;
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
2
inst/www/shared/shiny.min.js
vendored
2
inst/www/shared/shiny.min.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -21,6 +21,7 @@ import { debounce, Debouncer } from "../time";
|
|||||||
import {
|
import {
|
||||||
$escape,
|
$escape,
|
||||||
compareVersion,
|
compareVersion,
|
||||||
|
getBoundingClientSizeBeforeZoom,
|
||||||
getComputedLinkColor,
|
getComputedLinkColor,
|
||||||
getStyle,
|
getStyle,
|
||||||
hasDefinedProperty,
|
hasDefinedProperty,
|
||||||
@@ -289,7 +290,7 @@ class ShinyClass {
|
|||||||
$(".shiny-image-output, .shiny-plot-output, .shiny-report-size").each(
|
$(".shiny-image-output, .shiny-plot-output, .shiny-report-size").each(
|
||||||
function () {
|
function () {
|
||||||
const id = getIdFromEl(this),
|
const id = getIdFromEl(this),
|
||||||
rect = this.getBoundingClientRect();
|
rect = getBoundingClientSizeBeforeZoom(this);
|
||||||
|
|
||||||
if (rect.width !== 0 || rect.height !== 0) {
|
if (rect.width !== 0 || rect.height !== 0) {
|
||||||
initialValues[".clientdata_output_" + id + "_width"] = rect.width;
|
initialValues[".clientdata_output_" + id + "_width"] = rect.width;
|
||||||
@@ -425,7 +426,7 @@ class ShinyClass {
|
|||||||
$(".shiny-image-output, .shiny-plot-output, .shiny-report-size").each(
|
$(".shiny-image-output, .shiny-plot-output, .shiny-report-size").each(
|
||||||
function () {
|
function () {
|
||||||
const id = getIdFromEl(this),
|
const id = getIdFromEl(this),
|
||||||
rect = this.getBoundingClientRect();
|
rect = getBoundingClientSizeBeforeZoom(this);
|
||||||
|
|
||||||
if (rect.width !== 0 || rect.height !== 0) {
|
if (rect.width !== 0 || rect.height !== 0) {
|
||||||
inputs.setInput(".clientdata_output_" + id + "_width", rect.width);
|
inputs.setInput(".clientdata_output_" + id + "_width", rect.width);
|
||||||
|
|||||||
@@ -144,6 +144,20 @@ function pixelRatio(): number {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getBoundingClientSizeBeforeZoom(el: HTMLElement): {
|
||||||
|
width: number;
|
||||||
|
height: number;
|
||||||
|
} {
|
||||||
|
const rect = el.getBoundingClientRect();
|
||||||
|
// Cast to any because currentCSSZoom isn't in the type def of HTMLElement
|
||||||
|
// TODO: typescript >= 5.5.2 added this property to the type definition
|
||||||
|
const zoom = (el as any).currentCSSZoom || 1;
|
||||||
|
return {
|
||||||
|
width: rect.width / zoom,
|
||||||
|
height: rect.height / zoom,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// Takes a string expression and returns a function that takes an argument.
|
// Takes a string expression and returns a function that takes an argument.
|
||||||
//
|
//
|
||||||
// When the function is executed, it will evaluate that expression using
|
// When the function is executed, it will evaluate that expression using
|
||||||
@@ -398,6 +412,7 @@ export {
|
|||||||
formatDateUTC,
|
formatDateUTC,
|
||||||
makeResizeFilter,
|
makeResizeFilter,
|
||||||
pixelRatio,
|
pixelRatio,
|
||||||
|
getBoundingClientSizeBeforeZoom,
|
||||||
scopeExprToFunc,
|
scopeExprToFunc,
|
||||||
asArray,
|
asArray,
|
||||||
mergeSort,
|
mergeSort,
|
||||||
|
|||||||
6
srcts/types/src/utils/index.d.ts
vendored
6
srcts/types/src/utils/index.d.ts
vendored
@@ -10,6 +10,10 @@ declare function parseDate(dateString: string): Date;
|
|||||||
declare function formatDateUTC(x: Date): string;
|
declare function formatDateUTC(x: Date): string;
|
||||||
declare function makeResizeFilter(el: HTMLElement, func: (width: HTMLElement["offsetWidth"], height: HTMLElement["offsetHeight"]) => void): () => void;
|
declare function makeResizeFilter(el: HTMLElement, func: (width: HTMLElement["offsetWidth"], height: HTMLElement["offsetHeight"]) => void): () => void;
|
||||||
declare function pixelRatio(): number;
|
declare function pixelRatio(): number;
|
||||||
|
declare function getBoundingClientSizeBeforeZoom(el: HTMLElement): {
|
||||||
|
width: number;
|
||||||
|
height: number;
|
||||||
|
};
|
||||||
declare function scopeExprToFunc(expr: string): (scope: unknown) => unknown;
|
declare function scopeExprToFunc(expr: string): (scope: unknown) => unknown;
|
||||||
declare function asArray<T>(value: T | T[] | null | undefined): T[];
|
declare function asArray<T>(value: T | T[] | null | undefined): T[];
|
||||||
declare function mergeSort<Item>(list: Item[], sortfunc: (a: Item, b: Item) => boolean | number): Item[];
|
declare function mergeSort<Item>(list: Item[], sortfunc: (a: Item, b: Item) => boolean | number): Item[];
|
||||||
@@ -26,4 +30,4 @@ declare function updateLabel(labelTxt: string | undefined, labelNode: JQuery<HTM
|
|||||||
declare function getComputedLinkColor(el: HTMLElement): string;
|
declare function getComputedLinkColor(el: HTMLElement): string;
|
||||||
declare function isBS3(): boolean;
|
declare function isBS3(): boolean;
|
||||||
declare function toLowerCase<T extends string>(str: T): Lowercase<T>;
|
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, };
|
||||||
|
|||||||
Reference in New Issue
Block a user