document.addEventListener("DOMContentLoaded", function() { // Select the latest-post container const latestPosts = document.querySelector('.latest-post'); if (latestPosts) { // Find the grid container inside const postsContainer = latestPosts.querySelector('.elementor-posts-container'); if (postsContainer) { // Set role="list" on the container postsContainer.setAttribute('role', 'list'); // Fix each article inside const articles = postsContainer.querySelectorAll('article.elementor-post'); articles.forEach(article => { // Ensure role="listitem" article.setAttribute('role', 'listitem'); // Fix thumbnail links tabindex const thumbLink = article.querySelector('.elementor-post__thumbnail__link'); if (thumbLink) { thumbLink.setAttribute('tabindex', '0'); } }); } } }); (function () { function cleanAltText(raw) { if (!raw) return ''; // Remove all # characters completely let cleaned = raw.replace(/#/g, ''); // collapse excessive whitespace cleaned = cleaned.replace(/\s{2,}/g, ' ').trim(); // remove leading/trailing punctuation or separators cleaned = cleaned.replace(/^[\s\-\:\|]+|[\s\-\:\|]+$/g, ''); // if nothing meaningful remains if (!cleaned || cleaned.length < 3) return ''; // keep under 125 chars return cleaned.slice(0, 125).trim(); } function processImg(img) { if (!img || !(img instanceof Element)) return; const feedRoot = document.getElementById('sb-tiktok-feeds-container-3'); if (!feedRoot || !feedRoot.contains(img)) return; const existingAria = img.getAttribute('aria-label'); if (existingAria && existingAria.trim().length) return; const alt = (img.getAttribute('alt') || '').trim(); const cleaned = cleanAltText(alt); if (cleaned) { img.setAttribute('aria-label', cleaned); } else if (alt && alt.length) { img.setAttribute('aria-label', 'TikTok post thumbnail'); } else { img.setAttribute('aria-label', 'TikTok post thumbnail'); } } function processAll() { const feedRoot = document.getElementById('sb-tiktok-feeds-container-3'); if (!feedRoot) return; feedRoot.querySelectorAll('img.sb-post-item-image').forEach(processImg); } document.addEventListener('DOMContentLoaded', processAll); window.addEventListener('load', processAll); const root = document.getElementById('sb-tiktok-feeds-container-3'); if (root) { const mo = new MutationObserver((mutations) => { for (const m of mutations) { m.addedNodes.forEach(node => { if (node.nodeType !== 1) return; if (node.matches?.('img.sb-post-item-image')) { processImg(node); } else { node.querySelectorAll?.('img.sb-post-item-image').forEach(processImg); } }); } }); mo.observe(root, { childList: true, subtree: true }); } })(); document.addEventListener("DOMContentLoaded", function () { // Find all links with "Learn more" const learnMoreLinks = document.querySelectorAll('a[href*="/practice-areas/"]:not([aria-label])'); learnMoreLinks.forEach(link => { // Find the closest parent container (loop item) const loopItem = link.closest('.e-loop-item'); if (loopItem) { // Find the heading (h3) inside that loop item const heading = loopItem.querySelector('h3.elementor-heading-title'); if (heading) { // Set aria-label based on the heading text link.setAttribute('aria-label', `Learn more about ${heading.textContent.trim()}`); } } }); }); // document.addEventListener('DOMContentLoaded', function() { // const owlDots = document.querySelectorAll('.owl-carousel .owl-dot'); // owlDots.forEach((dot, index) => { // // Add aria-label for accessibility // dot.setAttribute('aria-label', `Go to slide ${index + 1}`); // dot.setAttribute('role', 'button'); // // Set aria-current for active slide // if (dot.classList.contains('active')) { // dot.setAttribute('aria-current', 'true'); // } else { // dot.setAttribute('aria-current', 'false'); // } // // Optional: update aria-current dynamically on click // dot.addEventListener('click', () => { // owlDots.forEach(d => d.setAttribute('aria-current', 'false')); // dot.setAttribute('aria-current', 'true'); // }); // }); // }); // document.addEventListener("DOMContentLoaded", function() { // const owlDotsContainers = document.querySelectorAll('.sb-feed-posts .owl-dots'); // owlDotsContainers.forEach(container => { // const buttons = container.querySelectorAll('button.owl-dot'); // buttons.forEach((btn, index) => { // // Ensure aria-label exists // if (!btn.hasAttribute('aria-label') || btn.getAttribute('aria-label') === '') { // btn.setAttribute('aria-label', `Go to slide ${index + 1}`); // } // // Ensure role="button" // btn.setAttribute('role', 'button'); // // Set aria-current based on active class // btn.setAttribute('aria-current', btn.classList.contains('active') ? 'true' : 'false'); // }); // }); // }); // document.addEventListener("DOMContentLoaded", function() { function updateOwlDots(containerSelector = '.owl-dots') { const owlDotsContainers = document.querySelectorAll(containerSelector); owlDotsContainers.forEach(container => { const buttons = container.querySelectorAll('button.owl-dot'); buttons.forEach((btn, index) => { // Ensure aria-label exists if (!btn.hasAttribute('aria-label') || btn.getAttribute('aria-label') === '') { btn.setAttribute('aria-label', `Go to slide ${index + 1}`); } // Ensure role="button" btn.setAttribute('role', 'button'); // Set aria-current based on active class btn.setAttribute('aria-current', btn.classList.contains('active') ? 'true' : 'false'); }); }); } // Initial run updateOwlDots(); // Optional: observe dynamically added carousels const observer = new MutationObserver(() => updateOwlDots()); observer.observe(document.body, { childList: true, subtree: true }); }); // Add aria-labels to specific links document.addEventListener("DOMContentLoaded", function() { // For the "back to top" link const topLink = document.querySelector('a.elementor-icon[href="#top"]'); if (topLink) { topLink.setAttribute('aria-label', 'Back to top'); } // For the cancel link const cancelLink = document.querySelector('a.sbr_lb-cancel'); if (cancelLink) { cancelLink.setAttribute('aria-label', 'Cancel'); } // For the close link const closeLink = document.querySelector('a.sbr_lb-close'); if (closeLink) { closeLink.setAttribute('aria-label', 'Close'); } }); document.addEventListener("DOMContentLoaded", function() { // Find all dialogs const dialogs = document.querySelectorAll('div[role="dialog"]'); dialogs.forEach((dialog, index) => { // Skip if already has aria-label or aria-labelledby if (!dialog.hasAttribute('aria-label') && !dialog.hasAttribute('aria-labelledby')) { // Create a unique label const labelText = "Dialog window " + (index + 1); // Option 1: Use aria-label dialog.setAttribute('aria-label', labelText); // Optional: Log for debugging console.log(`Added aria-label="${labelText}" to dialog:`, dialog); } }); }); document.addEventListener("DOMContentLoaded", function() { // Select all loop items with our-team-loop class const teamItems = document.querySelectorAll('.our-team-loop'); teamItems.forEach(item => { // Find the heading link inside the item const headingLink = item.querySelector('.elementor-widget-heading h3 a'); if (!headingLink) return; // Skip if no heading link const personName = headingLink.textContent.trim(); if (!personName) return; // Skip if heading has no text // Find the "Read more" button inside this item const readMoreButton = item.querySelector('.elementor-button-link'); if (readMoreButton) { // Set the aria-label readMoreButton.setAttribute('aria-label', `Read more about ${personName}`); } }); }); document.addEventListener("DOMContentLoaded", function () { // Find all immigration loop items const items = document.querySelectorAll(".immigration-loop"); items.forEach(item => { // Get title from .elementor-icon-list-text const titleEl = item.querySelector(".elementor-icon-list-text"); if (!titleEl) return; const title = titleEl.textContent.trim(); if (!title) return; // Get the Read More button const readMore = item.querySelector("a.elementor-button.elementor-button-link"); if (!readMore) return; // Add aria-label readMore.setAttribute("aria-label", `Read more about ${title}`); }); }); (function () { // Run after DOM ready function initSkipLink() { // Find any skip link that looks like "skip to content" const skip = document.querySelector('a.skip-link[href^="#"], a[href^="#content"].skip-link, a.skip-link.screen-reader-text[href^="#"]'); if (!skip) return; // Ensure it's the very first focusable thing for keyboard users: // move it to be the first child of if it's not already first if (document.body.firstElementChild !== skip) { document.body.insertBefore(skip, document.body.firstElementChild); } // Get target id from href (strip leading '#') const targetId = (skip.getAttribute('href') || '').replace(/^#/, ''); if (!targetId) return; // Ensure the target exists; if not, try to find a good main candidate and give it the id let target = document.getElementById(targetId); if (!target) { target = document.querySelector('main, [role="main"], #primary, #content, .site-main'); if (target) { target.id = targetId; } else { // As a last resort create a focus target at top of body so link doesn't break const fallback = document.createElement('div'); fallback.id = targetId; document.body.appendChild(fallback); target = fallback; } } // Make sure target is programmatically focusable if (!target.hasAttribute('tabindex')) { target.setAttribute('tabindex', '-1'); } // Ensure activation moves keyboard focus into the target skip.addEventListener('click', function (e) { // Allow default anchor behavior, but also ensure focus lands on target // Use setTimeout to let the browser perform the fragment jump first setTimeout(function () { const t = document.getElementById(targetId); if (t) { try { t.focus({ preventScroll: false }); } catch (ex) { // fallback for older browsers t.focus(); } } }, 0); }); } if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', initSkipLink); } else { initSkipLink(); } })(); (function () { const tabSelector = '.e-n-tabs-heading'; const accordionSelector = '.e-n-accordion'; function fixTabindexes(container) { if (!container) return; container.querySelectorAll('[tabindex="-1"]').forEach(el => { el.setAttribute('tabindex', '0'); }); } function initWatcher(container) { if (!container || container.__fixed) return; // Initial fix fixTabindexes(container); // Fix again on click (Elementor updates attrs on click) container.addEventListener('click', () => fixTabindexes(container)); // Watch DOM changes inside container const observer = new MutationObserver((mutations) => { for (const m of mutations) { if ( m.type === 'childList' || (m.type === 'attributes' && m.attributeName === 'tabindex') ) { fixTabindexes(container); break; } } }); observer.observe(container, { childList: true, subtree: true, attributes: true, attributeFilter: ['tabindex'] }); container.__fixed = true; } function initAll() { document.querySelectorAll(tabSelector).forEach(initWatcher); document.querySelectorAll(accordionSelector).forEach(initWatcher); } // Run immediately initAll(); // Also watch entire page if tabs/accordions load later const rootObserver = new MutationObserver(initAll); rootObserver.observe(document.documentElement, { childList: true, subtree: true }); // Extra: run after page fully loads if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', initAll); } })(); // Function to fix ARIA role function fixSwiperRoles() { const slides = document.querySelectorAll('.swiper-slide[role="group"]'); slides.forEach(slide => { slide.setAttribute('role', 'listitem'); }); } // Fix existing slides on page load document.addEventListener('DOMContentLoaded', () => { fixSwiperRoles(); }); // Optional: Observe for new slides added dynamically (like in Swiper) const swiperContainer = document.querySelector('.swiper-wrapper'); if (swiperContainer) { const observer = new MutationObserver(() => { fixSwiperRoles(); }); observer.observe(swiperContainer, { childList: true, subtree: true }); } document.addEventListener("DOMContentLoaded", function() { const iconLinks = document.querySelectorAll('a.elementor-icon'); iconLinks.forEach(link => { // Check if link has no text content and no aria-label if (!link.textContent.trim() && !link.hasAttribute('aria-label')) { // Set a descriptive label, e.g., based on href or context if (link.getAttribute('href') === '#top') { link.setAttribute('aria-label', 'Back to top'); } else { link.setAttribute('aria-label', 'Icon link'); } } }); });
US-ILC REPRESENTS IN ALL 50 STATES