From 133bcddeda1c5bc43782eef8a3e2ba143a7dbd39 Mon Sep 17 00:00:00 2001 From: Richard Knoll Date: Tue, 22 Oct 2024 11:12:29 -0700 Subject: [PATCH 1/4] add check visibility polyfill --- pxtblocks/loader.ts | 3 +++ pxtblocks/polyfills.ts | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 pxtblocks/polyfills.ts diff --git a/pxtblocks/loader.ts b/pxtblocks/loader.ts index 7104f37deb7..495abc70d1b 100644 --- a/pxtblocks/loader.ts +++ b/pxtblocks/loader.ts @@ -24,6 +24,7 @@ import { initContextMenu } from "./contextMenu"; import { renderCodeCard } from "./codecardRenderer"; import { FieldDropdown } from "./fields/field_dropdown"; import { setDraggableShadowBlocks, setDuplicateOnDragStrategy } from "./plugins/duplicateOnDrag"; +import { applyPolyfills } from "./polyfills"; interface BlockDefinition { @@ -587,6 +588,8 @@ function init(blockInfo: pxtc.BlocksInfo) { if (blocklyInitialized) return; blocklyInitialized = true; + applyPolyfills(); + initFieldEditors(); initContextMenu(); initOnStart(); diff --git a/pxtblocks/polyfills.ts b/pxtblocks/polyfills.ts new file mode 100644 index 00000000000..36a8353d286 --- /dev/null +++ b/pxtblocks/polyfills.ts @@ -0,0 +1,33 @@ +export function applyPolyfills() { + if (!Element.prototype.checkVisibility) { + Element.prototype.checkVisibility = function checkVisibility(this: Element): boolean { + const computedStyle = getComputedStyle(this); + + // technically, this should also check for contentVisibility === "auto" and then + // traverse the ancestors of this node to see if any have contentVisibility set + // to "hidden", but Blockly doesn't use content-visibility AFAIK + if ( + computedStyle.opacity === "0" || + computedStyle.visibility === "hidden" || + computedStyle.display === "none" || + computedStyle.contentVisibility === "hidden" + ) { + return false; + } + + try { + const rec = this.getBoundingClientRect(); + if (rec.width === 0 || rec.height === 0) { + return false; + } + } + catch { + // some versions of firefox throw if an element is not in the DOM + // and getBoundingClientRect is called + return false; + } + + return true; + } + } +} \ No newline at end of file From 3df1407a05459ec8e628e9d11ff6c5d3c33b78f6 Mon Sep 17 00:00:00 2001 From: Richard Knoll Date: Tue, 22 Oct 2024 18:18:52 +0000 Subject: [PATCH 2/4] fix type errors for new element APIs --- pxtblocks/polyfills.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pxtblocks/polyfills.ts b/pxtblocks/polyfills.ts index 36a8353d286..cfe519b20e6 100644 --- a/pxtblocks/polyfills.ts +++ b/pxtblocks/polyfills.ts @@ -1,6 +1,6 @@ export function applyPolyfills() { - if (!Element.prototype.checkVisibility) { - Element.prototype.checkVisibility = function checkVisibility(this: Element): boolean { + if (!(Element.prototype as any).checkVisibility) { + (Element.prototype as any).checkVisibility = function checkVisibility(this: Element): boolean { const computedStyle = getComputedStyle(this); // technically, this should also check for contentVisibility === "auto" and then @@ -10,7 +10,7 @@ export function applyPolyfills() { computedStyle.opacity === "0" || computedStyle.visibility === "hidden" || computedStyle.display === "none" || - computedStyle.contentVisibility === "hidden" + (computedStyle as any).contentVisibility === "hidden" ) { return false; } From dabdc532c0a3642828db95d082663c0462248c87 Mon Sep 17 00:00:00 2001 From: Richard Knoll Date: Tue, 22 Oct 2024 18:31:16 +0000 Subject: [PATCH 3/4] add options --- pxtblocks/polyfills.ts | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/pxtblocks/polyfills.ts b/pxtblocks/polyfills.ts index cfe519b20e6..1855fb9f391 100644 --- a/pxtblocks/polyfills.ts +++ b/pxtblocks/polyfills.ts @@ -1,16 +1,43 @@ +// all options default to true +interface CheckVisibilityOptions { + contentVisibilityAuto?: boolean; + opacityProperty?: boolean; + visibilityProperty?: boolean; + checkOpacity?: boolean; + checkVisibilityCSS?: boolean; +} + export function applyPolyfills() { if (!(Element.prototype as any).checkVisibility) { - (Element.prototype as any).checkVisibility = function checkVisibility(this: Element): boolean { + (Element.prototype as any).checkVisibility = function checkVisibility(this: Element, options: CheckVisibilityOptions = {}): boolean { + let checkOpacity = true; + + if (options.opacityProperty != undefined || options.checkOpacity != undefined) { + checkOpacity = !!(options.opacityProperty || options.checkOpacity); + } + + let checkVisibility = true; + + if (options.visibilityProperty != undefined || options.checkVisibilityCSS != undefined) { + checkVisibility = !!(options.visibilityProperty || options.checkVisibilityCSS); + } + + let checkContentVisibility = true; + + if (options.contentVisibilityAuto != undefined) { + checkContentVisibility = !!options.contentVisibilityAuto; + } + const computedStyle = getComputedStyle(this); // technically, this should also check for contentVisibility === "auto" and then // traverse the ancestors of this node to see if any have contentVisibility set // to "hidden", but Blockly doesn't use content-visibility AFAIK if ( - computedStyle.opacity === "0" || - computedStyle.visibility === "hidden" || computedStyle.display === "none" || - (computedStyle as any).contentVisibility === "hidden" + (checkOpacity && computedStyle.opacity === "0") || + (checkVisibility && computedStyle.visibility === "hidden") || + (checkContentVisibility && (computedStyle as any).contentVisibility === "hidden") ) { return false; } From d3347476be0871632583a24fd421f36328b307bb Mon Sep 17 00:00:00 2001 From: Richard Knoll Date: Tue, 22 Oct 2024 18:35:38 +0000 Subject: [PATCH 4/4] lint --- pxtblocks/polyfills.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pxtblocks/polyfills.ts b/pxtblocks/polyfills.ts index 1855fb9f391..dfdbd92928d 100644 --- a/pxtblocks/polyfills.ts +++ b/pxtblocks/polyfills.ts @@ -27,7 +27,7 @@ export function applyPolyfills() { if (options.contentVisibilityAuto != undefined) { checkContentVisibility = !!options.contentVisibilityAuto; } - + const computedStyle = getComputedStyle(this); // technically, this should also check for contentVisibility === "auto" and then