(function() {
'use strict';
// Get the organization ID from the script tag
const scriptTag = document.currentScript || document.querySelector('script[data-organization-id]');
const organizationId = scriptTag ? scriptTag.getAttribute('data-organization-id') : null;
if (!organizationId) {
console.error('Anablock Widget: data-organization-id attribute is required');
return;
}
// Development-only logging
const isDevelopment = window.location.hostname === 'localhost' || window.location.hostname.includes('vercel.app');
if (isDevelopment) {
console.log('Anablock Widget: Initializing with org ID:', organizationId);
}
// Widget configuration
const config = {
organizationId: organizationId,
widgetUrl: 'https://widget.anablock.com',
position: 'bottom-right',
zIndex: 9999
};
// Advanced Analytics System
const analytics = {
sessionId: 'ws_' + Date.now() + '_' + Math.random().toString(36).slice(2, 11),
sessionStartTime: Date.now(),
parentDomain: window.location.hostname,
track: function(eventName, properties = {}) {
const eventData = {
type: 'widget:analytics',
event: eventName,
properties: {
...properties,
organizationId: config.organizationId,
sessionId: this.sessionId,
parentDomain: this.parentDomain,
timestamp: Date.now(),
sessionDuration: Date.now() - this.sessionStartTime,
viewport: {
width: window.innerWidth,
height: window.innerHeight
},
userAgent: navigator.userAgent,
referrer: document.referrer
},
source: 'anablock-widget',
version: '1.0'
};
// Send analytics to multiple destinations
this.sendToParent(eventData);
this.sendToWidget(eventData);
// Console logging for debugging (development only)
if (window.location.hostname === 'localhost' || window.location.hostname.includes('vercel.app')) {
console.log('Anablock Widget Analytics:', eventData);
}
},
sendToParent: function(data) {
try {
// Send to parent window for their analytics
if (window.parent && window.parent !== window) {
window.parent.postMessage(data, '*');
}
} catch (error) {
console.warn('Analytics parent communication failed:', error);
}
},
sendToWidget: function(data) {
try {
// Send to widget iframe for Vercel Analytics
const iframe = document.getElementById('anablock-widget-iframe');
if (iframe && iframe.contentWindow) {
iframe.contentWindow.postMessage(data, config.widgetUrl);
}
} catch (error) {
console.warn('Analytics widget communication failed:', error);
}
}
};
// Track widget script loaded
analytics.track('Widget Script Loaded', {
loadTime: Date.now() - analytics.sessionStartTime
});
// Create widget container (modal overlay)
function createWidgetContainer() {
const container = document.createElement('div');
container.id = 'anablock-widget-container';
container.setAttribute('role', 'dialog');
container.setAttribute('aria-modal', 'true');
container.setAttribute('aria-label', 'AI Assistant Chat');
container.style.cssText = `
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 100vw;
height: 100vh;
z-index: ${config.zIndex - 1};
background: rgba(0, 0, 0, 0.5);
backdrop-filter: blur(8px);
-webkit-backdrop-filter: blur(8px);
display: none;
opacity: 0;
transition: all 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94);
padding: 20px;
box-sizing: border-box;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
`;
return container;
}
// Create modal content wrapper (holds iframe + header)
function createModalContent() {
const modalContent = document.createElement('div');
const isMobile = window.innerWidth <= 768;
if (isMobile) {
modalContent.style.cssText = `
position: absolute;
top: 12px;
left: 12px;
right: 12px;
bottom: 12px;
width: calc(100% - 24px);
height: calc(100% - 24px);
border-radius: 12px;
background-color: #FFFFFF;
transition: all 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94);
transform: ${isOpen ? 'scale(1)' : 'scale(0.96)'};
`;
} else {
const width = isExpanded ? '1300px' : '1040px';
const height = isExpanded ? '975px' : '780px';
modalContent.style.cssText = `
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%) scale(${isOpen ? '1' : '0.9'});
width: min(${width}, 90vw);
height: min(${height}, 80vh);
max-width: ${width};
max-height: ${height};
border-radius: 16px;
background: white;
box-shadow:
0 25px 50px -12px rgba(0, 0, 0, 0.25),
0 0 0 1px rgba(0, 0, 0, 0.05);
transition: all 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94);
`;
}
return modalContent;
}
// Create modal header with controls
function createModalHeader() {
const header = document.createElement('div');
header.style.cssText = `
position: absolute;
top: 8px;
right: 8px;
display: flex;
gap: 8px;
z-index: 2;
`;
// Create "Open in new tab" button
const newTabButton = document.createElement('button');
newTabButton.setAttribute('aria-label', 'Open chat in new tab');
newTabButton.setAttribute('title', 'Open in new tab');
newTabButton.style.cssText = `
width: 36px;
height: 36px;
border-radius: 8px;
background: rgba(255, 255, 255, 0.9);
color: #374151;
border: none;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
font-size: 16px;
transition: all 0.2s ease;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
backdrop-filter: blur(8px);
-webkit-backdrop-filter: blur(8px);
`;
// External link icon
newTabButton.innerHTML = `
`;
// Add hover effects
newTabButton.addEventListener('mouseenter', () => {
newTabButton.style.background = 'rgba(255, 255, 255, 1)';
newTabButton.style.transform = 'scale(1.05)';
});
newTabButton.addEventListener('mouseleave', () => {
newTabButton.style.background = 'rgba(255, 255, 255, 0.9)';
newTabButton.style.transform = 'scale(1)';
});
// Add accessible focus styles for keyboard users
newTabButton.addEventListener('focus', () => {
newTabButton.style.outline = '2px solid #2563eb';
newTabButton.style.outlineOffset = '2px';
newTabButton.style.boxShadow = '0 2px 8px rgba(0, 0, 0, 0.1), 0 0 0 3px rgba(37, 99, 235, 0.2)';
newTabButton.style.background = 'rgba(255, 255, 255, 1)';
});
newTabButton.addEventListener('blur', () => {
newTabButton.style.outline = 'none';
newTabButton.style.outlineOffset = '';
newTabButton.style.boxShadow = '0 2px 8px rgba(0, 0, 0, 0.1)';
newTabButton.style.background = 'rgba(255, 255, 255, 0.9)';
});
// Handle keyboard activation (Enter/Space)
newTabButton.addEventListener('keydown', (e) => {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
newTabButton.style.transform = 'scale(0.95)';
newTabButton.style.background = 'rgba(255, 255, 255, 0.8)';
}
});
newTabButton.addEventListener('keyup', (e) => {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
newTabButton.style.transform = 'scale(1.05)';
newTabButton.style.background = 'rgba(255, 255, 255, 1)';
// Trigger click programmatically
newTabButton.click();
}
});
// Add click handler to open new tab
newTabButton.addEventListener('click', (e) => {
e.stopPropagation(); // Prevent modal close
analytics.track('Widget Opened in New Tab', {
trigger: 'new_tab_button'
});
const fullScreenUrl = `https://widget.anablock.com/?orgId=${config.organizationId}`;
window.open(fullScreenUrl, '_blank', 'noopener,noreferrer');
});
// Create size toggle button
sizeToggleButton = document.createElement('button');
sizeToggleButton.setAttribute('aria-label', 'Expand view');
sizeToggleButton.setAttribute('title', 'Expand view');
const isMobile = window.innerWidth <= 768;
sizeToggleButton.style.cssText = `
width: 36px;
height: 36px;
border-radius: 8px;
background: rgba(255, 255, 255, 0.9);
color: #374151;
border: none;
cursor: pointer;
display: ${isMobile ? 'none' : 'flex'};
align-items: center;
justify-content: center;
font-size: 16px;
transition: all 0.2s ease;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
backdrop-filter: blur(8px);
-webkit-backdrop-filter: blur(8px);
`;
// Expand icon (default state)
sizeToggleButton.innerHTML = `
`;
// Add hover effects
sizeToggleButton.addEventListener('mouseenter', () => {
sizeToggleButton.style.background = 'rgba(255, 255, 255, 1)';
sizeToggleButton.style.transform = 'scale(1.05)';
});
sizeToggleButton.addEventListener('mouseleave', () => {
sizeToggleButton.style.background = 'rgba(255, 255, 255, 0.9)';
sizeToggleButton.style.transform = 'scale(1)';
});
// Add accessible focus styles for keyboard users
sizeToggleButton.addEventListener('focus', () => {
sizeToggleButton.style.outline = '2px solid #2563eb';
sizeToggleButton.style.outlineOffset = '2px';
sizeToggleButton.style.boxShadow = '0 2px 8px rgba(0, 0, 0, 0.1), 0 0 0 3px rgba(37, 99, 235, 0.2)';
sizeToggleButton.style.background = 'rgba(255, 255, 255, 1)';
});
sizeToggleButton.addEventListener('blur', () => {
sizeToggleButton.style.outline = 'none';
sizeToggleButton.style.outlineOffset = '';
sizeToggleButton.style.boxShadow = '0 2px 8px rgba(0, 0, 0, 0.1)';
sizeToggleButton.style.background = 'rgba(255, 255, 255, 0.9)';
});
// Handle keyboard activation (Enter/Space)
sizeToggleButton.addEventListener('keydown', (e) => {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
sizeToggleButton.style.transform = 'scale(0.95)';
sizeToggleButton.style.background = 'rgba(255, 255, 255, 0.8)';
}
});
sizeToggleButton.addEventListener('keyup', (e) => {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
sizeToggleButton.style.transform = 'scale(1.05)';
sizeToggleButton.style.background = 'rgba(255, 255, 255, 1)';
// Trigger click programmatically
sizeToggleButton.click();
}
});
// Add click handler to toggle size
sizeToggleButton.addEventListener('click', (e) => {
e.stopPropagation(); // Prevent modal close
toggleSize();
});
// Create close button
const closeButton = document.createElement('button');
closeButton.setAttribute('aria-label', 'Close chat');
closeButton.setAttribute('title', 'Close chat');
closeButton.style.cssText = `
width: 36px;
height: 36px;
border-radius: 8px;
background: rgba(255, 255, 255, 0.9);
color: #374151;
border: none;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
font-size: 18px;
transition: all 0.2s ease;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
backdrop-filter: blur(8px);
-webkit-backdrop-filter: blur(8px);
`;
// Close icon
closeButton.innerHTML = `
`;
// Add hover effects
closeButton.addEventListener('mouseenter', () => {
closeButton.style.background = 'rgba(255, 255, 255, 1)';
closeButton.style.transform = 'scale(1.05)';
});
closeButton.addEventListener('mouseleave', () => {
closeButton.style.background = 'rgba(255, 255, 255, 0.9)';
closeButton.style.transform = 'scale(1)';
});
// Add accessible focus styles for keyboard users
closeButton.addEventListener('focus', () => {
closeButton.style.outline = '2px solid #2563eb';
closeButton.style.outlineOffset = '2px';
closeButton.style.boxShadow = '0 2px 8px rgba(0, 0, 0, 0.1), 0 0 0 3px rgba(37, 99, 235, 0.2)';
closeButton.style.background = 'rgba(255, 255, 255, 1)';
});
closeButton.addEventListener('blur', () => {
closeButton.style.outline = 'none';
closeButton.style.outlineOffset = '';
closeButton.style.boxShadow = '0 2px 8px rgba(0, 0, 0, 0.1)';
closeButton.style.background = 'rgba(255, 255, 255, 0.9)';
});
// Handle keyboard activation (Enter/Space)
closeButton.addEventListener('keydown', (e) => {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
closeButton.style.transform = 'scale(0.95)';
closeButton.style.background = 'rgba(255, 255, 255, 0.8)';
}
});
closeButton.addEventListener('keyup', (e) => {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
closeButton.style.transform = 'scale(1.05)';
closeButton.style.background = 'rgba(255, 255, 255, 1)';
// Trigger click programmatically
closeButton.click();
}
});
// Add click handler to close modal
closeButton.addEventListener('click', (e) => {
e.stopPropagation(); // Prevent event bubbling
toggleWidget();
});
header.appendChild(newTabButton);
header.appendChild(sizeToggleButton);
header.appendChild(closeButton);
return header;
}
// Create widget iframe (now positioned within modal content wrapper)
function createWidgetIframe() {
const iframe = document.createElement('iframe');
iframe.id = 'anablock-widget-iframe';
iframe.src = `${config.widgetUrl}?orgId=${config.organizationId}`;
iframe.setAttribute('title', 'AI Assistant Chat Interface');
iframe.setAttribute('tabindex', '0');
iframe.style.cssText = `
width: 100%;
height: 100%;
border: none;
border-radius: inherit;
background: transparent;
`;
return iframe;
}
// Update modal content wrapper styles based on viewport size
function updateModalContentStyles() {
if (!modalContent) return;
const isMobile = window.innerWidth <= 768;
if (isMobile) {
modalContent.style.cssText = `
position: absolute;
top: 12px;
left: 12px;
right: 12px;
bottom: 12px;
width: calc(100% - 24px);
height: calc(100% - 24px);
border-radius: 12px;
background-color: #FFFFFF;
transition: all 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94);
transform: ${isOpen ? 'scale(1)' : 'scale(0.96)'};
`;
} else {
const width = isExpanded ? '1300px' : '1040px';
const height = isExpanded ? '975px' : '780px';
modalContent.style.cssText = `
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%) scale(${isOpen ? '1' : '0.9'});
width: min(${width}, 90vw);
height: min(${height}, 80vh);
max-width: ${width};
max-height: ${height};
border-radius: 16px;
background: white;
box-shadow:
0 25px 50px -12px rgba(0, 0, 0, 0.25),
0 0 0 1px rgba(0, 0, 0, 0.05);
transition: all 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94);
`;
}
}
// Create widget button (floating action button)
function createWidgetButton() {
const button = document.createElement('button');
button.id = 'anablock-widget-button';
button.setAttribute('aria-label', 'Open AI Assistant');
button.style.cssText = `
position: fixed;
bottom: 24px;
right: 24px;
width: 60px;
height: 60px;
border-radius: 50%;
background: linear-gradient(135deg, #6366F1 0%, #4338CA 100%);
color: white;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
box-shadow: 0 10px 25px rgba(99, 102, 241, 0.3);
border: none;
font-size: 24px;
transition: all 0.2s ease;
z-index: ${config.zIndex};
touch-action: manipulation;
-webkit-tap-highlight-color: transparent;
`;
// Add chat icon (static logo)
button.innerHTML = `
`;
// Add fallback if image fails to load
setTimeout(() => {
const img = button.querySelector('img');
if (img && img.style.display === 'none') {
button.innerHTML = '💬';
button.setAttribute('aria-label', 'AI Assistant Chat');
}
}, 1000);
// Add hover effects
button.addEventListener('mouseenter', () => {
button.style.transform = 'scale(1.05)';
button.style.boxShadow = '0 6px 16px rgba(99, 102, 241, 0.4)';
});
button.addEventListener('mouseleave', () => {
button.style.transform = 'scale(1)';
button.style.boxShadow = '0 4px 12px rgba(99, 102, 241, 0.3)';
});
return button;
}
// Widget state
let isOpen = false;
let isExpanded = false;
let container, iframe, button, modalHeader, modalContent, sizeToggleButton;
let previousActiveElement = null;
let resizeTimeout = null;
let scrollY = 0;
let onKeyDown = null;
let onMessage = null;
// Debounced resize handler for responsive modal content styling
function handleResize() {
if (resizeTimeout) {
clearTimeout(resizeTimeout);
}
resizeTimeout = setTimeout(() => {
updateModalContentStyles();
// Hide size toggle button on mobile, show on desktop
if (sizeToggleButton) {
const isMobile = window.innerWidth <= 768;
sizeToggleButton.style.display = isMobile ? 'none' : 'flex';
}
resizeTimeout = null;
}, 150); // 150ms debounce
}
// Enhanced scroll locking for iOS Safari compatibility
function lockScroll() {
// Store current scroll position
scrollY = window.scrollY;
// Apply iOS-compatible scroll lock
document.body.style.position = 'fixed';
document.body.style.top = `-${scrollY}px`;
document.body.style.width = '100%';
document.body.style.overflow = 'hidden';
// Prevent touch scrolling on mobile
document.addEventListener('touchmove', preventTouchScroll, { passive: false });
}
function unlockScroll() {
// Remove touch scroll prevention
document.removeEventListener('touchmove', preventTouchScroll);
// Restore body styles
document.body.style.position = '';
document.body.style.top = '';
document.body.style.width = '';
document.body.style.overflow = '';
// Restore scroll position
window.scrollTo(0, scrollY);
}
// Prevent touch scrolling when modal is open
function preventTouchScroll(e) {
if (!container || !container.contains(e.target)) {
e.preventDefault();
}
}
// Toggle modal size between compact and expanded
function toggleSize() {
isExpanded = !isExpanded;
// Track size toggle
analytics.track('Widget Modal Resized', {
newSize: isExpanded ? 'expanded' : 'compact'
});
// Update modal content styles with new size
updateModalContentStyles();
// Update size toggle button icon and aria-label
if (sizeToggleButton) {
sizeToggleButton.innerHTML = isExpanded ? `
` : `
`;
sizeToggleButton.setAttribute('aria-label', isExpanded ? 'Compact view' : 'Expand view');
sizeToggleButton.setAttribute('title', isExpanded ? 'Compact view' : 'Expand view');
}
}
// Basic focus trap for modal accessibility
function handleFocusTrap(e) {
if (!isOpen || !container) return;
const focusableElements = container.querySelectorAll(
'button, iframe, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
);
const firstElement = focusableElements[0];
const lastElement = focusableElements[focusableElements.length - 1];
if (e.key === 'Tab') {
if (e.shiftKey) {
// Shift + Tab
if (document.activeElement === firstElement) {
e.preventDefault();
lastElement.focus();
}
} else {
// Tab
if (document.activeElement === lastElement) {
e.preventDefault();
firstElement.focus();
}
}
}
}
// Toggle widget visibility (modal)
function toggleWidget() {
isOpen = !isOpen;
if (isOpen) {
// Track widget opened
analytics.track('Widget Modal Opened', {
trigger: 'button_click'
});
// Store the currently focused element
previousActiveElement = document.activeElement;
// Open modal
container.style.display = 'block';
button.style.setProperty('display', 'none', 'important'); // Hide widget button when modal is open
lockScroll();
// Add focus trap
document.addEventListener('keydown', handleFocusTrap);
// Announce to screen readers that modal opened
container.setAttribute('aria-live', 'polite');
container.setAttribute('aria-atomic', 'true');
setTimeout(() => {
container.style.opacity = '1';
// Update modal content styles for open state
updateModalContentStyles();
// Focus management - focus the iframe when modal opens
setTimeout(() => {
iframe.focus();
}, 50);
}, 10);
// Change button icon to close
button.innerHTML = `
`;
// Update button aria-label
button.setAttribute('aria-label', 'Close AI Assistant');
} else {
// Track widget closed
analytics.track('Widget Modal Closed', {
trigger: 'button_click',
sessionDuration: Date.now() - analytics.sessionStartTime
});
// Close modal
container.style.opacity = '0';
button.style.setProperty('display', 'flex', 'important'); // Show widget button when modal is closed
unlockScroll();
// Remove focus trap
document.removeEventListener('keydown', handleFocusTrap);
// Return focus to the previously focused element or button
if (previousActiveElement && previousActiveElement.focus) {
previousActiveElement.focus();
} else {
button.focus();
}
// Update modal content styles for closed state
updateModalContentStyles();
setTimeout(() => {
container.style.display = 'none';
// Remove aria-live to prevent unnecessary announcements
container.removeAttribute('aria-live');
container.removeAttribute('aria-atomic');
}, 300);
// Change button icon back to static logo
button.innerHTML = `
`;
// Add fallback if image fails to load
setTimeout(() => {
const img = button.querySelector('img');
if (img && img.style.display === 'none') {
button.innerHTML = '💬';
button.setAttribute('aria-label', 'AI Assistant Chat');
}
}, 1000);
// Update button aria-label
button.setAttribute('aria-label', 'Open AI Assistant');
}
}
// Initialize widget
function initWidget() {
// Create elements
container = createWidgetContainer();
modalContent = createModalContent();
iframe = createWidgetIframe();
modalHeader = createModalHeader();
button = createWidgetButton();
// Apply initial modal content styles based on current viewport
updateModalContentStyles();
// Assemble widget - modalContent contains iframe and header
modalContent.appendChild(iframe);
modalContent.appendChild(modalHeader);
container.appendChild(modalContent);
document.body.appendChild(container);
document.body.appendChild(button);
// Add click handler
button.addEventListener('click', toggleWidget);
// Handle escape key - capture handler for proper cleanup
onKeyDown = (e) => {
if (e.key === 'Escape' && isOpen) {
toggleWidget();
}
};
document.addEventListener('keydown', onKeyDown);
// Handle clicks outside iframe (on backdrop)
container.addEventListener('click', (e) => {
if (e.target === container && isOpen) {
toggleWidget();
}
});
// Add responsive resize listener
window.addEventListener('resize', handleResize);
// Track successful initialization
analytics.track('Widget Successfully Initialized', {
initializationTime: Date.now() - analytics.sessionStartTime
});
if (isDevelopment) {
console.log('Anablock Widget: Successfully initialized');
}
}
// Wait for DOM to be ready
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', initWidget);
} else {
initWidget();
}
// Listen for messages from the widget iframe - capture handler for cleanup
onMessage = (event) => {
// Guard against accessing destroyed elements
if (!container || !iframe) {
return;
}
// Filter out unwanted messages (React DevTools, browser extensions, etc.)
if (event.data?.source === 'react-devtools-content-script' ||
event.data?.source === 'react-devtools-bridge' ||
event.data?.source === 'react-devtools-detector' ||
event.data?.hello === true ||
typeof event.data === 'string' && event.data.includes('webpack') ||
typeof event.data === 'string' && event.data.includes('webpackOk')) {
return;
}
// Verify origin for security
if (!event.origin.includes('anablock') && !event.origin.includes('vercel.app') && event.origin !== window.location.origin) {
return;
}
try {
const data = typeof event.data === 'string' ? JSON.parse(event.data) : event.data;
// Handle different message types
switch (data.type) {
case 'widget:close':
if (isOpen) toggleWidget();
break;
case 'widget:minimize':
if (isOpen) toggleWidget();
break;
case 'widget:resize':
if (data.height && iframe) {
iframe.style.height = `${data.height}px`;
}
break;
default:
// Only log relevant widget messages, not spam
if (data.type && data.type.startsWith('widget:')) {
console.log('Anablock Widget: Received message', data);
}
}
} catch (error) {
// Silently ignore parsing errors from unwanted messages
if (event.data?.source !== 'react-devtools-content-script') {
// Silently ignore parsing errors
}
}
};
window.addEventListener('message', onMessage);
// Cleanup function to remove event listeners (called when widget is torn down)
function cleanup() {
// Remove resize listener
window.removeEventListener('resize', handleResize);
// Clear any pending resize timeout
if (resizeTimeout) {
clearTimeout(resizeTimeout);
resizeTimeout = null;
}
// Remove message listener
if (onMessage) {
window.removeEventListener('message', onMessage);
onMessage = null;
}
// Remove keydown listeners
if (onKeyDown) {
document.removeEventListener('keydown', onKeyDown);
onKeyDown = null;
}
// Remove focus trap if active
if (isOpen) {
document.removeEventListener('keydown', handleFocusTrap);
}
// Remove elements from DOM
if (container) {
container.remove();
container = null;
}
if (button) {
button.remove();
button = null;
}
iframe = null;
modalHeader = null;
modalContent = null;
// Restore body scroll if modal was open
if (isOpen) {
unlockScroll();
}
if (isDevelopment) {
console.log('Anablock Widget: Cleanup completed');
}
}
// Expose cleanup function globally (useful for single-page apps)
window.AnablockWidget = {
cleanup: cleanup
};
})();