From 6cf7c88242f2f4fe9f83871560039767b5b90273 Mon Sep 17 00:00:00 2001 From: Eli Bosley Date: Wed, 3 Sep 2025 17:29:51 -0400 Subject: [PATCH] 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. --- plugin/plugins/dynamix.unraid.net.plg | 8 +++++++ web/components/Wrapper/vue-mount-app.ts | 31 +++++++++++++------------ 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/plugin/plugins/dynamix.unraid.net.plg b/plugin/plugins/dynamix.unraid.net.plg index 1bf4db846..3efb0c7e6 100755 --- a/plugin/plugins/dynamix.unraid.net.plg +++ b/plugin/plugins/dynamix.unraid.net.plg @@ -332,6 +332,14 @@ if [ -d "/usr/local/unraid-api/node_modules" ]; then rm -rf "/usr/local/unraid-api/node_modules" 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 upgradepkg --install-new --reinstall "${PKG_FILE}" if [ $? -ne 0 ]; then diff --git a/web/components/Wrapper/vue-mount-app.ts b/web/components/Wrapper/vue-mount-app.ts index c2d6c3ddb..ca085a1b4 100644 --- a/web/components/Wrapper/vue-mount-app.ts +++ b/web/components/Wrapper/vue-mount-app.ts @@ -524,30 +524,31 @@ export function autoMountComponent(component: Component, selector: string, optio const elements = document.querySelectorAll(selector); 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 element = el as HTMLElement; - // Basic connectivity check + // Basic connectivity check - element must be in DOM if (!element.isConnected || !element.parentNode || !document.contains(element)) { return false; } - // Check if the element appears to be in a stable state - const rect = element.getBoundingClientRect(); - const hasStableGeometry = rect.width >= 0 && rect.height >= 0; - - // Check if element is being hidden/manipulated by other scripts - const computedStyle = window.getComputedStyle(element); - const isVisible = computedStyle.display !== 'none' && - computedStyle.visibility !== 'hidden' && - computedStyle.opacity !== '0'; - - if (!hasStableGeometry) { - console.debug(`[VueMountApp] Element ${selector} has unstable geometry, may be manipulated by scripts`); + // Additional check: ensure the element's parentNode relationship is stable + // This catches cases where elements appear connected but have DOM manipulation issues + try { + // Try to access nextSibling - this will throw if DOM is in inconsistent state + void element.nextSibling; + // Verify parent-child relationship is intact + if (element.parentNode && !Array.from(element.parentNode.childNodes).includes(element)) { + console.warn(`[VueMountApp] Element ${selector} has broken parent-child relationship`); + return false; + } + } catch (error) { + console.warn(`[VueMountApp] Element ${selector} has unstable DOM state:`, error); + return false; } - return hasStableGeometry && isVisible; + return true; }); if (validElements.length > 0) {