/** * AllDayDomReader - Centralized DOM reading utilities for all-day services * * STATELESS UTILITY - Pure functions for reading DOM state * - Consistent selectors across all services * - Unified computed style approach (not inline styles) * - Type-safe return values * - Single source of truth for DOM queries */ export class AllDayDomReader { // ============================================ // CONTAINER GETTERS // ============================================ /** * Get the all-day events container element */ static getAllDayContainer() { return document.querySelector('swp-calendar-header swp-allday-container'); } /** * Get the calendar header element */ static getCalendarHeader() { return document.querySelector('swp-calendar-header'); } /** * Get the header spacer element */ static getHeaderSpacer() { return document.querySelector('swp-header-spacer'); } // ============================================ // EVENT ELEMENT GETTERS // ============================================ /** * Get all all-day event elements (excluding overflow indicators) * Returns raw HTMLElements for DOM manipulation */ static getEventElements() { const container = this.getAllDayContainer(); if (!container) return []; return Array.from(container.querySelectorAll('swp-allday-event:not(.max-event-indicator)')); } /** * Get all-day events as ICalendarEvent objects * Returns parsed data for business logic */ static getEventsAsData() { const elements = this.getEventElements(); return elements .map(element => { const eventId = element.dataset.eventId; const startStr = element.dataset.start; const endStr = element.dataset.end; // Validate required fields if (!eventId || !startStr || !endStr) { console.warn('AllDayDomReader: Invalid event data in DOM:', element); return null; } const start = new Date(startStr); const end = new Date(endStr); if (isNaN(start.getTime()) || isNaN(end.getTime())) { console.warn('AllDayDomReader: Invalid event dates:', { startStr, endStr }); return null; } return { id: eventId, title: element.dataset.title || '', start, end, type: element.dataset.type || 'task', allDay: true, syncStatus: (element.dataset.syncStatus || 'synced') }; }) .filter((event) => event !== null); } // ============================================ // GRID POSITION READERS // ============================================ /** * Get grid row from element using computed style * Always uses computed style for consistency */ static getGridRow(element) { const computedStyle = window.getComputedStyle(element); return parseInt(computedStyle.gridRowStart) || 0; } /** * Get grid column range from element using computed style */ static getGridColumnRange(element) { const computedStyle = window.getComputedStyle(element); return { start: parseInt(computedStyle.gridColumnStart) || 0, end: parseInt(computedStyle.gridColumnEnd) || 0 }; } /** * Get grid area from element using computed style */ static getGridArea(element) { const computedStyle = window.getComputedStyle(element); return computedStyle.gridArea; } /** * Calculate max row number from all events * Uses computed styles for accurate reading */ static getMaxRowFromEvents() { const events = this.getEventElements(); if (events.length === 0) return 0; let maxRow = 0; events.forEach(event => { const row = this.getGridRow(event); maxRow = Math.max(maxRow, row); }); return maxRow; } // ============================================ // STATE READERS // ============================================ /** * Check if all-day container is expanded */ static isExpanded() { const container = this.getAllDayContainer(); return container?.classList.contains('expanded') || false; } /** * Get current all-day height from CSS variable */ static getCurrentHeight() { const root = document.documentElement; const heightStr = root.style.getPropertyValue('--all-day-row-height') || '0px'; return parseInt(heightStr) || 0; } /** * Count events in specific column */ static countEventsInColumn(columnIndex) { const events = this.getEventElements(); let count = 0; events.forEach((event) => { const { start, end } = this.getGridColumnRange(event); if (start <= columnIndex && end > columnIndex) { count++; } }); return count; } // ============================================ // LAYOUT READERS // ============================================ /** * Get current layouts from DOM elements * Returns map of eventId → layout info for comparison */ static getCurrentLayouts() { const layoutsMap = new Map(); const events = this.getEventElements(); events.forEach(event => { const eventId = event.dataset.eventId; if (eventId) { layoutsMap.set(eventId, { gridArea: this.getGridArea(event) }); } }); return layoutsMap; } } //# sourceMappingURL=AllDayDomReader.js.map