Refactoring. New args function
This commit is contained in:
381
card-tools.js
381
card-tools.js
@@ -1,208 +1,223 @@
|
||||
if (!window.cardTools){
|
||||
const version = 0.2;
|
||||
const CUSTOM_TYPE_PREFIX = "custom:";
|
||||
customElements.define('card-tools',
|
||||
class {
|
||||
static CUSTOM_TYPE_PREFIX() { return "custom:"}
|
||||
static version() { return "0.3"}
|
||||
|
||||
let cardTools =
|
||||
{};
|
||||
static v() {return version};
|
||||
|
||||
cardTools.v =
|
||||
version;
|
||||
|
||||
cardTools.checkVersion =
|
||||
(v) => {
|
||||
if (version < v) {
|
||||
static checkVersion(v) {
|
||||
if (this.version() < v) {
|
||||
throw new Error(`Old version of card-tools found. Get the latest version of card-tools.js from https://github.com/thomasloven/lovelace-card-tools`);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
cardTools.LitElement =
|
||||
Object.getPrototypeOf(customElements.get('hui-error-entity-row'));
|
||||
static litElement() {
|
||||
return Object.getPrototypeOf(customElements.get('hui-error-entity-row'));
|
||||
}
|
||||
|
||||
cardTools.litHtml =
|
||||
cardTools.LitElement.prototype.html;
|
||||
static litHtml() {
|
||||
return this.litElement().prototype.html;
|
||||
}
|
||||
|
||||
cardTools.hass =
|
||||
() => {
|
||||
return document.querySelector('home-assistant').hass;
|
||||
static hass() {
|
||||
return document.querySelector('home-assistant').hass;
|
||||
}
|
||||
|
||||
static fireEvent(ev, detail, entity=null) {
|
||||
ev = new Event(ev, {
|
||||
bubbles: true,
|
||||
cancelable: false,
|
||||
composed: true,
|
||||
});
|
||||
ev.detail = detail || {};
|
||||
if(entity) {
|
||||
entity.dispatchEvent(ev);
|
||||
} else {
|
||||
document
|
||||
.querySelector("home-assistant")
|
||||
.shadowRoot.querySelector("home-assistant-main")
|
||||
.shadowRoot.querySelector("app-drawer-layout partial-panel-resolver")
|
||||
.shadowRoot.querySelector("ha-panel-lovelace")
|
||||
.shadowRoot.querySelector("hui-root")
|
||||
.shadowRoot.querySelector("ha-app-layout #view hui-view")
|
||||
.dispatchEvent(ev);
|
||||
}
|
||||
}
|
||||
|
||||
static createThing(thing, config) {
|
||||
const _createThing = (tag, config) => {
|
||||
const element = document.createElement(tag);
|
||||
try {
|
||||
element.setConfig(config);
|
||||
} catch (err) {
|
||||
console.error(tag, err);
|
||||
return _createError(err.message, config);
|
||||
}
|
||||
return element;
|
||||
};
|
||||
|
||||
cardTools.fireEvent =
|
||||
(ev, detail) => {
|
||||
ev = new Event(ev, {
|
||||
bubbles: true,
|
||||
cancelable: false,
|
||||
composed: true,
|
||||
const _createError = (error, config) => {
|
||||
return _createThing("hui-error-card", {
|
||||
type: "error",
|
||||
error,
|
||||
config,
|
||||
});
|
||||
ev.detail = detail || {};
|
||||
document
|
||||
.querySelector("home-assistant")
|
||||
.shadowRoot.querySelector("home-assistant-main")
|
||||
.shadowRoot.querySelector("app-drawer-layout partial-panel-resolver")
|
||||
.shadowRoot.querySelector("ha-panel-lovelace")
|
||||
.shadowRoot.querySelector("hui-root")
|
||||
.shadowRoot.querySelector("ha-app-layout #view hui-view")
|
||||
.dispatchEvent(ev);
|
||||
};
|
||||
|
||||
if(!config || typeof config !== "object" || !config.type)
|
||||
return _createError(`No ${thing} type configured`, config);
|
||||
let tag = config.type;
|
||||
if(config.error) {
|
||||
const err = config.error;
|
||||
delete config.error;
|
||||
return _createError(err, config);
|
||||
}
|
||||
if(tag.startsWith(this.CUSTOM_TYPE_PREFIX()))
|
||||
tag = tag.substr(this.CUSTOM_TYPE_PREFIX().length);
|
||||
else
|
||||
tag = `hui-${tag}-${thing}`;
|
||||
|
||||
if(customElements.get(tag))
|
||||
return _createThing(tag, config);
|
||||
|
||||
// If element doesn't exist (yet) create an error
|
||||
const element = _createError(
|
||||
`Custom element doesn't exist: ${tag}.`,
|
||||
config
|
||||
);
|
||||
element.style.display = "None";
|
||||
const time = setTimeout(() => {
|
||||
element.style.display = "";
|
||||
}, 2000);
|
||||
// Remove error if element is defined later
|
||||
customElements.whenDefined(tag).then(() => {
|
||||
clearTimeout(timer);
|
||||
this.fireEvent("ll-rebuild", {}, element);
|
||||
});
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
static createCard(config) {
|
||||
return this.createThing("card", config);
|
||||
}
|
||||
|
||||
static createElement(config) {
|
||||
return this.createThing("element", config);
|
||||
}
|
||||
|
||||
static createEntityRow(config) {
|
||||
const SPECIAL_TYPES = new Set([
|
||||
"call-service",
|
||||
"divider",
|
||||
"section",
|
||||
"weblink",
|
||||
]);
|
||||
const DEFAULT_ROWS = {
|
||||
alert: "toggle",
|
||||
automation: "toggle",
|
||||
climate: "toggle",
|
||||
cover: "cover",
|
||||
fan: "toggle",
|
||||
group: "group",
|
||||
input_boolean: "toggle",
|
||||
input_number: "input-number",
|
||||
input_select: "input-select",
|
||||
input_text: "input-text",
|
||||
light: "toggle",
|
||||
media_player: "media-player",
|
||||
lock: "lock",
|
||||
scene: "scene",
|
||||
script: "script",
|
||||
sensor: "sensor",
|
||||
timer: "timer",
|
||||
switch: "toggle",
|
||||
vacuum: "toggle",
|
||||
};
|
||||
|
||||
if(!config || typeof config !== "object" || (!config.entity && !config.type)) {
|
||||
Object.assign(config, {error: "Invalid config given"});
|
||||
return this.createThing("", config);
|
||||
}
|
||||
|
||||
cardTools.createThing =
|
||||
(thing, config) => {
|
||||
const _createThing = (tag, config) => {
|
||||
const element = document.createElement(tag);
|
||||
try {
|
||||
element.setConfig(config);
|
||||
} catch (err) {
|
||||
console.error(tag, err);
|
||||
return _createError(err.message, config);
|
||||
}
|
||||
return element;
|
||||
};
|
||||
const type = config.type || "default";
|
||||
if(SPECIAL_TYPES.has(type) || type.startsWith(this.CUSTOM_TYPE_PREFIX()))
|
||||
return this.createThing("row", config);
|
||||
|
||||
const _createError = (error, config) => {
|
||||
return _createThing("hui-error-card", {
|
||||
type: "error",
|
||||
error,
|
||||
config,
|
||||
});
|
||||
};
|
||||
const domain = config.entity.split(".", 1)[0];
|
||||
Object.assign(config, {type: DEFAULT_ROWS[domain] || "text"});
|
||||
return this.createThing("entity-row", config);
|
||||
}
|
||||
|
||||
if(!config || typeof config !== "object" || !config.type)
|
||||
return _createError(`No ${thing} type configured`, config);
|
||||
let tag = config.type;
|
||||
if(config.error) {
|
||||
const err = config.error;
|
||||
delete config.error;
|
||||
return _createError(err, config);
|
||||
static deviceID() {
|
||||
const ID_STORAGE_KEY = 'lovelace-player-device-id';
|
||||
if(window['fully'] && typeof fully.getDeviceId === "function")
|
||||
return fully.getDeviceId();
|
||||
if(!localStorage[ID_STORAGE_KEY])
|
||||
{
|
||||
const s4 = () => {
|
||||
return Math.floor((1+Math.random())*100000).toString(16).substring(1);
|
||||
}
|
||||
if(tag.startsWith(CUSTOM_TYPE_PREFIX))
|
||||
tag = tag.substr(CUSTOM_TYPE_PREFIX.length);
|
||||
else
|
||||
tag = `hui-${tag}-${thing}`;
|
||||
localStorage[ID_STORAGE_KEY] = `${s4()}${s4()}-${s4()}${s4()}`;
|
||||
}
|
||||
return localStorage[ID_STORAGE_KEY];
|
||||
}
|
||||
|
||||
if(customElements.get(tag))
|
||||
return _createThing(tag, config);
|
||||
static moreInfo(entity) {
|
||||
this.fireEvent("hass-more-info", {entityId: entity});
|
||||
}
|
||||
|
||||
// If element doesn't exist (yet) create an error
|
||||
const element = _createError(
|
||||
`Custom element doesn't exist: ${tag}.`,
|
||||
config
|
||||
);
|
||||
element.style.display = "None";
|
||||
const time = setTimeout(() => {
|
||||
element.style.display = "";
|
||||
}, 2000);
|
||||
// Remove error if element is defined later
|
||||
customElements.whenDefined(tag).then(() => {
|
||||
clearTimeout(timer);
|
||||
cardTools.fireEvent("rebuild-view");
|
||||
});
|
||||
static longpress(element) {
|
||||
customElements.whenDefined("long-press").then(() => {
|
||||
const longpress = document.body.querySelector("long-press");
|
||||
longpress.bind(element);
|
||||
});
|
||||
return element;
|
||||
}
|
||||
|
||||
return element;
|
||||
};
|
||||
static hasTemplate(text) {
|
||||
return /\[\[\s+.*\s+\]\]/.test(text);
|
||||
}
|
||||
|
||||
cardTools.createCard =
|
||||
(config) => { return cardTools.createThing("card", config); };
|
||||
|
||||
cardTools.createElement =
|
||||
(config) => { return cardTools.createThing("element", config); };
|
||||
|
||||
cardTools.createEntityRow =
|
||||
(config) => {
|
||||
const SPECIAL_TYPES = new Set([
|
||||
"call-service",
|
||||
"divider",
|
||||
"section",
|
||||
"weblink",
|
||||
]);
|
||||
const DEFAULT_ROWS = {
|
||||
alert: "toggle",
|
||||
automation: "toggle",
|
||||
climate: "toggle",
|
||||
cover: "cover",
|
||||
fan: "toggle",
|
||||
group: "group",
|
||||
input_boolean: "toggle",
|
||||
input_number: "input-number",
|
||||
input_select: "input-select",
|
||||
input_text: "input-text",
|
||||
light: "toggle",
|
||||
media_player: "media-player",
|
||||
lock: "lock",
|
||||
scene: "scene",
|
||||
script: "script",
|
||||
sensor: "sensor",
|
||||
timer: "timer",
|
||||
switch: "toggle",
|
||||
vacuum: "toggle",
|
||||
};
|
||||
|
||||
if(!config || typeof config !== "object" || (!config.entity && !config.type)) {
|
||||
Object.assign(config, {error: "Invalid config given"});
|
||||
return cardTools.createThing("", config);
|
||||
static parseTemplate(text, error) {
|
||||
const _parse = (str) => {
|
||||
try {
|
||||
str = str.replace(/^\[\[\s+|\s+\]\]$/g, '')
|
||||
const parts = str.split(".");
|
||||
let v = this.hass().states[`${parts[0]}.${parts[1]}`];
|
||||
parts.shift();
|
||||
parts.shift();
|
||||
parts.forEach(item => v = v[item]);
|
||||
return v;
|
||||
} catch (err) {
|
||||
return error || `[[ Template matching failed ${str} ]]`;
|
||||
}
|
||||
}
|
||||
text = text.replace(/(\[\[\s.*?\s\]\])/g, (str, p1, offset, s) => _parse(str));
|
||||
return text;
|
||||
}
|
||||
|
||||
const type = config.type || "default";
|
||||
if(SPECIAL_TYPES.has(type) || type.startsWith(CUSTOM_TYPE_PREFIX))
|
||||
return cardTools.createThing("row", config);
|
||||
|
||||
const domain = config.entity.split(".", 1)[0];
|
||||
Object.assign(config, {type: DEFAULT_ROWS[domain] || "text"});
|
||||
return cardTools.createThing("entity-row", config);
|
||||
};
|
||||
|
||||
cardTools.deviceID =
|
||||
(() => {
|
||||
const ID_STORAGE_KEY = 'lovelace-player-device-id';
|
||||
if(window['fully'] && typeof fully.getDeviceId === "function")
|
||||
return fully.getDeviceId();
|
||||
if(!localStorage[ID_STORAGE_KEY])
|
||||
{
|
||||
const s4 = () => {
|
||||
return Math.floor((1+Math.random())*100000).toString(16).substring(1);
|
||||
}
|
||||
localStorage[ID_STORAGE_KEY] = `${s4()}${s4()}-${s4()}${s4()}`;
|
||||
static args() {
|
||||
var url = document.currentScript.src
|
||||
url = url.substr(url.indexOf("?")+1)
|
||||
let args = {};
|
||||
url.split("&").forEach((a) => {
|
||||
if(a.indexOf("=")) {
|
||||
var parts = a.split("=");
|
||||
args[parts[0]] = parts[1]
|
||||
} else {
|
||||
args[a] = true;
|
||||
}
|
||||
return localStorage[ID_STORAGE_KEY];
|
||||
})();
|
||||
});
|
||||
return args;
|
||||
}
|
||||
|
||||
cardTools.moreInfo =
|
||||
(entity) => {
|
||||
cardTools.fireEvent("hass-more-info", {entityId: entity});
|
||||
};
|
||||
});
|
||||
|
||||
cardTools.longpress =
|
||||
(element) => {
|
||||
customElements.whenDefined("long-press").then(() => {
|
||||
const longpress = document.body.querySelector("long-press");
|
||||
longpress.bind(element);
|
||||
});
|
||||
return element;
|
||||
};
|
||||
// Global definition of cardTools
|
||||
cardTools = customElements.get('card-tools');
|
||||
|
||||
cardTools.hasTemplate =
|
||||
(text) => {
|
||||
return /\[\[\s+.*\s+\]\]/.test(text);
|
||||
};
|
||||
|
||||
cardTools.parseTemplate =
|
||||
(text, error) => {
|
||||
const _parse = (str) => {
|
||||
try {
|
||||
str = str.replace(/^\[\[\s+|\s+\]\]$/g, '')
|
||||
const parts = str.split(".");
|
||||
let v = cardTools.hass().states[`${parts[0]}.${parts[1]}`];
|
||||
parts.shift();
|
||||
parts.shift();
|
||||
parts.forEach(item => v = v[item]);
|
||||
return v;
|
||||
} catch (err) {
|
||||
return error || `[[ Template matching failed ${str} ]]`;
|
||||
}
|
||||
}
|
||||
text = text.replace(/(\[\[\s.*?\s\]\])/g, (str, p1, offset, s) => _parse(str));
|
||||
return text;
|
||||
};
|
||||
|
||||
window.cardTools = cardTools;
|
||||
customElements.define('card-tools', class {});
|
||||
console.info("%cCARD-TOOLS IS INSTALLED", "color: green; font-weight: bold");
|
||||
}
|
||||
console.info(`%cCARD-TOOLS IS INSTALLED
|
||||
%cDeviceID: ${customElements.get('card-tools').deviceID()}`,
|
||||
"color: green; font-weight: bold",
|
||||
"");
|
||||
|
||||
Reference in New Issue
Block a user