diff --git a/fe/src/components/panels/PanelEdit.vue b/fe/src/components/panels/PanelEdit.vue index 9bb6ad3..c9f4907 100644 --- a/fe/src/components/panels/PanelEdit.vue +++ b/fe/src/components/panels/PanelEdit.vue @@ -76,6 +76,7 @@ import { CheckMacroListChange, GetMacroList } from '@/services/MacroService' import { PanelButtonListeners, + PanelDialogListeners, RemovePanelStyle, SetPanelStyle, StripPanelHTML, @@ -151,6 +152,7 @@ function EditButtonListeners() { } PanelButtonListeners(panelPreview.value, callback) + PanelDialogListeners(panelPreview.value) } function setEditButton(id) { diff --git a/fe/src/components/panels/PanelView.vue b/fe/src/components/panels/PanelView.vue index 0796571..f08ff33 100644 --- a/fe/src/components/panels/PanelView.vue +++ b/fe/src/components/panels/PanelView.vue @@ -8,6 +8,8 @@ import { RunMacro } from '@/services/MacroService' import { PanelButtonListeners, + PanelDialogListeners, + RemovePanelScripts, RemovePanelStyle, SetPanelStyle, StripPanelHTML, @@ -33,20 +35,26 @@ onMounted(async () => { SetPanelStyle(viewPanel.value.style) setTimeout(() => { - viewPanelButtonListeners() + viewPanelListeners() + + if (typeof window.onPanelLoaded === 'function') { + window.onPanelLoaded() + } }, 50) }) onUnmounted(() => { RemovePanelStyle() + RemovePanelScripts() }) -const viewPanelButtonListeners = () => { +const viewPanelListeners = () => { const callback = (button) => { RunMacro(viewPanel.value.macros[button.id]) } PanelButtonListeners(panelView.value, callback) + PanelDialogListeners(panelView.value) } diff --git a/fe/src/services/PanelService.js b/fe/src/services/PanelService.js index 5868191..ca85f55 100644 --- a/fe/src/services/PanelService.js +++ b/fe/src/services/PanelService.js @@ -15,6 +15,13 @@ export const RemovePanelStyle = () => { export const StripPanelHTML = (html, aspectRatio) => { const parser = new DOMParser() const doc = parser.parseFromString(html, 'text/html') + let scripts = [] + + if (doc.querySelectorAll('script').length > 0) { + const stripped = StripPanelScripts(doc) + doc.body = stripped.body + scripts = stripped.scripts + } const body = doc.body const bodyContents = body.innerHTML @@ -24,9 +31,41 @@ export const StripPanelHTML = (html, aspectRatio) => { panelBody.style = `aspect-ratio: ${aspectRatio}` panelBody.innerHTML = bodyContents + if (scripts.length > 0) { + SetPanelScripts(scripts) + } + return panelBody.outerHTML } +export const StripPanelScripts = (doc) => { + const scriptEls = doc.querySelectorAll('script') + const scripts = [] + + scriptEls.forEach((script) => { + if (script.getAttribute('no-compile') != '') scripts.push(script.innerHTML) + script.remove() + }) + + return { body: doc.body, scripts } +} + +export const SetPanelScripts = (scripts) => { + scripts.forEach((script) => { + const scriptEl = document.createElement('script') + scriptEl.setAttribute('custom_panel_script', true) + scriptEl.innerHTML = script + document.body.appendChild(scriptEl) + }) +} + +export const RemovePanelScripts = () => { + const scripts = document.querySelectorAll('script[custom_panel_script]') + scripts.forEach((script) => { + script.remove() + }) +} + export const PanelButtonListeners = (panelEl, callback) => { panelEl.querySelectorAll('[mcrm__button]').forEach((button) => { button.addEventListener('click', () => { @@ -34,3 +73,27 @@ export const PanelButtonListeners = (panelEl, callback) => { }) }) } + +export const PanelDialogListeners = (panelEl) => { + panelEl.querySelectorAll('[mcrm__dialog-trigger]').forEach((dialogTrigger) => { + const dialogEl = document.querySelector(dialogTrigger.getAttribute('dialog-trigger')) + + if (dialogEl) { + dialogTrigger.addEventListener('click', () => { + dialogEl.show() + }) + } + }) + + document.querySelectorAll('dialog, dialog .dialog__close').forEach((dialogClose) => { + dialogClose.addEventListener('click', (e) => { + if ( + e.target.classList.contains('dialog__close') || + e.target.closest('.dialog__close') || + e.target.tagName == 'DIALOG' + ) { + dialogClose.closest('dialog').close() + } + }) + }) +}