132 lines
4.0 KiB
JavaScript
132 lines
4.0 KiB
JavaScript
/**
|
|
* Gancio Events Block Hydration for MkDocs
|
|
*
|
|
* Scans for .gancio-events-block elements and replaces them with
|
|
* Gancio's official <gancio-events> web component.
|
|
*
|
|
* Follows the video-player.js hydration pattern.
|
|
*/
|
|
(function () {
|
|
'use strict';
|
|
|
|
var scriptLoaded = false;
|
|
var scriptLoading = false;
|
|
|
|
function getGancioUrl() {
|
|
// Check env-config.js injected global
|
|
if (window.GANCIO_URL) return window.GANCIO_URL;
|
|
|
|
// Fallback: derive from current hostname
|
|
var host = window.location.hostname;
|
|
if (host !== 'localhost' && host.indexOf('.') !== -1) {
|
|
var parts = host.split('.');
|
|
var base = parts.slice(-2).join('.');
|
|
return window.location.protocol + '//events.' + base;
|
|
}
|
|
return 'http://localhost:8092';
|
|
}
|
|
|
|
function loadGancioScript(gancioUrl, callback) {
|
|
if (scriptLoaded) {
|
|
callback();
|
|
return;
|
|
}
|
|
if (scriptLoading) {
|
|
// Wait for existing load
|
|
var interval = setInterval(function () {
|
|
if (scriptLoaded) {
|
|
clearInterval(interval);
|
|
callback();
|
|
}
|
|
}, 100);
|
|
return;
|
|
}
|
|
|
|
scriptLoading = true;
|
|
var script = document.createElement('script');
|
|
script.src = gancioUrl + '/gancio-events.es.js';
|
|
script.type = 'module';
|
|
script.onload = function () {
|
|
scriptLoaded = true;
|
|
scriptLoading = false;
|
|
console.log('[GancioEvents] Web component script loaded');
|
|
callback();
|
|
};
|
|
script.onerror = function () {
|
|
scriptLoading = false;
|
|
console.warn('[GancioEvents] Failed to load web component script from', script.src);
|
|
// Show fallback message
|
|
var blocks = document.querySelectorAll('.gancio-events-block');
|
|
blocks.forEach(function (block) {
|
|
if (!block.querySelector('gancio-events')) {
|
|
block.innerHTML =
|
|
'<div style="text-align:center; padding:24px; opacity:0.6;">' +
|
|
'<p>Events calendar unavailable</p>' +
|
|
'<a href="' + gancioUrl + '" target="_blank" rel="noopener noreferrer" style="color:#3498db;">View events directly</a>' +
|
|
'</div>';
|
|
}
|
|
});
|
|
};
|
|
document.head.appendChild(script);
|
|
}
|
|
|
|
function hydrateBlocks() {
|
|
var blocks = document.querySelectorAll('.gancio-events-block');
|
|
if (blocks.length === 0) return;
|
|
|
|
var gancioUrl = getGancioUrl();
|
|
console.log('[GancioEvents] Found', blocks.length, 'block(s), Gancio URL:', gancioUrl);
|
|
|
|
loadGancioScript(gancioUrl, function () {
|
|
blocks.forEach(function (block) {
|
|
// Skip if already hydrated
|
|
if (block.querySelector('gancio-events')) return;
|
|
|
|
var maxlength = block.getAttribute('data-maxlength') || '10';
|
|
var theme = block.getAttribute('data-theme') || 'dark';
|
|
var tags = block.getAttribute('data-tags') || '';
|
|
var title = block.getAttribute('data-title') || 'Upcoming Events';
|
|
|
|
// Build the web component
|
|
var container = document.createElement('div');
|
|
|
|
// Add title if provided
|
|
if (title) {
|
|
var heading = document.createElement('h2');
|
|
heading.textContent = title;
|
|
heading.style.cssText = 'text-align:center; margin-bottom:24px; font-size:1.75rem;';
|
|
container.appendChild(heading);
|
|
}
|
|
|
|
var widget = document.createElement('gancio-events');
|
|
widget.setAttribute('baseurl', gancioUrl);
|
|
widget.setAttribute('maxlength', maxlength);
|
|
widget.setAttribute('theme', theme);
|
|
if (tags) {
|
|
widget.setAttribute('tags', tags);
|
|
}
|
|
|
|
container.appendChild(widget);
|
|
|
|
// Replace placeholder content
|
|
block.innerHTML = '';
|
|
block.appendChild(container);
|
|
});
|
|
});
|
|
}
|
|
|
|
// Initial hydration
|
|
if (document.readyState === 'loading') {
|
|
document.addEventListener('DOMContentLoaded', hydrateBlocks);
|
|
} else {
|
|
hydrateBlocks();
|
|
}
|
|
|
|
// Re-hydrate on MkDocs SPA navigation
|
|
if (typeof document$ !== 'undefined') {
|
|
document$.subscribe(function () {
|
|
setTimeout(hydrateBlocks, 100);
|
|
});
|
|
}
|
|
})();
|