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');
}
}
});
});
Skip to content
Do you want to change your F-1 visa to a green card to continue living in the U.S.? Here is everything you need to know about this process, including the different ways that you can get a green card.
Are you wondering if US citizens are allowed to have dual citizenship? Consulting with a knowledgeable immigration attorney can make your journey to becoming a bona fide citizen of the United States much smoother.
Are you trying to decide between a fiancรฉ visa vs a marriage green card? If so, here is everything you need to know about these options and which one is better than the other.
Are you worried about your visa expiring while waiting for a green card? If so, here is everything you need to know about visa expiration and what this could mean for your immigration status.
Do you need to renew your visa for foreign military members stationed in the United States? If so, here is everything you need to know about the visa renewal process and the documentation required.