From d28cfcaa8968d5fa0c1504244fb2c204a95a92ec Mon Sep 17 00:00:00 2001 From: Suherdy Yacob Date: Mon, 2 Feb 2026 16:13:42 +0700 Subject: [PATCH] refactor: Replace DOM observer-based decimal styling with direct `wrapDecimal` integration in field formatters. --- static/src/views/decimal_observer.js | 26 +++++----- static/src/views/fields/formatters_patch.js | 57 ++++++--------------- 2 files changed, 29 insertions(+), 54 deletions(-) diff --git a/static/src/views/decimal_observer.js b/static/src/views/decimal_observer.js index f97066b..d67bc69 100644 --- a/static/src/views/decimal_observer.js +++ b/static/src/views/decimal_observer.js @@ -151,26 +151,27 @@ const ultraSafeObserver = new MutationObserver((mutations) => { // Start ultra-safe observing function startUltraSafeObserver() { - console.log('Ultra-Safe Decimal Observer: Starting ultra-conservative observation'); + // console.log('Ultra-Safe Decimal Observer: Starting ultra-conservative observation'); // Process existing content safely with delay - setTimeout(() => { - ultraSafelyProcessContainer(document.body); - }, 1000); // Initial delay to let everything load + // setTimeout(() => { + // ultraSafelyProcessContainer(document.body); + // }, 1000); // Initial delay to let everything load // Start observing for new content with very reduced frequency - ultraSafeObserver.observe(document.body, { - childList: true, - subtree: true - }); + // ultraSafeObserver.observe(document.body, { + // childList: true, + // subtree: true + // }); // Much less frequent periodic processing to reduce conflicts - setInterval(() => { - ultraSafelyProcessContainer(document.body); - }, 10000); // Every 10 seconds instead of 5 + // setInterval(() => { + // ultraSafelyProcessContainer(document.body); + // }, 10000); // Every 10 seconds instead of 5 } // Start ultra-safely +/* if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', () => { setTimeout(startUltraSafeObserver, 2000); // Extra delay @@ -178,5 +179,6 @@ if (document.readyState === 'loading') { } else { setTimeout(startUltraSafeObserver, 2000); // Extra delay } +*/ -console.log('Ultra-safe decimal observer loaded'); \ No newline at end of file +console.log('Ultra-safe decimal observer disabled'); \ No newline at end of file diff --git a/static/src/views/fields/formatters_patch.js b/static/src/views/fields/formatters_patch.js index 6eb0172..cd20963 100644 --- a/static/src/views/fields/formatters_patch.js +++ b/static/src/views/fields/formatters_patch.js @@ -20,27 +20,13 @@ try { currencyId: this.currencyId, noSymbol: !this.props.readonly || this.props.hideSymbol, }); - - // For readonly fields, apply decimal styling via safe DOM manipulation + + // Start of Owl Safe Decimal Styling if (this.props.readonly) { - // Use a longer timeout to avoid Owl lifecycle conflicts - setTimeout(() => { - try { - const element = this.el?.querySelector('.o_field_monetary'); - if (element && !element.querySelector('.o_decimal') && document.contains(element)) { - const text = element.textContent; - const match = text?.match(/^(.*)(\d{1,3}(?:[.,]\d{3})*)[.,](\d+)(.*)$/); - if (match && element.textContent === text) { // Double-check content hasn't changed - const [, prefix, integerPart, decimalPart, suffix] = match; - element.innerHTML = `${prefix}${integerPart}.${decimalPart}${suffix}`; - } - } - } catch (error) { - console.warn('Monetary field decimal styling error (non-critical):', error); - } - }, 150); // Longer delay to avoid Owl conflicts + return wrapDecimal(res); } - + // End of Owl Safe Decimal Styling + return res; } }); @@ -67,26 +53,13 @@ try { } else { res = formatFloat(this.value, { ...options, humanReadable: false }); } - - // For readonly fields, apply decimal styling via safe DOM manipulation + + // Start of Owl Safe Decimal Styling if (this.props.readonly) { - setTimeout(() => { - try { - const element = this.el?.querySelector('.o_field_float'); - if (element && !element.querySelector('.o_decimal') && document.contains(element)) { - const text = element.textContent; - const match = text?.match(/^(.*)(\d+)[.](\d+)(.*)$/); - if (match && element.textContent === text) { // Double-check content hasn't changed - const [, prefix, integerPart, decimalPart, suffix] = match; - element.innerHTML = `${prefix}${integerPart}.${decimalPart}${suffix}`; - } - } - } catch (error) { - console.warn('Float field decimal styling error (non-critical):', error); - } - }, 150); + return wrapDecimal(res); } - + // End of Owl Safe Decimal Styling + return res; } }); @@ -94,6 +67,7 @@ try { console.warn('Field patching error (non-critical):', error); } +// Safe Registry Patching for List Views // Safe Registry Patching for List Views try { const formattersRegistry = registry.category("formatters"); @@ -106,19 +80,18 @@ try { try { const original = formattersRegistry.get(name); originalFormatters.set(name, original); - + formattersRegistry.add(name, (...args) => { try { const res = original(...args); - // Return the result as-is, let DOM observer handle styling - // This avoids markup escaping issues and Owl conflicts - return res; + // Safely wrap with Owl Markup + return wrapDecimal(res); } catch (error) { console.warn(`Formatter ${name} error (non-critical):`, error); return original(...args); // Fallback to original } }, { force: true }); - + console.log('Web Decimal Style: Safely patched formatter', name); } catch (error) { console.warn(`Error patching formatter ${name} (non-critical):`, error);