From 26ae02b2ebf41d6ab1b2534feb52b03a43668c87 Mon Sep 17 00:00:00 2001 From: Steve Repsher Date: Tue, 7 May 2024 19:49:49 +0000 Subject: [PATCH] Inject ResizeObserver polyfill where needed --- .../babel-plugins/custom-polyfill-plugin.js | 21 ++++++++++++++++++- build-scripts/bundle.cjs | 16 ++++++++------ src/components/map/ha-map.ts | 2 -- .../media-player/ha-media-player-browse.ts | 2 -- .../lovelace/cards/hui-calendar-card.ts | 2 -- .../lovelace/cards/hui-media-control-card.ts | 2 -- .../cards/hui-weather-forecast-card.ts | 2 -- .../components/hui-energy-period-selector.ts | 2 -- .../hui-input-number-entity-row.ts | 2 -- .../hui-media-player-entity-row.ts | 2 -- .../entity-rows/hui-number-entity-row.ts | 2 -- src/resources/compatibility.ts | 4 ---- src/resources/polyfills/resize-observer.ts | 9 ++++++++ src/resources/resize-observer.polyfill.ts | 12 ----------- src/resources/virtualizer.ts | 3 --- src/state-summary/state-card-input_number.ts | 2 -- src/state-summary/state-card-number.ts | 2 -- 17 files changed, 39 insertions(+), 48 deletions(-) create mode 100644 src/resources/polyfills/resize-observer.ts delete mode 100644 src/resources/resize-observer.polyfill.ts diff --git a/build-scripts/babel-plugins/custom-polyfill-plugin.js b/build-scripts/babel-plugins/custom-polyfill-plugin.js index ce53fa522bb7..d2a02bf8c60a 100644 --- a/build-scripts/babel-plugins/custom-polyfill-plugin.js +++ b/build-scripts/babel-plugins/custom-polyfill-plugin.js @@ -1,4 +1,8 @@ import defineProvider from "@babel/helper-define-polyfill-provider"; +import { join } from "node:path"; +import paths from "../paths.cjs"; + +const POLYFILL_DIR = join(paths.polymer_dir, "src/resources/polyfills"); // List of polyfill keys with supported browser targets for the functionality const PolyfillSupport = { @@ -36,14 +40,29 @@ const PolyfillSupport = { safari: 10.0, samsung: 5.0, }, + "resize-observer": { + android: 64, + chrome: 64, + edge: 79, + firefox: 69, + ios: 13.4, + opera: 51, + opera_mobile: 47, + safari: 13.1, + samsung: 9.0, + }, }; // Map of global variables and/or instance and static properties to the // corresponding polyfill key and actual module to import const polyfillMap = { global: { - Proxy: { key: "proxy", module: "proxy-polyfill" }, fetch: { key: "fetch", module: "unfetch/polyfill" }, + Proxy: { key: "proxy", module: "proxy-polyfill" }, + ResizeObserver: { + key: "resize-observer", + module: join(POLYFILL_DIR, "resize-observer.ts"), + }, }, instance: { attachInternals: { diff --git a/build-scripts/bundle.cjs b/build-scripts/bundle.cjs index ce07a61281ea..cc2d671e5e36 100644 --- a/build-scripts/bundle.cjs +++ b/build-scripts/bundle.cjs @@ -147,7 +147,7 @@ module.exports.babelOptions = ({ latestBuild, isProdBuild, isTestBuild }) => ({ overrides: [ { // Add plugin to inject various polyfills, excluding the polyfills - // themselves to prevent self- injection. + // themselves to prevent self-injection. plugins: [ [ path.join(BABEL_PLUGINS, "custom-polyfill-plugin.js"), @@ -155,11 +155,15 @@ module.exports.babelOptions = ({ latestBuild, isProdBuild, isTestBuild }) => ({ ], ], exclude: [ - "@webcomponents/scoped-custom-element-registry", - "element-internals-polyfill", - "proxy-polyfill", - "unfetch", - ].map((p) => new RegExp(`/node_modules/${p}/`)), + path.join(paths.polymer_dir, "src/resources/polyfills"), + ...[ + "@lit-labs/virtualizer/polyfills", + "@webcomponents/scoped-custom-element-registry", + "element-internals-polyfill", + "proxy-polyfill", + "unfetch", + ].map((p) => new RegExp(`/node_modules/${p}/`)), + ], }, { // Use unambiguous for dependencies so that require() is correctly injected into CommonJS files diff --git a/src/components/map/ha-map.ts b/src/components/map/ha-map.ts index 629770864d54..d9592abfd4de 100644 --- a/src/components/map/ha-map.ts +++ b/src/components/map/ha-map.ts @@ -22,7 +22,6 @@ import { } from "../../common/dom/setup-leaflet-map"; import { computeStateDomain } from "../../common/entity/compute_state_domain"; import { computeStateName } from "../../common/entity/compute_state_name"; -import { loadPolyfillIfNeeded } from "../../resources/resize-observer.polyfill"; import { HomeAssistant, ThemeMode } from "../../types"; import { isTouch } from "../../util/is_touch"; import "../ha-icon-button"; @@ -536,7 +535,6 @@ export class HaMap extends ReactiveElement { private async _attachObserver(): Promise { if (!this._resizeObserver) { - await loadPolyfillIfNeeded(); this._resizeObserver = new ResizeObserver(() => { this.leafletMap?.invalidateSize({ debounceMoveend: true }); }); diff --git a/src/components/media-player/ha-media-player-browse.ts b/src/components/media-player/ha-media-player-browse.ts index 6f205de5fdd5..b0ed61efe5f1 100644 --- a/src/components/media-player/ha-media-player-browse.ts +++ b/src/components/media-player/ha-media-player-browse.ts @@ -39,7 +39,6 @@ import { import { browseLocalMediaPlayer } from "../../data/media_source"; import { isTTSMediaSource } from "../../data/tts"; import { showAlertDialog } from "../../dialogs/generic/show-dialog-box"; -import { loadPolyfillIfNeeded } from "../../resources/resize-observer.polyfill"; import { haStyle } from "../../resources/styles"; import type { HomeAssistant } from "../../types"; import { @@ -770,7 +769,6 @@ export class HaMediaPlayerBrowse extends LitElement { private async _attachResizeObserver(): Promise { if (!this._resizeObserver) { - await loadPolyfillIfNeeded(); this._resizeObserver = new ResizeObserver( debounce(() => this._measureCard(), 250, false) ); diff --git a/src/panels/lovelace/cards/hui-calendar-card.ts b/src/panels/lovelace/cards/hui-calendar-card.ts index 1a31a6d1cf64..e791db6a5d79 100644 --- a/src/panels/lovelace/cards/hui-calendar-card.ts +++ b/src/panels/lovelace/cards/hui-calendar-card.ts @@ -25,7 +25,6 @@ import type { } from "../../../types"; import "../../calendar/ha-full-calendar"; import { findEntities } from "../common/find-entities"; -import { loadPolyfillIfNeeded } from "../../../resources/resize-observer.polyfill"; import "../components/hui-warning"; import type { LovelaceCard, LovelaceCardEditor } from "../types"; import type { CalendarCardConfig } from "./types"; @@ -210,7 +209,6 @@ export class HuiCalendarCard extends LitElement implements LovelaceCard { private async _attachObserver(): Promise { if (!this._resizeObserver) { - await loadPolyfillIfNeeded(); this._resizeObserver = new ResizeObserver( debounce(() => this._measureCard(), 250, false) ); diff --git a/src/panels/lovelace/cards/hui-media-control-card.ts b/src/panels/lovelace/cards/hui-media-control-card.ts index d28d0f612f8f..ffdfe2c34a2f 100644 --- a/src/panels/lovelace/cards/hui-media-control-card.ts +++ b/src/panels/lovelace/cards/hui-media-control-card.ts @@ -38,7 +38,6 @@ import { import type { HomeAssistant } from "../../../types"; import { findEntities } from "../common/find-entities"; import { hasConfigOrEntityChanged } from "../common/has-changed"; -import { loadPolyfillIfNeeded } from "../../../resources/resize-observer.polyfill"; import "../components/hui-marquee"; import { createEntityNotFoundWarning } from "../components/hui-warning"; import type { LovelaceCard, LovelaceCardEditor } from "../types"; @@ -482,7 +481,6 @@ export class HuiMediaControlCard extends LitElement implements LovelaceCard { private async _attachObserver(): Promise { if (!this._resizeObserver) { - await loadPolyfillIfNeeded(); this._resizeObserver = new ResizeObserver( debounce(() => this._measureCard(), 250, false) ); diff --git a/src/panels/lovelace/cards/hui-weather-forecast-card.ts b/src/panels/lovelace/cards/hui-weather-forecast-card.ts index 3d0d2ac047f2..51a072f79cfe 100644 --- a/src/panels/lovelace/cards/hui-weather-forecast-card.ts +++ b/src/panels/lovelace/cards/hui-weather-forecast-card.ts @@ -31,7 +31,6 @@ import { weatherAttrIcons, weatherSVGStyles, } from "../../../data/weather"; -import { loadPolyfillIfNeeded } from "../../../resources/resize-observer.polyfill"; import type { HomeAssistant } from "../../../types"; import { actionHandler } from "../common/directives/action-handler-directive"; import { findEntities } from "../common/find-entities"; @@ -419,7 +418,6 @@ class HuiWeatherForecastCard extends LitElement implements LovelaceCard { private async _attachObserver(): Promise { if (!this._resizeObserver) { - await loadPolyfillIfNeeded(); this._resizeObserver = new ResizeObserver( debounce(() => this._measureCard(), 250, false) ); diff --git a/src/panels/lovelace/components/hui-energy-period-selector.ts b/src/panels/lovelace/components/hui-energy-period-selector.ts index 11e863560750..38853f69b0ec 100644 --- a/src/panels/lovelace/components/hui-energy-period-selector.ts +++ b/src/panels/lovelace/components/hui-energy-period-selector.ts @@ -54,7 +54,6 @@ import "../../../components/ha-icon-button-next"; import "../../../components/ha-icon-button-prev"; import { EnergyData, getEnergyDataCollection } from "../../../data/energy"; import { SubscribeMixin } from "../../../mixins/subscribe-mixin"; -import { loadPolyfillIfNeeded } from "../../../resources/resize-observer.polyfill"; import { HomeAssistant } from "../../../types"; @customElement("hui-energy-period-selector") @@ -89,7 +88,6 @@ export class HuiEnergyPeriodSelector extends SubscribeMixin(LitElement) { private async _attachObserver(): Promise { if (!this._resizeObserver) { - await loadPolyfillIfNeeded(); this._resizeObserver = new ResizeObserver( debounce(() => this._measure(), 250, false) ); diff --git a/src/panels/lovelace/entity-rows/hui-input-number-entity-row.ts b/src/panels/lovelace/entity-rows/hui-input-number-entity-row.ts index f6888a5d02af..94a875f995e2 100644 --- a/src/panels/lovelace/entity-rows/hui-input-number-entity-row.ts +++ b/src/panels/lovelace/entity-rows/hui-input-number-entity-row.ts @@ -12,7 +12,6 @@ import "../../../components/ha-slider"; import "../../../components/ha-textfield"; import { isUnavailableState } from "../../../data/entity"; import { setValue } from "../../../data/input_text"; -import { loadPolyfillIfNeeded } from "../../../resources/resize-observer.polyfill"; import { HomeAssistant } from "../../../types"; import { hasConfigOrEntityChanged } from "../common/has-changed"; import "../components/hui-generic-entity-row"; @@ -161,7 +160,6 @@ class HuiInputNumberEntityRow extends LitElement implements LovelaceRow { private async _attachObserver(): Promise { if (!this._resizeObserver) { - await loadPolyfillIfNeeded(); this._resizeObserver = new ResizeObserver( debounce(() => this._measureCard(), 250, false) ); diff --git a/src/panels/lovelace/entity-rows/hui-media-player-entity-row.ts b/src/panels/lovelace/entity-rows/hui-media-player-entity-row.ts index f3a11a7178f7..ac7b6951561d 100644 --- a/src/panels/lovelace/entity-rows/hui-media-player-entity-row.ts +++ b/src/panels/lovelace/entity-rows/hui-media-player-entity-row.ts @@ -33,7 +33,6 @@ import { MediaPlayerEntityFeature, computeMediaDescription, } from "../../../data/media-player"; -import { loadPolyfillIfNeeded } from "../../../resources/resize-observer.polyfill"; import type { HomeAssistant } from "../../../types"; import { hasConfigOrEntityChanged } from "../common/has-changed"; import "../components/hui-generic-entity-row"; @@ -291,7 +290,6 @@ class HuiMediaPlayerEntityRow extends LitElement implements LovelaceRow { private async _attachObserver(): Promise { if (!this._resizeObserver) { - await loadPolyfillIfNeeded(); this._resizeObserver = new ResizeObserver( debounce(() => this._measureCard(), 250, false) ); diff --git a/src/panels/lovelace/entity-rows/hui-number-entity-row.ts b/src/panels/lovelace/entity-rows/hui-number-entity-row.ts index 1b57c6ee4135..2002450499a6 100644 --- a/src/panels/lovelace/entity-rows/hui-number-entity-row.ts +++ b/src/panels/lovelace/entity-rows/hui-number-entity-row.ts @@ -12,7 +12,6 @@ import "../../../components/ha-slider"; import "../../../components/ha-textfield"; import { UNAVAILABLE } from "../../../data/entity"; import { setValue } from "../../../data/input_text"; -import { loadPolyfillIfNeeded } from "../../../resources/resize-observer.polyfill"; import { HomeAssistant } from "../../../types"; import { hasConfigOrEntityChanged } from "../common/has-changed"; import "../components/hui-generic-entity-row"; @@ -167,7 +166,6 @@ class HuiNumberEntityRow extends LitElement implements LovelaceRow { private async _attachObserver(): Promise { if (!this._resizeObserver) { - await loadPolyfillIfNeeded(); this._resizeObserver = new ResizeObserver( debounce(() => this._measureCard(), 250, false) ); diff --git a/src/resources/compatibility.ts b/src/resources/compatibility.ts index 75ca9bace83b..51aeab4883d1 100644 --- a/src/resources/compatibility.ts +++ b/src/resources/compatibility.ts @@ -1,10 +1,6 @@ // Caution before editing - For latest builds, this module is replaced with emptiness and thus not imported (see build-scripts/bundle.js) import "lit/polyfill-support"; -import ResizeObserver from "@lit-labs/virtualizer/polyfills/resize-observer-polyfill/ResizeObserver"; - -window.ResizeObserver = ResizeObserver; - // Source: https://github.com/jserz/js_piece/blob/master/DOM/ParentNode/append()/append().md (function (arr) { arr.forEach((item) => { diff --git a/src/resources/polyfills/resize-observer.ts b/src/resources/polyfills/resize-observer.ts new file mode 100644 index 000000000000..1820c4eb4014 --- /dev/null +++ b/src/resources/polyfills/resize-observer.ts @@ -0,0 +1,9 @@ +if (typeof window.ResizeObserver !== "function") { + window.ResizeObserver = ( + await import( + "@lit-labs/virtualizer/polyfills/resize-observer-polyfill/ResizeObserver" + ) + ).default; +} + +export {}; diff --git a/src/resources/resize-observer.polyfill.ts b/src/resources/resize-observer.polyfill.ts deleted file mode 100644 index 5023714d600e..000000000000 --- a/src/resources/resize-observer.polyfill.ts +++ /dev/null @@ -1,12 +0,0 @@ -export const loadPolyfillIfNeeded = async () => { - try { - // eslint-disable-next-line no-new - new ResizeObserver(() => {}); - } catch (e) { - window.ResizeObserver = ( - await import( - "@lit-labs/virtualizer/polyfills/resize-observer-polyfill/ResizeObserver" - ) - ).default; - } -}; diff --git a/src/resources/virtualizer.ts b/src/resources/virtualizer.ts index ba92a2b2f40d..4948b0b68f4a 100644 --- a/src/resources/virtualizer.ts +++ b/src/resources/virtualizer.ts @@ -1,6 +1,3 @@ -import { loadPolyfillIfNeeded } from "./resize-observer.polyfill"; - export const loadVirtualizer = async () => { - await loadPolyfillIfNeeded(); await import("@lit-labs/virtualizer"); }; diff --git a/src/state-summary/state-card-input_number.ts b/src/state-summary/state-card-input_number.ts index 884253d3e67e..1d4ff8913687 100644 --- a/src/state-summary/state-card-input_number.ts +++ b/src/state-summary/state-card-input_number.ts @@ -7,7 +7,6 @@ import "../components/ha-slider"; import "../components/ha-textfield"; import { isUnavailableState } from "../data/entity"; import { setValue } from "../data/input_text"; -import { loadPolyfillIfNeeded } from "../resources/resize-observer.polyfill"; import { HomeAssistant } from "../types"; @customElement("state-card-input_number") @@ -132,7 +131,6 @@ class StateCardInputNumber extends LitElement { private async _attachObserver(): Promise { if (!this._resizeObserver) { - await loadPolyfillIfNeeded(); this._resizeObserver = new ResizeObserver( debounce(() => this._measureCard(), 250, false) ); diff --git a/src/state-summary/state-card-number.ts b/src/state-summary/state-card-number.ts index 10cda4b7dd5b..dab30bf078da 100644 --- a/src/state-summary/state-card-number.ts +++ b/src/state-summary/state-card-number.ts @@ -6,7 +6,6 @@ import "../components/ha-slider"; import "../components/ha-textfield"; import { HomeAssistant } from "../types"; import { haStyle } from "../resources/styles"; -import { loadPolyfillIfNeeded } from "../resources/resize-observer.polyfill"; import { isUnavailableState } from "../data/entity"; import { debounce } from "../common/util/debounce"; @@ -109,7 +108,6 @@ class StateCardNumber extends LitElement { private async _attachObserver(): Promise { if (!this._resizeObserver) { - await loadPolyfillIfNeeded(); this._resizeObserver = new ResizeObserver( debounce(() => this._measureCard(), 250, false) );