[FIX] web: fix colorpicker "unknown CORS error" on safari
Previously, when opening a colorpicker in safari, the crash manager would open with the message "An unknown CORS error occured [...]". This is actually odoo's default message when an error has no file, line or column, which is usually the case for security reasons on CORS error. This is however not a true CORS error, but a "ResizeObserver loop completed with undelivered notifications" error, which also does not report file, line and col for the error. This error is caused by the fact that in webkit, the baseline of an empty input is considered to be at the bottom of the input element, rather than at the baseline of the text of the input once it has some content. (see https://bugs.webkit.org/show_bug.cgi?id=142968 ) In the case of the colorpicker, it uses a ResizeObserver to update its UI, including updating the content of its inputs. This will cause the first _updateUI to fill the empty inputs, which changes the layout of the widget content and changes its size. Changing the size of an element inside of a handler of a ResizeObserver on that same element will cause an error and not call the callback again, so as to prevent infinite loop. This commit fixes that by filling the inputs before attaching the ResizeObserver, so that it has its final size from the get-go, and _updateUI will no longer change the layout/size, causing this error. opw-2419296 closes odoo/odoo#64389 X-original-commit: 5e9e35ef0d7b0cdecc5c25dc4db04925ed0408a6 Signed-off-by: Quentin Smetz (qsm) <qsm@odoo.com>
This commit is contained in:
@@ -66,16 +66,32 @@ var ColorpickerWidget = Widget.extend({
|
||||
this.$opacitySlider = this.$('.o_opacity_slider');
|
||||
this.$opacitySliderPointer = this.$('.o_opacity_pointer');
|
||||
|
||||
const resizeObserver = new window.ResizeObserver(() => {
|
||||
this._updateUI();
|
||||
});
|
||||
resizeObserver.observe(this.el);
|
||||
|
||||
var defaultColor = this.options.defaultColor || '#FF0000';
|
||||
var rgba = ColorpickerWidget.convertCSSColorToRgba(defaultColor);
|
||||
if (rgba) {
|
||||
this._updateRgba(rgba.red, rgba.green, rgba.blue, rgba.opacity);
|
||||
}
|
||||
|
||||
// Pre-fill the inputs. This is because on safari, the baseline for empty
|
||||
// input is not the baseline of where the text would be, but the bottom
|
||||
// of the input itself. (see https://bugs.webkit.org/show_bug.cgi?id=142968)
|
||||
// This will cause the first _updateUI to alter the layout of the colorpicker
|
||||
// which will change its height. Changing the height of an element inside of
|
||||
// the callback to a ResizeObserver observing it will cause an error
|
||||
// (ResizeObserver loop completed with undelivered notifications) that cannot
|
||||
// be caught, which will open the crash manager. Prefilling the inputs sets
|
||||
// the baseline correctly from the start so the layout doesn't change.
|
||||
Object.entries(this.colorComponents).forEach(([component, value]) => {
|
||||
const input = this.el.querySelector(`.o_${component}_input`);
|
||||
if (input) {
|
||||
input.value = value;
|
||||
}
|
||||
});
|
||||
const resizeObserver = new window.ResizeObserver(() => {
|
||||
this._updateUI();
|
||||
});
|
||||
resizeObserver.observe(this.el);
|
||||
|
||||
this.previewActive = true;
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user