From af99dbaf90887e6ce1c4eba6535c495a440c47bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Lov=C3=A9n?= Date: Wed, 11 Mar 2020 20:34:50 +0100 Subject: [PATCH] Hopefully make things work in safari too --- layout-card.js | 10 +++++----- package-lock.json | 5 +++++ package.json | 5 +++-- src/main.js | 35 ++++++++++++++++++++++------------- 4 files changed, 35 insertions(+), 20 deletions(-) diff --git a/layout-card.js b/layout-card.js index 2b508ad..88cf782 100644 --- a/layout-card.js +++ b/layout-card.js @@ -1,21 +1,21 @@ -!function(t){var e={};function n(o){if(e[o])return e[o].exports;var i=e[o]={i:o,l:!1,exports:{}};return t[o].call(i.exports,i,i.exports,n),i.l=!0,i.exports}n.m=t,n.c=e,n.d=function(t,e,o){n.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:o})},n.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},n.t=function(t,e){if(1&e&&(t=n(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var o=Object.create(null);if(n.r(o),Object.defineProperty(o,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var i in t)n.d(o,i,function(e){return t[e]}.bind(null,i));return o},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="",n(n.s=1)}([function(t){t.exports=JSON.parse('{"name":"layout-card","version":"1.2.0","description":"","private":true,"scripts":{"build":"webpack","watch":"webpack --watch --mode=development","update-card-tools":"npm uninstall card-tools && npm install thomasloven/lovelace-card-tools"},"author":"Thomas Lovén","license":"MIT","devDependencies":{"webpack":"^4.41.5","webpack-cli":"^3.3.10"},"dependencies":{"card-tools":"github:thomasloven/lovelace-card-tools"}}')},function(t,e,n){"use strict";n.r(e);const o=customElements.get("home-assistant-main")?Object.getPrototypeOf(customElements.get("home-assistant-main")):Object.getPrototypeOf(customElements.get("hui-view")),i=o.prototype.html,s=o.prototype.css;function r(){return document.querySelector("hc-main")?document.querySelector("hc-main").hass:document.querySelector("home-assistant")?document.querySelector("home-assistant").hass:void 0}function a(t,e,n=null){if((t=new Event(t,{bubbles:!0,cancelable:!1,composed:!0})).detail=e||{},n)n.dispatchEvent(t);else{var o=function(){var t=document.querySelector("hc-main");return t=t?(t=(t=(t=t&&t.shadowRoot)&&t.querySelector("hc-lovelace"))&&t.shadowRoot)&&t.querySelector("hui-view"):(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=document.querySelector("home-assistant"))&&t.shadowRoot)&&t.querySelector("home-assistant-main"))&&t.shadowRoot)&&t.querySelector("app-drawer-layout partial-panel-resolver"))&&t.shadowRoot||t)&&t.querySelector("ha-panel-lovelace"))&&t.shadowRoot)&&t.querySelector("hui-root"))&&t.shadowRoot)&&t.querySelector("ha-app-layout #view"))&&t.firstElementChild}();o&&o.dispatchEvent(t)}}let c=window.cardHelpers;const l=new Promise(async(t,e)=>{c&&t(),window.loadCardHelpers&&(c=await window.loadCardHelpers(),window.cardHelpers=c,t())});function d(t,e){const n=document.createElement("hui-error-card");return n.setConfig({type:"error",error:t,origConfig:e}),n}function u(t,e){if(!e||"object"!=typeof e||!e.type)return d(`No ${t} type configured`,e);let n=e.type;if(n=n.startsWith("custom:")?n.substr("custom:".length):`hui-${n}-${t}`,customElements.get(n))return function(t,e){let n=document.createElement(t);try{n.setConfig(JSON.parse(JSON.stringify(e)))}catch(t){n=d(t,e)}return l.then(()=>{a("ll-rebuild",{},n)}),n}(n,e);const o=d(`Custom element doesn't exist: ${n}.`,e);o.style.display="None";const i=setTimeout(()=>{o.style.display=""},2e3);return customElements.whenDefined(n).then(()=>{clearTimeout(i),a("ll-rebuild",{},o)}),o}function h(t,e,n){t.forEach(t=>{if(!t)return;const o=e[function(){let t=0;for(let o=0;o{for(let e of t)if(e.contentRect&&e.contentRect.width)return this._layoutWidth=e.contentRect.width,void this.place_cards()}),this.resizer.observe(this)}connectedCallback(){super.connectedCallback();let t=this.parentElement,e=10;for(;e--&&t&&("HUI-PANEL-VIEW"===t.tagName&&this.classList.add("panel"),"DIV"!==t.tagName););}async firstUpdated(){window.addEventListener("location-changed",()=>{""===location.hash&&setTimeout(()=>this.place_cards(),100)})}async updated(t){if(!this.cards.length&&(this._config.entities&&this._config.entities.length||this._config.cards&&this._config.cards.length)){this.clientWidth;this.cards=await this.build_cards(),this.place_cards()}t.has("hass")&&this.hass&&this.cards&&this.cards.forEach(t=>{t&&(t.hass=this.hass)})}async build_card(t){if("break"===t)return null;const e={...t,...this._config.card_options},n=function(t){return c?c.createCardElement(t):u("card",t)}(e);return n.hass=r(),n.style.gridColumn=e.gridcol,n.style.gridRow=e.gridrow,this.shadowRoot.querySelector("#staging").appendChild(n),new Promise((t,e)=>n.updateComplete?n.updateComplete.then(()=>t(n)):t(n))}async build_cards(){const t=this.shadowRoot.querySelector("#staging");for(;t.lastChild;)t.removeChild(t.lastChild);return Promise.all((this._config.entities||this._config.cards).map(t=>this.build_card(t)))}place_cards(){"grid"!==this._config.layout&&(this.columns=function(t,e,n){const o=t=>"string"==typeof t&&t.endsWith("%")?Math.floor(e*parseInt(t)/100):parseInt(t);let i=0;if("object"==typeof n.column_width){let t=e;for(;t>0;){let e=n.column_width[i];void 0===e&&(e=n.column_width.slice(-1)[0]),t-=o(e),i+=1}i=Math.max(i-1,1)}else i=Math.floor(e/o(n.column_width));i=Math.max(i,n.min_columns),i=Math.min(i,n.max_columns),i=Math.max(i,1);let s=[];for(let t=0;t{if(o+=1,!t)return;const n=e[(o-1)%e.length];n.appendChild(t),n.length+=t.getCardSize?t.getCardSize():1})}(t,s);break;case"vertical":!function(t,e,n){let o=0;t.forEach(t=>{if(!t)return void(o+=1);const n=e[o%e.length];n.appendChild(t),n.length+=t.getCardSize?t.getCardSize():1})}(t,s);break;case"auto":default:h(t,s,n)}return s=s.filter(t=>t.childElementCount>0),s}(this.cards,this._layoutWidth||1,this._config),this._config.rtl&&this.columns.reverse(),this.format_columns(),this.requestUpdate())}format_columns(){const t=(t,e,n,o="px")=>{if(void 0===this._config[e])return"";let i=`${t}: `;const s=this._config[e];return"object"==typeof s?s.length>n?i+=`${s[n]}`:i+=`${s.slice(-1)}`:i+=`${s}`,i.endsWith("px")||i.endsWith("%")||(i+=o),i+";"};for(const[e,n]of this.columns.entries()){const o=[t("max-width","max_width",e),t("min-width","min_width",e),t("width","column_width",e),t("flex-grow","flex_grow",e,"")];n.style.cssText="".concat(...o)}}getCardSize(){if(this.columns)return Math.max.apply(Math,this.columns.map(t=>t.length))}render(){return"grid"===this._config.layout?i` +!function(t){var e={};function i(n){if(e[n])return e[n].exports;var r=e[n]={i:n,l:!1,exports:{}};return t[n].call(r.exports,r,r.exports,i),r.l=!0,r.exports}i.m=t,i.c=e,i.d=function(t,e,n){i.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:n})},i.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},i.t=function(t,e){if(1&e&&(t=i(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var n=Object.create(null);if(i.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var r in t)i.d(n,r,function(e){return t[e]}.bind(null,r));return n},i.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return i.d(e,"a",e),e},i.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},i.p="",i(i.s=5)}([function(t,e,i){"use strict";Object.defineProperty(e,"__esModule",{value:!0});e.ContentRect=function(t){if("getBBox"in t){var e=t.getBBox();return Object.freeze({height:e.height,left:0,top:0,width:e.width})}var i=window.getComputedStyle(t);return Object.freeze({height:parseFloat(i.height||"0"),left:parseFloat(i.paddingLeft||"0"),top:parseFloat(i.paddingTop||"0"),width:parseFloat(i.width||"0")})}},function(t,e,i){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var n=i(2),r=i(3),o=[],s=function(){function t(t){this.$$observationTargets=[],this.$$activeTargets=[],this.$$skippedTargets=[];var e=function(t){if(void 0===t)return"Failed to construct 'ResizeObserver': 1 argument required, but only 0 present.";if("function"!=typeof t)return"Failed to construct 'ResizeObserver': The callback provided as parameter 1 is not a function."}(t);if(e)throw TypeError(e);this.$$callback=t,o.push(this)}return t.prototype.observe=function(t){var e=a("observe",t);if(e)throw TypeError(e);c(this.$$observationTargets,t)>0||(this.$$observationTargets.push(new n.ResizeObservation(t)),p())},t.prototype.unobserve=function(t){var e=a("unobserve",t);if(e)throw TypeError(e);var i=c(this.$$observationTargets,t);i<0||(this.$$observationTargets.splice(i,1),m())},t.prototype.disconnect=function(){this.$$observationTargets=[],this.$$activeTargets=[]},t}();function a(t,e){return void 0===e?"Failed to execute '"+t+"' on 'ResizeObserver': 1 argument required, but only 0 present.":e instanceof window.Element?void 0:"Failed to execute '"+t+"' on 'ResizeObserver': parameter 1 is not of type 'Element'."}function c(t,e){for(var i=0;it?e.$$activeTargets.push(i):e.$$skippedTargets.push(i))}))}))},u=function(){var t=1/0;return o.forEach((function(e){if(e.$$activeTargets.length){var i=[];e.$$activeTargets.forEach((function(e){var n=new r.ResizeObserverEntry(e.target);i.push(n),e.$$broadcastWidth=n.contentRect.width,e.$$broadcastHeight=n.contentRect.height;var o=h(e.target);o{c&&t(),window.loadCardHelpers&&(c=await window.loadCardHelpers(),window.cardHelpers=c,t())});function d(t,e){const i=document.createElement("hui-error-card");return i.setConfig({type:"error",error:t,origConfig:e}),i}function u(t,e){if(!e||"object"!=typeof e||!e.type)return d(`No ${t} type configured`,e);let i=e.type;if(i=i.startsWith("custom:")?i.substr("custom:".length):`hui-${i}-${t}`,customElements.get(i))return function(t,e){let i=document.createElement(t);try{i.setConfig(JSON.parse(JSON.stringify(e)))}catch(t){i=d(t,e)}return l.then(()=>{a("ll-rebuild",{},i)}),i}(i,e);const n=d(`Custom element doesn't exist: ${i}.`,e);n.style.display="None";const r=setTimeout(()=>{n.style.display=""},2e3);return customElements.whenDefined(i).then(()=>{clearTimeout(r),a("ll-rebuild",{},n)}),n}function h(t,e,i){t.forEach(t=>{if(!t)return;const n=e[function(){let t=0;for(let n=0;n{""===location.hash&&setTimeout(()=>this.updateSize(),100)}),this.resizer||(this.resizer=new f.ResizeObserver(()=>this.updateSize()),this.resizer.observe(this)),this.updateSize()}updateSize(){const t=this.getBoundingClientRect().width;t&&t!==this._layoutWidth&&(this._layoutWidth=t,this.resizer.disconnect(),this.place_cards(),this.requestUpdate().then(()=>this.resizer.observe(this)))}async updated(t){if(!this.cards.length&&(this._config.entities&&this._config.entities.length||this._config.cards&&this._config.cards.length)){this.clientWidth;this.cards=await this.build_cards(),this.place_cards(),this.requestUpdate()}t.has("hass")&&this.hass&&this.cards&&this.cards.forEach(t=>{t&&(t.hass=this.hass)})}async build_card(t){if("break"===t)return null;const e={...t,...this._config.card_options},i=function(t){return c?c.createCardElement(t):u("card",t)}(e);return i.hass=s(),i.style.gridColumn=e.gridcol,i.style.gridRow=e.gridrow,this.shadowRoot.querySelector("#staging").appendChild(i),new Promise((t,e)=>i.updateComplete?i.updateComplete.then(()=>t(i)):t(i))}async build_cards(){const t=this.shadowRoot.querySelector("#staging");for(;t.lastChild;)t.removeChild(t.lastChild);return Promise.all((this._config.entities||this._config.cards).map(t=>this.build_card(t)))}place_cards(){"grid"!==this._config.layout&&this.cards.length&&(this.columns=function(t,e,i){const n=t=>"string"==typeof t&&t.endsWith("%")?Math.floor(e*parseInt(t)/100):parseInt(t);let r=0;if("object"==typeof i.column_width){let t=e;for(;t>0;){let e=i.column_width[r];void 0===e&&(e=i.column_width.slice(-1)[0]),t-=n(e),r+=1}r=Math.max(r-1,1)}else r=Math.floor(e/n(i.column_width));r=Math.max(r,i.min_columns),r=Math.min(r,i.max_columns),r=Math.max(r,1);let o=[];for(let t=0;t{if(n+=1,!t)return;const i=e[(n-1)%e.length];i.appendChild(t),i.length+=t.getCardSize?t.getCardSize():1})}(t,o);break;case"vertical":!function(t,e,i){let n=0;t.forEach(t=>{if(!t)return void(n+=1);const i=e[n%e.length];i.appendChild(t),i.length+=t.getCardSize?t.getCardSize():1})}(t,o);break;case"auto":default:h(t,o,i)}return o=o.filter(t=>t.childElementCount>0),o}(this.cards,this._layoutWidth||1,this._config),this._config.rtl&&this.columns.reverse(),this.format_columns())}format_columns(){const t=(t,e,i,n="px")=>{if(void 0===this._config[e])return"";let r=`${t}: `;const o=this._config[e];return"object"==typeof o?o.length>i?r+=`${o[i]}`:r+=`${o.slice(-1)}`:r+=`${o}`,r.endsWith("px")||r.endsWith("%")||(r+=n),r+";"};for(const[e,i]of this.columns.entries()){const n=[t("max-width","max_width",e),t("min-width","min_width",e),t("width","column_width",e),t("flex-grow","flex_grow",e,"")];i.style.cssText="".concat(...n)}}getCardSize(){if(this.columns)return Math.max.apply(Math,this.columns.map(t=>t.length))}render(){return"grid"===this._config.layout?r`
- `:i` + `:r`
- ${this.columns.map(t=>i` + ${this.columns.map(t=>r` ${t} `)}
- `}static get styles(){return s` + `}static get styles(){return o` :host { padding: 0; display: block; @@ -65,4 +65,4 @@ #staging.grid { margin: 0 -4px; } - `}get _cardModder(){return{target:this}}}if(!customElements.get("layout-card")){customElements.define("layout-card",m);const t=n(0);console.info(`%cLAYOUT-CARD ${t.version} IS INSTALLED`,"color: green; font-weight: bold","")}}]); \ No newline at end of file + `}get _cardModder(){return{target:this}}}if(!customElements.get("layout-card")){customElements.define("layout-card",p);const t=i(4);console.info(`%cLAYOUT-CARD ${t.version} IS INSTALLED`,"color: green; font-weight: bold","")}}]); \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 8b5ae54..1e28bf3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3168,6 +3168,11 @@ "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", "dev": true }, + "resize-observer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resize-observer/-/resize-observer-1.0.0.tgz", + "integrity": "sha512-D7UFShDm2TgrEDEyeg+/tTEbvOgPWlvPAfJtxiKp+qutu6HowmcGJKjECgGru0PPDIj3SAucn3ZPpOx54fF7DQ==" + }, "resolve-cwd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz", diff --git a/package.json b/package.json index 9179c1b..574c226 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "layout-card", - "version": "1.2.0", + "version": "1.2.1", "description": "", "private": true, "scripts": { @@ -15,6 +15,7 @@ "webpack-cli": "^3.3.10" }, "dependencies": { - "card-tools": "github:thomasloven/lovelace-card-tools" + "card-tools": "github:thomasloven/lovelace-card-tools", + "resize-observer": "^1.0.0" } } diff --git a/src/main.js b/src/main.js index 05cd6fa..1894670 100644 --- a/src/main.js +++ b/src/main.js @@ -4,6 +4,8 @@ import { hass } from "card-tools/src/hass"; import {buildLayout} from "./layout"; +import { ResizeObserver } from "resize-observer"; + class LayoutCard extends LitElement { static get properties() { @@ -28,16 +30,7 @@ class LayoutCard extends LitElement { this.cards = []; this.columns = []; - this.resizer = new ResizeObserver((entries) => { - for (let e of entries) { - if(e.contentRect && e.contentRect.width) { - this._layoutWidth = e.contentRect.width; - this.place_cards(); - return; - } - } - }); - this.resizer.observe(this); + this._layoutWidth = 0; } connectedCallback() { @@ -55,8 +48,23 @@ class LayoutCard extends LitElement { async firstUpdated() { window.addEventListener('location-changed', () => { if(location.hash === "") - setTimeout(() => this.place_cards(), 100) + setTimeout(() => this.updateSize(), 100) }); + if(!this.resizer) { + this.resizer = new ResizeObserver(() => this.updateSize()); + this.resizer.observe(this); + } + this.updateSize(); + } + + updateSize() { + const width = this.getBoundingClientRect().width; + if(width && width !== this._layoutWidth) { + this._layoutWidth = width; + this.resizer.disconnect(); + this.place_cards(); + this.requestUpdate().then(() => this.resizer.observe(this)); + } } async updated(changedproperties) { @@ -68,6 +76,7 @@ class LayoutCard extends LitElement { const width = this.clientWidth; this.cards = await this.build_cards(); this.place_cards(); + this.requestUpdate(); } if(changedproperties.has("hass") && this.hass && this.cards) { @@ -112,6 +121,8 @@ class LayoutCard extends LitElement { place_cards() { if(this._config.layout === "grid") return; + if(!this.cards.length) + return; this.columns = buildLayout( this.cards, this._layoutWidth || 1, @@ -122,8 +133,6 @@ class LayoutCard extends LitElement { this.columns.reverse(); this.format_columns(); - - this.requestUpdate(); } format_columns() {