2025-11-24 14:01:48 +01:00
|
|
|
<script setup>
|
|
|
|
|
import PagedJsWrapper from './components/PagedJsWrapper.vue';
|
2025-12-03 15:20:49 +01:00
|
|
|
import EditorPanel from './components/editor/EditorPanel.vue';
|
2025-11-24 16:51:55 +01:00
|
|
|
import StylesheetViewer from './components/StylesheetViewer.vue';
|
|
|
|
|
import ElementPopup from './components/ElementPopup.vue';
|
|
|
|
|
import { onMounted, ref, watch } from 'vue';
|
2025-11-24 17:55:42 +01:00
|
|
|
import { useStylesheetStore } from './stores/stylesheet';
|
|
|
|
|
|
|
|
|
|
const stylesheetStore = useStylesheetStore();
|
2025-11-24 18:01:47 +01:00
|
|
|
const previewFrame = ref(null);
|
2025-11-24 18:18:27 +01:00
|
|
|
const elementPopup = ref(null);
|
|
|
|
|
|
2025-12-03 15:20:49 +01:00
|
|
|
let savedScrollPercentage = 0;
|
|
|
|
|
|
|
|
|
|
const renderPreview = async (shouldReloadFromFile = false) => {
|
2025-11-24 16:51:55 +01:00
|
|
|
const iframe = previewFrame.value;
|
|
|
|
|
if (!iframe) return;
|
|
|
|
|
|
2025-12-03 15:20:49 +01:00
|
|
|
if (iframe.contentWindow && iframe.contentDocument) {
|
|
|
|
|
const scrollTop = iframe.contentWindow.scrollY || 0;
|
|
|
|
|
const scrollHeight = iframe.contentDocument.documentElement.scrollHeight;
|
|
|
|
|
const clientHeight = iframe.contentWindow.innerHeight;
|
|
|
|
|
const maxScroll = scrollHeight - clientHeight;
|
|
|
|
|
|
|
|
|
|
savedScrollPercentage = maxScroll > 0 ? scrollTop / maxScroll : 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (shouldReloadFromFile || !stylesheetStore.content) {
|
|
|
|
|
await stylesheetStore.loadStylesheet();
|
|
|
|
|
}
|
2025-11-24 16:51:55 +01:00
|
|
|
|
2025-11-24 17:55:42 +01:00
|
|
|
iframe.srcdoc = `
|
2025-11-24 16:51:55 +01:00
|
|
|
<!DOCTYPE html>
|
|
|
|
|
<html>
|
|
|
|
|
<head>
|
|
|
|
|
<link rel="stylesheet" href="/assets/css/pagedjs-interface.css">
|
2025-11-24 17:55:42 +01:00
|
|
|
<style id="dynamic-styles">${stylesheetStore.content}</style>
|
2025-11-24 16:51:55 +01:00
|
|
|
<script src="https://unpkg.com/pagedjs/dist/paged.polyfill.js"><\/script>
|
|
|
|
|
</head>
|
2025-11-24 17:55:42 +01:00
|
|
|
<body>${document.getElementById('content-source').innerHTML}</body>
|
2025-11-24 16:51:55 +01:00
|
|
|
</html>
|
2025-11-24 17:55:42 +01:00
|
|
|
`;
|
2025-11-24 16:51:55 +01:00
|
|
|
|
|
|
|
|
iframe.onload = () => {
|
2025-11-24 18:18:27 +01:00
|
|
|
iframe.contentDocument.addEventListener('click', elementPopup.value.handleIframeClick);
|
2025-12-03 15:20:49 +01:00
|
|
|
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
const scrollHeight = iframe.contentDocument.documentElement.scrollHeight;
|
|
|
|
|
const clientHeight = iframe.contentWindow.innerHeight;
|
|
|
|
|
const maxScroll = scrollHeight - clientHeight;
|
|
|
|
|
const targetScroll = savedScrollPercentage * maxScroll;
|
|
|
|
|
|
|
|
|
|
iframe.contentWindow.scrollTo(0, targetScroll);
|
|
|
|
|
}, 500);
|
2025-11-24 18:01:47 +01:00
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
2025-12-03 15:20:49 +01:00
|
|
|
watch(() => stylesheetStore.content, () => {
|
|
|
|
|
renderPreview();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
onMounted(() => renderPreview(true));
|
2025-11-24 14:01:48 +01:00
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<template>
|
2025-11-24 16:51:55 +01:00
|
|
|
<div id="content-source" style="display: none">
|
2025-11-24 14:01:48 +01:00
|
|
|
<PagedJsWrapper />
|
|
|
|
|
</div>
|
|
|
|
|
|
2025-11-24 18:18:27 +01:00
|
|
|
<EditorPanel />
|
2025-11-24 14:01:48 +01:00
|
|
|
|
2025-11-24 16:51:55 +01:00
|
|
|
<iframe ref="previewFrame" id="preview-frame"></iframe>
|
2025-11-24 14:01:48 +01:00
|
|
|
|
2025-11-24 17:55:42 +01:00
|
|
|
<StylesheetViewer :stylesheet="stylesheetStore.content" />
|
2025-11-24 14:01:48 +01:00
|
|
|
|
2025-11-24 18:18:27 +01:00
|
|
|
<ElementPopup ref="elementPopup" :iframeRef="previewFrame" />
|
2025-11-24 16:51:55 +01:00
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<style>
|
|
|
|
|
#preview-frame {
|
|
|
|
|
position: fixed;
|
|
|
|
|
top: 0;
|
|
|
|
|
left: 250px;
|
|
|
|
|
width: calc(100% - 600px);
|
|
|
|
|
height: 100vh;
|
|
|
|
|
border: none;
|
2025-11-24 14:01:48 +01:00
|
|
|
}
|
|
|
|
|
</style>
|