Make chrome work-around work in iframes (#9200)

This commit is contained in:
Bram Kragten 2021-05-21 09:09:31 +02:00 committed by GitHub
parent 9328576b55
commit fd9bb4d8cc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 79 additions and 40 deletions

View File

@ -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<HassioSnapshotDialogParams> {
@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`
<ha-dialog open @closing=${this._closeDialog} .heading=${true}>
<ha-dialog open @closing=${this.closeDialog} .heading=${true}>
<div slot="heading">
<ha-header-bar>
<span slot="title"> ${this._computeName} </span>
@ -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 {

View File

@ -15,5 +15,11 @@ body {
padding: 0;
height: 100vh;
}
@media (prefers-color-scheme: dark) {
body {
background-color: #111111;
color: #e1e1e1;
}
}
`;
document.head.appendChild(styleEl);

View File

@ -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,

View File

@ -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;

View File

@ -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,
});
};

1
src/data/main_window.ts Normal file
View File

@ -0,0 +1 @@
export const MAIN_WINDOW_NAME = "ha-main-window";

View File

@ -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<boolean> => {

View File

@ -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 {

View File

@ -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;

View File

@ -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,