This commit is contained in:
Zack Arnett 2020-09-08 10:25:50 -05:00
commit 291983e4c3
24 changed files with 102 additions and 630 deletions

View File

@ -1,7 +1,12 @@
import { HassEntity } from "home-assistant-js-websocket";
import durationToSeconds from "../datetime/duration_to_seconds";
export const timerTimeRemaining = (stateObj: HassEntity) => {
export const timerTimeRemaining = (
stateObj: HassEntity
): undefined | number => {
if (!stateObj.attributes.remaining) {
return undefined;
}
let timeRemaining = durationToSeconds(stateObj.attributes.remaining);
if (stateObj.state === "active") {

View File

@ -176,6 +176,11 @@ class HaColorPicker extends EventsMixin(PolymerElement) {
this.drawColorWheel();
this.drawMarker();
if (this.desiredHsColor) {
this.setMarkerOnColor(this.desiredHsColor);
this.applyColorToCanvas(this.desiredHsColor);
}
this.interactionLayer.addEventListener("mousedown", (ev) =>
this.onMouseDown(ev)
);
@ -319,6 +324,9 @@ class HaColorPicker extends EventsMixin(PolymerElement) {
// set marker position to the given color
setMarkerOnColor(hs) {
if (!this.marker || !this.tooltip) {
return;
}
const dist = hs.s * this.radius;
const theta = ((hs.h - 180) / 180) * Math.PI;
const markerdX = -dist * Math.cos(theta);
@ -330,6 +338,9 @@ class HaColorPicker extends EventsMixin(PolymerElement) {
// apply given color to interface elements
applyColorToCanvas(hs) {
if (!this.interactionLayer) {
return;
}
// we're not really converting hs to hsl here, but we keep it cheap
// setting the color on the interactionLayer, the svg elements can inherit
this.interactionLayer.style.color = `hsl(${hs.h}, 100%, ${

View File

@ -322,7 +322,7 @@ class HaSidebar extends LitElement {
)}
href="#external-app-configuration"
tabindex="-1"
@click=${this._handleExternalAppConfiguration}
@panel-tap=${this._handleExternalAppConfiguration}
@mouseenter=${this._itemMouseEnter}
@mouseleave=${this._itemMouseLeave}
>
@ -479,7 +479,8 @@ class HaSidebar extends LitElement {
}
private async _handleAction(ev: CustomEvent<ActionHandlerDetail>) {
if (ev.detail.action !== "hold") {
if (ev.detail.action === "tap") {
fireEvent(ev.target as HTMLElement, "panel-tap");
return;
}
@ -497,6 +498,10 @@ class HaSidebar extends LitElement {
}
this._editMode = true;
if (!this.expanded) {
fireEvent(this, "hass-toggle-menu");
}
await this.updateComplete;
this._createSortable();
@ -655,8 +660,11 @@ class HaSidebar extends LitElement {
);
}
private _handlePanelTap(ev: Event) {
navigate(this, (ev.currentTarget as HTMLAnchorElement).href);
private async _handlePanelTap(ev: Event) {
const path = __DEMO__
? (ev.currentTarget as HTMLAnchorElement).getAttribute("href")!
: (ev.currentTarget as HTMLAnchorElement).href;
navigate(this, path);
}
private _renderPanel(
@ -668,10 +676,10 @@ class HaSidebar extends LitElement {
return html`
<a
aria-role="option"
href="${`/${urlPath}`}"
data-panel="${urlPath}"
href=${`/${urlPath}`}
data-panel=${urlPath}
tabindex="-1"
@tap=${this._handlePanelTap}
@panel-tap=${this._handlePanelTap}
@mouseenter=${this._itemMouseEnter}
@mouseleave=${this._itemMouseLeave}
>
@ -980,4 +988,8 @@ declare global {
interface HTMLElementTagNameMap {
"ha-sidebar": HaSidebar;
}
interface HASSDomEvents {
"panel-tap": undefined;
}
}

View File

@ -172,6 +172,7 @@ export class HaMediaPlayerBrowse extends LitElement {
<div
class="header ${classMap({
"no-img": !currentItem.thumbnail,
"no-dialog": !this.dialog,
})}"
>
<div class="header-content">
@ -543,6 +544,7 @@ export class HaMediaPlayerBrowse extends LitElement {
.header {
background-color: var(--card-background-color);
position: sticky;
position: -webkit-sticky;
top: 0;
z-index: 5;
padding: 20px 24px 10px;
@ -740,6 +742,10 @@ export class HaMediaPlayerBrowse extends LitElement {
padding: 0;
}
:host([narrow]) .header.no-dialog {
display: block;
}
:host([narrow]) .header_button {
position: absolute;
top: 14px;

View File

@ -134,7 +134,7 @@ class MoreInfoLight extends LitElement {
attr-for-selected="item-name"
>${this.stateObj.attributes.effect_list.map(
(effect: string) => html`
<paper-item itemName=${effect}
<paper-item .itemName=${effect}
>${effect}</paper-item
>
`
@ -170,7 +170,7 @@ class MoreInfoLight extends LitElement {
}
private _effectChanged(ev: CustomEvent) {
const newVal = ev.detail.value;
const newVal = ev.detail.item.itemName;
if (!newVal || this.stateObj!.attributes.effect === newVal) {
return;

View File

@ -26,15 +26,12 @@ class MoreInfoTimer extends LitElement {
return html`
<ha-attributes
.stateObj=${this.stateObj}
.extraFilters=${"remaining"}
extra-filters="remaining"
></ha-attributes>
<div class="actions">
${this.stateObj.state === "idle" || this.stateObj.state === "paused"
? html`
<mwc-button
.action="${"start"}"
@click="${this._handleActionClick}"
>
<mwc-button .action=${"start"} @click=${this._handleActionClick}>
${this.hass!.localize("ui.card.timer.actions.start")}
</mwc-button>
`
@ -42,7 +39,7 @@ class MoreInfoTimer extends LitElement {
${this.stateObj.state === "active"
? html`
<mwc-button
.action="${"pause"}"
.action=${"pause"}
@click="${this._handleActionClick}"
>
${this.hass!.localize("ui.card.timer.actions.pause")}
@ -52,13 +49,13 @@ class MoreInfoTimer extends LitElement {
${this.stateObj.state === "active" || this.stateObj.state === "paused"
? html`
<mwc-button
.action="${"cancel"}"
.action=${"cancel"}
@click="${this._handleActionClick}"
>
${this.hass!.localize("ui.card.timer.actions.cancel")}
</mwc-button>
<mwc-button
.action="${"finish"}"
.action=${"finish"}
@click="${this._handleActionClick}"
>
${this.hass!.localize("ui.card.timer.actions.finish")}

View File

@ -274,6 +274,7 @@ export class MoreInfoDialog extends LitElement {
--mdc-theme-on-primary: var(--primary-text-color);
--mdc-theme-primary: var(--mdc-theme-surface);
flex-shrink: 0;
display: block;
}
@media all and (max-width: 450px), all and (max-height: 500px) {

View File

@ -7,5 +7,3 @@ import "../util/legacy-support";
setPassiveTouchGestures(true);
(window as any).frontendVersion = __VERSION__;
import("../resources/html-import/polyfill");

View File

@ -100,9 +100,5 @@
{% endfor -%}
}
</script>
{% for extra_url in extra_urls -%}
<link rel="import" href="{{ extra_url }}" async />
{% endfor -%}
</body>
</html>

View File

@ -173,7 +173,7 @@ export default class HaAutomationActionRow extends LitElement {
"ui.panel.config.automation.editor.actions.duplicate"
)}
</mwc-list-item>
<mwc-list-item>
<mwc-list-item class="warning">
${this.hass.localize(
"ui.panel.config.automation.editor.actions.delete"
)}

View File

@ -19,6 +19,7 @@ import { Condition } from "../../../../data/automation";
import { showConfirmationDialog } from "../../../../dialogs/generic/show-dialog-box";
import { HomeAssistant } from "../../../../types";
import "./ha-automation-condition-editor";
import { haStyle } from "../../../../resources/styles";
export interface ConditionElement extends LitElement {
condition: Condition;
@ -86,7 +87,7 @@ export default class HaAutomationConditionRow extends LitElement {
"ui.panel.config.automation.editor.actions.duplicate"
)}
</mwc-list-item>
<mwc-list-item>
<mwc-list-item class="warning">
${this.hass.localize(
"ui.panel.config.automation.editor.actions.delete"
)}
@ -134,20 +135,23 @@ export default class HaAutomationConditionRow extends LitElement {
this._yamlMode = !this._yamlMode;
}
static get styles(): CSSResult {
return css`
.card-menu {
float: right;
z-index: 3;
--mdc-theme-text-primary-on-background: var(--primary-text-color);
}
.rtl .card-menu {
float: left;
}
mwc-list-item[disabled] {
--mdc-theme-text-primary-on-background: var(--disabled-text-color);
}
`;
static get styles(): CSSResult[] {
return [
haStyle,
css`
.card-menu {
float: right;
z-index: 3;
--mdc-theme-text-primary-on-background: var(--primary-text-color);
}
.rtl .card-menu {
float: left;
}
mwc-list-item[disabled] {
--mdc-theme-text-primary-on-background: var(--disabled-text-color);
}
`,
];
}
}

View File

@ -118,7 +118,7 @@ export default class HaAutomationTriggerRow extends LitElement {
"ui.panel.config.automation.editor.actions.duplicate"
)}
</mwc-list-item>
<mwc-list-item>
<mwc-list-item class="warning">
${this.hass.localize(
"ui.panel.config.automation.editor.actions.delete"
)}

View File

@ -23,6 +23,8 @@ import { HomeAssistant, Route } from "../../../types";
import "../ha-config-section";
import { configSections } from "../ha-panel-config";
const platformsWithReload = ["template"];
@customElement("ha-config-server-control")
export class HaConfigServerControl extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@ -49,11 +51,13 @@ export class HaConfigServerControl extends LitElement {
changedProperties.has("hass") &&
(!oldHass || oldHass.config.components !== this.hass.config.components)
) {
this._reloadableDomains = this.hass.config.components.filter(
(component) =>
!component.includes(".") &&
isServiceLoaded(this.hass, component, "reload")
);
this._reloadableDomains = this.hass.config.components
.concat(platformsWithReload)
.filter(
(component) =>
!component.includes(".") &&
isServiceLoaded(this.hass, component, "reload")
);
}
}

View File

@ -216,7 +216,7 @@ class HaLogbook extends LitElement {
display: flex;
justify-content: center;
flex-direction: column;
width: 70px;
width: 75px;
flex-shrink: 0;
font-size: 12px;
color: var(--secondary-text-color);

View File

@ -76,11 +76,11 @@ export class HuiCalendarCard extends LitElement implements LovelaceCard {
private _resizeObserver?: ResizeObserver;
public setConfig(config: CalendarCardConfig): void {
if (!config.entities) {
if (!config.entities?.length) {
throw new Error("Entities must be defined");
}
if (config.entities && !Array.isArray(config.entities)) {
if (!Array.isArray(config.entities)) {
throw new Error("Entities need to be an array");
}

View File

@ -154,6 +154,7 @@ class ActionHandler extends HTMLElement implements ActionHandler {
if (["touchend", "touchcancel"].includes(ev.type) && this.cancelled) {
return;
}
const target = ev.target as HTMLElement;
// Prevent mouse event if touch event
if (ev.cancelable) {
ev.preventDefault();
@ -164,7 +165,7 @@ class ActionHandler extends HTMLElement implements ActionHandler {
this.timer = undefined;
}
if (options.hasHold && this.held) {
fireEvent(element, "action", { action: "hold" });
fireEvent(target, "action", { action: "hold" });
} else if (options.hasDoubleClick) {
if (
(ev.type === "click" && (ev as MouseEvent).detail < 2) ||
@ -172,15 +173,15 @@ class ActionHandler extends HTMLElement implements ActionHandler {
) {
this.dblClickTimeout = window.setTimeout(() => {
this.dblClickTimeout = undefined;
fireEvent(element, "action", { action: "tap" });
fireEvent(target, "action", { action: "tap" });
}, 250);
} else {
clearTimeout(this.dblClickTimeout);
this.dblClickTimeout = undefined;
fireEvent(element, "action", { action: "double_tap" });
fireEvent(target, "action", { action: "double_tap" });
}
} else {
fireEvent(element, "action", { action: "tap" });
fireEvent(target, "action", { action: "tap" });
}
};

View File

@ -30,12 +30,6 @@ export const loadLovelaceResources = (
loadModule(normalizedUrl);
break;
case "html":
import(
/* webpackChunkName: "import-href-polyfill" */ "../../../resources/html-import/import-href"
).then(({ importHref }) => importHref(normalizedUrl));
break;
default:
// eslint-disable-next-line
console.warn(`Unknown resource type specified: ${resource.type}`);

View File

@ -5,7 +5,7 @@ import {
ShowViewConfig,
} from "../../../data/lovelace";
import { EntityConfig } from "../entity-rows/types";
import { optional, string, object, union } from "superstruct";
import { optional, string, object, union, boolean } from "superstruct";
import { EntityId } from "../common/structs/is-entity-id";
import { Icon } from "../common/structs/is-icon";
@ -81,6 +81,10 @@ export const entitiesConfigStruct = union([
entity: EntityId,
name: optional(string()),
icon: optional(Icon),
image: optional(string()),
secondary_info: optional(string()),
format: optional(string()),
state_color: optional(boolean()),
}),
EntityId,
]);

View File

@ -2,9 +2,9 @@ import { HassEntity } from "home-assistant-js-websocket";
import {
customElement,
html,
internalProperty,
LitElement,
property,
internalProperty,
PropertyValues,
TemplateResult,
} from "lit-element";
@ -125,7 +125,9 @@ class HuiTimerEntityRow extends LitElement {
}
if (stateObj.state === "idle" || this._timeRemaining === 0) {
return this.hass!.localize("state.timer." + stateObj.state);
return (
this.hass!.localize(`state.timer.${stateObj.state}`) || stateObj.state
);
}
let display = secondsToDuration(this._timeRemaining || 0);

View File

@ -20,8 +20,6 @@ export const sortableStyles = css`
#sortable {
outline: none;
display: flex;
flex-direction: column;
}
.sortable-ghost {

View File

@ -1,101 +0,0 @@
/* eslint-disable */
import "./polyfill";
/**
@license
Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
Code distributed by Google as part of the polymer project is also
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
*/
// run a callback when HTMLImports are ready or immediately if
// this api is not available.
function whenImportsReady(cb) {
if (window.HTMLImports) {
HTMLImports.whenReady(cb);
} else {
cb();
}
}
/**
* Convenience method for importing an HTML document imperatively.
*
* This method creates a new `<link rel="import">` element with
* the provided URL and appends it to the document to start loading.
* In the `onload` callback, the `import` property of the `link`
* element will contain the imported document contents.
*
* @param {string} href URL to document to load.
* @param {?function(!Event):void=} onload Callback to notify when an import successfully
* loaded.
* @param {?function(!ErrorEvent):void=} onerror Callback to notify when an import
* unsuccessfully loaded.
* @param {boolean=} optAsync True if the import should be loaded `async`.
* Defaults to `false`.
* @return {!HTMLLinkElement} The link element for the URL to be loaded.
*/
export const importHref = function (href, onload, onerror, optAsync) {
let link /** @type {HTMLLinkElement} */ = document.head.querySelector(
'link[href="' + href + '"][import-href]'
);
if (!link) {
link = /** @type {HTMLLinkElement} */ (document.createElement("link"));
link.rel = "import";
link.href = href;
link.setAttribute("import-href", "");
}
// always ensure link has `async` attribute if user specified one,
// even if it was previously not async. This is considered less confusing.
if (optAsync) {
link.setAttribute("async", "");
}
// NOTE: the link may now be in 3 states: (1) pending insertion,
// (2) inflight, (3) already loaded. In each case, we need to add
// event listeners to process callbacks.
const cleanup = function () {
link.removeEventListener("load", loadListener);
link.removeEventListener("error", errorListener);
};
let loadListener = function (event) {
cleanup();
// In case of a successful load, cache the load event on the link so
// that it can be used to short-circuit this method in the future when
// it is called with the same href param.
link.__dynamicImportLoaded = true;
if (onload) {
whenImportsReady(() => {
onload(event);
});
}
};
let errorListener = function (event) {
cleanup();
// In case of an error, remove the link from the document so that it
// will be automatically created again the next time `importHref` is
// called.
if (link.parentNode) {
link.parentNode.removeChild(link);
}
if (onerror) {
whenImportsReady(() => {
onerror(event);
});
}
};
link.addEventListener("load", loadListener);
link.addEventListener("error", errorListener);
if (link.parentNode == null) {
document.head.appendChild(link);
// if the link already loaded, dispatch a fake load event
// so that listeners are called and get a proper event argument.
} else if (link.__dynamicImportLoaded) {
link.dispatchEvent(new Event("load"));
}
return link;
};
export const importHrefPromise = (href) =>
new Promise((resolve, reject) => importHref(href, resolve, reject));

View File

@ -1,451 +0,0 @@
/* eslint-disable */
/*
Copyright (c) 2016 The Polymer Project Authors. All rights reserved.
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
Code distributed by Google as part of the polymer project is also
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
*/
(function (q) {
function y(a, b) {
if ("function" === typeof window.CustomEvent) return new CustomEvent(a, b);
var c = document.createEvent("CustomEvent");
c.initCustomEvent(a, !!b.bubbles, !!b.cancelable, b.detail);
return c;
}
function m(a) {
if (u) return a.ownerDocument !== document ? a.ownerDocument : null;
var b = a.__importDoc;
if (!b && a.parentNode) {
b = a.parentNode;
if ("function" === typeof b.closest) b = b.closest("link[rel=import]");
else for (; !r(b) && (b = b.parentNode); );
a.__importDoc = b;
}
return b;
}
function D(a) {
var b = k(document, "link[rel=import]:not([import-dependency])"),
c = b.length;
c
? g(b, function (b) {
return t(b, function () {
0 === --c && a();
});
})
: a();
}
function z(a) {
function b() {
"loading" !== document.readyState &&
document.body &&
(document.removeEventListener("readystatechange", b), a());
}
document.addEventListener("readystatechange", b);
b();
}
function A(a) {
z(function () {
return D(function () {
return a && a();
});
});
}
function t(a, b) {
if (a.__loaded) b && b();
else if (
("script" === a.localName && !a.src) ||
("style" === a.localName && !a.firstChild)
)
(a.__loaded = !0), b && b();
else {
var c = function (d) {
a.removeEventListener(d.type, c);
a.__loaded = !0;
b && b();
};
a.addEventListener("load", c);
(v && "style" === a.localName) || a.addEventListener("error", c);
}
}
function r(a) {
return (
a.nodeType === Node.ELEMENT_NODE &&
"link" === a.localName &&
"import" === a.rel
);
}
function h() {
var a = this;
this.a = {};
this.b = 0;
this.g = new MutationObserver(function (b) {
return a.w(b);
});
this.g.observe(document.head, { childList: !0, subtree: !0 });
this.loadImports(document);
}
function B(a) {
g(k(a, "template"), function (a) {
g(
k(
a.content,
'script:not([type]),script[type="application/javascript"],script[type="text/javascript"]'
),
function (a) {
var b = document.createElement("script");
g(a.attributes, function (a) {
return b.setAttribute(a.name, a.value);
});
b.textContent = a.textContent;
a.parentNode.replaceChild(b, a);
}
);
B(a.content);
});
}
function k(a, b) {
return a.childNodes.length ? a.querySelectorAll(b) : E;
}
function g(a, b, c) {
var d = a ? a.length : 0,
f = c ? -1 : 1;
for (c = c ? d - 1 : 0; c < d && 0 <= c; c += f) b(a[c], c);
}
var n = document.createElement("link"),
u = "import" in n,
E = n.querySelectorAll("*"),
w = null;
!1 === "currentScript" in document &&
Object.defineProperty(document, "currentScript", {
get: function () {
return (
w ||
("complete" !== document.readyState
? document.scripts[document.scripts.length - 1]
: null)
);
},
configurable: !0,
});
var F = /(url\()([^)]*)(\))/g,
G = /(@import[\s]+(?!url\())([^;]*)(;)/g,
H = /(<link[^>]*)(rel=['|"]?stylesheet['|"]?[^>]*>)/g,
e = {
u: function (a, b) {
a.href && a.setAttribute("href", e.c(a.getAttribute("href"), b));
a.src && a.setAttribute("src", e.c(a.getAttribute("src"), b));
if ("style" === a.localName) {
var c = e.o(a.textContent, b, F);
a.textContent = e.o(c, b, G);
}
},
o: function (a, b, c) {
return a.replace(c, function (a, c, l, g) {
a = l.replace(/["']/g, "");
b && (a = e.c(a, b));
return c + "'" + a + "'" + g;
});
},
c: function (a, b) {
if (void 0 === e.f) {
e.f = !1;
try {
var c = new URL("b", "http://a");
c.pathname = "c%20d";
e.f = "http://a/c%20d" === c.href;
} catch (d) {}
}
if (e.f) return new URL(a, b).href;
c = e.s;
c ||
((c = document.implementation.createHTMLDocument("temp")),
(e.s = c),
(c.i = c.createElement("base")),
c.head.appendChild(c.i),
(c.h = c.createElement("a")));
c.i.href = b;
c.h.href = a;
return c.h.href || a;
},
},
C = {
async: !0,
load: function (a, b, c) {
if (a)
if (a.match(/^data:/)) {
a = a.split(",");
var d = a[1];
d = -1 < a[0].indexOf(";base64") ? atob(d) : decodeURIComponent(d);
b(d);
} else {
var f = new XMLHttpRequest();
f.open("GET", a, C.async);
f.onload = function () {
var a = f.responseURL || f.getResponseHeader("Location");
a &&
0 === a.indexOf("/") &&
(a =
(location.origin ||
location.protocol + "//" + location.host) + a);
var d = f.response || f.responseText;
304 === f.status ||
0 === f.status ||
(200 <= f.status && 300 > f.status)
? b(d, a)
: c(d);
};
f.send();
}
else c("error: href must be specified");
},
},
v =
/Trident/.test(navigator.userAgent) ||
/Edge\/\d./i.test(navigator.userAgent);
h.prototype.loadImports = function (a) {
var b = this;
g(k(a, "link[rel=import]"), function (a) {
return b.l(a);
});
};
h.prototype.l = function (a) {
var b = this,
c = a.href;
if (void 0 !== this.a[c]) {
var d = this.a[c];
d && d.__loaded && ((a.__import = d), this.j(a));
} else
this.b++,
(this.a[c] = "pending"),
C.load(
c,
function (a, d) {
a = b.A(a, d || c);
b.a[c] = a;
b.b--;
b.loadImports(a);
b.m();
},
function () {
b.a[c] = null;
b.b--;
b.m();
}
);
};
h.prototype.A = function (a, b) {
if (!a) return document.createDocumentFragment();
v &&
(a = a.replace(H, function (a, b, c) {
return -1 === a.indexOf("type=") ? b + " type=import-disable " + c : a;
}));
var c = document.createElement("template");
c.innerHTML = a;
if (c.content) (a = c.content), B(a);
else
for (a = document.createDocumentFragment(); c.firstChild; )
a.appendChild(c.firstChild);
if ((c = a.querySelector("base")))
(b = e.c(c.getAttribute("href"), b)), c.removeAttribute("href");
var d = 0;
g(
k(
a,
'link[rel=import],link[rel=stylesheet][href][type=import-disable],style:not([type]),link[rel=stylesheet][href]:not([type]),script:not([type]),script[type="application/javascript"],script[type="text/javascript"]'
),
function (a) {
t(a);
e.u(a, b);
a.setAttribute("import-dependency", "");
"script" === a.localName &&
!a.src &&
a.textContent &&
(a.setAttribute(
"src",
"data:text/javascript;charset=utf-8," +
encodeURIComponent(
a.textContent +
("\n//# sourceURL=" + b + (d ? "-" + d : "") + ".js\n")
)
),
(a.textContent = ""),
d++);
}
);
return a;
};
h.prototype.m = function () {
var a = this;
if (!this.b) {
this.g.disconnect();
this.flatten(document);
var b = !1,
c = !1,
d = function () {
c &&
b &&
(a.loadImports(document),
a.b ||
(a.g.observe(document.head, { childList: !0, subtree: !0 }),
a.v()));
};
this.C(function () {
c = !0;
d();
});
this.B(function () {
b = !0;
d();
});
}
};
h.prototype.flatten = function (a) {
var b = this;
g(k(a, "link[rel=import]"), function (a) {
var c = b.a[a.href];
(a.__import = c) &&
c.nodeType === Node.DOCUMENT_FRAGMENT_NODE &&
((b.a[a.href] = a),
(a.readyState = "loading"),
(a.__import = a),
b.flatten(c),
a.appendChild(c));
});
};
h.prototype.B = function (a) {
function b(f) {
if (f < d) {
var l = c[f],
e = document.createElement("script");
l.removeAttribute("import-dependency");
g(l.attributes, function (a) {
return e.setAttribute(a.name, a.value);
});
w = e;
l.parentNode.replaceChild(e, l);
t(e, function () {
w = null;
b(f + 1);
});
} else a();
}
var c = k(document, "script[import-dependency]"),
d = c.length;
b(0);
};
h.prototype.C = function (a) {
var b = k(
document,
"style[import-dependency],link[rel=stylesheet][import-dependency]"
),
c = b.length;
if (c) {
var d =
v &&
!!document.querySelector(
"link[rel=stylesheet][href][type=import-disable]"
);
g(b, function (b) {
t(b, function () {
b.removeAttribute("import-dependency");
0 === --c && a();
});
if (d && b.parentNode !== document.head) {
var e = document.createElement(b.localName);
e.__appliedElement = b;
e.setAttribute("type", "import-placeholder");
b.parentNode.insertBefore(e, b.nextSibling);
for (e = m(b); e && m(e); ) e = m(e);
e.parentNode !== document.head && (e = null);
document.head.insertBefore(b, e);
b.removeAttribute("type");
}
});
} else a();
};
h.prototype.v = function () {
var a = this;
g(
k(document, "link[rel=import]"),
function (b) {
return a.j(b);
},
!0
);
};
h.prototype.j = function (a) {
a.__loaded ||
((a.__loaded = !0),
a.import && (a.import.readyState = "complete"),
a.dispatchEvent(
y(a.import ? "load" : "error", {
bubbles: !1,
cancelable: !1,
detail: void 0,
})
));
};
h.prototype.w = function (a) {
var b = this;
g(a, function (a) {
return g(a.addedNodes, function (a) {
a &&
a.nodeType === Node.ELEMENT_NODE &&
(r(a) ? b.l(a) : b.loadImports(a));
});
});
};
var x = null;
if (u)
g(k(document, "link[rel=import]"), function (a) {
(a.import && "loading" === a.import.readyState) || (a.__loaded = !0);
}),
(n = function (a) {
a = a.target;
r(a) && (a.__loaded = !0);
}),
document.addEventListener("load", n, !0),
document.addEventListener("error", n, !0);
else {
var p = Object.getOwnPropertyDescriptor(Node.prototype, "baseURI");
Object.defineProperty(
(!p || p.configurable ? Node : Element).prototype,
"baseURI",
{
get: function () {
var a = r(this) ? this : m(this);
return a
? a.href
: p && p.get
? p.get.call(this)
: (document.querySelector("base") || window.location).href;
},
configurable: !0,
enumerable: !0,
}
);
Object.defineProperty(HTMLLinkElement.prototype, "import", {
get: function () {
return this.__import || null;
},
configurable: !0,
enumerable: !0,
});
z(function () {
x = new h();
});
}
A(function () {
return document.dispatchEvent(
y("HTMLImportsLoaded", { cancelable: !0, bubbles: !0, detail: void 0 })
);
});
q.useNative = u;
q.whenReady = A;
q.importForElement = m;
q.loadImports = function (a) {
x && x.loadImports(a);
};
})((window.HTMLImports = window.HTMLImports || {}));

View File

@ -23,7 +23,7 @@ class StateCardTimer extends PolymerElement {
<div class="horizontal justified layout">
${this.stateInfoTemplate}
<div class="state">[[_secondsToDuration(timeRemaining)]]</div>
<div class="state">[[_displayState(timeRemaining, stateObj)]]</div>
</div>
`;
}
@ -90,8 +90,10 @@ class StateCardTimer extends PolymerElement {
this.timeRemaining = timerTimeRemaining(stateObj);
}
_secondsToDuration(time) {
return secondsToDuration(time);
_displayState(time, stateObj) {
return time
? secondsToDuration(time)
: this.hass.localize(`state.timer.${stateObj.state}`) || stateObj.state;
}
}
customElements.define("state-card-timer", StateCardTimer);

View File

@ -47,17 +47,6 @@ export const loadCustomPanel = (
): Promise<unknown> => {
const panelSource = getUrl(panelConfig);
if (panelSource.type === "html") {
const toLoad = [
import(
/* webpackChunkName: "import-href-polyfill" */ "../../resources/html-import/import-href"
),
];
return Promise.all(toLoad).then(([{ importHrefPromise }]) =>
importHrefPromise(panelSource.url)
);
}
if (panelSource.type === "js") {
if (!(panelSource.url in JS_CACHE)) {
JS_CACHE[panelSource.url] = loadJS(panelSource.url);