feat: Add dynamic cleanup to prevent decimal styling duplication and remove stale decimal spans.

This commit is contained in:
Suherdy Yacob 2026-02-06 14:09:11 +07:00
parent b819935025
commit f269b1455d
2 changed files with 23 additions and 1 deletions

View File

@ -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 `<span class="o_decimal">` 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.

View File

@ -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()) {