diff --git a/README.md b/README.md index 2c843d2..38330c3 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,7 @@ The module has been refactored to use a **MutationObserver** approach: - Example (Indonesian): Matches `123,45` (,45 is styled). - **Smart Exclusion**: It intelligently ignores thousands separators (e.g., `1,200` is **not** matched in English/US locale). 4. **DOM Wrapping**: Matches are wrapped in a `` element for styling. +5. **Dynamic Cleanup**: Includes a smart cleanup mechanism that automatically removes decimal styling when a field switches to edit mode, preventing visual duplication. ### Advantages - **No Conflicts**: Does not override `formatFloat` or `formatMonetary` functions, avoiding conflicts with other modules that modify formatting. diff --git a/static/src/views/decimal_observer.js b/static/src/views/decimal_observer.js index c1e8704..ac9ced9 100644 --- a/static/src/views/decimal_observer.js +++ b/static/src/views/decimal_observer.js @@ -7,8 +7,19 @@ console.log('Web Decimal Style: Loading DOM Decorator observer...'); let timeout; const processedNodes = new WeakSet(); + +function cleanupOrphans() { + const decimals = document.querySelectorAll('.o_decimal'); + for (const span of decimals) { + const prev = span.previousSibling; + if (!prev || prev.nodeType !== Node.TEXT_NODE || !/\d$/.test(prev.nodeValue)) { + span.remove(); + } + } +} + function processNode(textNode) { - if (processedNodes.has(textNode)) return; + // if (processedNodes.has(textNode)) return; // Safety check: is it still in doc? if (!document.contains(textNode)) return; @@ -41,6 +52,14 @@ function processNode(textNode) { const match = regex.exec(text); if (match) { + // Fix for Odoo 16+ (Owl): Owl updates text nodes in-place. + // If the text node now contains the full number (e.g. "2.000"), we might still have an old ".000" span sibling. + // We must remove these stale siblings to avoid duplication (e.g. "2.000.000"). + while (textNode.nextSibling && + textNode.nextSibling.nodeType === 1 && + textNode.nextSibling.classList.contains('o_decimal')) { + textNode.parentNode.removeChild(textNode.nextSibling); + } // match[0] = "0.00" // match[1] = "0" (last int digit) // match[2] = "." (decimal point) @@ -87,6 +106,8 @@ function scanDocument() { return; } + cleanupOrphans(); + const walker = document.createTreeWalker(document.body, NodeFilter.SHOW_TEXT, null); const nodesToProcess = []; while (walker.nextNode()) {