diff --git a/static/src/views/decimal_observer.js b/static/src/views/decimal_observer.js
index f583948..ab92fac 100644
--- a/static/src/views/decimal_observer.js
+++ b/static/src/views/decimal_observer.js
@@ -1,6 +1,6 @@
/** @odoo-module **/
-console.log('Loading safe decimal observer...');
+console.log('Loading ultra-safe decimal observer...');
// Function to safely apply decimal styling to any element
function safelyApplyDecimalStyling(element) {
@@ -12,6 +12,19 @@ function safelyApplyDecimalStyling(element) {
element.hasAttribute('data-decimal-processed') ||
element.hasAttribute('data-owl-updating')) return false;
+ // CRITICAL: Skip any editable elements or elements that might become editable
+ if (element.isContentEditable ||
+ element.closest('.o_field_widget:not(.o_readonly_modifier)') ||
+ element.closest('[contenteditable="true"]') ||
+ element.closest('input') ||
+ element.closest('textarea') ||
+ element.closest('.o_input') ||
+ element.closest('.o_field_float:not(.o_readonly_modifier)') ||
+ element.closest('.o_field_monetary:not(.o_readonly_modifier)') ||
+ element.hasAttribute('contenteditable')) {
+ return false;
+ }
+
try {
const text = element.textContent.trim();
if (!text) return false;
@@ -34,10 +47,12 @@ function safelyApplyDecimalStyling(element) {
if (match) {
const [, prefix, integerPart, decimalPart, suffix] = match;
- console.log('Safe Decimal Observer: Styling', text);
+ console.log('Ultra-Safe Decimal Observer: Styling decimal number', text);
- // Double-check the element hasn't changed before updating
- if (element.textContent.trim() === text && document.contains(element)) {
+ // Triple-check the element is safe to modify
+ if (element.textContent.trim() === text &&
+ document.contains(element) &&
+ !element.closest('.o_field_widget:not(.o_readonly_modifier)')) {
const newHTML = `${prefix || ''}${integerPart}.${decimalPart}${suffix || ''}`;
element.innerHTML = newHTML;
return true;
@@ -45,17 +60,20 @@ function safelyApplyDecimalStyling(element) {
}
}
- // Handle whole numbers in quantity contexts (be more selective)
- // Only add decimals to numbers that are clearly quantities, not prices with thousands separators
- if (text.match(/^\d+$/) && text.length > 0 && text.length <= 4 && (
+ // Handle whole numbers in quantity contexts (be even more selective)
+ // Only add decimals to numbers that are clearly quantities in readonly contexts
+ if (text.match(/^\d+$/) && text.length > 0 && text.length <= 4 &&
+ element.closest('.o_readonly_modifier') && (
element.closest('[name="quantity"]') ||
element.closest('[name="quantity_done"]') ||
element.closest('[name="reserved_availability"]')
)) {
- console.log('Safe Decimal Observer: Adding decimals to quantity', text);
+ console.log('Ultra-Safe Decimal Observer: Adding decimals to readonly quantity', text);
- // Double-check before updating
- if (element.textContent.trim() === text && document.contains(element)) {
+ // Triple-check before updating
+ if (element.textContent.trim() === text &&
+ document.contains(element) &&
+ element.closest('.o_readonly_modifier')) {
element.innerHTML = `${text}.000`;
return true;
}
@@ -64,12 +82,12 @@ function safelyApplyDecimalStyling(element) {
// Do NOT process numbers with commas that don't have decimal points
// These are likely thousands separators (e.g., 8,500 should stay as 8,500)
if (text.match(/^\d{1,3}(?:,\d{3})+$/) && !text.includes('.')) {
- console.log('Safe Decimal Observer: Skipping thousands separator number', text);
+ console.log('Ultra-Safe Decimal Observer: Skipping thousands separator number', text);
return false;
}
} catch (error) {
- console.warn('Safe decimal styling error (non-critical):', error);
+ console.warn('Ultra-safe decimal styling error (non-critical):', error);
// Remove the processing flag if there was an error
element.removeAttribute('data-decimal-processed');
}
@@ -77,79 +95,80 @@ function safelyApplyDecimalStyling(element) {
return false;
}
-// Safe processing of containers
-function safelyProcessContainer(container) {
+// Ultra-safe processing of containers
+function ultraSafelyProcessContainer(container) {
if (!container || !document.contains(container)) return;
try {
- // Find all text-containing elements, but be more selective
- const elements = container.querySelectorAll('td:not([data-decimal-processed]), span:not([data-decimal-processed]), .o_field_monetary:not([data-decimal-processed]), .o_field_float:not([data-decimal-processed])');
+ // Only process elements in readonly contexts to avoid editable field conflicts
+ const elements = container.querySelectorAll('.o_readonly_modifier td:not([data-decimal-processed]), .o_readonly_modifier span:not([data-decimal-processed]), .o_field_monetary.o_readonly_modifier:not([data-decimal-processed]), .o_field_float.o_readonly_modifier:not([data-decimal-processed])');
elements.forEach(element => {
- // Only process leaf elements and skip if Owl is managing them
+ // Only process leaf elements in readonly contexts
if ((element.children.length === 0 ||
(element.children.length === 1 && element.children[0].tagName === 'SPAN')) &&
- !element.hasAttribute('data-owl-updating')) {
+ !element.hasAttribute('data-owl-updating') &&
+ !element.closest('.o_field_widget:not(.o_readonly_modifier)')) {
safelyApplyDecimalStyling(element);
}
});
} catch (error) {
- console.warn('Safe container processing error (non-critical):', error);
+ console.warn('Ultra-safe container processing error (non-critical):', error);
}
}
-// More conservative observer
-const safeObserver = new MutationObserver((mutations) => {
- // Debounce the processing to avoid conflicts
- clearTimeout(safeObserver.timeout);
- safeObserver.timeout = setTimeout(() => {
+// Ultra-conservative observer with longer debounce
+const ultraSafeObserver = new MutationObserver((mutations) => {
+ // Longer debounce to avoid conflicts with user interactions
+ clearTimeout(ultraSafeObserver.timeout);
+ ultraSafeObserver.timeout = setTimeout(() => {
try {
mutations.forEach((mutation) => {
if (mutation.type === 'childList') {
mutation.addedNodes.forEach((node) => {
if (node.nodeType === Node.ELEMENT_NODE && document.contains(node)) {
- // Use requestAnimationFrame to ensure we run after Owl updates
- requestAnimationFrame(() => {
- safelyProcessContainer(node);
- });
+ // Use longer delay to ensure Owl has finished all updates
+ setTimeout(() => {
+ ultraSafelyProcessContainer(node);
+ }, 500); // Much longer delay
}
});
}
});
} catch (error) {
- console.warn('Safe observer error (non-critical):', error);
+ console.warn('Ultra-safe observer error (non-critical):', error);
}
- }, 200); // Debounce for 200ms
+ }, 500); // Longer debounce for 500ms
});
-// Start observing safely
-function startSafeObserver() {
- console.log('Safe Decimal Observer: Starting conservative observation');
+// Start ultra-safe observing
+function startUltraSafeObserver() {
+ console.log('Ultra-Safe Decimal Observer: Starting ultra-conservative observation');
- // Process existing content safely
- requestAnimationFrame(() => {
- safelyProcessContainer(document.body);
- });
+ // Process existing content safely with delay
+ setTimeout(() => {
+ ultraSafelyProcessContainer(document.body);
+ }, 1000); // Initial delay to let everything load
- // Start observing for new content with reduced frequency
- safeObserver.observe(document.body, {
+ // Start observing for new content with very reduced frequency
+ ultraSafeObserver.observe(document.body, {
childList: true,
subtree: true
});
- // Periodic processing with longer intervals to reduce conflicts
+ // Much less frequent periodic processing to reduce conflicts
setInterval(() => {
- requestAnimationFrame(() => {
- safelyProcessContainer(document.body);
- });
- }, 5000); // Every 5 seconds instead of 2
+ ultraSafelyProcessContainer(document.body);
+ }, 10000); // Every 10 seconds instead of 5
}
-// Start safely
+// Start ultra-safely
if (document.readyState === 'loading') {
- document.addEventListener('DOMContentLoaded', startSafeObserver);
+ document.addEventListener('DOMContentLoaded', () => {
+ setTimeout(startUltraSafeObserver, 2000); // Extra delay
+ });
} else {
- startSafeObserver();
+ setTimeout(startUltraSafeObserver, 2000); // Extra delay
}
-console.log('Safe decimal observer loaded');
\ No newline at end of file
+console.log('Ultra-safe decimal observer loaded');
\ No newline at end of file