From 46de23727f77c2300775b014a9a8e59cd3cc2d9e Mon Sep 17 00:00:00 2001 From: Maarten Lakerveld Date: Wed, 2 Sep 2026 07:15:36 +0200 Subject: [PATCH] Remove ES5 specific code (#53899) * Remove web components polyfills and ES5 custom elements adapter All supported browsers (legacy floor: Chrome 59, Safari/iOS 12, Firefox 94) have native shadow DOM and custom elements, so the webcomponents bundle, ShadyCSS branch, and lit polyfill-support are unreachable. The legacy build now emits ES2017 classes, so custom-elements-es5-adapter and the window.loadES5Adapter hook (no known third-party consumers) are removed. Also stops shipping the never-loaded dialog-polyfill css and drops both now-unused dependencies. * Remove keyed-es5 Terser workaround The custom keyed directive existed because Terser with ecma: 5 miscompiled the destructured update() parameters (#28732). The legacy build now minifies with ecma: 2017, so the stock lit-html keyed directive works in both builds. * Remove old-browser JS shims and stale ES5 build references Drops the IE-only navigator.msMaxTouchPoints check, replaces the toggleAttribute helper with the native method (polyfilled automatically for Chrome < 69 in the legacy build), and removes babel excludes for the uninstalled proxy-polyfill and unfetch packages. Updates comments that still described the legacy build as ES5. * Remove vendor prefixes for no-longer-supported browsers Deletes -ms- prefixes (IE/EdgeHTML only) and -webkit-/-moz- prefixed declarations that every supported browser understands unprefixed, or that Lightning CSS re-adds automatically from the unprefixed property in production builds. Blocks that only had prefixed user-select now use the standard property (previously Firefox got no user-select there at all). Converts the four -webkit-linear-gradient() declarations - the sole gradient syntax on those sliders - to standard linear-gradient(). * Remove dead html_url custom panel support html_url pointed to an HTML Import, a Polymer-era feature removed from Chrome in 2019 and never shipped elsewhere. The loader has not handled the html type for years (it fell through to a rejection), and core's panel_custom integration no longer accepts the option, so the branch was unreachable. Also drops the ha-panel-${name} legacy tag naming that was keyed on html_url. * Repair list-plugins-and-polyfills script for Babel 8 The audit script died at startup since the Babel 8 update: preset-env no longer exposes lib/debug.js (logPlugin is now inlined locally, built on the public getInclusionReasons helper) and babel-plugin-polyfill-corejs3 v1 no longer ships lib/shipped-proposals.js (list inlined). Instead of invoking the preset with a hand-mocked plugin API - the part that kept drifting - the plugin listing now runs a real transform of an empty file with preset-env in debug mode, declaring the same caller capabilities as babel-loader. The polyfill listing now passes the configured core-js version to core-js-compat, mirroring the provider's own filtering so the report cannot list modules the installed core-js lacks. Output is byte-identical to the direct-invocation approach. Also documents the script in the build-scripts README. * Correct macOS floor for Safari 26 in companion app UA regex Safari 26 ships for macOS 14 Sonoma and 15 Sequoia, not only macOS 26, so the SAFARI_TO_MACOS entry breaking the minimum-supported-macOS pattern would have sent updated macOS 14/15 companion apps to the legacy build once the modern floor reaches Safari 26. * Remove orphaned values left behind by vendor prefix removal * Require macOS 14.6 for Safari 26 in companion app UA regex --- build-scripts/README.md | 10 +- build-scripts/bundle.cjs | 4 +- build-scripts/gulp/entry-html.js | 4 +- build-scripts/gulp/gather-static.js | 35 ------ build-scripts/list-plugins-and-polyfills.js | 89 ++++++++++---- build-scripts/rspack.cjs | 5 +- cast/src/launcher/layout/hc-cast.ts | 4 +- gallery/src/ha-gallery.ts | 4 +- package.json | 2 - .../controllers/filter-panel-controller.ts | 1 - src/common/dom/apply_themes_on_element.ts | 15 +-- src/common/dom/toggle_attribute.ts | 25 ---- .../feature-detect/support-web-components.ts | 1 - src/common/lit/keyed-es5.ts | 50 -------- src/components/data-table/ha-data-table.ts | 4 +- src/components/ha-adaptive-popover.ts | 5 - src/components/ha-assist-chat.ts | 13 -- src/components/ha-badge.ts | 1 - src/components/ha-bottom-sheet.ts | 11 -- src/components/ha-card.ts | 1 - src/components/ha-control-select.ts | 2 - src/components/ha-dialog.ts | 8 -- src/components/ha-faded.ts | 5 - src/components/ha-markdown.ts | 4 +- src/components/ha-sidebar.ts | 8 +- src/components/map/ha-map.ts | 2 - src/components/trace/hat-trace-timeline.ts | 3 +- src/data/panel_custom.ts | 1 - .../ha-more-info-control-select-container.ts | 1 - .../components/ha-more-info-state-header.ts | 1 - .../lights/light-color-rgb-picker.ts | 2 - .../lights/light-color-temp-picker.ts | 4 +- .../ha-more-info-view-vacuum-clean-areas.ts | 1 - .../notification-item-template.ts | 3 - src/entrypoints/custom-panel.ts | 116 ++++++------------ src/html/_js_base.html.template | 4 - src/layouts/hass-tabs-subpage-data-table.ts | 1 - src/layouts/home-assistant-main.ts | 6 +- src/onboarding/onboarding-loading.ts | 15 --- src/panels/climate/ha-panel-climate.ts | 4 +- .../account/dialog-cloud-support-package.ts | 1 - .../config/helpers/forms/ha-schedule-form.ts | 2 - .../mqtt/mqtt-config-panel.ts | 4 +- src/panels/config/logs/ha-config-logs.ts | 4 +- src/panels/config/tools/event/tools-event.ts | 4 +- src/panels/config/tools/state/tools-state.ts | 4 +- .../tools/statistics/tools-statistics.ts | 1 - src/panels/energy/ha-panel-energy.ts | 4 +- src/panels/light/ha-panel-light.ts | 4 +- .../hui-cover-tilt-position-card-feature.ts | 2 +- .../hui-light-color-temp-card-feature.ts | 4 +- src/panels/lovelace/cards/hui-heading-card.ts | 1 - src/panels/lovelace/cards/hui-light-card.ts | 2 - .../lovelace/cards/hui-toggle-group-card.ts | 1 - .../components/hui-energy-period-selector.ts | 4 - .../components/hui-generic-entity-row.ts | 4 +- .../lovelace/elements/hui-image-element.ts | 2 +- src/panels/lovelace/hui-root.ts | 5 +- .../maintenance/ha-panel-maintenance.ts | 4 +- src/panels/profile/ha-profile-dashboard.ts | 4 +- .../profile/ha-profile-section-browser.ts | 4 +- .../ha-profile-section-localization.ts | 4 +- .../profile/ha-profile-section-preferences.ts | 4 +- .../profile/ha-profile-section-security.ts | 4 +- src/panels/security/ha-panel-security.ts | 4 +- .../ha-state-control-cover-tilt-position.ts | 2 +- src/types.ts | 9 -- .../create-custom-panel-element.ts | 10 +- src/util/custom-panel/load-custom-panel.ts | 16 +-- src/util/is_touch.ts | 6 +- yarn.lock | 16 --- 71 files changed, 157 insertions(+), 458 deletions(-) delete mode 100644 src/common/dom/toggle_attribute.ts delete mode 100644 src/common/feature-detect/support-web-components.ts delete mode 100644 src/common/lit/keyed-es5.ts diff --git a/build-scripts/README.md b/build-scripts/README.md index 8e7933d2f8..ba88a37e0e 100644 --- a/build-scripts/README.md +++ b/build-scripts/README.md @@ -34,6 +34,14 @@ In production, the following responsibilities are added: - Minify HTML - Bundle multiple imports so that the browser can fetch less files -- Generate a second version that is ES5 compatible +- Generate a second version that is compatible with older browsers (legacy build) Configuration for all these steps are specified in [bundle.js](bundle.js). + +## Auditing browser support changes + +`node build-scripts/list-plugins-and-polyfills.js` prints, per browserslist +environment (modern/legacy), the Babel transforms preset-env enables and the +Core-JS polyfills that may be injected — as collapsible markdown ready to +paste into a PR. Use it to show the bundle impact when changing +`.browserslistrc` or the Babel configuration. diff --git a/build-scripts/bundle.cjs b/build-scripts/bundle.cjs index b14032dada..b03fd69b3d 100644 --- a/build-scripts/bundle.cjs +++ b/build-scripts/bundle.cjs @@ -121,7 +121,7 @@ module.exports.babelOptions = ({ latestBuild, isTestBuild, sw }) => ({ ignoreModuleNotFound: true, }, ], - // Import helpers and regenerator from runtime package. + // Import helpers from runtime package. // `moduleName` is pinned so helpers resolve from `@babel/runtime`: the // corejs3 polyfill provider above otherwise redirects them to the // (uninstalled) `@babel/runtime-corejs3`, which preset-env used to suppress @@ -155,8 +155,6 @@ module.exports.babelOptions = ({ latestBuild, isTestBuild, sw }) => ({ "@lit-labs/virtualizer/polyfills", "@webcomponents/scoped-custom-element-registry", "element-internals-polyfill", - "proxy-polyfill", - "unfetch", ].map((p) => new RegExp(`/node_modules/${p}/`)), ], }, diff --git a/build-scripts/gulp/entry-html.js b/build-scripts/gulp/entry-html.js index 9c5d2d9446..f3bcbf5a58 100644 --- a/build-scripts/gulp/entry-html.js +++ b/build-scripts/gulp/entry-html.js @@ -25,7 +25,7 @@ const SAFARI_TO_MACOS = { 16: [11, 0, 0], 17: [12, 0, 0], 18: [13, 0, 0], - 26: [26, 0, 0], + 26: [14, 6, 0], }; const getCommonTemplateVars = () => { @@ -89,7 +89,7 @@ const minifyHtml = (content, ext) => { ...htmlMinifierOptions, conservativeCollapse: false, minifyJS: terserOptions({ - latestBuild: false, // Shared scripts should be ES5 + latestBuild: false, // Shared scripts must satisfy the legacy targets isTestBuild: true, // Don't need source maps }), }).then((wrapped) => diff --git a/build-scripts/gulp/gather-static.js b/build-scripts/gulp/gather-static.js index 9535d1e13d..2c0dd3427b 100644 --- a/build-scripts/gulp/gather-static.js +++ b/build-scripts/gulp/gather-static.js @@ -42,37 +42,6 @@ function copyMdiIcons(staticDir) { fs.copySync(polyPath("build/mdi"), staticPath("mdi")); } -function copyPolyfills(staticDir) { - const staticPath = genStaticPath(staticDir); - - // For custom panels using ES5 builds that don't use Babel 7+ - copyFileDir( - npmPath("@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"), - staticPath("polyfills/") - ); - - // Web Component polyfills and adapters - copyFileDir( - npmPath("@webcomponents/webcomponentsjs/webcomponents-bundle.js"), - staticPath("polyfills/") - ); - copyFileDir( - npmPath("@webcomponents/webcomponentsjs/webcomponents-bundle.js.map"), - staticPath("polyfills/") - ); - // Lit polyfill support - fs.copySync( - npmPath("lit/polyfill-support.js"), - path.join(staticPath("polyfills/"), "lit-polyfill-support.js") - ); - - // dialog-polyfill css - copyFileDir( - npmPath("dialog-polyfill/dialog-polyfill.css"), - staticPath("polyfills/") - ); -} - function copyFonts(staticDir) { const staticPath = genStaticPath(staticDir); // Local fonts @@ -141,7 +110,6 @@ gulp.task("copy-static-app", async () => { const staticDir = paths.app_output_static; // Basic static files fs.copySync(polyPath("public"), paths.app_output_root); - copyPolyfills(staticDir); copyFonts(staticDir); copyTranslations(staticDir); copyLocaleData(staticDir); @@ -163,7 +131,6 @@ gulp.task("copy-static-demo", async () => { ); // Copy demo static files fs.copySync(path.resolve(paths.demo_dir, "public"), paths.demo_output_root); - copyPolyfills(paths.demo_output_static); await copyMapPanel(paths.demo_output_static); copyFonts(paths.demo_output_static); copyTranslations(paths.demo_output_static); @@ -176,7 +143,6 @@ gulp.task("copy-static-cast", async () => { fs.copySync(polyPath("public/static"), paths.cast_output_static); // Copy cast static files fs.copySync(path.resolve(paths.cast_dir, "public"), paths.cast_output_root); - copyPolyfills(paths.cast_output_static); await copyMapPanel(paths.cast_output_static); copyFonts(paths.cast_output_static); copyTranslations(paths.cast_output_static); @@ -223,7 +189,6 @@ gulp.task("copy-static-e2e-test-app", async () => { fs.copySync(e2ePublic, paths.e2eTestApp_output_root); } - copyPolyfills(paths.e2eTestApp_output_static); await copyMapPanel(paths.e2eTestApp_output_static); copyFonts(paths.e2eTestApp_output_static); copyTranslations(paths.e2eTestApp_output_static); diff --git a/build-scripts/list-plugins-and-polyfills.js b/build-scripts/list-plugins-and-polyfills.js index 53b1606a1b..a6f1a87952 100755 --- a/build-scripts/list-plugins-and-polyfills.js +++ b/build-scripts/list-plugins-and-polyfills.js @@ -1,38 +1,55 @@ #!/usr/bin/env node // Script to print Babel plugins and Core JS polyfills that will be used by browserslist environments -import { version as babelVersion } from "@babel/core"; -import presetEnv from "@babel/preset-env"; -import compilationTargets from "@babel/helper-compilation-targets"; +import { transformSync } from "@babel/core"; +import compilationTargets, { + getInclusionReasons, +} from "@babel/helper-compilation-targets"; import coreJSCompat from "core-js-compat"; -import { logPlugin } from "@babel/preset-env/lib/debug.js"; -import shippedPolyfills from "../node_modules/babel-plugin-polyfill-corejs3/lib/shipped-proposals.js"; import { babelOptions } from "./bundle.cjs"; const detailsOpen = (heading) => `
\n

${heading}

\n`; const detailsClose = "
\n"; -const dummyAPI = { - version: babelVersion, - // eslint-disable-next-line @typescript-eslint/no-empty-function - assertVersion: () => {}, - caller: (callback) => - callback({ - name: "Dummy Bundler", - supportsStaticESM: true, - supportsDynamicImport: true, - supportsTopLevelAwait: true, - supportsExportNamespaceFrom: true, - }), - targets: () => ({}), +// Copied from @babel/preset-env's internal `logPlugin`, which Babel 8 no +// longer exposes (the package rolls up into lib/index.js and exports nothing +// but the preset). Prints an item with the targets that require it. +const logPlugin = (item, targetVersions, list) => { + const filteredList = getInclusionReasons(item, targetVersions, list); + const support = list[item]; + if (!support) { + console.log(` ${item}`); + return; + } + let formattedTargets = `{`; + let first = true; + for (const target of Object.keys(filteredList)) { + if (!first) formattedTargets += `,`; + first = false; + formattedTargets += ` ${target}`; + if (support[target]) formattedTargets += ` < ${support[target]}`; + } + formattedTargets += ` }`; + console.log(` ${item} ${formattedTargets}`); }; +// Copied from babel-plugin-polyfill-corejs3's generated +// corejs3ShippedProposalsList, which v1 no longer exposes (it is inlined in +// the package's rolled-up bundle). +const shippedProposalsList = new Set([ + "esnext.array.group", + "esnext.array.group-to-map", + "esnext.iterator.zip", + "esnext.iterator.zip-keyed", + "esnext.symbol.metadata", +]); + // Generate filter function based on proposal/method inputs // Copied and adapted from babel-plugin-polyfill-corejs3/esm/index.mjs const polyfillFilter = (method, proposals, shippedProposals) => (name) => { if (proposals || method === "entry-global") return true; - if (shippedProposals && shippedPolyfills.default.has(name)) { + if (shippedProposals && shippedProposalsList.has(name)) { return true; } if (name.startsWith("esnext.")) { @@ -47,7 +64,9 @@ const polyfillFilter = (method, proposals, shippedProposals) => (name) => { for (const buildType of ["Modern", "Legacy"]) { const browserslistEnv = buildType.toLowerCase(); const babelOpts = babelOptions({ latestBuild: browserslistEnv === "modern" }); - const presetEnvOpts = babelOpts.presets[0][1]; + const presetEnvOpts = babelOpts.presets.find( + (preset) => Array.isArray(preset) && preset[0] === "@babel/preset-env" + )?.[1]; // Core-JS polyfills are injected by babel-plugin-polyfill-corejs3 (Babel 8 // removed preset-env's `useBuiltIns`), so read its options here. const corejsOpts = babelOpts.plugins.find( @@ -55,22 +74,38 @@ for (const buildType of ["Modern", "Legacy"]) { Array.isArray(plugin) && plugin[0] === "babel-plugin-polyfill-corejs3" )?.[1]; - // Invoking preset-env in debug mode will log the included plugins + // Transforming an empty file with preset-env in debug mode logs the included + // plugins. The caller declares the same capabilities babel-loader does, so + // plugins gated on bundler support (e.g. transform-export-namespace-from) + // match the build. + presetEnvOpts.debug = true; console.log(detailsOpen(`${buildType} Build Babel Plugins`)); - presetEnv.default(dummyAPI, { - ...presetEnvOpts, - browserslistEnv, - debug: true, + transformSync("", { + ...babelOpts, + configFile: false, + filename: "audit.js", + caller: { + name: "list-plugins-and-polyfills", + supportsStaticESM: true, + supportsDynamicImport: true, + supportsTopLevelAwait: true, + supportsExportNamespaceFrom: true, + }, }); console.log(detailsClose); // Manually log the Core-JS polyfills using the same technique if (corejsOpts) { console.log(detailsOpen(`${buildType} Build Core-JS Polyfills`)); - const targets = compilationTargets.default(babelOpts?.targets, { + const targets = compilationTargets(babelOpts.targets, { browserslistEnv, }); - const polyfillList = coreJSCompat({ targets }).list.filter( + // `version` limits the list to modules the installed core-js ships, + // mirroring the provider's own filtering. + const polyfillList = coreJSCompat({ + targets, + version: corejsOpts.version, + }).list.filter( polyfillFilter( corejsOpts.method, corejsOpts.proposals, diff --git a/build-scripts/rspack.cjs b/build-scripts/rspack.cjs index 546cf50b7e..bf96e3d6f8 100644 --- a/build-scripts/rspack.cjs +++ b/build-scripts/rspack.cjs @@ -345,10 +345,7 @@ const createRspackConfig = ({ "lit/directives/join$": "lit/directives/join.js", "lit/directives/repeat$": "lit/directives/repeat.js", "lit/directives/live$": "lit/directives/live.js", - "lit/directives/keyed$": latestBuild - ? "lit/directives/keyed.js" - : path.resolve(__dirname, "../src/common/lit/keyed-es5.ts"), - "lit/polyfill-support$": "lit/polyfill-support.js", + "lit/directives/keyed$": "lit/directives/keyed.js", "@lit-labs/virtualizer/layouts/grid": "@lit-labs/virtualizer/layouts/grid.js", "@lit-labs/virtualizer/polyfills/resize-observer-polyfill/ResizeObserver": diff --git a/cast/src/launcher/layout/hc-cast.ts b/cast/src/launcher/layout/hc-cast.ts index eaf974388c..06b4c5db03 100644 --- a/cast/src/launcher/layout/hc-cast.ts +++ b/cast/src/launcher/layout/hc-cast.ts @@ -15,7 +15,6 @@ import { saveTokens, } from "../../../../src/common/auth/token_storage"; import { atLeastVersion } from "../../../../src/common/config/version"; -import { toggleAttribute } from "../../../../src/common/dom/toggle_attribute"; import "../../../../src/components/ha-button"; import "../../../../src/components/ha-icon"; import "../../../../src/components/ha-list"; @@ -197,8 +196,7 @@ class HcCast extends LitElement { protected updated(changedProps: PropertyValues) { super.updated(changedProps); - toggleAttribute( - this, + this.toggleAttribute( "hide-icons", this.lovelaceViews ? !this.lovelaceViews.some((view) => view.icon) : true ); diff --git a/gallery/src/ha-gallery.ts b/gallery/src/ha-gallery.ts index 9923f335c2..fa11c71182 100644 --- a/gallery/src/ha-gallery.ts +++ b/gallery/src/ha-gallery.ts @@ -693,9 +693,7 @@ class HaGallery extends LitElement { haStyle, css` :host { - -ms-user-select: initial; - -webkit-user-select: initial; - -moz-user-select: initial; + user-select: initial; --ha-sidebar-width: 300px; --ha-sidebar-expanded-width: 300px; --ha-sidebar-expanded-item-width: 292px; diff --git a/package.json b/package.json index fba59b6f09..ff13c1148c 100644 --- a/package.json +++ b/package.json @@ -90,7 +90,6 @@ "@vibrant/color": "4.0.4", "@vvo/tzdb": "6.198.0", "@webcomponents/scoped-custom-element-registry": "0.0.10", - "@webcomponents/webcomponentsjs": "2.8.0", "barcode-detector": "3.2.2", "cally": "0.9.2", "color-name": "2.1.1", @@ -101,7 +100,6 @@ "date-fns": "4.4.0", "deep-clone-simple": "1.1.1", "deep-freeze": "0.0.1", - "dialog-polyfill": "0.5.6", "echarts": "6.1.0", "echarts-extension-chart2music": "0.1.1", "element-internals-polyfill": "3.0.2", diff --git a/src/common/controllers/filter-panel-controller.ts b/src/common/controllers/filter-panel-controller.ts index 72af5c1783..e3b86d36b5 100644 --- a/src/common/controllers/filter-panel-controller.ts +++ b/src/common/controllers/filter-panel-controller.ts @@ -33,7 +33,6 @@ export const filterPanelStyles = css` --ha-card-border-radius: var(--ha-border-radius-square); } ha-expansion-panel::part(summary) { - -webkit-user-select: none; user-select: none; } .content { diff --git a/src/common/dom/apply_themes_on_element.ts b/src/common/dom/apply_themes_on_element.ts index 535c2bafa1..6f314b954f 100644 --- a/src/common/dom/apply_themes_on_element.ts +++ b/src/common/dom/apply_themes_on_element.ts @@ -145,16 +145,11 @@ export const applyThemesOnElement = ( element.__themes = { cacheKey, keys: newTheme?.keys }; // Set and/or reset styles - if (window.ShadyCSS) { - // Use ShadyCSS if available - window.ShadyCSS.styleSubtree(/** @type {!HTMLElement} */ element, styles); - } else { - for (const s in styles) { - if (s === null) { - element.style.removeProperty(s); - } else { - element.style.setProperty(s, styles[s]); - } + for (const s in styles) { + if (s === null) { + element.style.removeProperty(s); + } else { + element.style.setProperty(s, styles[s]); } } }; diff --git a/src/common/dom/toggle_attribute.ts b/src/common/dom/toggle_attribute.ts deleted file mode 100644 index c37be7a4f8..0000000000 --- a/src/common/dom/toggle_attribute.ts +++ /dev/null @@ -1,25 +0,0 @@ -// Toggle Attribute Polyfill because it's too new for some browsers -export const toggleAttribute = ( - el: HTMLElement, - name: string, - force?: boolean -) => { - if (force !== undefined) { - force = !!force; - } - - if (el.hasAttribute(name)) { - if (force) { - return true; - } - - el.removeAttribute(name); - return false; - } - if (force === false) { - return false; - } - - el.setAttribute(name, ""); - return true; -}; diff --git a/src/common/feature-detect/support-web-components.ts b/src/common/feature-detect/support-web-components.ts deleted file mode 100644 index 8017d682ee..0000000000 --- a/src/common/feature-detect/support-web-components.ts +++ /dev/null @@ -1 +0,0 @@ -export const webComponentsSupported = "attachShadow" in Element.prototype; diff --git a/src/common/lit/keyed-es5.ts b/src/common/lit/keyed-es5.ts deleted file mode 100644 index a9fb928d65..0000000000 --- a/src/common/lit/keyed-es5.ts +++ /dev/null @@ -1,50 +0,0 @@ -/** - * ES5-compatible implementation of the keyed directive. - * Based on lit-html's keyed directive but written to avoid ES5 minification issues. - * - * This implementation avoids parameter destructuring in the update() method, - * which causes Terser with ecma: 5 to generate invalid references like `_k`. - * - * Used only for ES5 builds (legacy browsers). Modern builds use the original - * lit-html keyed directive. - * - * @see https://github.com/home-assistant/frontend/issues/28732 - */ -import { directive, Directive } from "lit-html/directive.js"; -import { setCommittedValue } from "lit-html/directive-helpers.js"; -// eslint-disable-next-line lit/no-legacy-imports -import { nothing } from "lit-html"; -import type { Part } from "lit-html/directive.js"; - -class KeyedES5 extends Directive { - private _key: unknown = nothing; - - render(k: unknown, v: unknown) { - this._key = k; - return v; - } - - update(part: unknown, args: [unknown, unknown]) { - const k = args[0]; - const v = args[1]; - if (k !== this._key) { - // Clear the part before returning a value. The one-arg form of - // setCommittedValue sets the value to a sentinel which forces a - // commit the next render. - setCommittedValue(part as Part); - this._key = k; - } - return v; - } -} - -/** - * Associates a renderable value with a unique key. When the key changes, the - * previous DOM is removed and disposed before rendering the next value, even - * if the value - such as a template - is the same. - * - * This is useful for forcing re-renders of stateful components, or working - * with code that expects new data to generate new HTML elements, such as some - * animation techniques. - */ -export const keyed = directive(KeyedES5); diff --git a/src/components/data-table/ha-data-table.ts b/src/components/data-table/ha-data-table.ts index de890e9ba5..e0ff725bcb 100644 --- a/src/components/data-table/ha-data-table.ts +++ b/src/components/data-table/ha-data-table.ts @@ -1235,10 +1235,8 @@ export class HaDataTable extends LitElement { display: none; } - /* Hide scrollbar for IE, Edge and Firefox */ .mdc-data-table__header-row { - -ms-overflow-style: none; /* IE and Edge */ - scrollbar-width: none; /* Firefox */ + scrollbar-width: none; } .mdc-data-table__cell, diff --git a/src/components/ha-adaptive-popover.ts b/src/components/ha-adaptive-popover.ts index 858dc53cb9..ae5c40fe9e 100644 --- a/src/components/ha-adaptive-popover.ts +++ b/src/components/ha-adaptive-popover.ts @@ -293,12 +293,7 @@ export class HaAdaptivePopover extends ScrollLockMixin(HaAdaptiveDialog) { ); overflow: hidden; color: var(--primary-text-color); - -webkit-backdrop-filter: var( - --ha-dialog-surface-backdrop-filter, - none - ); backdrop-filter: var(--ha-dialog-surface-backdrop-filter, none); - -webkit-user-select: text; user-select: text; } diff --git a/src/components/ha-assist-chat.ts b/src/components/ha-assist-chat.ts index 33936b5c99..1f0b724e44 100644 --- a/src/components/ha-assist-chat.ts +++ b/src/components/ha-assist-chat.ts @@ -1061,31 +1061,18 @@ ${JSON.stringify(toolCall.result, null, 2)} position: absolute; top: 0; left: 0; - -webkit-animation: sk-bounce 2s infinite ease-in-out; animation: sk-bounce 2s infinite ease-in-out; } .double-bounce2 { - -webkit-animation-delay: -1s; animation-delay: -1s; } - @-webkit-keyframes sk-bounce { - 0%, - 100% { - -webkit-transform: scale(0); - } - 50% { - -webkit-transform: scale(1); - } - } @keyframes sk-bounce { 0%, 100% { transform: scale(0); - -webkit-transform: scale(0); } 50% { transform: scale(1); - -webkit-transform: scale(1); } } diff --git a/src/components/ha-badge.ts b/src/components/ha-badge.ts index aa3dbc1de1..4e8a60a1d6 100644 --- a/src/components/ha-badge.ts +++ b/src/components/ha-badge.ts @@ -70,7 +70,6 @@ export class HaBadge extends LitElement { --ha-card-background, var(--card-background-color, white) ); - -webkit-backdrop-filter: var(--ha-card-backdrop-filter, none); backdrop-filter: var(--ha-card-backdrop-filter, none); border-width: var(--ha-card-border-width, 1px); box-shadow: var(--ha-card-box-shadow, none); diff --git a/src/components/ha-bottom-sheet.ts b/src/components/ha-bottom-sheet.ts index d49b4928b5..650e2efa3f 100644 --- a/src/components/ha-bottom-sheet.ts +++ b/src/components/ha-bottom-sheet.ts @@ -432,13 +432,6 @@ export class HaBottomSheet extends ScrollableFadeMixin(LitElement) { } } wa-drawer::part(dialog)::backdrop { - -webkit-backdrop-filter: var( - --ha-bottom-sheet-scrim-backdrop-filter, - var( - --ha-dialog-scrim-backdrop-filter, - var(--dialog-backdrop-filter, none) - ) - ); backdrop-filter: var( --ha-bottom-sheet-scrim-backdrop-filter, var( @@ -470,10 +463,6 @@ export class HaBottomSheet extends ScrollableFadeMixin(LitElement) { var(--card-background-color, var(--ha-color-surface-default)) ) ); - -webkit-backdrop-filter: var( - --ha-bottom-sheet-surface-backdrop-filter, - var(--ha-dialog-surface-backdrop-filter, none) - ); backdrop-filter: var( --ha-bottom-sheet-surface-backdrop-filter, var(--ha-dialog-surface-backdrop-filter, none) diff --git a/src/components/ha-card.ts b/src/components/ha-card.ts index c8953d8be5..4b62e75001 100644 --- a/src/components/ha-card.ts +++ b/src/components/ha-card.ts @@ -13,7 +13,6 @@ export class HaCard extends LitElement { --ha-card-background, var(--card-background-color, white) ); - -webkit-backdrop-filter: var(--ha-card-backdrop-filter, none); backdrop-filter: var(--ha-card-backdrop-filter, none); box-shadow: var(--ha-card-box-shadow, none); box-sizing: border-box; diff --git a/src/components/ha-control-select.ts b/src/components/ha-control-select.ts index a0ed93ae33..10c7a178c4 100644 --- a/src/components/ha-control-select.ts +++ b/src/components/ha-control-select.ts @@ -323,8 +323,6 @@ export class HaControlSelect extends LitElement { .option .content span { display: block; width: 100%; - -webkit-hyphens: auto; - -moz-hyphens: auto; hyphens: auto; } :host([vertical]) { diff --git a/src/components/ha-dialog.ts b/src/components/ha-dialog.ts index 7ca383c804..063b911f15 100644 --- a/src/components/ha-dialog.ts +++ b/src/components/ha-dialog.ts @@ -393,10 +393,6 @@ export class HaDialog extends ScrollableFadeMixin(LitElement) { } wa-dialog::part(dialog) { - -webkit-backdrop-filter: var( - --ha-dialog-surface-backdrop-filter, - none - ); backdrop-filter: var(--ha-dialog-surface-backdrop-filter, none); box-shadow: var(--dialog-box-shadow, var(--wa-shadow-l)); color: var(--primary-text-color); @@ -429,10 +425,6 @@ export class HaDialog extends ScrollableFadeMixin(LitElement) { } wa-dialog::part(dialog)::backdrop { - -webkit-backdrop-filter: var( - --ha-dialog-scrim-backdrop-filter, - var(--dialog-backdrop-filter, none) - ); backdrop-filter: var( --ha-dialog-scrim-backdrop-filter, var(--dialog-backdrop-filter, none) diff --git a/src/components/ha-faded.ts b/src/components/ha-faded.ts index 445c703c16..e7ed046db0 100644 --- a/src/components/ha-faded.ts +++ b/src/components/ha-faded.ts @@ -63,11 +63,6 @@ class HaFaded extends LitElement { } .faded { cursor: pointer; - -webkit-mask-image: linear-gradient( - to bottom, - black 25%, - transparent 100% - ); mask-image: linear-gradient(to bottom, black 25%, transparent 100%); overflow-y: hidden; } diff --git a/src/components/ha-markdown.ts b/src/components/ha-markdown.ts index 0ae4af0674..b5134e7ba0 100644 --- a/src/components/ha-markdown.ts +++ b/src/components/ha-markdown.ts @@ -53,9 +53,7 @@ export class HaMarkdown extends LitElement { display: block; } ha-markdown-element { - -ms-user-select: text; - -webkit-user-select: text; - -moz-user-select: text; + user-select: text; } ha-markdown-element > *:first-child { margin-top: 0; diff --git a/src/components/ha-sidebar.ts b/src/components/ha-sidebar.ts index 0987f7f0e0..8787f80b57 100644 --- a/src/components/ha-sidebar.ts +++ b/src/components/ha-sidebar.ts @@ -12,7 +12,6 @@ import { customElement, property, query, state } from "lit/decorators"; import { classMap } from "lit/directives/class-map"; import memoizeOne from "memoize-one"; import { fireEvent } from "../common/dom/fire_event"; -import { toggleAttribute } from "../common/dom/toggle_attribute"; import { stringCompare } from "../common/string/compare"; import { computeRTL } from "../common/util/compute_rtl"; import { throttle } from "../common/util/throttle"; @@ -296,7 +295,7 @@ class HaSidebar extends SubscribeMixin(ScrollableFadeMixin(LitElement)) { protected updated(changedProps: PropertyValues) { super.updated(changedProps); if (changedProps.has("alwaysExpand")) { - toggleAttribute(this, "expanded", this.alwaysExpand); + this.toggleAttribute("expanded", this.alwaysExpand); } if (!changedProps.has("hass")) { return; @@ -665,9 +664,7 @@ class HaSidebar extends SubscribeMixin(ScrollableFadeMixin(LitElement)) { flex-direction: column; overflow: hidden; overscroll-behavior: contain; - -ms-user-select: none; - -webkit-user-select: none; - -moz-user-select: none; + user-select: none; background-color: var(--sidebar-background-color); width: 100%; box-sizing: border-box; @@ -897,7 +894,6 @@ class HaSidebar extends SubscribeMixin(ScrollableFadeMixin(LitElement)) { } .menu ha-icon-button { - -webkit-transform: scaleX(var(--scale-direction)); transform: scaleX(var(--scale-direction)); } diff --git a/src/components/map/ha-map.ts b/src/components/map/ha-map.ts index b1c8c9f734..b35901ae57 100644 --- a/src/components/map/ha-map.ts +++ b/src/components/map/ha-map.ts @@ -914,8 +914,6 @@ export class HaMap extends ReactiveElement { #map.clickable:active, #map:active { cursor: grabbing; - cursor: -moz-grabbing; - cursor: -webkit-grabbing; } /* Only the raster fallback is inverted for dark mode, the vector style ships its own dark cartography. */ diff --git a/src/components/trace/hat-trace-timeline.ts b/src/components/trace/hat-trace-timeline.ts index bf3ea96652..b5cd83ebdb 100644 --- a/src/components/trace/hat-trace-timeline.ts +++ b/src/components/trace/hat-trace-timeline.ts @@ -15,7 +15,6 @@ import { ifDefined } from "lit/directives/if-defined"; import { formatDateTimeWithSeconds } from "../../common/datetime/format_date_time"; import { relativeTime } from "../../common/datetime/relative_time"; import { fireEvent } from "../../common/dom/fire_event"; -import { toggleAttribute } from "../../common/dom/toggle_attribute"; import { fullEntitiesContext } from "../../data/context"; import type { EntityRegistryEntry } from "../../data/entity/entity_registry"; import type { LogbookEntry } from "../../data/logbook"; @@ -870,7 +869,7 @@ export class HaAutomationTracer extends LitElement { this.shadowRoot!.querySelectorAll( "ha-timeline[data-path]" ).forEach((el) => { - toggleAttribute(el, "selected", this.selectedPath === el.dataset.path); + el.toggleAttribute("selected", this.selectedPath === el.dataset.path); if (!this.allowPick || el.tabIndex === 0) { return; } diff --git a/src/data/panel_custom.ts b/src/data/panel_custom.ts index 4edb3bee6d..81cc8e294e 100644 --- a/src/data/panel_custom.ts +++ b/src/data/panel_custom.ts @@ -6,7 +6,6 @@ export interface CustomPanelConfig { trust_external: boolean; js_url?: string; module_url?: string; - html_url?: string; // When true, the panel takes care of the safe-area insets itself (e.g. it // consumes the `--safe-area-inset-*` variables or draws into the safe area on // purpose). Home Assistant then skips adding its own safe-area padding around diff --git a/src/dialogs/more-info/components/ha-more-info-control-select-container.ts b/src/dialogs/more-info/components/ha-more-info-control-select-container.ts index 468a79bab7..0ec3bfa946 100644 --- a/src/dialogs/more-info/components/ha-more-info-control-select-container.ts +++ b/src/dialogs/more-info/components/ha-more-info-control-select-container.ts @@ -35,7 +35,6 @@ export class HaMoreInfoControlSelectContainer extends LitElement { gap: var(--ha-space-3); margin: auto; overflow: auto; - -ms-overflow-style: none; /* IE and Edge */ scrollbar-width: none; /* Firefox */ margin: -2px calc(var(--ha-space-6) * -1); padding: 2px var(--ha-space-6); diff --git a/src/dialogs/more-info/components/ha-more-info-state-header.ts b/src/dialogs/more-info/components/ha-more-info-state-header.ts index 387e200f87..1c35f4ed92 100644 --- a/src/dialogs/more-info/components/ha-more-info-state-header.ts +++ b/src/dialogs/more-info/components/ha-more-info-state-header.ts @@ -111,7 +111,6 @@ export class HaMoreInfoStateHeader extends LitElement { padding: var(--ha-space-1) 0; cursor: pointer; user-select: none; - -webkit-user-select: none; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); } `; diff --git a/src/dialogs/more-info/components/lights/light-color-rgb-picker.ts b/src/dialogs/more-info/components/lights/light-color-rgb-picker.ts index e7f0c12e90..03df49508b 100644 --- a/src/dialogs/more-info/components/lights/light-color-rgb-picker.ts +++ b/src/dialogs/more-info/components/lights/light-color-rgb-picker.ts @@ -483,8 +483,6 @@ class LightRgbColorPicker extends LitElement { input[type="color"] { appearance: none; - -webkit-appearance: none; - -moz-appearance: none; border: none; outline: none; display: block; diff --git a/src/dialogs/more-info/components/lights/light-color-temp-picker.ts b/src/dialogs/more-info/components/lights/light-color-temp-picker.ts index 9cccbacf07..8d2cae5f7e 100644 --- a/src/dialogs/more-info/components/lights/light-color-temp-picker.ts +++ b/src/dialogs/more-info/components/lights/light-color-temp-picker.ts @@ -191,8 +191,8 @@ class LightColorTempPicker extends LitElement { --control-slider-thickness: 130px; --control-slider-border-radius: var(--ha-border-radius-6xl); --control-slider-color: var(--primary-color); - --control-slider-background: -webkit-linear-gradient( - top, + --control-slider-background: linear-gradient( + to bottom, var(--gradient) ); --control-slider-tooltip-font-size: var(--ha-font-size-xl); diff --git a/src/dialogs/more-info/components/vacuum/ha-more-info-view-vacuum-clean-areas.ts b/src/dialogs/more-info/components/vacuum/ha-more-info-view-vacuum-clean-areas.ts index f8c73026c1..3e3caf997a 100644 --- a/src/dialogs/more-info/components/vacuum/ha-more-info-view-vacuum-clean-areas.ts +++ b/src/dialogs/more-info/components/vacuum/ha-more-info-view-vacuum-clean-areas.ts @@ -362,7 +362,6 @@ export class HaMoreInfoViewVacuumCleanAreas extends LitElement { border: 1px solid var(--divider-color); cursor: pointer; user-select: none; - -webkit-user-select: none; -webkit-tap-highlight-color: transparent; overflow: hidden; min-height: 80px; diff --git a/src/dialogs/notifications/notification-item-template.ts b/src/dialogs/notifications/notification-item-template.ts index 978de1f4a6..497f916756 100644 --- a/src/dialogs/notifications/notification-item-template.ts +++ b/src/dialogs/notifications/notification-item-template.ts @@ -18,9 +18,6 @@ export class HuiNotificationItemTemplate extends LitElement { static styles = css` .contents { padding: 16px; - -ms-user-select: text; - -webkit-user-select: text; - -moz-user-select: text; user-select: text; } diff --git a/src/entrypoints/custom-panel.ts b/src/entrypoints/custom-panel.ts index 2633cedaca..267c2d3053 100644 --- a/src/entrypoints/custom-panel.ts +++ b/src/entrypoints/custom-panel.ts @@ -2,8 +2,6 @@ import type { Connection } from "home-assistant-js-websocket"; import type { CSSResult } from "lit"; import { fireEvent } from "../common/dom/fire_event"; import { isNavigationClick } from "../common/dom/is-navigation-click"; -import { loadJS } from "../common/dom/load_resource"; -import { webComponentsSupported } from "../common/feature-detect/support-web-components"; import { navigate } from "../common/navigate"; import type { CustomPanelInfo } from "../data/panel_custom"; import { baseEntrypointStyles } from "../resources/styles"; @@ -12,23 +10,6 @@ import { dropRealmCollections } from "../util/custom-panel/drop-realm-collection import { loadCustomPanel } from "../util/custom-panel/load-custom-panel"; import { setCustomPanelProperties } from "../util/custom-panel/set-custom-panel-properties"; -declare global { - interface Window { - loadES5Adapter: () => Promise; - } -} - -let es5Loaded: Promise | undefined; - -window.loadES5Adapter = () => { - if (!es5Loaded) { - es5Loaded = loadJS( - `${__STATIC_PATH__}polyfills/custom-elements-es5-adapter.js` - ).catch(); // Swallow errors as it raises errors on old browsers. - } - return es5Loaded; -}; - let panelEl: HTMLElement | undefined; let initialized = false; // Kept so we can clean up after ourselves on pagehide without depending on @@ -66,68 +47,49 @@ function initialize( document.head.appendChild(style); const config = panel.config._panel_custom; - let start: Promise = Promise.resolve(); - if (!webComponentsSupported) { - start = start.then(() => { - loadJS(`${__STATIC_PATH__}polyfills/webcomponents-bundle.js`); - loadJS(`${__STATIC_PATH__}polyfills/lit-polyfill-support.js`); - }); - } + loadCustomPanel(config).then( + () => { + panelEl = createCustomPanelElement(config); - if (__BUILD__ === "legacy") { - start = start.then(() => window.loadES5Adapter()); - } - - start - .then(() => loadCustomPanel(config)) - // If our element is using es5, let it finish loading that and define element - // This avoids elements getting upgraded after being added to the DOM - .then(() => es5Loaded || Promise.resolve()) - .then( - () => { - panelEl = createCustomPanelElement(config); - - const forwardEvent = (ev) => { - if (window.parent.customPanel) { - fireEvent(window.parent.customPanel, ev.type, ev.detail); - } - }; - panelEl!.addEventListener("hass-toggle-menu", forwardEvent); - window.addEventListener("location-changed", (ev: any) => { - if (window.parent.customPanel) { - window.parent.customPanel.navigate( - window.location.pathname, - ev.detail - ); - } - }); - setProperties({ panel, ...properties }); - document.body.appendChild(panelEl!); - }, - (err) => { - // eslint-disable-next-line - console.error(err, panel); - let errorScreen; - if (panel.url_path === "hassio") { - import("../layouts/supervisor-error-screen"); - errorScreen = document.createElement( - "supervisor-error-screen" - ) as any; - } else { - import("../layouts/hass-error-screen"); - errorScreen = document.createElement("hass-error-screen") as any; - errorScreen.error = `Unable to load the panel source: ${err}.`; + const forwardEvent = (ev) => { + if (window.parent.customPanel) { + fireEvent(window.parent.customPanel, ev.type, ev.detail); } - - const errorStyle = document.createElement("style"); - errorStyle.innerHTML = (baseEntrypointStyles as CSSResult).cssText; - document.body.appendChild(errorStyle); - - errorScreen.hass = properties.hass; - document.body.appendChild(errorScreen); + }; + panelEl!.addEventListener("hass-toggle-menu", forwardEvent); + window.addEventListener("location-changed", (ev: any) => { + if (window.parent.customPanel) { + window.parent.customPanel.navigate( + window.location.pathname, + ev.detail + ); + } + }); + setProperties({ panel, ...properties }); + document.body.appendChild(panelEl!); + }, + (err) => { + // eslint-disable-next-line + console.error(err, panel); + let errorScreen; + if (panel.url_path === "hassio") { + import("../layouts/supervisor-error-screen"); + errorScreen = document.createElement("supervisor-error-screen") as any; + } else { + import("../layouts/hass-error-screen"); + errorScreen = document.createElement("hass-error-screen") as any; + errorScreen.error = `Unable to load the panel source: ${err}.`; } - ); + + const errorStyle = document.createElement("style"); + errorStyle.innerHTML = (baseEntrypointStyles as CSSResult).cssText; + document.body.appendChild(errorStyle); + + errorScreen.hass = properties.hass; + document.body.appendChild(errorScreen); + } + ); document.body.addEventListener("click", (ev) => { const href = isNavigationClick(ev); diff --git a/src/html/_js_base.html.template b/src/html/_js_base.html.template index 356a4fc6fc..8c4baa3612 100644 --- a/src/html/_js_base.html.template +++ b/src/html/_js_base.html.template @@ -7,10 +7,6 @@ script.src = src; return document.head.appendChild(script); } - if (!("attachShadow" in Element.prototype)) { - _ls("/static/polyfills/webcomponents-bundle.js", true); - _ls("/static/polyfills/lit-polyfill-support.js", true); - } // Modern browsers are detected primarily using the user agent string. // A feature detection which roughly lines up with the modern targets is used // as a fallback to guard against spoofs. It should be updated periodically. diff --git a/src/layouts/hass-tabs-subpage-data-table.ts b/src/layouts/hass-tabs-subpage-data-table.ts index ad3ae94f2a..2af018b1ec 100644 --- a/src/layouts/hass-tabs-subpage-data-table.ts +++ b/src/layouts/hass-tabs-subpage-data-table.ts @@ -884,7 +884,6 @@ export class HaTabsSubpageDataTable extends KeyboardShortcutMixin(LitElement) { padding: 0 16px; box-sizing: border-box; overflow-x: scroll; - -ms-overflow-style: none; scrollbar-width: none; } diff --git a/src/layouts/home-assistant-main.ts b/src/layouts/home-assistant-main.ts index fe3deeddfe..9904836df1 100644 --- a/src/layouts/home-assistant-main.ts +++ b/src/layouts/home-assistant-main.ts @@ -5,7 +5,6 @@ import { customElement, property, state } from "lit/decorators"; import type { HASSDomEvent } from "../common/dom/fire_event"; import { fireEvent } from "../common/dom/fire_event"; import { listenMediaQuery } from "../common/dom/media_query"; -import { toggleAttribute } from "../common/dom/toggle_attribute"; import { computeRTLDirection } from "../common/util/compute_rtl"; import "../components/ha-drawer"; import { narrowViewportContext } from "../data/context"; @@ -141,10 +140,9 @@ export class HomeAssistantMain extends LitElement { protected updated(changedProps: PropertyValues) { super.updated(changedProps); - toggleAttribute(this, "expanded", this.hass.dockedSidebar === "docked"); + this.toggleAttribute("expanded", this.hass.dockedSidebar === "docked"); - toggleAttribute( - this, + this.toggleAttribute( "modal", this._sidebarNarrow || this._externalSidebar || this.hass.kioskMode ); diff --git a/src/onboarding/onboarding-loading.ts b/src/onboarding/onboarding-loading.ts index 38a3d93b0f..c55bf5e940 100644 --- a/src/onboarding/onboarding-loading.ts +++ b/src/onboarding/onboarding-loading.ts @@ -25,29 +25,14 @@ class OnboardingLoading extends LitElement { border-right: 1.1em solid rgba(3, 169, 244, 0.2); border-bottom: 1.1em solid rgba(3, 169, 244, 0.2); border-left: 1.1em solid rgb(3, 168, 244); - -webkit-transform: translateZ(0); - -ms-transform: translateZ(0); transform: translateZ(0); - -webkit-animation: load8 1.4s infinite linear; animation: load8 1.4s infinite linear; } - @-webkit-keyframes load8 { - 0% { - -webkit-transform: rotate(0deg); - transform: rotate(0deg); - } - 100% { - -webkit-transform: rotate(360deg); - transform: rotate(360deg); - } - } @keyframes load8 { 0% { - -webkit-transform: rotate(0deg); transform: rotate(0deg); } 100% { - -webkit-transform: rotate(360deg); transform: rotate(360deg); } } diff --git a/src/panels/climate/ha-panel-climate.ts b/src/panels/climate/ha-panel-climate.ts index c81f4e27f2..48dbdda872 100644 --- a/src/panels/climate/ha-panel-climate.ts +++ b/src/panels/climate/ha-panel-climate.ts @@ -151,9 +151,7 @@ class PanelClimate extends LitElement { haStyle, css` :host { - -ms-user-select: none; - -webkit-user-select: none; - -moz-user-select: none; + user-select: none; } hui-view-container { position: relative; diff --git a/src/panels/config/cloud/account/dialog-cloud-support-package.ts b/src/panels/config/cloud/account/dialog-cloud-support-package.ts index 226acb7090..6a22448466 100644 --- a/src/panels/config/cloud/account/dialog-cloud-support-package.ts +++ b/src/panels/config/cloud/account/dialog-cloud-support-package.ts @@ -151,7 +151,6 @@ export class DialogSupportPackage extends LitElement { } table > tbody > tr { - -webkit-transition: background-color 0.25s ease; transition: background-color 0.25s ease; } diff --git a/src/panels/config/helpers/forms/ha-schedule-form.ts b/src/panels/config/helpers/forms/ha-schedule-form.ts index ce4589d112..733291b905 100644 --- a/src/panels/config/helpers/forms/ha-schedule-form.ts +++ b/src/panels/config/helpers/forms/ha-schedule-form.ts @@ -434,8 +434,6 @@ class HaScheduleForm extends LitElement { margin: var(--ha-space-2) 0; height: 450px; width: 100%; - -webkit-user-select: none; - -ms-user-select: none; user-select: none; --fc-border-color: var(--divider-color); --fc-event-border-color: var(--divider-color); diff --git a/src/panels/config/integrations/integration-panels/mqtt/mqtt-config-panel.ts b/src/panels/config/integrations/integration-panels/mqtt/mqtt-config-panel.ts index 995583fe2a..c979532cde 100644 --- a/src/panels/config/integrations/integration-panels/mqtt/mqtt-config-panel.ts +++ b/src/panels/config/integrations/integration-panels/mqtt/mqtt-config-panel.ts @@ -377,9 +377,7 @@ export class MQTTConfigPanel extends LitElement { haStyle, css` :host { - -ms-user-select: initial; - -webkit-user-select: initial; - -moz-user-select: initial; + user-select: initial; } .nav-card { diff --git a/src/panels/config/logs/ha-config-logs.ts b/src/panels/config/logs/ha-config-logs.ts index 686aedabd3..cecfd06105 100644 --- a/src/panels/config/logs/ha-config-logs.ts +++ b/src/panels/config/logs/ha-config-logs.ts @@ -344,9 +344,7 @@ export class HaConfigLogs extends LitElement { haStyle, css` :host { - -ms-user-select: initial; - -webkit-user-select: initial; - -moz-user-select: initial; + user-select: initial; } .search { position: sticky; diff --git a/src/panels/config/tools/event/tools-event.ts b/src/panels/config/tools/event/tools-event.ts index afcde634ba..dc41df8726 100644 --- a/src/panels/config/tools/event/tools-event.ts +++ b/src/panels/config/tools/event/tools-event.ts @@ -163,9 +163,7 @@ class HaPanelDevEvent extends LitElement { } :host { - -ms-user-select: initial; - -webkit-user-select: initial; - -moz-user-select: initial; + user-select: initial; display: block; height: 100%; } diff --git a/src/panels/config/tools/state/tools-state.ts b/src/panels/config/tools/state/tools-state.ts index 525a396510..039046bf50 100644 --- a/src/panels/config/tools/state/tools-state.ts +++ b/src/panels/config/tools/state/tools-state.ts @@ -650,9 +650,7 @@ class HaPanelDevState extends LitElement { haStyle, css` :host { - -ms-user-select: initial; - -webkit-user-select: initial; - -moz-user-select: initial; + user-select: initial; display: block; padding: var(--ha-space-4); } diff --git a/src/panels/config/tools/statistics/tools-statistics.ts b/src/panels/config/tools/statistics/tools-statistics.ts index cc472db83f..2c3ab86548 100644 --- a/src/panels/config/tools/statistics/tools-statistics.ts +++ b/src/panels/config/tools/statistics/tools-statistics.ts @@ -865,7 +865,6 @@ class HaPanelDevStatistics extends KeyboardShortcutMixin(LitElement) { gap: var(--ha-space-4); padding: 0 var(--ha-space-4); overflow-x: scroll; - -ms-overflow-style: none; scrollbar-width: none; } diff --git a/src/panels/energy/ha-panel-energy.ts b/src/panels/energy/ha-panel-energy.ts index c04f10e821..824371d77e 100644 --- a/src/panels/energy/ha-panel-energy.ts +++ b/src/panels/energy/ha-panel-energy.ts @@ -196,9 +196,7 @@ class PanelEnergy extends LitElement { css` :host { --ha-view-sections-column-max-width: 100%; - -ms-user-select: none; - -webkit-user-select: none; - -moz-user-select: none; + user-select: none; } .centered { width: 100%; diff --git a/src/panels/light/ha-panel-light.ts b/src/panels/light/ha-panel-light.ts index 9382b7e9a2..f8a37fc26e 100644 --- a/src/panels/light/ha-panel-light.ts +++ b/src/panels/light/ha-panel-light.ts @@ -151,9 +151,7 @@ class PanelLight extends LitElement { haStyle, css` :host { - -ms-user-select: none; - -webkit-user-select: none; - -moz-user-select: none; + user-select: none; } hui-view-container { position: relative; diff --git a/src/panels/lovelace/card-features/hui-cover-tilt-position-card-feature.ts b/src/panels/lovelace/card-features/hui-cover-tilt-position-card-feature.ts index 236015121b..e66a824d34 100644 --- a/src/panels/lovelace/card-features/hui-cover-tilt-position-card-feature.ts +++ b/src/panels/lovelace/card-features/hui-cover-tilt-position-card-feature.ts @@ -171,7 +171,7 @@ class HuiCoverTiltPositionCardFeature cardFeatureStyles, css` .gradient { - background: -webkit-linear-gradient(left, ${GRADIENT}); + background: linear-gradient(to right, ${GRADIENT}); opacity: 0.6; } `, diff --git a/src/panels/lovelace/card-features/hui-light-color-temp-card-feature.ts b/src/panels/lovelace/card-features/hui-light-color-temp-card-feature.ts index 6116346458..f7ff10e8df 100644 --- a/src/panels/lovelace/card-features/hui-light-color-temp-card-feature.ts +++ b/src/panels/lovelace/card-features/hui-light-color-temp-card-feature.ts @@ -159,8 +159,8 @@ class HuiLightColorTempCardFeature cardFeatureStyles, css` ha-control-slider { - --control-slider-background: -webkit-linear-gradient( - left, + --control-slider-background: linear-gradient( + to right, var(--gradient) ); --control-slider-background-opacity: 1; diff --git a/src/panels/lovelace/cards/hui-heading-card.ts b/src/panels/lovelace/cards/hui-heading-card.ts index 97ec43c381..b2bd43768d 100644 --- a/src/panels/lovelace/cards/hui-heading-card.ts +++ b/src/panels/lovelace/cards/hui-heading-card.ts @@ -214,7 +214,6 @@ export class HuiHeadingCard extends LitElement implements LovelaceCard { ha-card { background: none; backdrop-filter: none; - -webkit-backdrop-filter: none; border: none; box-shadow: none; padding: 0; diff --git a/src/panels/lovelace/cards/hui-light-card.ts b/src/panels/lovelace/cards/hui-light-card.ts index 2fac6faa8d..5507db9a75 100644 --- a/src/panels/lovelace/cards/hui-light-card.ts +++ b/src/panels/lovelace/cards/hui-light-card.ts @@ -332,8 +332,6 @@ export class HuiLightCard extends LitElement implements LovelaceCard { font-size: var(--brightness-font-size); opacity: 0; transition: opacity 0.5s ease-in-out; - -moz-transition: opacity 0.5s ease-in-out; - -webkit-transition: opacity 0.5s ease-in-out; } .show_brightness { diff --git a/src/panels/lovelace/cards/hui-toggle-group-card.ts b/src/panels/lovelace/cards/hui-toggle-group-card.ts index 72e3fda661..0807924a22 100644 --- a/src/panels/lovelace/cards/hui-toggle-group-card.ts +++ b/src/panels/lovelace/cards/hui-toggle-group-card.ts @@ -143,7 +143,6 @@ export class HuiToggleGroupCard extends LitElement implements LovelaceCard { ha-card { background: none; backdrop-filter: none; - -webkit-backdrop-filter: none; border: none; box-shadow: none; height: 100%; diff --git a/src/panels/lovelace/components/hui-energy-period-selector.ts b/src/panels/lovelace/components/hui-energy-period-selector.ts index 33393fd915..6d8b9ccc8e 100644 --- a/src/panels/lovelace/components/hui-energy-period-selector.ts +++ b/src/panels/lovelace/components/hui-energy-period-selector.ts @@ -852,10 +852,6 @@ export class HuiEnergyPeriodSelector extends SubscribeMixin(LitElement) { right: 0; bottom: 0; z-index: var(--dialog-z-index, 8); - -webkit-backdrop-filter: var( - --ha-dialog-scrim-backdrop-filter, - var(--dialog-backdrop-filter) - ); backdrop-filter: var( --ha-dialog-scrim-backdrop-filter, var(--dialog-backdrop-filter) diff --git a/src/panels/lovelace/components/hui-generic-entity-row.ts b/src/panels/lovelace/components/hui-generic-entity-row.ts index 2132911872..c699c9de7b 100644 --- a/src/panels/lovelace/components/hui-generic-entity-row.ts +++ b/src/panels/lovelace/components/hui-generic-entity-row.ts @@ -5,7 +5,6 @@ import { classMap } from "lit/directives/class-map"; import { ifDefined } from "lit/directives/if-defined"; import { DOMAINS_INPUT_ROW } from "../../../common/const"; import { stopPropagation } from "../../../common/dom/stop_propagation"; -import { toggleAttribute } from "../../../common/dom/toggle_attribute"; import { computeDomain } from "../../../common/entity/compute_domain"; import "../../../components/entity/state-badge"; import "../../../components/ha-relative-time"; @@ -134,8 +133,7 @@ export class HuiGenericEntityRow extends LitElement { protected updated(changedProps: PropertyValues): void { super.updated(changedProps); - toggleAttribute( - this, + this.toggleAttribute( "no-secondary", !this.secondaryText && !this.config?.secondary_info ); diff --git a/src/panels/lovelace/elements/hui-image-element.ts b/src/panels/lovelace/elements/hui-image-element.ts index fd6baaf6d6..8547c91450 100644 --- a/src/panels/lovelace/elements/hui-image-element.ts +++ b/src/panels/lovelace/elements/hui-image-element.ts @@ -95,7 +95,7 @@ export class HuiImageElement extends LitElement implements LovelaceElement { -webkit-touch-callout: none !important; } hui-image { - -webkit-user-select: none !important; + user-select: none !important; pointer-events: none; } div:focus { diff --git a/src/panels/lovelace/hui-root.ts b/src/panels/lovelace/hui-root.ts index 8eeca3a3c8..238b44ea93 100644 --- a/src/panels/lovelace/hui-root.ts +++ b/src/panels/lovelace/hui-root.ts @@ -1336,9 +1336,7 @@ class HUIRoot extends LitElement { haStyle, css` :host { - -ms-user-select: none; - -webkit-user-select: none; - -moz-user-select: none; + user-select: none; } .header { background-color: var(--app-header-background-color); @@ -1351,7 +1349,6 @@ class HUIRoot extends LitElement { 0px ) ); - -webkit-backdrop-filter: var(--app-header-backdrop-filter, none); backdrop-filter: var(--app-header-backdrop-filter, none); padding-top: var(--safe-area-inset-top); padding-right: var(--safe-area-inset-right); diff --git a/src/panels/maintenance/ha-panel-maintenance.ts b/src/panels/maintenance/ha-panel-maintenance.ts index 2db35e7490..a63fb68276 100644 --- a/src/panels/maintenance/ha-panel-maintenance.ts +++ b/src/panels/maintenance/ha-panel-maintenance.ts @@ -151,9 +151,7 @@ class PanelMaintenance extends LitElement { haStyle, css` :host { - -ms-user-select: none; - -webkit-user-select: none; - -moz-user-select: none; + user-select: none; } hui-view-container { position: relative; diff --git a/src/panels/profile/ha-profile-dashboard.ts b/src/panels/profile/ha-profile-dashboard.ts index 9220edd774..a44ba48fa3 100644 --- a/src/panels/profile/ha-profile-dashboard.ts +++ b/src/panels/profile/ha-profile-dashboard.ts @@ -140,9 +140,7 @@ class HaProfileDashboard extends LitElement { haStyle, css` :host { - -ms-user-select: initial; - -webkit-user-select: initial; - -moz-user-select: initial; + user-select: initial; } .container { diff --git a/src/panels/profile/ha-profile-section-browser.ts b/src/panels/profile/ha-profile-section-browser.ts index 813edaa3c3..7e84b263b2 100644 --- a/src/panels/profile/ha-profile-section-browser.ts +++ b/src/panels/profile/ha-profile-section-browser.ts @@ -98,9 +98,7 @@ class HaProfileSectionBrowser extends LitElement { haStyle, css` :host { - -ms-user-select: initial; - -webkit-user-select: initial; - -moz-user-select: initial; + user-select: initial; } .container { diff --git a/src/panels/profile/ha-profile-section-localization.ts b/src/panels/profile/ha-profile-section-localization.ts index ef9fa066ae..a67368ac99 100644 --- a/src/panels/profile/ha-profile-section-localization.ts +++ b/src/panels/profile/ha-profile-section-localization.ts @@ -72,9 +72,7 @@ class HaProfileSectionLocalization extends LitElement { haStyle, css` :host { - -ms-user-select: initial; - -webkit-user-select: initial; - -moz-user-select: initial; + user-select: initial; } .container { diff --git a/src/panels/profile/ha-profile-section-preferences.ts b/src/panels/profile/ha-profile-section-preferences.ts index 07470ecde7..8575f21eb0 100644 --- a/src/panels/profile/ha-profile-section-preferences.ts +++ b/src/panels/profile/ha-profile-section-preferences.ts @@ -130,9 +130,7 @@ class HaProfileSectionPreferences extends LitElement { haStyle, css` :host { - -ms-user-select: initial; - -webkit-user-select: initial; - -moz-user-select: initial; + user-select: initial; } .container { diff --git a/src/panels/profile/ha-profile-section-security.ts b/src/panels/profile/ha-profile-section-security.ts index 444b5fdf38..4d592423f6 100644 --- a/src/panels/profile/ha-profile-section-security.ts +++ b/src/panels/profile/ha-profile-section-security.ts @@ -85,9 +85,7 @@ class HaProfileSectionSecurity extends LitElement { haStyle, css` :host { - -ms-user-select: initial; - -webkit-user-select: initial; - -moz-user-select: initial; + user-select: initial; } .container { diff --git a/src/panels/security/ha-panel-security.ts b/src/panels/security/ha-panel-security.ts index 72be3f38b9..a5765e67f8 100644 --- a/src/panels/security/ha-panel-security.ts +++ b/src/panels/security/ha-panel-security.ts @@ -249,9 +249,7 @@ class PanelSecurity extends LitElement { haStyle, css` :host { - -ms-user-select: none; - -webkit-user-select: none; - -moz-user-select: none; + user-select: none; } hui-view-container { position: relative; diff --git a/src/state-control/cover/ha-state-control-cover-tilt-position.ts b/src/state-control/cover/ha-state-control-cover-tilt-position.ts index 10554ccc76..2d371dc184 100644 --- a/src/state-control/cover/ha-state-control-cover-tilt-position.ts +++ b/src/state-control/cover/ha-state-control-cover-tilt-position.ts @@ -137,7 +137,7 @@ export class HaStateControlInfoCoverTiltPosition extends LitElement { --control-slider-tooltip-font-size: var(--ha-font-size-xl); } .gradient { - background: -webkit-linear-gradient(top, ${GRADIENT}); + background: linear-gradient(to bottom, ${GRADIENT}); opacity: 0.6; } `; diff --git a/src/types.ts b/src/types.ts index 1f370c49c9..82eb47992e 100644 --- a/src/types.ts +++ b/src/types.ts @@ -43,15 +43,6 @@ declare global { interface Window { // Custom panel entry point url customPanelJS: string; - ShadyCSS: { - nativeCss: boolean; - nativeShadow: boolean; - prepareTemplate(templateElement, elementName, elementExtension); - styleElement(element); - styleSubtree(element, overrideProperties); - styleDocument(overrideProperties); - getComputedStyleValue(element, propertyName); - }; } // for fire event diff --git a/src/util/custom-panel/create-custom-panel-element.ts b/src/util/custom-panel/create-custom-panel-element.ts index d4a23699b4..15313b1578 100644 --- a/src/util/custom-panel/create-custom-panel-element.ts +++ b/src/util/custom-panel/create-custom-panel-element.ts @@ -1,8 +1,2 @@ -export const createCustomPanelElement = (panelConfig) => { - // Legacy support. Custom panels used to have to define element ha-panel-{name} - const tagName = - "html_url" in panelConfig - ? `ha-panel-${panelConfig.name}` - : panelConfig.name; - return document.createElement(tagName); -}; +export const createCustomPanelElement = (panelConfig) => + document.createElement(panelConfig.name); diff --git a/src/util/custom-panel/load-custom-panel.ts b/src/util/custom-panel/load-custom-panel.ts index 235d153d6e..a3accb1ecc 100644 --- a/src/util/custom-panel/load-custom-panel.ts +++ b/src/util/custom-panel/load-custom-panel.ts @@ -1,19 +1,12 @@ import { loadJS, loadModule } from "../../common/dom/load_resource"; import type { CustomPanelConfig } from "../../data/panel_custom"; -// Make sure we only import every JS-based panel once (HTML import has this built-in) +// Make sure we only import every JS-based panel once const JS_CACHE = {}; export const getUrl = ( panelConfig: CustomPanelConfig -): { type: "module" | "html" | "js"; url: string } => { - if (panelConfig.html_url) { - return { - type: "html", - url: panelConfig.html_url, - }; - } - +): { type: "module" | "js"; url: string } => { // if both module and JS provided, base url on frontend build if (panelConfig.module_url && panelConfig.js_url) { if (__BUILD__ === "modern") { @@ -53,8 +46,5 @@ export const loadCustomPanel = ( } return JS_CACHE[panelSource.url]; } - if (panelSource.type === "module") { - return loadModule(panelSource.url); - } - return Promise.reject("No valid url found in panel config."); + return loadModule(panelSource.url); }; diff --git a/src/util/is_touch.ts b/src/util/is_touch.ts index d5a0ad1235..c13d499934 100644 --- a/src/util/is_touch.ts +++ b/src/util/is_touch.ts @@ -1,5 +1 @@ -export const isTouch = - "ontouchstart" in window || - navigator.maxTouchPoints > 0 || - // @ts-ignore - navigator.msMaxTouchPoints > 0; +export const isTouch = "ontouchstart" in window || navigator.maxTouchPoints > 0; diff --git a/yarn.lock b/yarn.lock index b811362701..5ca31e8ee9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6909,13 +6909,6 @@ __metadata: languageName: node linkType: hard -"@webcomponents/webcomponentsjs@npm:2.8.0": - version: 2.8.0 - resolution: "@webcomponents/webcomponentsjs@npm:2.8.0" - checksum: 10/acba7dce2cb60f0505369247ce54eeca3efbd386b98c6cc50d7d318090f551d753b20477038983d7ead9376669b4d702effca21a24c0a1b511d42b1ea53ee9a9 - languageName: node - linkType: hard - "@zeit/schemas@npm:2.36.0": version: 2.36.0 resolution: "@zeit/schemas@npm:2.36.0" @@ -8648,13 +8641,6 @@ __metadata: languageName: node linkType: hard -"dialog-polyfill@npm:0.5.6": - version: 0.5.6 - resolution: "dialog-polyfill@npm:0.5.6" - checksum: 10/42428793b04fd2e0a67dfb75838703488d7d05f73663c3251441ad6ed154b8dc71d65ed03d5a0ba4a83c6167c2e6f791cbe1574d0dca37dac1405ce3816033ca - languageName: node - linkType: hard - "didyoumean2@npm:4.1.0": version: 4.1.0 resolution: "didyoumean2@npm:4.1.0" @@ -10418,7 +10404,6 @@ __metadata: "@vitest/coverage-v8": "npm:4.1.11" "@vvo/tzdb": "npm:6.198.0" "@webcomponents/scoped-custom-element-registry": "npm:0.0.10" - "@webcomponents/webcomponentsjs": "npm:2.8.0" babel-loader: "npm:10.1.1" babel-plugin-polyfill-corejs3: "npm:1.0.0" barcode-detector: "npm:3.2.2" @@ -10434,7 +10419,6 @@ __metadata: deep-clone-simple: "npm:1.1.1" deep-freeze: "npm:0.0.1" del: "npm:8.0.1" - dialog-polyfill: "npm:0.5.6" echarts: "npm:6.1.0" echarts-extension-chart2music: "npm:0.1.1" element-internals-polyfill: "npm:3.0.2"