131 lines
4.1 KiB
JavaScript
131 lines
4.1 KiB
JavaScript
/* global window, document */
|
|
|
|
(function () {
|
|
'use strict';
|
|
|
|
var Luxtools = window.Luxtools || (window.Luxtools = {});
|
|
var Lightbox = Luxtools.Lightbox;
|
|
var OpenService = Luxtools.OpenService;
|
|
var GalleryThumbnails = Luxtools.GalleryThumbnails;
|
|
var Scratchpads = Luxtools.Scratchpads;
|
|
var CalendarWidget = Luxtools.CalendarWidget;
|
|
|
|
// ============================================================
|
|
// Click Handlers
|
|
// ============================================================
|
|
function findOpenElement(target) {
|
|
var el = target;
|
|
while (el && el !== document) {
|
|
if (el.classList && el.classList.contains('luxtools-open')) return el;
|
|
el = el.parentNode;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
function findGalleryItem(target) {
|
|
var el = target;
|
|
while (el && el !== document) {
|
|
if (el.classList && el.classList.contains('luxtools-gallery-item')) return el;
|
|
el = el.parentNode;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
function onClick(event) {
|
|
// Image gallery lightbox: intercept clicks so we don't navigate away.
|
|
var galleryItem = findGalleryItem(event.target);
|
|
if (galleryItem && Lightbox && Lightbox.open) {
|
|
var gallery = galleryItem.closest ? galleryItem.closest('div.luxtools-gallery[data-luxtools-gallery="1"]') : null;
|
|
if (gallery) {
|
|
event.preventDefault();
|
|
Lightbox.open(gallery, galleryItem);
|
|
return;
|
|
}
|
|
}
|
|
|
|
var el = findOpenElement(event.target);
|
|
if (!el) return;
|
|
|
|
// {{open>...}} renders as a link; avoid jumping to '#'.
|
|
if (el.tagName && el.tagName.toLowerCase() === 'a') {
|
|
event.preventDefault();
|
|
}
|
|
|
|
var raw = el.getAttribute('data-path') || '';
|
|
if (!raw) return;
|
|
if (!OpenService || !OpenService.openViaService) return;
|
|
|
|
// Prefer local client service.
|
|
OpenService.openViaService(el, raw)
|
|
.catch(function (err) {
|
|
// If the browser blocks the request before it reaches localhost (mixed-content,
|
|
// extensions, stricter CORS handling), fall back to a no-CORS GET ping.
|
|
if (OpenService && OpenService.pingOpenViaImage) {
|
|
OpenService.pingOpenViaImage(el, raw);
|
|
}
|
|
|
|
// Fallback to old behavior (often blocked in modern browsers).
|
|
var url = OpenService && OpenService.normalizeToFileUrl ? OpenService.normalizeToFileUrl(raw) : '';
|
|
if (!url) return;
|
|
console.warn('Local client service failed, falling back to file:// navigation:', err);
|
|
try {
|
|
window.open(url, '_blank', 'noopener');
|
|
} catch (e) {
|
|
try {
|
|
window.location.href = url;
|
|
} catch (e2) {
|
|
console.error('Failed to open file URL:', e2);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
function initChronologicalEventTimes() {
|
|
var nodes = document.querySelectorAll('.luxtools-event-time[data-luxtools-start]');
|
|
if (!nodes || nodes.length === 0) return;
|
|
|
|
var formatter;
|
|
try {
|
|
formatter = new Intl.DateTimeFormat(undefined, {
|
|
hour: '2-digit',
|
|
minute: '2-digit'
|
|
});
|
|
} catch (e) {
|
|
formatter = null;
|
|
}
|
|
|
|
for (var i = 0; i < nodes.length; i++) {
|
|
var node = nodes[i];
|
|
var raw = node.getAttribute('data-luxtools-start') || '';
|
|
if (!raw) continue;
|
|
|
|
var date = new Date(raw);
|
|
if (isNaN(date.getTime())) continue;
|
|
|
|
var label;
|
|
if (formatter) {
|
|
label = formatter.format(date);
|
|
} else {
|
|
var hh = String(date.getHours()).padStart(2, '0');
|
|
var mm = String(date.getMinutes()).padStart(2, '0');
|
|
label = hh + ':' + mm;
|
|
}
|
|
|
|
node.textContent = label;
|
|
}
|
|
}
|
|
|
|
// ============================================================
|
|
// Initialize
|
|
// ============================================================
|
|
document.addEventListener('click', onClick, false);
|
|
document.addEventListener('DOMContentLoaded', function () {
|
|
if (GalleryThumbnails && GalleryThumbnails.init) GalleryThumbnails.init();
|
|
initChronologicalEventTimes();
|
|
if (CalendarWidget && CalendarWidget.init) CalendarWidget.init();
|
|
}, false);
|
|
document.addEventListener('DOMContentLoaded', function () {
|
|
if (Scratchpads && Scratchpads.init) Scratchpads.init();
|
|
}, false);
|
|
})();
|