From c45bcea1916e627a081fc45c900db025bb7072b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Lov=C3=A9n?= Date: Tue, 23 Jul 2019 21:20:54 +0200 Subject: [PATCH] Fix for non-chrome browsers. Add debug information --- README.md | 3 +++ card-mod.js | 2 +- src/main.js | 46 ++++++++++++++++++++++++++++++++++------------ 3 files changed, 38 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 4b008c3..cf3d500 100644 --- a/README.md +++ b/README.md @@ -109,6 +109,8 @@ In this case, you can make `style:` a dictionary instead of a string, where each This is not for the faint of heart. +For some extra help, add `debug_cardMod: true` to the card config, and the steps taken to apply the styling will be printed in the browser console. It can be removed later. + **Example**: Change some things in an `alarm-panel` card. @@ -116,6 +118,7 @@ Change some things in an `alarm-panel` card. type: alarm-panel card_icon: mdi:bell name: Alarm Panel +debug_cardMod: true style: .: | ha-card { diff --git a/card-mod.js b/card-mod.js index 8e20bd8..76df872 100644 --- a/card-mod.js +++ b/card-mod.js @@ -1 +1 @@ -!function(e){var t={};function r(s){if(t[s])return t[s].exports;var a=t[s]={i:s,l:!1,exports:{}};return e[s].call(a.exports,a,a.exports,r),a.l=!0,a.exports}r.m=e,r.c=t,r.d=function(e,t,s){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:s})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var s=Object.create(null);if(r.r(s),Object.defineProperty(s,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var a in e)r.d(s,a,function(t){return e[t]}.bind(null,a));return s},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="",r(r.s=3)}([function(e,t,r){"use strict";function s(){return document.querySelector("home-assistant").hass}r.d(t,"a",function(){return s})},function(module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.d(__webpack_exports__,"a",function(){return parseTemplate});var _hass_js__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(0),_deviceID_js__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(2);function hasTemplate(e){return/\[\[\s+.*\s+\]\]/.test(e)}function parseTemplateString(str,specialData={}){if("string"!=typeof str)return text;const FUNCTION=/^[a-zA-Z0-9_]+\(.*\)$/,EXPR=/([^=<>!]+)\s*(==|!=|<|>|<=|>=)\s*([^=<>!]+)/,SPECIAL=/^\{.+\}$/,STRING=/^"[^"]*"|'[^']*'$/;"string"==typeof specialData&&(specialData={}),specialData=Object.assign({user:Object(_hass_js__WEBPACK_IMPORTED_MODULE_0__.a)().user.name,browser:_deviceID_js__WEBPACK_IMPORTED_MODULE_1__.a,hash:location.hash.substr(1)||" "},specialData);const _parse_function=e=>{let t=[e.substr(0,e.indexOf("(")).trim()];for(e=e.substr(e.indexOf("(")+1);e;){let r=0,s=0,a=!1;for(;e[r];){let t=e[r++];if(t===a&&r>1&&"\\"!==e[r-2]?a=!1:"\"'".includes(t)&&(a=t),!a){if("("===t)s+=1;else if(")"===t){s-=1;continue}if(!(s>0)&&",)".includes(t))break}}t.push(e.substr(0,r-1).trim()),e=e.substr(r)}return t},_parse_special=e=>(e=e.substr(1,e.length-2),specialData[e]||`{${e}}`),_parse_entity=e=>{let t;if((e=e.split("."))[0].match(SPECIAL))t=_parse_special(e.shift()),t=Object(_hass_js__WEBPACK_IMPORTED_MODULE_0__.a)().states[t]||t;else if(t=Object(_hass_js__WEBPACK_IMPORTED_MODULE_0__.a)().states[`${e.shift()}.${e.shift()}`],!e.length)return t.state;return e.forEach(e=>t=t[e]),t},_eval_expr=str=>{if(str=EXPR.exec(str),null===str)return!1;const lhs=parseTemplateString(str[1]),rhs=parseTemplateString(str[3]);var expr="";return expr=parseFloat(lhs)!=lhs?`"${lhs}" ${str[2]} "${rhs}"`:`${parseFloat(lhs)} ${str[2]} ${parseFloat(rhs)}`,eval(expr)},_eval_function=e=>{if("if"===e[0])return _eval_expr(e[1])?parseTemplateString(e[2]):parseTemplateString(e[3])};try{return str=str.trim(),str.match(STRING)?str.substr(1,str.length-2):str.match(SPECIAL)?_parse_special(str):str.match(FUNCTION)?_eval_function(_parse_function(str)):str.includes(".")?_parse_entity(str):str}catch(e){return`[[ Template matching failed: ${str} ]]`}}function parseTemplate(e,t={}){if("string"!=typeof e)return e;return e=e.replace(/\[\[\s(.*?)\s\]\]/g,(e,r,s,a)=>parseTemplateString(r,t))}},function(e,t,r){"use strict";r.d(t,"a",function(){return s});let s=function(){if(window.fully&&"function"==typeof fully.getDeviceId)return fully.getDeviceId();if(!localStorage["lovelace-player-device-id"]){const e=()=>Math.floor(1e5*(1+Math.random())).toString(16).substring(1);localStorage["lovelace-player-device-id"]=`${e()}${e()}-${e()}${e()}`}return localStorage["lovelace-player-device-id"]}()},function(e,t,r){"use strict";r.r(t);const s=Object.getPrototypeOf(customElements.get("home-assistant-main"));s.prototype.html,s.prototype.css;var a=r(1);customElements.whenDefined("ha-card").then(()=>{const e=customElements.get("ha-card"),t=function(e){return e.config?e.config:e._config?e._config:e.host?t(e.host):e.parentElement?t(e.parentElement):e.parentNode?t(e.parentNode):null},r=function(e,t){if(e&&t)if("string"==typeof t){e.querySelector(":scope >.card-mod-style")&&e.removeChild(e.querySelector(":scope > .card-mod-style"));const r=document.createElement("style");r.classList="card-mod-style",r.innerHTML=Object(a.a)(t),e.appendChild(r)}else Object.keys(t).forEach(s=>"."===s?r(e,t[s]):"$"===s?r(e.shadowRoot,t[s]):void e.querySelectorAll(`:scope > ${s}`).forEach(e=>{r(e,t[s])}))};e.prototype.updated=function(e){const s=t(this);s&&s.style&&r(this,s.style)},e.prototype.firstUpdated=function(){const e=this.shadowRoot.querySelector(".card-header");e&&this.insertBefore(e,this.children[0]),document.querySelector("home-assistant").provideHass(this),window.addEventListener("location-changed",()=>this._requestUpdate())},Object.defineProperty(e.prototype,"hass",{get(){return this._hass},set(e){if(e!==this._hass){const t=this._hass;this._hass=e,this._requestUpdate("hass",t)}}}),function(e,t,r=null){if((e=new Event(e,{bubbles:!0,cancelable:!1,composed:!0})).detail=t||{},r)r.dispatchEvent(e);else{var s=document.querySelector("home-assistant");(s=(s=(s=(s=(s=(s=(s=(s=(s=(s=(s=s&&s.shadowRoot)&&s.querySelector("home-assistant-main"))&&s.shadowRoot)&&s.querySelector("app-drawer-layout partial-panel-resolver"))&&s.shadowRoot||s)&&s.querySelector("ha-panel-lovelace"))&&s.shadowRoot)&&s.querySelector("hui-root"))&&s.shadowRoot)&&s.querySelector("ha-app-layout #view"))&&s.firstElementChild)&&s.dispatchEvent(e)}}("ll-rebuild",{})})}]); \ No newline at end of file +!function(e){var t={};function r(s){if(t[s])return t[s].exports;var o=t[s]={i:s,l:!1,exports:{}};return e[s].call(o.exports,o,o.exports,r),o.l=!0,o.exports}r.m=e,r.c=t,r.d=function(e,t,s){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:s})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var s=Object.create(null);if(r.r(s),Object.defineProperty(s,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)r.d(s,o,function(t){return e[t]}.bind(null,o));return s},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="",r(r.s=3)}([function(e,t,r){"use strict";function s(){return document.querySelector("home-assistant").hass}r.d(t,"a",function(){return s})},function(module,__webpack_exports__,__webpack_require__){"use strict";__webpack_require__.d(__webpack_exports__,"a",function(){return parseTemplate});var _hass_js__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(0),_deviceID_js__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(2);function hasTemplate(e){return/\[\[\s+.*\s+\]\]/.test(e)}function parseTemplateString(str,specialData={}){if("string"!=typeof str)return text;const FUNCTION=/^[a-zA-Z0-9_]+\(.*\)$/,EXPR=/([^=<>!]+)\s*(==|!=|<|>|<=|>=)\s*([^=<>!]+)/,SPECIAL=/^\{.+\}$/,STRING=/^"[^"]*"|'[^']*'$/;"string"==typeof specialData&&(specialData={}),specialData=Object.assign({user:Object(_hass_js__WEBPACK_IMPORTED_MODULE_0__.a)().user.name,browser:_deviceID_js__WEBPACK_IMPORTED_MODULE_1__.a,hash:location.hash.substr(1)||" "},specialData);const _parse_function=e=>{let t=[e.substr(0,e.indexOf("(")).trim()];for(e=e.substr(e.indexOf("(")+1);e;){let r=0,s=0,o=!1;for(;e[r];){let t=e[r++];if(t===o&&r>1&&"\\"!==e[r-2]?o=!1:"\"'".includes(t)&&(o=t),!o){if("("===t)s+=1;else if(")"===t){s-=1;continue}if(!(s>0)&&",)".includes(t))break}}t.push(e.substr(0,r-1).trim()),e=e.substr(r)}return t},_parse_special=e=>(e=e.substr(1,e.length-2),specialData[e]||`{${e}}`),_parse_entity=e=>{let t;if((e=e.split("."))[0].match(SPECIAL))t=_parse_special(e.shift()),t=Object(_hass_js__WEBPACK_IMPORTED_MODULE_0__.a)().states[t]||t;else if(t=Object(_hass_js__WEBPACK_IMPORTED_MODULE_0__.a)().states[`${e.shift()}.${e.shift()}`],!e.length)return t.state;return e.forEach(e=>t=t[e]),t},_eval_expr=str=>{if(str=EXPR.exec(str),null===str)return!1;const lhs=parseTemplateString(str[1]),rhs=parseTemplateString(str[3]);var expr="";return expr=parseFloat(lhs)!=lhs?`"${lhs}" ${str[2]} "${rhs}"`:`${parseFloat(lhs)} ${str[2]} ${parseFloat(rhs)}`,eval(expr)},_eval_function=e=>{if("if"===e[0])return _eval_expr(e[1])?parseTemplateString(e[2]):parseTemplateString(e[3])};try{return str=str.trim(),str.match(STRING)?str.substr(1,str.length-2):str.match(SPECIAL)?_parse_special(str):str.match(FUNCTION)?_eval_function(_parse_function(str)):str.includes(".")?_parse_entity(str):str}catch(e){return`[[ Template matching failed: ${str} ]]`}}function parseTemplate(e,t={}){if("string"!=typeof e)return e;return e=e.replace(/\[\[\s(.*?)\s\]\]/g,(e,r,s,o)=>parseTemplateString(r,t))}},function(e,t,r){"use strict";r.d(t,"a",function(){return s});let s=function(){if(window.fully&&"function"==typeof fully.getDeviceId)return fully.getDeviceId();if(!localStorage["lovelace-player-device-id"]){const e=()=>Math.floor(1e5*(1+Math.random())).toString(16).substring(1);localStorage["lovelace-player-device-id"]=`${e()}${e()}-${e()}${e()}`}return localStorage["lovelace-player-device-id"]}()},function(e,t,r){"use strict";r.r(t);const s=Object.getPrototypeOf(customElements.get("home-assistant-main"));s.prototype.html,s.prototype.css;var o=r(1);customElements.whenDefined("ha-card").then(()=>{const e=customElements.get("ha-card"),t=function(e){return e.config?e.config:e._config?e._config:e.host?t(e.host):e.parentElement?t(e.parentElement):e.parentNode?t(e.parentNode):null},r=function(e,t,s){const n=function(e){s&&("string"==typeof e?console.log(" ".repeat(2*(s-1))+e):console.log(e))};if(e&&t)if("string"==typeof t){e.querySelector(".card-mod-style")&&e.removeChild(e.querySelector(".card-mod-style"));const r=document.createElement("style");r.classList="card-mod-style",r.innerHTML=Object(o.a)(t),e.appendChild(r),s&&(n("Applied styles to:"),console.log(e))}else Object.keys(t).forEach(o=>"."===o?(n(`Stepping into root of ${e.tagName}`),r(e,t[o],s?s+1:0)):"$"===o?(n(`Stepping into ShadowRoot of ${e.tagName}`),r(e.shadowRoot,t[o],s?s+1:0)):(n(`Searching for: "${o}". ${e.querySelectorAll(o).length} matches.`),void e.querySelectorAll(`${o}`).forEach(e=>{n(`Stepping into ${e.tagName}`),r(e,t[o],s?s+1:0)})))};e.prototype.updated=function(e){const s=t(this);s&&s.style&&(s.debug_cardmod&&console.log("--- APPLYING STYLES START ---"),r(this,s.style,s.debug_cardmod?1:0),s.debug_cardmod&&console.log("--- APPLYING STYLES END ---"))},e.prototype.firstUpdated=function(){const e=this.shadowRoot.querySelector(".card-header");e&&this.insertBefore(e,this.children[0]),document.querySelector("home-assistant").provideHass(this),window.addEventListener("location-changed",()=>this._requestUpdate())},Object.defineProperty(e.prototype,"hass",{get(){return this._hass},set(e){if(e!==this._hass){const t=this._hass;this._hass=e,this._requestUpdate("hass",t)}}}),function(e,t,r=null){if((e=new Event(e,{bubbles:!0,cancelable:!1,composed:!0})).detail=t||{},r)r.dispatchEvent(e);else{var s=document.querySelector("home-assistant");(s=(s=(s=(s=(s=(s=(s=(s=(s=(s=(s=s&&s.shadowRoot)&&s.querySelector("home-assistant-main"))&&s.shadowRoot)&&s.querySelector("app-drawer-layout partial-panel-resolver"))&&s.shadowRoot||s)&&s.querySelector("ha-panel-lovelace"))&&s.shadowRoot)&&s.querySelector("hui-root"))&&s.shadowRoot)&&s.querySelector("ha-app-layout #view"))&&s.firstElementChild)&&s.dispatchEvent(e)}}("ll-rebuild",{})})}]); \ No newline at end of file diff --git a/src/main.js b/src/main.js index 9e26d1b..8f48c4c 100644 --- a/src/main.js +++ b/src/main.js @@ -19,28 +19,45 @@ customElements.whenDefined('ha-card').then(() => { return null; }; - const applyStyle = function(root, style) { + const applyStyle = function(root, style, debug) { + + const debugPrint = function(str){ + if(!debug) return; + if(typeof str === "string") + console.log(' '.repeat(2*(debug-1)) + str); + else + console.log(str); + } + if(!root || !style) return; if(typeof style === "string") { // Remove old styles if we're updating - if(root.querySelector(":scope >.card-mod-style")) - root.removeChild(root.querySelector(":scope > .card-mod-style")); + if(root.querySelector(".card-mod-style")) + root.removeChild(root.querySelector(".card-mod-style")); // Add new style tag to the root element const styleEl = document.createElement('style'); styleEl.classList = "card-mod-style"; styleEl.innerHTML = parseTemplate(style); root.appendChild(styleEl); + if(debug) { + debugPrint("Applied styles to:") + console.log(root); + } } else { Object.keys(style).forEach((k) => { - if(k === ".") - return applyStyle(root, style[k]); - else if(k === "$") - return applyStyle(root.shadowRoot, style[k]); - else { - root.querySelectorAll(`:scope > ${k}`).forEach((el) => { - applyStyle(el, style[k]); + if(k === ".") { + debugPrint(`Stepping into root of ${root.tagName}`) + return applyStyle(root, style[k], debug?debug+1:0); + } else if(k === "$") { + debugPrint(`Stepping into ShadowRoot of ${root.tagName}`) + return applyStyle(root.shadowRoot, style[k], debug?debug+1:0); + } else { + debugPrint(`Searching for: "${k}". ${root.querySelectorAll(k).length} matches.`); + root.querySelectorAll(`${k}`).forEach((el) => { + debugPrint(`Stepping into ${el.tagName}`) + applyStyle(el, style[k], debug?debug+1:0); }); return; } @@ -51,8 +68,13 @@ customElements.whenDefined('ha-card').then(() => { HaCard.prototype.updated = function(_) { // Apply styles after updates, if specified const config = findConfig(this); - if(config && config.style) - applyStyle(this, config.style); + if(config && config.style) { + if(config.debug_cardmod) + console.log("--- APPLYING STYLES START ---"); + applyStyle(this, config.style, config.debug_cardmod ? 1 : 0); + if(config.debug_cardmod) + console.log("--- APPLYING STYLES END ---"); + } } HaCard.prototype.firstUpdated = function() {