226 lines
6.9 KiB
Handlebars
226 lines
6.9 KiB
Handlebars
<style>
|
|
html,
|
|
body {
|
|
width: 100%;
|
|
height: 100%;
|
|
margin: 0;
|
|
overflow: hidden;
|
|
background: #111;
|
|
color: #fff;
|
|
}
|
|
|
|
#popup-preview-stage {
|
|
width: 100%;
|
|
height: 100%;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
overflow: hidden;
|
|
}
|
|
|
|
#popup-preview-canvas {
|
|
position: relative;
|
|
left: auto;
|
|
top: auto;
|
|
transform-origin: center center;
|
|
flex: 0 0 auto;
|
|
box-sizing: border-box;
|
|
display: block;
|
|
}
|
|
|
|
#popup-preview-canvas iframe {
|
|
width: 100%;
|
|
height: 100%;
|
|
border: 0;
|
|
display: block;
|
|
overflow: hidden;
|
|
}
|
|
|
|
#popup-preview-canvas .slide-preview-webpage-region iframe {
|
|
background: #fff;
|
|
}
|
|
|
|
#popup-preview-canvas .slide-preview-html-region iframe {
|
|
background: transparent;
|
|
}
|
|
|
|
.slide-preview-text-content {
|
|
line-height: 1.5;
|
|
}
|
|
|
|
.slide-preview-text-content > * {
|
|
margin: 1em 0;
|
|
}
|
|
|
|
.slide-preview-text-content > *:first-child {
|
|
margin-top: 0;
|
|
}
|
|
|
|
.slide-preview-text-content > *:last-child {
|
|
margin-bottom: 1em;
|
|
}
|
|
|
|
.slide-preview-text-content ul,
|
|
.slide-preview-text-content ol {
|
|
padding-left: 1.2em;
|
|
}
|
|
|
|
.slide-preview-text-content code {
|
|
white-space: pre-wrap;
|
|
}
|
|
</style>
|
|
|
|
<div class="slide-preview-popup-stage" id="popup-preview-stage">
|
|
<div class="slide-preview-popup-canvas" id="popup-preview-canvas"></div>
|
|
</div>
|
|
|
|
{{#if popupPreviewPayloadJson}}
|
|
<script>
|
|
window.__pulsePopupPreviewPayload = {{{popupPreviewPayloadJson}}};
|
|
</script>
|
|
{{/if}}
|
|
|
|
<script>
|
|
(function () {
|
|
function startPreviewVideoPlayback(root) {
|
|
if (!root) {
|
|
return;
|
|
}
|
|
|
|
var videos = root.querySelectorAll('video.slide-preview-video');
|
|
Array.prototype.forEach.call(videos, function (video) {
|
|
if (!video) {
|
|
return;
|
|
}
|
|
|
|
video.autoplay = true;
|
|
video.loop = true;
|
|
video.muted = true;
|
|
video.playsInline = true;
|
|
|
|
function tryPlay() {
|
|
try {
|
|
video.load();
|
|
} catch (_error) {
|
|
// Ignore load failures and try to play anyway.
|
|
}
|
|
|
|
var playPromise = video.play && video.play();
|
|
if (playPromise && typeof playPromise.catch === 'function') {
|
|
playPromise.catch(function () {
|
|
return null;
|
|
});
|
|
}
|
|
}
|
|
|
|
if (video.readyState >= 2) {
|
|
tryPlay();
|
|
return;
|
|
}
|
|
|
|
video.addEventListener('canplay', tryPlay, { once: true });
|
|
video.addEventListener('loadedmetadata', tryPlay, { once: true });
|
|
});
|
|
}
|
|
|
|
function injectFontStylesheet(href) {
|
|
var normalizedHref = String(href || '').trim();
|
|
if (!normalizedHref) {
|
|
return;
|
|
}
|
|
|
|
var existing = document.querySelector('link[data-slide-preview-fonts="true"]');
|
|
if (existing && existing.getAttribute('href') === normalizedHref) {
|
|
return;
|
|
}
|
|
|
|
if (existing && existing.parentNode) {
|
|
existing.parentNode.removeChild(existing);
|
|
}
|
|
|
|
var link = document.createElement('link');
|
|
link.rel = 'stylesheet';
|
|
link.href = normalizedHref;
|
|
link.setAttribute('data-slide-preview-fonts', 'true');
|
|
document.head.appendChild(link);
|
|
}
|
|
|
|
var stage = document.getElementById('popup-preview-stage');
|
|
var canvas = document.getElementById('popup-preview-canvas');
|
|
|
|
function readPayload() {
|
|
if (window.__pulsePopupPreviewPayload) {
|
|
return window.__pulsePopupPreviewPayload;
|
|
}
|
|
|
|
var hash = String(window.location.hash || '').replace(/^#/, '');
|
|
if (!hash) {
|
|
return null;
|
|
}
|
|
|
|
try {
|
|
return JSON.parse(decodeURIComponent(hash));
|
|
} catch (_error) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
function applyPayload() {
|
|
if (!stage || !canvas) {
|
|
return;
|
|
}
|
|
|
|
var payload = readPayload();
|
|
if (!payload) {
|
|
canvas.innerHTML = '<div class="slide-preview-empty" style="display:flex;align-items:center;justify-content:center;min-height:100%;color:rgba(255,255,255,0.75);">No preview data available.</div>';
|
|
return;
|
|
}
|
|
|
|
injectFontStylesheet(payload.fontStylesheetHref);
|
|
|
|
var backgroundColor = String(payload.backgroundColor || '#111111').trim() || '#111111';
|
|
var backgroundImagePath = String(payload.backgroundImagePath || '').trim();
|
|
var backgroundGradient = '';
|
|
try {
|
|
var gradientData = typeof payload.backgroundGradient === 'string' ? JSON.parse(payload.backgroundGradient) : payload.backgroundGradient;
|
|
if (gradientData && gradientData.type === 'linear' && ((Array.isArray(gradientData.stops) && gradientData.stops.length >= 2) || (Array.isArray(gradientData.colors) && gradientData.colors.length >= 2))) {
|
|
var gradientStops = Array.isArray(gradientData.stops) ? gradientData.stops : (gradientData.colors || []).map(function (color, index, colors) { return { color: color, position: colors.length > 1 ? Math.round(index * 100 / (colors.length - 1)) : 0 }; });
|
|
gradientStops = gradientStops.filter(function (stop) { return stop && /^#[0-9a-fA-F]{3,8}$/.test(String(stop.color || '').trim()); }).slice(0, 12);
|
|
if (gradientStops.length >= 2) {
|
|
var gradientAngle = Number(gradientData.angle);
|
|
backgroundGradient = 'linear-gradient(' + (Number.isFinite(gradientAngle) ? Math.max(0, Math.min(360, gradientAngle)) : 90) + 'deg,' + gradientStops.map(function (stop) { return stop.color + ' ' + Math.max(0, Math.min(100, Number(stop.position) || 0)) + '%'; }).join(',') + ')';
|
|
}
|
|
}
|
|
} catch (_error) {
|
|
backgroundGradient = '';
|
|
}
|
|
|
|
var canvasWidth = Math.max(1, Number(payload.canvasWidth || 1920));
|
|
var canvasHeight = Math.max(1, Number(payload.canvasHeight || 1080));
|
|
canvas.style.backgroundColor = backgroundColor;
|
|
canvas.style.backgroundImage = [backgroundImagePath ? 'url("' + encodeURI(backgroundImagePath) + '")' : '', backgroundGradient].filter(Boolean).join(',') || 'none';
|
|
canvas.style.backgroundPosition = 'center';
|
|
canvas.style.backgroundSize = backgroundImagePath ? 'contain, cover' : 'cover';
|
|
canvas.style.backgroundRepeat = 'no-repeat';
|
|
canvas.style.transformOrigin = 'center center';
|
|
canvas.style.width = canvasWidth + 'px';
|
|
canvas.style.height = canvasHeight + 'px';
|
|
canvas.innerHTML = String(payload.html || '');
|
|
startPreviewVideoPlayback(canvas);
|
|
|
|
var stageRect = stage.getBoundingClientRect();
|
|
if (!stageRect.width || !stageRect.height) {
|
|
window.requestAnimationFrame(applyPayload);
|
|
return;
|
|
}
|
|
|
|
var scale = Math.min(stageRect.width / canvasWidth, stageRect.height / canvasHeight) || 1;
|
|
canvas.style.transform = 'scale(' + scale + ')';
|
|
}
|
|
|
|
window.addEventListener('hashchange', applyPayload);
|
|
window.addEventListener('resize', applyPayload);
|
|
window.addEventListener('load', applyPayload);
|
|
applyPayload();
|
|
}());
|
|
</script> |