From 98590f45f2d980671027da8a14074e0464519903 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Lov=C3=A9n?= Date: Sun, 9 Jun 2019 19:41:03 +0200 Subject: [PATCH] Stability improvements --- .gitattributes | 1 + markdown-mod.js | 11 +----- src/main.js | 95 ++++++++++++++++++++++++------------------------- 3 files changed, 49 insertions(+), 58 deletions(-) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..e15a818 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +markdown-mod.js binary diff --git a/markdown-mod.js b/markdown-mod.js index dd408c0..8a13813 100644 --- a/markdown-mod.js +++ b/markdown-mod.js @@ -1,10 +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")),a=s.prototype.html;s.prototype.css;var n=r(1);const o=customElements.get("hui-markdown-card"),i=customElements.get("ha-markdown"),l=["svg","path","ha-icon"],c=i.prototype._render;i.prototype._render=function(){this.oldFilterXSS||(this.oldFilterXSS=this.filterXSS,this.filterXSS=function(e,t){return this.oldFilterXSS(e,{onIgnoreTag:this.allowSvg?(e,t)=>l.indexOf(e)>=0?t:null:null})}),c.bind(this)()},o.prototype.render=function(){return this._config?a` - - - - - `:a``},o.prototype.firstUpdated=function(){window.addEventListener("location-changed",()=>this._requestUpdate())},Object.defineProperty(o.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 n=t[s]={i:s,l:!1,exports:{}};return e[s].call(n.exports,n,n.exports,r),n.l=!0,n.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 n in e)r.d(s,n,function(t){return e[t]}.bind(null,n));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,n=!1;for(;e[r];){let t=e[r++];if(t===n&&r>1&&"\\"!==e[r-2]?n=!1:"\"'".includes(t)&&(n=t),!n){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,n)=>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 n=r(1);function a(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)}}customElements.whenDefined("ha-markdown").then(()=>{const e=customElements.get("ha-markdown"),t=["svg","path","ha-icon"],r=e.prototype._render;e.prototype._render=function(){0===this._scriptLoaded||this._renderScheduled||(this.oldFilterXSS||(this.oldFilterXSS=this.filterXSS),this.filterXSS=function(e,r){return-1==e?1:this.oldFilterXSS(e,{onIgnoreTag:this.allowSvg?(e,r)=>t.indexOf(e)>=0?r:null:null})},r.bind(this)())},a("ll-rebuild",{})}),customElements.whenDefined("hui-markdown-card").then(()=>{const e=customElements.get("hui-markdown-card");e.prototype.updated=function(e){const t=this.shadowRoot.querySelector("ha-markdown");t&&(t.allowSvg=!0,t.content=Object(n.a)(this._config.content))},e.prototype.firstUpdated=function(){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)}}}),a("ll-rebuild",{})})}]); \ No newline at end of file diff --git a/src/main.js b/src/main.js index 1e24414..a7f6563 100644 --- a/src/main.js +++ b/src/main.js @@ -2,64 +2,63 @@ import {html} from "/card-tools/lit-element.js"; import {parseTemplate} from "/card-tools/templates.js"; import {fireEvent} from "/card-tools/event.js"; -const HuiMarkDownCard = customElements.get('hui-markdown-card'); -const HaMarkdown = customElements.get('ha-markdown'); +customElements.whenDefined('ha-markdown').then(() => { + const HaMarkdown = customElements.get('ha-markdown'); -// Patch ha-markdown.filterXSS to allow ha-icon tags -// filterXSS is lazy-loaded, so we need to patch it in the _render function -const svgWhiteList = ["svg", "path", "ha-icon"]; -const oldRender = HaMarkdown.prototype._render; -HaMarkdown.prototype._render = function () { - if(! this.oldFilterXSS) { - this.oldFilterXSS = this.filterXSS; + // Patch ha-markdown.filterXSS to allow ha-icon tags + // filterXSS is lazy-loaded, so we need to patch it in the _render function + const svgWhiteList = ["svg", "path", "ha-icon"]; + const oldRender = HaMarkdown.prototype._render; + HaMarkdown.prototype._render = function () { + if (this._scriptLoaded === 0 || this._renderScheduled) return; + if(! this.oldFilterXSS) { + this.oldFilterXSS = this.filterXSS; + } this.filterXSS = function(data, options) { + if(data == -1) return 1; return this.oldFilterXSS(data, { onIgnoreTag: this.allowSvg ? (tag, html) => (svgWhiteList.indexOf(tag) >= 0 ? html: null) : null, }); } - } - oldRender.bind(this)(); -}; + oldRender.bind(this)(); + }; + // Rebuild everything to make sure the patched versions are loaded + fireEvent('ll-rebuild', {}); +}); -// Patch hui-markdown-card to allow tags and parse templates -HuiMarkDownCard.prototype.render = function () { - if (!this._config) { - return html``; - } - return html` - - - - - `; -}; +customElements.whenDefined('hui-markdown-card').then(() => { + const HuiMarkDownCard = customElements.get('hui-markdown-card'); -// Add a listener for location-changed on first update -// This helps keeping track of the page hash -HuiMarkDownCard.prototype.firstUpdated = function () { - window.addEventListener("location-changed", () => this._requestUpdate()); -} + // Change content of ha-markdown element and allow svgs after each update + HuiMarkDownCard.prototype.updated = function(_) { + const markdown = this.shadowRoot.querySelector("ha-markdown"); + if(!markdown) return; + markdown.allowSvg = true; + markdown.content = parseTemplate(this._config.content); + } -// Add a .hass property to hui-markdown-card and update when it's changed -Object.defineProperty(HuiMarkDownCard.prototype, 'hass', { - get() { - return this._hass; - }, - set(value) { - if(value !== this._hass) { - const oldval = this._hass; - this._hass = value; - this._requestUpdate('hass', oldval); - } - }, -}); + // Add a listener for location-changed on first update + // This helps keeping track of the page hash + HuiMarkDownCard.prototype.firstUpdated = function () { + window.addEventListener("location-changed", () => this._requestUpdate()); + } -// Rebuild everything to make sure the patched versions are loaded -fireEvent('ll-rebuild', {}); + // Add a .hass property to hui-markdown-card and update when it's changed + Object.defineProperty(HuiMarkDownCard.prototype, 'hass', { + get() { + return this._hass; + }, + set(value) { + if(value !== this._hass) { + const oldval = this._hass; + this._hass = value; + this._requestUpdate('hass', oldval); + } + }, + }); + // Rebuild everything to make sure the patched versions are loaded + fireEvent('ll-rebuild', {}); +});