Daily updates from Odoo
Monday, March 16, 2026
3 changes
1 change
Resolved issues and error corrections
This update addresses a critical issue where switching tabs in the mass mailing editor would lose user changes due to delays in updating the email HTML. The fix introduces a new strategy to ensure changes are saved promptly, preventing data loss and improving the editor's responsiveness. Additionally, the code was optimized to eliminate flickering during HTML conversion and improve the overall stability of the mass mailing workflow.
Original PR description
Main issue: Prior to this commit, updateValue would guarantee that `body_arch` and `body_html` were always updated in sync (to avoid an inconsistent state where the user thinks they updated the…
Main issue:
Prior to this commit, updateValue would guarantee that `body_arch` and
`body_html` were always updated in sync (to avoid an inconsistent state where
the user thinks they updated the mailing, and they see the new html in the
editor, but the email html is obsolete and would be sent as is).
However this caused another issue, that the user would lose their work when
switching tab in the Notebook, because computing the `body_html` may be slower
than the view patch to switch tab (`updateValue` is interrupted). In such a
case, neither `body_arch` nor `body_html` was updated on the record, and when
the user comes back to edit them, they see that all changes were lost.
To prevent this, a new strategy is adopted:
- `body_arch` is now updated as soon as possible to save the latest user
changes
- `body_html` is set to an empty string to avoid inconsistencies, and in order
to trigger `convert_inline` automatically the next time the
`mass_mailing_html_field` is instanced without any user action.
- after `convert_inline`, if `updateValue` was not aborted, the record is
updated again with the new value for `body_html`
Minor issues:
1) Prior to this commit, the iframe would flicker during `convert_inline`
because it was done inside that very iframe, and the `convert_inline` needs a
specific width (1320px) for it to work properly, meaning that if the iframe was
not at that specific dimension, it was resized temporarily for that process.
This commit introduces hooks to execute the `convert_inline` process in a
separate iframe, outside of the user view, which removes this flickering.
2) Prior to this commit, assets for readonly/basic editor/builder were all
loaded inside the iframe, and then toggled on/off depending on which were
needed. Since the `convert_inline` process is moved in another iframe, it's as
good time as any to deprecate this toggling (as it could be a bit unreliable and
could cause some flickering when unloading/reloading the style). There is now a
separate asset bundle for the 3 use case, and only one of them is loaded per
iframe depending on the needs.
3) Prior to this commit, `body_html` was hard-coded as a dependency of the
`mass_mailing_html_field`, and that dependency lacked the `required` attribute,
which should depend on the value of `body_arch`. The dependency is now added in
the related views, and the field is now generic. This also prevents the user
from leaving the view if `convert_inline` could not be completed successfully.
4) Prior to this commit, switching to another view through `doAction` could
throw an error if the field was dirty, as the `form view` would be destroyed
before `commitChanges` had the time to be completed. Now, `commitChanges`
promise is properly awaited by the `action_service` if the field is dirty before
`doAction` (unless `forceLeave` is true).
5) Prior to this commit, the record was updated through a `blur` event on the
iframe window. However, it means that every time the iframe looses focus when
the users interacts with the builder, a popover or the form status indicator,
that blur event would fire, triggering the `convert_inline` process. This commit
reduces the amount of such updates by only triggering the update outside of
these elements, as we don't need to update the record value while the user is
still actively editing the mailing.
Blur handlers/props are deprecated with this commit and will be removed further
down the line.
6) Ensure that in the rare case where a `html_field` value is exactly the same
on different records, the `html_field` state key is updated (triggers a
wysiwyg/mass_mailing_iframe reset).
7) Remove an erroneous part in `onWillUpdateProps` of `mass_mailing_html_field`
which could display the theme selector again on the same record just after
selecting a theme if props were updated.
8) Ensure `withBuilder` getter of `mass_mailing_html_field` properly reads the
state activeTheme every time it is used (if it does not, it could cause issues
with the reactivity, since reading on the state is required for a property
subscription).
9) Remove a useless `onWillUpdateProps` of `mass_mailing_iframe` which was never
used because when `props.showCodeView` changes, the iframe is always destroyed,
so there is no need to update its state.
10) Deprecate usage of `<meta http-equiv="X-UA-Compatible" content="IE=edge"/>`,
to be removed further down the line, as it is useless in the modern web.
11) Ignore errors during a builder "Operation" that was not finished before the
editor was destroyed. In `mass_mailing`, the editor is expected to be
destroyable synchronously to work inside an Odoo view, unlike in `website`.
What's already in the DOM just before destruction will be updated on the
`record`, and the rest of the operation will be lost. However, an attempt is
made to wait for ongoing operations at the start of the
`HtmlField.commitChanges`.
12) Ensure correct visibility option state
Prior to this commit, the `dataAttributeChangeAction` selected item depended on
the domain value computed during the last template rendering, compared to the
current edited element value. The issue is that when an edited element receives
a new `data-filter-domain`, the selected options are evaluated before the
component can register the new domain in its state, so the wrong values are
compared. In this particular case, since we only need 2 values (on/off), an
acceptable trade-off is to choose the selected item ("always visible" vs
"conditionally") based on the Boolean value of the attribute.
13) Remove deprecated assets toggle test
The toggle assets feature was deprecated in a prior [commit1].
The test is removed as its outcome is non-deterministic, because it depends on
the `target` property of `event` returned as a promise resolution value by
`loadBundle`, however the browser can set that target to `null` after the event
was dispatched, so relying on the target value to keep track of the inserted
link is not reliable.
Since that `toggle` feature is not used anymore, it is not needed to run a test
for it. The feature will be removed in the latest `dev` branch.
[commit1]: https://github.com/odoo/odoo/commit/a0aa581636e257894c6c7e87c3793edebecad303
14) Prevent crash on commitChanges if editor is not ready
Prior to this commit, various checks in `commitChanges` did not take into
account that the editor could be instanced but not ready yet (meaning that
plugins are not available, and it is not possible to extract the editable
content).
This commit ensures that `commitChanges` can not crash if called when the editor
is not ready.
15) Properly keep track of dirtiness
mass_mailing changes related to [commit2], which added a way to keep track of a
specific change handled during one `commitChanges` call. The field should stay
dirty if it received changes during a `commitChanges` execution.
In mass_mailing specifically, there were 2 other situations with invalid
tracking of dirtiness:
a) A new record with no change could not be discarded as it was incorrectly
marked as dirty since the `inlineField` value is "".
After this commit, the field is marked as dirty only if the edited field value
is not "" while the `inlineField` value is "", which is the problematic
situation where both values are desynchronized. A new record with both values at
"" is not marked as dirty anymore.
b) Setting a new theme in mass_mailing did not communicate properly with the
relational model about dirtiness.
After this commit, using `setThemeHTML` triggers `onChange`, and the record
update properly tracks that change to communicate with the
`FormStatusIndicator`. The field `isDirty` property stays at `true` though,
because it still needs to execute `convertToEmailHtml` to compute the
`inlineField` value, and it needs the `editor` for that. A `commitChanges`
occurs `onEditorReady` to execute this computation, at the end of which the
field is finally set as not dirty.
[commit2]: https://github.com/odoo/odoo/commit/378580735c785bdcf8b184342834d2b3ddaaaedd
16) Prevent crash with null selection
`document.getSelection()` returns `null` when the selection is not in the
document. However the selection plugin `isSelectionInEditable` function only
support a selection object or `undefined` as an argument, and will crash with
`null`.
This commit ensures that a valid value is provided to the plugin function to
prevent crashes where the selection is moved outside of the `mass_mailing`
iframe before `normalize_handlers` execution.
task-5976348
Forward-Port-Of: odoo/odoo#252571
Forward-Port-Of: odoo/odoo#2508831 change
Resolved issues and error corrections
This update resolves a critical issue where users could cancel documents after all parties had signed, potentially compromising legal records. Now, the cancel button disappears automatically after signing is complete, and backend cancellations are blocked to ensure document permanence and security. This strengthens legal proof of agreements and protects data integrity.
Original PR description
Before this commit, users could cancel documents after everyone had signed. This weakened legal records and proof of agreement. After this commit, the cancel button disappears once signing is complete. We also blocked backend cancellations to keep finished documents permanent and secure. task-5980337 Forward-Port-Of: odoo/enterprise#109353
1 change
Resolved issues and error corrections
This update resolves a critical issue where users could cancel documents after all parties had signed, potentially compromising legal records. Now, the cancel button disappears automatically after signing is complete, and backend cancellations are blocked to ensure documents remain permanently secure and reliable. This strengthens the integrity of our document signing process.
Original PR description
Before this commit, users could cancel documents after everyone had signed. This weakened legal records and proof of agreement. After this commit, the cancel button disappears once signing is complete. We also blocked backend cancellations to keep finished documents permanent and secure. task-5980337 Forward-Port-Of: odoo/enterprise#109353