/* global window, document, fetch, URLSearchParams */ (function () { 'use strict'; var Luxtools = window.Luxtools || (window.Luxtools = {}); function findCalendarRoot(target) { var el = target; while (el && el !== document) { if (el.classList && el.classList.contains('luxtools-calendar') && el.getAttribute('data-luxtools-calendar') === '1') { return el; } el = el.parentNode; } return null; } function getNextMonth(year, month, direction) { var cursor = new Date(year, month - 1, 1); cursor.setMonth(cursor.getMonth() + direction); return { year: cursor.getFullYear(), month: cursor.getMonth() + 1 }; } function parseCalendarFromHtml(html) { if (!html) return null; var wrapper = document.createElement('div'); wrapper.innerHTML = html; return wrapper.querySelector('div.luxtools-calendar[data-luxtools-calendar="1"]'); } function setCalendarBusy(calendar, busy) { if (!calendar) return; if (busy) { calendar.setAttribute('data-luxtools-loading', '1'); } else { calendar.removeAttribute('data-luxtools-loading'); } var buttons = calendar.querySelectorAll('button.luxtools-calendar-nav-button'); for (var i = 0; i < buttons.length; i++) { buttons[i].disabled = !!busy; } } function fetchCalendarMonth(calendar, year, month) { var ajaxUrl = calendar.getAttribute('data-luxtools-ajax-url') || ''; if (!ajaxUrl) return Promise.reject(new Error('Missing calendar ajax url')); var baseNs = calendar.getAttribute('data-base-ns') || 'chronological'; var params = new URLSearchParams({ call: 'luxtools_calendar_month', year: String(year), month: String(month), base: baseNs }); var url = ajaxUrl + (ajaxUrl.indexOf('?') >= 0 ? '&' : '?') + params.toString(); return fetch(url, { method: 'GET', credentials: 'same-origin', headers: { 'X-Requested-With': 'XMLHttpRequest' } }).then(function (response) { if (!response.ok) { throw new Error('Calendar request failed: ' + response.status); } return response.text(); }); } function navigateCalendarMonth(calendar, direction) { var year = parseInt(calendar.getAttribute('data-current-year') || '', 10); var month = parseInt(calendar.getAttribute('data-current-month') || '', 10); if (!year || !month) return; var next = getNextMonth(year, month, direction); setCalendarBusy(calendar, true); fetchCalendarMonth(calendar, next.year, next.month) .then(function (html) { var replacement = parseCalendarFromHtml(html); if (!replacement) { throw new Error('Calendar markup missing in response'); } calendar.replaceWith(replacement); }) .catch(function () { var fallbackLink = calendar.querySelector('a.luxtools-calendar-month-link'); if (fallbackLink && fallbackLink.href) { window.location.href = fallbackLink.href; } }) .finally(function () { setCalendarBusy(calendar, false); }); } function onCalendarClick(event) { var target = event.target; if (!target || !target.classList || !target.classList.contains('luxtools-calendar-nav-button')) return; var calendar = findCalendarRoot(target); if (!calendar) return; var direction = parseInt(target.getAttribute('data-luxtools-dir') || '0', 10); if (direction !== -1 && direction !== 1) return; event.preventDefault(); navigateCalendarMonth(calendar, direction); } function initCalendarWidgets() { document.addEventListener('click', onCalendarClick, false); } Luxtools.CalendarWidget = { init: initCalendarWidgets }; })();