diff --git a/hassio/src/dialogs/snapshot/dialog-hassio-snapshot.ts b/hassio/src/dialogs/snapshot/dialog-hassio-snapshot.ts index 2fa53b66bf..81f21bb908 100755 --- a/hassio/src/dialogs/snapshot/dialog-hassio-snapshot.ts +++ b/hassio/src/dialogs/snapshot/dialog-hassio-snapshot.ts @@ -20,6 +20,7 @@ import { showAlertDialog, showConfirmationDialog, } from "../../../../src/dialogs/generic/show-dialog-box"; +import { HassDialog } from "../../../../src/dialogs/make-dialog-manager"; import { PolymerChangedEvent } from "../../../../src/polymer-types"; import { haStyle, haStyleDialog } from "../../../../src/resources/styles"; import { HomeAssistant } from "../../../../src/types"; @@ -68,7 +69,9 @@ interface FolderItem { } @customElement("dialog-hassio-snapshot") -class HassioSnapshotDialog extends LitElement { +class HassioSnapshotDialog + extends LitElement + implements HassDialog { @property({ attribute: false }) public hass!: HomeAssistant; @property({ attribute: false }) public supervisor?: Supervisor; @@ -106,12 +109,21 @@ class HassioSnapshotDialog extends LitElement { } } + public closeDialog() { + this._dialogParams = undefined; + this._snapshot = undefined; + this._snapshotPassword = ""; + this._folders = []; + this._addons = []; + fireEvent(this, "dialog-closed", { dialog: this.localName }); + } + protected render(): TemplateResult { if (!this._dialogParams || !this._snapshot) { return html``; } return html` - +
${this._computeName} @@ -359,7 +371,7 @@ class HassioSnapshotDialog extends LitElement { .then( () => { alert("Snapshot restored!"); - this._closeDialog(); + this.closeDialog(); }, (error) => { this._error = error.body.message; @@ -371,7 +383,7 @@ class HassioSnapshotDialog extends LitElement { method: "POST", body: JSON.stringify(data), }); - this._closeDialog(); + this.closeDialog(); } } @@ -410,7 +422,7 @@ class HassioSnapshotDialog extends LitElement { .then( () => { alert("Snapshot restored!"); - this._closeDialog(); + this.closeDialog(); }, (error) => { this._error = error.body.message; @@ -422,7 +434,7 @@ class HassioSnapshotDialog extends LitElement { method: "POST", body: JSON.stringify(data), }); - this._closeDialog(); + this.closeDialog(); } } @@ -445,7 +457,7 @@ class HassioSnapshotDialog extends LitElement { if (this._dialogParams!.onDelete) { this._dialogParams!.onDelete(); } - this._closeDialog(); + this.closeDialog(); }, (error) => { this._error = error.body.message; @@ -496,14 +508,6 @@ class HassioSnapshotDialog extends LitElement { private get _computeSize() { return Math.ceil(this._snapshot!.size * 10) / 10 + " MB"; } - - private _closeDialog() { - this._dialogParams = undefined; - this._snapshot = undefined; - this._snapshotPassword = ""; - this._folders = []; - this._addons = []; - } } declare global { diff --git a/hassio/src/entrypoint.ts b/hassio/src/entrypoint.ts index 24d3e45359..48c4a33180 100644 --- a/hassio/src/entrypoint.ts +++ b/hassio/src/entrypoint.ts @@ -15,5 +15,11 @@ body { padding: 0; height: 100vh; } +@media (prefers-color-scheme: dark) { + body { + background-color: #111111; + color: #e1e1e1; + } +} `; document.head.appendChild(styleEl); diff --git a/hassio/src/hassio-main.ts b/hassio/src/hassio-main.ts index c91a024347..6ee732b846 100644 --- a/hassio/src/hassio-main.ts +++ b/hassio/src/hassio-main.ts @@ -4,6 +4,7 @@ import { atLeastVersion } from "../../src/common/config/version"; import { applyThemesOnElement } from "../../src/common/dom/apply_themes_on_element"; import { fireEvent } from "../../src/common/dom/fire_event"; import { isNavigationClick } from "../../src/common/dom/is-navigation-click"; +import { mainWindow } from "../../src/common/dom/get_main_window"; import { navigate } from "../../src/common/navigate"; import { HassioPanelInfo } from "../../src/data/hassio/supervisor"; import { Supervisor } from "../../src/data/supervisor/supervisor"; @@ -50,7 +51,7 @@ export class HassioMain extends SupervisorBaseElement { // Joakim - April 26, 2021 // Due to changes in behavior in Google Chrome, we changed navigate to listen on the top element - top.addEventListener("location-changed", (ev) => + mainWindow.addEventListener("location-changed", (ev) => // @ts-ignore fireEvent(this, ev.type, ev.detail, { bubbles: false, diff --git a/src/common/dom/get_main_window.ts b/src/common/dom/get_main_window.ts new file mode 100644 index 0000000000..5bf9e2687b --- /dev/null +++ b/src/common/dom/get_main_window.ts @@ -0,0 +1,8 @@ +import { MAIN_WINDOW_NAME } from "../../data/main_window"; + +export const mainWindow = + window.name === MAIN_WINDOW_NAME + ? window + : parent.name === MAIN_WINDOW_NAME + ? parent + : top; diff --git a/src/common/navigate.ts b/src/common/navigate.ts index 7bbc589f29..662ad2bc1f 100644 --- a/src/common/navigate.ts +++ b/src/common/navigate.ts @@ -1,4 +1,5 @@ import { fireEvent } from "./dom/fire_event"; +import { mainWindow } from "./dom/get_main_window"; declare global { // for fire event @@ -12,24 +13,24 @@ declare global { export const navigate = (_node: any, path: string, replace = false) => { if (__DEMO__) { if (replace) { - top.history.replaceState( - top.history.state?.root ? { root: true } : null, + mainWindow.history.replaceState( + mainWindow.history.state?.root ? { root: true } : null, "", - `${top.location.pathname}#${path}` + `${mainWindow.location.pathname}#${path}` ); } else { - top.location.hash = path; + mainWindow.location.hash = path; } } else if (replace) { - top.history.replaceState( - top.history.state?.root ? { root: true } : null, + mainWindow.history.replaceState( + mainWindow.history.state?.root ? { root: true } : null, "", path ); } else { - top.history.pushState(null, "", path); + mainWindow.history.pushState(null, "", path); } - fireEvent(top, "location-changed", { + fireEvent(mainWindow, "location-changed", { replace, }); }; diff --git a/src/data/main_window.ts b/src/data/main_window.ts new file mode 100644 index 0000000000..2a6a6d3e30 --- /dev/null +++ b/src/data/main_window.ts @@ -0,0 +1 @@ +export const MAIN_WINDOW_NAME = "ha-main-window"; diff --git a/src/dialogs/make-dialog-manager.ts b/src/dialogs/make-dialog-manager.ts index 17475259ab..2acfe6473f 100644 --- a/src/dialogs/make-dialog-manager.ts +++ b/src/dialogs/make-dialog-manager.ts @@ -1,4 +1,5 @@ import { HASSDomEvent, ValidHassDomEvent } from "../common/dom/fire_event"; +import { mainWindow } from "../common/dom/get_main_window"; import { ProvideHassElement } from "../mixins/provide-hass-lit-mixin"; declare global { @@ -67,25 +68,26 @@ export const showDialog = async ( } if (addHistory) { - top.history.replaceState( + mainWindow.history.replaceState( { dialog: dialogTag, open: false, oldState: - top.history.state?.open && top.history.state?.dialog !== dialogTag - ? top.history.state + mainWindow.history.state?.open && + mainWindow.history.state?.dialog !== dialogTag + ? mainWindow.history.state : null, }, "" ); try { - top.history.pushState( + mainWindow.history.pushState( { dialog: dialogTag, dialogParams: dialogParams, open: true }, "" ); } catch (err) { // dialogParams could not be cloned, probably contains callback - top.history.pushState( + mainWindow.history.pushState( { dialog: dialogTag, dialogParams: null, open: true }, "" ); @@ -96,7 +98,10 @@ export const showDialog = async ( }; export const replaceDialog = () => { - top.history.replaceState({ ...top.history.state, replaced: true }, ""); + mainWindow.history.replaceState( + { ...mainWindow.history.state, replaced: true }, + "" + ); }; export const closeDialog = async (dialogTag: string): Promise => { diff --git a/src/entrypoints/core.ts b/src/entrypoints/core.ts index 87c6275449..964c2ca99c 100644 --- a/src/entrypoints/core.ts +++ b/src/entrypoints/core.ts @@ -25,6 +25,9 @@ import { subscribeUser } from "../data/ws-user"; import type { ExternalAuth } from "../external_app/external_auth"; import "../resources/safari-14-attachshadow-patch"; import { HomeAssistant } from "../types"; +import { MAIN_WINDOW_NAME } from "../data/main_window"; + +window.name = MAIN_WINDOW_NAME; declare global { interface Window { diff --git a/src/entrypoints/custom-panel.ts b/src/entrypoints/custom-panel.ts index 856946d33b..6d77428bbc 100644 --- a/src/entrypoints/custom-panel.ts +++ b/src/entrypoints/custom-panel.ts @@ -47,7 +47,13 @@ function initialize( ) { const style = document.createElement("style"); - style.innerHTML = "body{margin:0}"; + style.innerHTML = `body { margin:0; } + @media (prefers-color-scheme: dark) { + body { + background-color: #111111; + color: #e1e1e1; + } + }`; document.head.appendChild(style); const config = panel.config._panel_custom; diff --git a/src/state/url-sync-mixin.ts b/src/state/url-sync-mixin.ts index 7597004b53..684f9a79dc 100644 --- a/src/state/url-sync-mixin.ts +++ b/src/state/url-sync-mixin.ts @@ -1,6 +1,7 @@ /* eslint-disable no-console */ import { ReactiveElement } from "lit"; import { HASSDomEvent } from "../common/dom/fire_event"; +import { mainWindow } from "../common/dom/get_main_window"; import { closeDialog, DialogClosedParams, @@ -28,13 +29,16 @@ export const urlSyncMixin = < if (history.length === 1) { history.replaceState({ ...history.state, root: true }, ""); } - top.addEventListener("popstate", this._popstateChangeListener); + mainWindow.addEventListener("popstate", this._popstateChangeListener); this.addEventListener("dialog-closed", this._dialogClosedListener); } public disconnectedCallback(): void { super.disconnectedCallback(); - top.removeEventListener("popstate", this._popstateChangeListener); + mainWindow.removeEventListener( + "popstate", + this._popstateChangeListener + ); this.removeEventListener("dialog-closed", this._dialogClosedListener); } @@ -45,21 +49,21 @@ export const urlSyncMixin = < console.log("dialog closed", ev.detail.dialog); console.log( "open", - top.history.state?.open, + mainWindow.history.state?.open, "dialog", - top.history.state?.dialog + mainWindow.history.state?.dialog ); } // If not closed by navigating back, and not a new dialog is open, remove the open state from history if ( - top.history.state?.open && - top.history.state?.dialog === ev.detail.dialog + mainWindow.history.state?.open && + mainWindow.history.state?.dialog === ev.detail.dialog ) { if (DEBUG) { console.log("remove state", ev.detail.dialog); } this._ignoreNextPopState = true; - top.history.back(); + mainWindow.history.back(); } }; @@ -73,7 +77,7 @@ export const urlSyncMixin = < if (DEBUG) { console.log("remove old state", ev.state.oldState); } - top.history.back(); + mainWindow.history.back(); return; } this._ignoreNextPopState = false; @@ -98,7 +102,7 @@ export const urlSyncMixin = < console.log("dialog could not be closed"); } // dialog could not be closed, push state again - top.history.pushState( + mainWindow.history.pushState( { dialog: state.dialog, open: true,