fix: enhance DOM validation and cleanup in vue-mount-app

- Improved validation logic for mounted elements to ensure stable DOM connections and prevent manipulation issues.
- Added cleanup step to clear existing unraid-components directory before installation, ensuring a clean setup.

This update aims to enhance the reliability of component mounting and reduce potential UI issues.
This commit is contained in:
Eli Bosley
2025-09-03 17:29:51 -04:00
parent 33774aa596
commit 6cf7c88242
2 changed files with 24 additions and 15 deletions

View File

@@ -332,6 +332,14 @@ if [ -d "/usr/local/unraid-api/node_modules" ]; then
rm -rf "/usr/local/unraid-api/node_modules" rm -rf "/usr/local/unraid-api/node_modules"
fi fi
# Clear existing unraid-components directory contents to ensure clean installation
echo "Cleaning up existing unraid-components directory..."
DIR="/usr/local/emhttp/plugins/dynamix.my.servers/unraid-components"
if [ -d "$DIR" ]; then
echo "Clearing contents of: $DIR"
rm -rf "$DIR"/*
fi
# Install the package using the explicit file path # Install the package using the explicit file path
upgradepkg --install-new --reinstall "${PKG_FILE}" upgradepkg --install-new --reinstall "${PKG_FILE}"
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then

View File

@@ -524,30 +524,31 @@ export function autoMountComponent(component: Component, selector: string, optio
const elements = document.querySelectorAll(selector); const elements = document.querySelectorAll(selector);
if (elements.length === 0) return; if (elements.length === 0) return;
// Validate all elements are properly connected to the DOM and not being manipulated // Validate all elements are properly connected to the DOM
const validElements = Array.from(elements).filter(el => { const validElements = Array.from(elements).filter(el => {
const element = el as HTMLElement; const element = el as HTMLElement;
// Basic connectivity check // Basic connectivity check - element must be in DOM
if (!element.isConnected || !element.parentNode || !document.contains(element)) { if (!element.isConnected || !element.parentNode || !document.contains(element)) {
return false; return false;
} }
// Check if the element appears to be in a stable state // Additional check: ensure the element's parentNode relationship is stable
const rect = element.getBoundingClientRect(); // This catches cases where elements appear connected but have DOM manipulation issues
const hasStableGeometry = rect.width >= 0 && rect.height >= 0; try {
// Try to access nextSibling - this will throw if DOM is in inconsistent state
// Check if element is being hidden/manipulated by other scripts void element.nextSibling;
const computedStyle = window.getComputedStyle(element); // Verify parent-child relationship is intact
const isVisible = computedStyle.display !== 'none' && if (element.parentNode && !Array.from(element.parentNode.childNodes).includes(element)) {
computedStyle.visibility !== 'hidden' && console.warn(`[VueMountApp] Element ${selector} has broken parent-child relationship`);
computedStyle.opacity !== '0'; return false;
}
if (!hasStableGeometry) { } catch (error) {
console.debug(`[VueMountApp] Element ${selector} has unstable geometry, may be manipulated by scripts`); console.warn(`[VueMountApp] Element ${selector} has unstable DOM state:`, error);
return false;
} }
return hasStableGeometry && isVisible; return true;
}); });
if (validElements.length > 0) { if (validElements.length > 0) {