From a4085ed3ab9eedc87bdd93b924ad1843638fc731 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Lov=C3=A9n?= Date: Tue, 19 Jul 2022 19:42:27 +0000 Subject: [PATCH] Navigate, refresh and javascript services --- custom_components/browser_mod/browser_mod.js | 70 ++++++++++--- custom_components/browser_mod/service.py | 8 +- custom_components/browser_mod/services.yaml | 101 ++++++++++++++++++- js/plugin/browser.ts | 12 ++- js/plugin/main.ts | 10 +- js/plugin/require-interact.ts | 2 +- js/plugin/services.ts | 55 ++++++++-- 7 files changed, 223 insertions(+), 35 deletions(-) diff --git a/custom_components/browser_mod/browser_mod.js b/custom_components/browser_mod/browser_mod.js index e9d9224..f6ae008 100644 --- a/custom_components/browser_mod/browser_mod.js +++ b/custom_components/browser_mod/browser_mod.js @@ -685,7 +685,7 @@ const RequireInteractMixin = (SuperClass) => { --mdc-icon-size: 48px; } ha-icon::before { - content: "browser_mod"; + content: "Browser\\00a0Mod"; font-size: 0.75rem; position: absolute; right: 0; @@ -813,6 +813,12 @@ const BrowserStateMixin = (SuperClass) => { }; update(); } + async browser_navigate(path) { + if (!path) + return; + history.pushState(null, "", path); + window.dispatchEvent(new CustomEvent("location-changed")); + } }; }; @@ -850,17 +856,39 @@ const ServicesMixin = (SuperClass) => { [timeout: ] [timeout_action: ] - Close popup - service: browser_mod.close_popup + Close popup: + service: browser_mod.close_popup - Javascript console print - service: browser_mod.console - data: - message: + Navigate to path: + service: browser_mod.navigate + data: + path: + + Refresh browser: + service: browser_mod.refresh + + Browser console print: + service: browser_mod.console + data: + message: + + Run javascript: + service: browser_mod.javascript + data: + code: */ constructor() { super(); - const cmds = ["sequence", "delay", "popup", "close_popup"]; + const cmds = [ + "sequence", + "delay", + "popup", + "close_popup", + "navigate", + "refresh", + "console", + "javascript", + ]; for (const service of cmds) { this.addEventListener(`command-${service}`, (ev) => { this._service_action({ @@ -901,9 +929,25 @@ const ServicesMixin = (SuperClass) => { case "close_popup": this.closePopup(); break; + case "navigate": + this.browser_navigate(data.path); + break; + case "refresh": + window.location.href = window.location.href; + break; case "console": console.log(data.message); break; + case "javascript": + const code = ` + "use strict"; + // Insert global definitions here + const hass = (document.querySelector("home-assistant") || document.querySelector("hc-main")).hass; + ${data.code} + `; + const fn = new Function(code); + fn(); + break; } } }; @@ -1302,7 +1346,7 @@ var pjson = { - Card-mod integration X Timeout X Fullscreen - - Motion/occupancy tracker + x Motion/occupancy tracker x Information about interaction requirement x Information about fullykiosk - Commands @@ -1313,13 +1357,13 @@ var pjson = { x popup x close_popup - more-info - - navigate - - lovelace-reload - - window-reload + x navigate + - lovelace-reload? + x window-reload - screensaver x sequence x delay - - javascript eval + x javascript eval - toast? x Redesign services to target devices - frontend editor for popup cards diff --git a/custom_components/browser_mod/service.py b/custom_components/browser_mod/service.py index b8841f0..267d6eb 100644 --- a/custom_components/browser_mod/service.py +++ b/custom_components/browser_mod/service.py @@ -59,5 +59,11 @@ async def async_setup_services(hass): call_service(service, browsers, data) - hass.services.async_register(DOMAIN, "test", handle_service) + hass.services.async_register(DOMAIN, "sequence", handle_service) + hass.services.async_register(DOMAIN, "delay", handle_service) hass.services.async_register(DOMAIN, "popup", handle_service) + hass.services.async_register(DOMAIN, "close_popup", handle_service) + hass.services.async_register(DOMAIN, "navigate", handle_service) + hass.services.async_register(DOMAIN, "refresh", handle_service) + hass.services.async_register(DOMAIN, "console", handle_service) + hass.services.async_register(DOMAIN, "javascript", handle_service) diff --git a/custom_components/browser_mod/services.yaml b/custom_components/browser_mod/services.yaml index ac1419b..fce57e2 100644 --- a/custom_components/browser_mod/services.yaml +++ b/custom_components/browser_mod/services.yaml @@ -1,5 +1,5 @@ -test: - description: "A debugging service" +sequence: + description: "Run a sequence of services" target: device: integration: "browser_mod" @@ -10,7 +10,32 @@ test: device: integration: "browser_mod" multiple: true - fields: {} + fields: + sequence: + name: Actions + description: List of services to run + selector: + object: + +delay: + description: "Wait for a time" + target: + device: + integration: "browser_mod" + multiple: true + entity: + integration: "browser_mod_none" + area: + device: + integration: "browser_mod" + multiple: true + fields: + time: + name: Time + description: Time to wait (ms) + selector: + number: + mode: box popup: description: "Display a popup" @@ -91,3 +116,73 @@ close_popup: device: integration: "browser_mod" multiple: true + +navigate: + description: "Navigate browser to a different page" + target: + device: + integration: "browser_mod" + multiple: true + entity: + integration: "browser_mod_none" + area: + device: + integration: "browser_mod" + multiple: true + fields: + path: + name: Path + description: "Target path" + selector: + text: + +refresh: + description: "Refresh page" + target: + device: + integration: "browser_mod" + multiple: true + entity: + integration: "browser_mod_none" + area: + device: + integration: "browser_mod" + multiple: true + +console: + description: "Print text to browser console" + target: + device: + integration: "browser_mod" + multiple: true + entity: + integration: "browser_mod_none" + area: + device: + integration: "browser_mod" + multiple: true + fields: + message: + name: Message + description: "Text to print" + selector: + text: + +javascript: + description: "Run arbitrary JavaScript code" + target: + device: + integration: "browser_mod" + multiple: true + entity: + integration: "browser_mod_none" + area: + device: + integration: "browser_mod" + multiple: true + fields: + code: + name: Code + description: "JavaScript code to run" + selector: + object: diff --git a/js/plugin/browser.ts b/js/plugin/browser.ts index bf3d3af..eed7229 100644 --- a/js/plugin/browser.ts +++ b/js/plugin/browser.ts @@ -1,3 +1,5 @@ +import { hass_base_el } from "../helpers"; + export const BrowserStateMixin = (SuperClass) => { return class BrowserStateMixinClass extends SuperClass { constructor() { @@ -38,10 +40,10 @@ export const BrowserStateMixin = (SuperClass) => { update(); } - // do_navigate(path) { - // if (!path) return; - // history.pushState(null, "", path); - // fireEvent("location-changed", {}, ha_element()); - // } + async browser_navigate(path) { + if (!path) return; + history.pushState(null, "", path); + window.dispatchEvent(new CustomEvent("location-changed")); + } }; }; diff --git a/js/plugin/main.ts b/js/plugin/main.ts index e42188f..8e00f65 100644 --- a/js/plugin/main.ts +++ b/js/plugin/main.ts @@ -24,7 +24,7 @@ import pjson from "../../package.json"; - Card-mod integration X Timeout X Fullscreen - - Motion/occupancy tracker + x Motion/occupancy tracker x Information about interaction requirement x Information about fullykiosk - Commands @@ -35,13 +35,13 @@ import pjson from "../../package.json"; x popup x close_popup - more-info - - navigate - - lovelace-reload - - window-reload + x navigate + - lovelace-reload? + x window-reload - screensaver x sequence x delay - - javascript eval + x javascript eval - toast? x Redesign services to target devices - frontend editor for popup cards diff --git a/js/plugin/require-interact.ts b/js/plugin/require-interact.ts index 210718a..c7245c0 100644 --- a/js/plugin/require-interact.ts +++ b/js/plugin/require-interact.ts @@ -34,7 +34,7 @@ export const RequireInteractMixin = (SuperClass) => { --mdc-icon-size: 48px; } ha-icon::before { - content: "browser_mod"; + content: "Browser\\00a0Mod"; font-size: 0.75rem; position: absolute; right: 0; diff --git a/js/plugin/services.ts b/js/plugin/services.ts index 2216cf5..07a9582 100644 --- a/js/plugin/services.ts +++ b/js/plugin/services.ts @@ -32,18 +32,40 @@ export const ServicesMixin = (SuperClass) => { [timeout: ] [timeout_action: ] - Close popup - service: browser_mod.close_popup + Close popup: + service: browser_mod.close_popup - Javascript console print - service: browser_mod.console - data: - message: + Navigate to path: + service: browser_mod.navigate + data: + path: + + Refresh browser: + service: browser_mod.refresh + + Browser console print: + service: browser_mod.console + data: + message: + + Run javascript: + service: browser_mod.javascript + data: + code: */ constructor() { super(); - const cmds = ["sequence", "delay", "popup", "close_popup"]; + const cmds = [ + "sequence", + "delay", + "popup", + "close_popup", + "navigate", + "refresh", + "console", + "javascript", + ]; for (const service of cmds) { this.addEventListener(`command-${service}`, (ev) => { this._service_action({ @@ -92,9 +114,28 @@ export const ServicesMixin = (SuperClass) => { this.closePopup(); break; + case "navigate": + this.browser_navigate(data.path); + break; + + case "refresh": + window.location.href = window.location.href; + break; + case "console": console.log(data.message); break; + + case "javascript": + const code = ` + "use strict"; + // Insert global definitions here + const hass = (document.querySelector("home-assistant") || document.querySelector("hc-main")).hass; + ${data.code} + `; + const fn = new Function(code); + fn(); + break; } } };