diff --git a/docs/widgets.md b/docs/widgets.md index bf02d07599..618dced09b 100644 --- a/docs/widgets.md +++ b/docs/widgets.md @@ -3350,6 +3350,7 @@ Many websites and apps provide their own embeddable widgets. These can be used w **Field** | **Type** | **Required** | **Description** --- | --- | --- | --- **`html`** | `string` | _Optional_ | HTML contents to render in the widget +**`htmlSrc`** | `string` | _Optional_ | A URL (local or remote) to fetch HTML contents from, instead of defining `html` **`script`** | `string` | _Optional_ | Raw JavaScript code to execute (caution) **`scriptSrc`** | `string` | _Optional_ | A URL to JavaScript content (caution) **`css`** | `string` | _Optional_ | Any stylings for widget contents @@ -3380,6 +3381,15 @@ Or scriptSrc: 'https://files.coinmarketcap.com/static/widget/currency.js' ``` +Or fetch the markup from a file, so it's styled like the rest of your dashboard: + +```yaml +- type: embed + options: + htmlSrc: /component.html + css: 'p { color: var(--widget-text-color); }' +``` + You can also use this widget to display an image, wither locally or from a remote origin. ```yaml diff --git a/src/components/Widgets/EmbedWidget.vue b/src/components/Widgets/EmbedWidget.vue index 2e90600705..24f11d650b 100644 --- a/src/components/Widgets/EmbedWidget.vue +++ b/src/components/Widgets/EmbedWidget.vue @@ -26,6 +26,10 @@ export default { scriptSrc() { return this.options.scriptSrc || ''; }, + /* Optional URL to fetch HTML markup from */ + htmlSrc() { + return this.options.htmlSrc || ''; + }, /* Unique element ID */ elementId() { return `elem-${Math.round(Math.random() * 10000)}`; @@ -38,6 +42,25 @@ export default { window.removeEventListener('load', this.injectHtml); }, methods: { + /* Fetches remote HTML (if htmlSrc set), then renders it */ + fetchData() { + if (!this.htmlSrc) { + this.finishLoading(); + return; + } + this.makeRequest(this.htmlSrc) + .then(this.processData) + .catch(() => { /* error already surfaced by the mixin */ }); + }, + /* Renders fetched HTML into the widget */ + processData(data) { + if (typeof data !== 'string') { + this.error('Fetched content is not HTML', data); + return; + } + const element = document.getElementById(this.elementId); + if (element) element.innerHTML = data; + }, /* Injects users content */ injectHtml() { if (this.html) { @@ -69,7 +92,12 @@ export default { } }, update() { - this.injectHtml(); + if (this.htmlSrc) { + this.startLoading(); + this.fetchData(); + } else { + this.injectHtml(); + } }, }, };