const TIMEOUT_ERROR = "SELECTTREE-TIMEOUT"; async function _await_el(el) { if (el.localName?.includes("-")) await customElements.whenDefined(el.localName); if (el.updateComplete) await el.updateComplete; } async function _selectTree(root, path, all = false) { let el = [root]; if (typeof path === "string") { path = path.split(/(\$| )/); } while (path[path.length - 1] === "") path.pop(); for (const [i, p] of path.entries()) { const e = el[0]; if (!e) return null; if (!p.trim().length) continue; _await_el(e); el = p === "$" ? [e.shadowRoot] : e.querySelectorAll(p); } return all ? el : el[0]; } export async function selectTree(root, path, all = false, timeout = 10000) { return Promise.race([ _selectTree(root, path, all), new Promise((_, reject) => setTimeout(() => reject(new Error(TIMEOUT_ERROR)), timeout) ), ]).catch((err) => { if (!err.message || err.message !== TIMEOUT_ERROR) throw err; return null; }); } export async function hass_base_el() { await Promise.race([ customElements.whenDefined("home-assistant"), customElements.whenDefined("hc-main"), ]); const element = customElements.get("home-assistant") ? "home-assistant" : "hc-main"; while (!document.querySelector(element)) await new Promise((r) => window.setTimeout(r, 100)); return document.querySelector(element); } export async function hass() { const base: any = await hass_base_el(); while (!base.hass) await new Promise((r) => window.setTimeout(r, 100)); return base.hass; } export async function provideHass(el) { const base: any = await hass_base_el(); base.provideHass(el); } export const loadLoadCardHelpers = async () => { if (window.loadCardHelpers !== undefined) return; await customElements.whenDefined("partial-panel-resolver"); const ppResolver = document.createElement("partial-panel-resolver"); const routes = (ppResolver as any).getRoutes([ { component_name: "lovelace", url_path: "a", }, ]); await routes?.routes?.a?.load?.(); }; export const loadHaForm = async () => { if (customElements.get("ha-form")) return; await loadLoadCardHelpers(); const helpers = await window.loadCardHelpers(); if (!helpers) return; const card = await helpers.createCardElement({ type: "entity" }); if (!card) return; await card.getConfigElement(); }; // Loads in ha-config-dashboard which is used to copy styling // Also provides ha-settings-row export const loadConfigDashboard = async () => { await customElements.whenDefined("partial-panel-resolver"); const ppResolver = document.createElement("partial-panel-resolver"); const routes = (ppResolver as any).getRoutes([ { component_name: "config", url_path: "a", }, ]); await routes?.routes?.a?.load?.(); await customElements.whenDefined("ha-panel-config"); const configRouter: any = document.createElement("ha-panel-config"); await configRouter?.routerOptions?.routes?.dashboard?.load?.(); // Load ha-config-dashboard await configRouter?.routerOptions?.routes?.cloud?.load?.(); // Load ha-settings-row await customElements.whenDefined("ha-config-dashboard"); }; export const loadDeveloperToolsTemplate = async () => { await customElements.whenDefined("partial-panel-resolver"); await customElements.whenDefined("partial-panel-resolver"); const ppResolver = document.createElement("partial-panel-resolver"); const routes = (ppResolver as any).getRoutes([ { component_name: "developer-tools", url_path: "a", }, ]); await routes?.routes?.a?.load?.(); const dtRouter: any = document.createElement("developer-tools-router"); await dtRouter?.routerOptions?.routes?.template?.load?.(); await customElements.whenDefined("developer-tools-template"); };