diff --git a/build-scripts/webpack.js b/build-scripts/webpack.js index e5207878d8..5bccece0bc 100644 --- a/build-scripts/webpack.js +++ b/build-scripts/webpack.js @@ -49,6 +49,9 @@ const createWebpackConfig = ({ }, ], }, + externals: { + esprima: "esprima", + }, optimization: { minimizer: [ new TerserPlugin({ diff --git a/package.json b/package.json index 12dfb85e21..8818999343 100644 --- a/package.json +++ b/package.json @@ -73,7 +73,6 @@ "@polymer/paper-tooltip": "^3.0.1", "@polymer/polymer": "3.1.0", "@thomasloven/round-slider": "0.3.7", - "@types/resize-observer-browser": "^0.1.3", "@vaadin/vaadin-combo-box": "^5.0.10", "@vaadin/vaadin-date-picker": "^4.0.7", "@webcomponents/shadycss": "^1.9.0", @@ -135,6 +134,7 @@ "@types/leaflet-draw": "^1.0.1", "@types/memoize-one": "4.1.0", "@types/mocha": "^5.2.6", + "@types/resize-observer-browser": "^0.1.3", "@types/webspeechapi": "^0.0.29", "@typescript-eslint/eslint-plugin": "^2.28.0", "@typescript-eslint/parser": "^2.28.0", diff --git a/script/size_stats b/script/size_stats index f6c95545eb..f93f0174dc 100755 --- a/script/size_stats +++ b/script/size_stats @@ -6,6 +6,6 @@ set -e cd "$(dirname "$0")/.." -STATS=1 NODE_ENV=production webpack --profile --json > compilation-stats.json +STATS=1 NODE_ENV=production ./node_modules/.bin/webpack --profile --json > compilation-stats.json npx webpack-bundle-analyzer compilation-stats.json hass_frontend/frontend_latest rm compilation-stats.json diff --git a/src/panels/lovelace/cards/hui-error-card.ts b/src/panels/lovelace/cards/hui-error-card.ts index e66da1aa88..2eaadf7dca 100644 --- a/src/panels/lovelace/cards/hui-error-card.ts +++ b/src/panels/lovelace/cards/hui-error-card.ts @@ -1,4 +1,3 @@ -import { safeDump } from "js-yaml"; import { css, CSSResult, @@ -11,18 +10,7 @@ import { import { HomeAssistant } from "../../../types"; import { LovelaceCard } from "../types"; import { ErrorCardConfig } from "./types"; - -export const createErrorCardElement = (config: ErrorCardConfig) => { - const el = document.createElement("hui-error-card"); - el.setConfig(config); - return el; -}; - -export const createErrorCardConfig = (error, origConfig) => ({ - type: "error", - error, - origConfig, -}); +import { safeDump } from "js-yaml"; @customElement("hui-error-card") export class HuiErrorCard extends LitElement implements LovelaceCard { @@ -46,7 +34,7 @@ export class HuiErrorCard extends LitElement implements LovelaceCard { return html` ${this._config.error} ${this._config.origConfig - ? html`
${safeDump(this._config.origConfig)}
` + ? html`
${safeDump(this._config.origConfig)}
` : ""} `; } diff --git a/src/panels/lovelace/cards/hui-picture-elements-card.ts b/src/panels/lovelace/cards/hui-picture-elements-card.ts index a57a4a53df..5ed9dcd1e3 100644 --- a/src/panels/lovelace/cards/hui-picture-elements-card.ts +++ b/src/panels/lovelace/cards/hui-picture-elements-card.ts @@ -19,6 +19,8 @@ import { PictureElementsCardConfig } from "./types"; @customElement("hui-picture-elements-card") class HuiPictureElementsCard extends LitElement implements LovelaceCard { + @property() public hass?: HomeAssistant; + public static getStubConfig( hass: HomeAssistant, entities: string[], @@ -51,18 +53,6 @@ class HuiPictureElementsCard extends LitElement implements LovelaceCard { @property() private _config?: PictureElementsCardConfig; - private _hass?: HomeAssistant; - - set hass(hass: HomeAssistant) { - this._hass = hass; - for (const el of Array.from( - this.shadowRoot!.querySelectorAll("#root > *") - )) { - const element = el as LovelaceElement; - element.hass = this._hass; - } - } - public getCardSize(): number { return 4; } @@ -84,9 +74,19 @@ class HuiPictureElementsCard extends LitElement implements LovelaceCard { protected updated(changedProps: PropertyValues): void { super.updated(changedProps); - if (!this._config || !this._hass) { + if (!this._config || !this.hass) { return; } + + if (changedProps.has("hass")) { + for (const el of Array.from( + this.shadowRoot!.querySelectorAll("#root > *") + )) { + const element = el as LovelaceElement; + element.hass = this.hass; + } + } + const oldHass = changedProps.get("hass") as HomeAssistant | undefined; const oldConfig = changedProps.get("_config") as | PictureElementsCardConfig @@ -98,12 +98,12 @@ class HuiPictureElementsCard extends LitElement implements LovelaceCard { oldHass.themes !== this.hass.themes || oldConfig.theme !== this._config.theme ) { - applyThemesOnElement(this, this._hass.themes, this._config.theme); + applyThemesOnElement(this, this.hass.themes, this._config.theme); } } protected render(): TemplateResult { - if (!this._config) { + if (!this.hass || !this._config) { return html``; } @@ -111,7 +111,7 @@ class HuiPictureElementsCard extends LitElement implements LovelaceCard {
{ const element = createStyledHuiElement(elementConfig); - element.hass = this._hass; + element.hass = this.hass; return element; } diff --git a/src/panels/lovelace/components/hui-image.ts b/src/panels/lovelace/components/hui-image.ts index 2198bd3754..4dbbfeac10 100644 --- a/src/panels/lovelace/components/hui-image.ts +++ b/src/panels/lovelace/components/hui-image.ts @@ -71,9 +71,11 @@ export class HuiImage extends LitElement { } protected render(): TemplateResult { + if (!this.hass) { + return html``; + } const ratio = this.aspectRatio ? parseAspectRatio(this.aspectRatio) : null; - const stateObj = - this.hass && this.entity ? this.hass.states[this.entity] : undefined; + const stateObj = this.entity ? this.hass.states[this.entity] : undefined; const state = stateObj ? stateObj.state : "unavailable"; // Figure out image source to use @@ -84,8 +86,7 @@ export class HuiImage extends LitElement { if (this.cameraImage) { if (this.cameraView === "live") { - cameraObj = - this.hass && (this.hass.states[this.cameraImage] as CameraEntity); + cameraObj = this.hass.states[this.cameraImage] as CameraEntity; } else { imageSrc = this._cameraImageSrc; } @@ -103,7 +104,7 @@ export class HuiImage extends LitElement { } if (imageSrc) { - imageSrc = this.hass!.hassUrl(imageSrc); + imageSrc = this.hass.hassUrl(imageSrc); } // Figure out filter to use diff --git a/src/panels/lovelace/create-element/create-card-element.ts b/src/panels/lovelace/create-element/create-card-element.ts index 6b586fa678..48a51b8782 100644 --- a/src/panels/lovelace/create-element/create-card-element.ts +++ b/src/panels/lovelace/create-element/create-card-element.ts @@ -21,7 +21,6 @@ const ALWAYS_LOADED_TYPES = new Set([ "entities", "button", "entity-button", - "error", "glance", "history-graph", "horizontal-stack", @@ -34,6 +33,7 @@ const ALWAYS_LOADED_TYPES = new Set([ const LAZY_LOAD_TYPES = { "alarm-panel": () => import("../cards/hui-alarm-panel-card"), + error: () => import("../cards/hui-error-card"), "empty-state": () => import("../cards/hui-empty-state-card"), "entity-filter": () => import("../cards/hui-entity-filter-card"), "media-control": () => import("../cards/hui-media-control-card"), diff --git a/src/panels/lovelace/create-element/create-element-base.ts b/src/panels/lovelace/create-element/create-element-base.ts index 88b46a6ec0..c8379e8f3a 100644 --- a/src/panels/lovelace/create-element/create-element-base.ts +++ b/src/panels/lovelace/create-element/create-element-base.ts @@ -4,11 +4,7 @@ import { LovelaceCardConfig, } from "../../../data/lovelace"; import { CUSTOM_TYPE_PREFIX } from "../../../data/lovelace_custom_cards"; -import { - createErrorCardConfig, - createErrorCardElement, - HuiErrorCard, -} from "../cards/hui-error-card"; +import type { HuiErrorCard } from "../cards/hui-error-card"; import { LovelaceElement, LovelaceElementConfig } from "../elements/types"; import { LovelaceRow, LovelaceRowConfig } from "../entity-rows/types"; import { LovelaceHeaderFooterConfig } from "../header-footer/types"; @@ -18,6 +14,7 @@ import { LovelaceCardConstructor, LovelaceHeaderFooter, } from "../types"; +import type { ErrorCardConfig } from "../cards/types"; const TIMEOUT = 2000; @@ -49,6 +46,25 @@ interface CreateElementConfigTypes { }; } +export const createErrorCardElement = (config: ErrorCardConfig) => { + const el = document.createElement("hui-error-card"); + if (customElements.get("hui-error-card")) { + el.setConfig(config); + } else { + import("../cards/hui-error-card"); + customElements + .whenDefined("hui-error-card") + .then(() => el.setConfig(config)); + } + return el; +}; + +export const createErrorCardConfig = (error, origConfig) => ({ + type: "error", + error, + origConfig, +}); + const _createElement = ( tag: string, config: CreateElementConfigTypes[T]["config"] @@ -73,7 +89,7 @@ const _createErrorElement = ( config: CreateElementConfigTypes[T]["config"] ): HuiErrorCard => createErrorCardElement(createErrorCardConfig(error, config)); -const _maybeCreate = ( +const _customCreate = ( tag: string, config: CreateElementConfigTypes[T]["config"] ) => { @@ -98,6 +114,28 @@ const _maybeCreate = ( return element; }; +const _lazyCreate = ( + tag: string, + config: CreateElementConfigTypes[T]["config"] +) => { + if (customElements.get(tag)) { + return _createElement(tag, config); + } + const element = document.createElement( + tag + ) as CreateElementConfigTypes[T]["element"]; + customElements.whenDefined(tag).then(() => { + try { + // @ts-ignore + element.setConfig(config); + } catch (err) { + // We let it rebuild and the error wil be handled by _createElement + fireEvent(element, "ll-rebuild"); + } + }); + return element; +}; + const _getCustomTag = (type: string) => type.startsWith(CUSTOM_TYPE_PREFIX) ? type.substr(CUSTOM_TYPE_PREFIX.length) @@ -129,7 +167,7 @@ export const createLovelaceElement = ( const customTag = config.type ? _getCustomTag(config.type) : undefined; if (customTag) { - return _maybeCreate(customTag, config); + return _customCreate(customTag, config); } let type: string | undefined; @@ -152,7 +190,7 @@ export const createLovelaceElement = ( if (lazyLoadTypes && type in lazyLoadTypes) { lazyLoadTypes[type](); - return _maybeCreate(tag, config); + return _lazyCreate(tag, config); } if (alwaysLoadTypes && alwaysLoadTypes.has(type)) { diff --git a/src/panels/lovelace/editor/card-editor/hui-card-preview.ts b/src/panels/lovelace/editor/card-editor/hui-card-preview.ts index fb622e95fc..7066b4f2c6 100644 --- a/src/panels/lovelace/editor/card-editor/hui-card-preview.ts +++ b/src/panels/lovelace/editor/card-editor/hui-card-preview.ts @@ -2,10 +2,10 @@ import "@polymer/paper-input/paper-textarea"; import { computeRTL } from "../../../../common/util/compute_rtl"; import { LovelaceCardConfig } from "../../../../data/lovelace"; import { HomeAssistant } from "../../../../types"; -import { createErrorCardConfig } from "../../cards/hui-error-card"; import { createCardElement } from "../../create-element/create-card-element"; import { LovelaceCard } from "../../types"; import { ConfigError } from "../types"; +import { createErrorCardConfig } from "../../create-element/create-element-base"; export class HuiCardPreview extends HTMLElement { private _hass?: HomeAssistant;