From 375f4dff1c7b1acc608a0eb3d6bcdc2f17de542e Mon Sep 17 00:00:00 2001 From: Benoit Socias Date: Tue, 12 Apr 2022 07:26:06 +0000 Subject: [PATCH] [FIX] web_editor, *: clean previously shown link in link popover *: web_tour, test_website Since [1] when the link popover was introduced, when the URL of a link was made empty, an validation error appeared by the previously shown URL did still appear inside the popover. After this commit the previously shown link is replaced by a message that indicates that no URL is specified. The telephone and envelope icons are now also always removed when the URL is change: they used to be only toggled, which made it possible to make them appear and disappear by updating an email address or a phone number. Steps to reproduce: - Add an image-text snippet to the page - Select the image - Add a link on the image - Specify URL - Click on image => link popup shows the entered URL - Make the URL field empty - Click on image => link popup still showed the previously entered URL [1]: https://github.com/odoo/odoo/commit/8fcf930a6b6b7ffb0965b0a689c7a3117962ce7e task-2765857 closes odoo/odoo#98845 X-original-commit: f212c56d73f5dad8eb5850b0b39cc92f55706ee2 Signed-off-by: Quentin Smetz (qsm) Signed-off-by: Benoit Socias (bso) --- .../static/tests/tours/image_link.js | 79 +++++++++++++++++++ addons/test_website/tests/test_media.py | 3 + addons/web_editor/i18n/web_editor.pot | 7 ++ .../static/src/js/editor/snippets.options.js | 1 + .../js/wysiwyg/widgets/link_popover_widget.js | 9 ++- .../src/js/running_tour_action_helper.js | 3 + 6 files changed, 100 insertions(+), 2 deletions(-) create mode 100644 addons/test_website/static/tests/tours/image_link.js diff --git a/addons/test_website/static/tests/tours/image_link.js b/addons/test_website/static/tests/tours/image_link.js new file mode 100644 index 00000000000..5fea93d982e --- /dev/null +++ b/addons/test_website/static/tests/tours/image_link.js @@ -0,0 +1,79 @@ +/** @odoo-module **/ + +import wTourUtils from 'website.tour_utils'; + +/** + * The purpose of this tour is to check the link on image flow. + */ + +wTourUtils.registerEditionTour('test_image_link', { + test: true, + url: '/', + edition: true, +}, [ + wTourUtils.dragNDrop({ + id: 's_text_image', + name: 'Text - Image', + }), { + content: "select image", + trigger: "iframe #wrapwrap .s_text_image img", + }, { + content: "enable link", + trigger: "#oe_snippets we-customizeblock-options:has(we-title:contains('Image')) we-customizeblock-option:has(we-title:contains(Media)) we-button.fa-link", + }, { + content: "enter site URL", + trigger: "#oe_snippets we-customizeblock-options:has(we-title:contains('Image')) we-input:contains(Your URL) input", + run: "text odoo.com", + }, { + content: "select image", + trigger: "iframe #wrapwrap .s_text_image img", + }, { + content: "check popover content has site URL", + trigger: ".o_edit_menu_popover a.o_we_url_link[href='http://odoo.com/']:contains(http://odoo.com/)", + run: () => {}, // check + }, { + content: "remove URL", + trigger: "#oe_snippets we-customizeblock-options:has(we-title:contains('Image')) we-input:contains(Your URL) input", + run: "remove_text", + }, { + content: "select image", + trigger: "iframe #wrapwrap .s_text_image img", + }, { + content: "check popover content has no URL", + trigger: ".o_edit_menu_popover a.o_we_url_link:not([href]):contains(No URL specified)", + run: () => {}, // check + }, { + content: "enter email URL", + trigger: "#oe_snippets we-customizeblock-options:has(we-title:contains('Image')) we-input:contains(Your URL) input", + run: "text mailto:test@test.com", + }, { + content: "select image", + trigger: "iframe #wrapwrap .s_text_image img", + }, { + content: "check popover content has mail URL", + trigger: ".o_edit_menu_popover:has(.fa-envelope-o) a.o_we_url_link[href='mailto:test@test.com']:contains(mailto:test@test.com)", + run: () => {}, // check + }, { + content: "enter phone URL", + trigger: "#oe_snippets we-customizeblock-options:has(we-title:contains('Image')) we-input:contains(Your URL) input", + run: "text tel:555-2368", + }, { + content: "select image", + trigger: "iframe #wrapwrap .s_text_image img", + }, { + content: "check popover content has phone URL", + trigger: ".o_edit_menu_popover:has(.fa-phone) a.o_we_url_link[href='tel:555-2368']:contains(tel:555-2368)", + run: () => {}, // check + }, { + content: "remove URL", + trigger: "#oe_snippets we-customizeblock-options:has(we-title:contains('Image')) we-input:contains(Your URL) input", + run: "remove_text", + }, { + content: "select image", + trigger: "iframe #wrapwrap .s_text_image img", + }, { + content: "check popover content has no URL", + trigger: ".o_edit_menu_popover a.o_we_url_link:not([href]):contains(No URL specified)", + run: () => {}, // check + }, +]); diff --git a/addons/test_website/tests/test_media.py b/addons/test_website/tests/test_media.py index ebdc3b62c57..e03890b5c90 100644 --- a/addons/test_website/tests/test_media.py +++ b/addons/test_website/tests/test_media.py @@ -20,3 +20,6 @@ class TestMedia(odoo.tests.HttpCase): 'datas': SVG, }) self.start_tour("/", 'test_replace_media', login="admin") + + def test_02_image_link(self): + self.start_tour("/", 'test_image_link', login="admin") diff --git a/addons/web_editor/i18n/web_editor.pot b/addons/web_editor/i18n/web_editor.pot index 38c9731c940..131ca5aa7d3 100644 --- a/addons/web_editor/i18n/web_editor.pot +++ b/addons/web_editor/i18n/web_editor.pot @@ -1626,6 +1626,13 @@ msgstr "" msgid "No" msgstr "" +#. module: web_editor +#. openerp-web +#: code:addons/web_editor/static/src/js/wysiwyg/widgets/link_popover_widget.js:0 +#, python-format +msgid "No URL specified" +msgstr "" + #. module: web_editor #. openerp-web #: code:addons/web_editor/static/src/xml/wysiwyg.xml:0 diff --git a/addons/web_editor/static/src/js/editor/snippets.options.js b/addons/web_editor/static/src/js/editor/snippets.options.js index 635f75b003a..90bf944099c 100644 --- a/addons/web_editor/static/src/js/editor/snippets.options.js +++ b/addons/web_editor/static/src/js/editor/snippets.options.js @@ -4839,6 +4839,7 @@ registry.ReplaceMedia = SnippetOptionWidget.extend({ if (!url) { // As long as there is no URL, the image is not considered a link. linkEl.removeAttribute('href'); + this.$target.trigger('href_changed'); return; } if (!url.startsWith('/') && !url.startsWith('#') diff --git a/addons/web_editor/static/src/js/wysiwyg/widgets/link_popover_widget.js b/addons/web_editor/static/src/js/wysiwyg/widgets/link_popover_widget.js index 175da65d21e..268705a5f88 100644 --- a/addons/web_editor/static/src/js/wysiwyg/widgets/link_popover_widget.js +++ b/addons/web_editor/static/src/js/wysiwyg/widgets/link_popover_widget.js @@ -169,6 +169,11 @@ const LinkPopoverWidget = Widget.extend({ */ async _loadAsyncLinkPreview() { let url; + if (this.target.href === '') { + this._resetPreview(''); + this.$previewFaviconFa.removeClass('fa-globe').addClass('fa-question-circle-o'); + return; + } try { url = new URL(this.target.href); // relative to absolute } catch (_e) { @@ -230,8 +235,8 @@ const LinkPopoverWidget = Widget.extend({ */ _resetPreview(url) { this.$previewFaviconImg.addClass('d-none'); - this.$previewFaviconFa.removeClass('d-none').addClass('fa-globe'); - this.$urlLink.text(url).attr('href', url); + this.$previewFaviconFa.removeClass('d-none fa-question-circle-o fa-envelope-o fa-phone').addClass('fa-globe'); + this.$urlLink.text(url || _t('No URL specified')).attr('href', url || null); this.$fullUrl.text(url).addClass('d-none').removeClass('o_we_webkit_box'); }, diff --git a/addons/web_tour/static/src/js/running_tour_action_helper.js b/addons/web_tour/static/src/js/running_tour_action_helper.js index f0c27750b4a..4978f4094ab 100644 --- a/addons/web_tour/static/src/js/running_tour_action_helper.js +++ b/addons/web_tour/static/src/js/running_tour_action_helper.js @@ -28,6 +28,9 @@ var RunningTourActionHelper = core.Class.extend({ text: function (text, element) { this._text(this._get_action_values(element), text); }, + remove_text(text, element) { + this._text(this._get_action_values(element), '\n'); + }, text_blur: function (text, element) { this._text_blur(this._get_action_values(element), text); },