diff --git a/addons/web_editor/static/src/js/editor/image_processing.js b/addons/web_editor/static/src/js/editor/image_processing.js index 1308c23b0e0..ee52f6ad31f 100644 --- a/addons/web_editor/static/src/js/editor/image_processing.js +++ b/addons/web_editor/static/src/js/editor/image_processing.js @@ -233,6 +233,8 @@ export async function applyModifications(img, dataOptions = {}) { // Crop const container = document.createElement('div'); const original = await loadImage(originalSrc); + // loadImage may have ended up loading a different src (see: LOAD_IMAGE_404) + originalSrc = original.getAttribute('src'); container.appendChild(original); await activateCropper(original, 0, data); let croppedImg = $(original).cropper('getCroppedCanvas', {width, height}); @@ -358,6 +360,7 @@ export function loadImage(src, img = new Image()) { img.src = source; }; // The server will return a placeholder image with the following src. + // grep: LOAD_IMAGE_404 const placeholderHref = "/web/image/__odoo__unknown__src__/"; return new Promise((resolve, reject) => { @@ -419,6 +422,8 @@ async function _updateImageData(src, key = 'objectURL') { } /** * Returns the size of a cached image. + * Warning: this supposes that the image is already in the cache, i.e. that + * _updateImageData was called before. * * @param {String} src used as a key on the image cache map. * @returns {Number} size of the image in bytes. diff --git a/addons/website/static/tests/tours/drop_404_ir_attachment_url.js b/addons/website/static/tests/tours/drop_404_ir_attachment_url.js new file mode 100644 index 00000000000..3906ac20d7c --- /dev/null +++ b/addons/website/static/tests/tours/drop_404_ir_attachment_url.js @@ -0,0 +1,44 @@ +/** @odoo-module **/ + +import wTourUtils from '@website/js/tours/tour_utils'; + +wTourUtils.registerWebsitePreviewTour('drop_404_ir_attachment_url', { + test: true, + url: '/', + edition: true, +}, () => [ + wTourUtils.dragNDrop({ + id: 's_404_snippet', + name: '404 Snippet', + }), + { + content: 'Click on the snippet image', + trigger: 'iframe .s_404_snippet img', + }, { + content: 'Once the image UI appears, check the image has no size (404)', + trigger: 'iframe .s_404_snippet img', + extra_trigger: '.snippet-option-ReplaceMedia', + run: function () { + const imgEl = this.$anchor[0]; + if (!imgEl.complete + || imgEl.naturalWidth !== 0 + || imgEl.naturalHeight !== 0) { + console.error('This is supposed to be a 404 image'); + } + }, + }, + wTourUtils.changeOption('ImageTools', 'we-select[data-name="shape_img_opt"] we-toggler'), + wTourUtils.changeOption('ImageTools', 'we-button[data-set-img-shape]'), + { + content: 'Once the shape is applied, check the image has now a size (placeholder image)', + trigger: 'iframe .s_404_snippet img[src^="data:"]', + run: function () { + const imgEl = this.$anchor[0]; + if (!imgEl.complete + || imgEl.naturalWidth === 0 + || imgEl.naturalHeight === 0) { + console.error('Even though the original image was a 404, the option should have been applied on the placeholder image'); + } + }, + }, +]); diff --git a/addons/website/tests/test_ui.py b/addons/website/tests/test_ui.py index 92ef59e4edf..fd967304945 100644 --- a/addons/website/tests/test_ui.py +++ b/addons/website/tests/test_ui.py @@ -515,3 +515,40 @@ class TestUi(odoo.tests.HttpCase): 'path': 'website/static/tests/tour_utils/widget_lifecycle_patch_wysiwyg.js', }) self.start_tour(self.env['website'].get_client_action_url('/'), 'widget_lifecycle', login='admin') + + def test_drop_404_ir_attachment_url(self): + website_snippets = self.env.ref('website.snippets') + self.env['ir.ui.view'].create([{ + 'name': '404 Snippet', + 'type': 'qweb', + 'key': 'website.s_404_snippet', + 'arch': """ +
+
+ +
+
+ """, + }, { + 'type': 'qweb', + 'inherit_id': website_snippets.id, + 'arch': """ + + + + """, + }]) + attachment = self.env['ir.attachment'].create({ + 'name': '404_ir_attachment', + 'type': 'url', + 'url': '/web/static/__some__typo__.png', + 'mimetype': 'image/png', + }) + self.env['ir.model.data'].create({ + 'name': '404_ir_attachment', + 'module': 'website', + 'model': 'ir.attachment', + 'res_id': attachment.id, + }) + self.start_tour(self.env['website'].get_client_action_url('/'), 'drop_404_ir_attachment_url', login='admin')