diff --git a/addons/website/models/ir_http.py b/addons/website/models/ir_http.py index 851ef10698be64aca93c1eae64f98d5969d1a26e..581e23018330c0646b89bd497c2f07dfca86d818 100644 --- a/addons/website/models/ir_http.py +++ b/addons/website/models/ir_http.py @@ -451,6 +451,7 @@ class Http(models.AbstractModel): session_info = super(Http, self).get_frontend_session_info() session_info.update({ 'is_website_user': request.env.user.id == request.website.user_id.id, + 'lang_url_code': request.lang._get_cached('url_code'), 'geoip_country_code': request.session.get('geoip', {}).get('country_code'), }) if request.env.user.has_group('website.group_website_publisher'): diff --git a/addons/website/static/src/js/content/snippets.animation.js b/addons/website/static/src/js/content/snippets.animation.js index 038453cee5fb60583bce88b8176cdaaff17627e6..4adc1524911e6881af2c391e458f0926c42ada41 100644 --- a/addons/website/static/src/js/content/snippets.animation.js +++ b/addons/website/static/src/js/content/snippets.animation.js @@ -12,7 +12,6 @@ var core = require('web.core'); const dom = require('web.dom'); var mixins = require('web.mixins'); var publicWidget = require('web.public.widget'); -var utils = require('web.utils'); const wUtils = require('website.utils'); var qweb = core.qweb; @@ -986,9 +985,6 @@ registry.anchorSlide = publicWidget.Widget.extend({ * @private */ _onAnimateClick: function (ev) { - if (this.$target[0].pathname !== window.location.pathname) { - return; - } var hash = this.$target[0].hash; if (hash === '#top' || hash === '#bottom') { // If the anchor targets #top or #bottom, directly call the @@ -1003,9 +999,11 @@ registry.anchorSlide = publicWidget.Widget.extend({ }); return; } - if (!utils.isValidAnchor(hash)) { + if (!hash.length) { return; } + // Escape special characters to make the jQuery selector to work. + hash = '#' + $.escapeSelector(hash.substring(1)); var $anchor = $(hash); const scrollValue = $anchor.attr('data-anchor'); if (!$anchor.length || !scrollValue) { diff --git a/addons/website/static/src/js/editor/snippets.options.js b/addons/website/static/src/js/editor/snippets.options.js index 6bee39ebb374230c38627df91a358d37969dd6aa..a516ba9906c69c3194710c63c68132769c052de0 100644 --- a/addons/website/static/src/js/editor/snippets.options.js +++ b/addons/website/static/src/js/editor/snippets.options.js @@ -2544,8 +2544,7 @@ options.registry.anchor = options.Class.extend({ this.$button = this.$el.find('we-button'); const clipboard = new ClipboardJS(this.$button[0], {text: () => this._getAnchorLink()}); clipboard.on('success', () => { - const anchor = decodeURIComponent(this._getAnchorLink()); - const message = sprintf(Markup(_t("Anchor copied to clipboard<br>Link: %s")), anchor); + const message = sprintf(Markup(_t("Anchor copied to clipboard<br>Link: %s")), this._getAnchorLink()); this.displayNotification({ type: 'success', message: message, diff --git a/addons/website/static/src/snippets/s_website_form/000.js b/addons/website/static/src/snippets/s_website_form/000.js index 52aaa8231905865813e58879291abbca5fb59517..ac84e342bc3e3672a80bd81c2628ef1f6269350e 100644 --- a/addons/website/static/src/snippets/s_website_form/000.js +++ b/addons/website/static/src/snippets/s_website_form/000.js @@ -339,12 +339,39 @@ odoo.define('website.s_website_form', function (require) { } switch (successMode) { case 'redirect': { - successPage = successPage.startsWith("/#") ? successPage.slice(1) : successPage; + let hashIndex = successPage.indexOf("#"); + if (hashIndex > 0) { + // URL containing an anchor detected: extract + // the anchor from the URL if the URL is the + // same as the current page URL so we can scroll + // directly to the element (if found) later + // instead of redirecting. + // Note that both currentUrlPath and successPage + // can exist with or without a trailing slash + // before the hash (e.g. "domain.com#footer" or + // "domain.com/#footer"). Therefore, if they are + // not present, we add them to be able to + // compare the two variables correctly. + let currentUrlPath = window.location.pathname; + if (!currentUrlPath.endsWith("/")) { + currentUrlPath = currentUrlPath + "/"; + } + if (!successPage.includes("/#")) { + successPage = successPage.replace("#", "/#"); + hashIndex++; + } + if ([successPage, "/" + session.lang_url_code + successPage].some(link => link.startsWith(currentUrlPath + '#'))) { + successPage = successPage.substring(hashIndex); + } + } if (successPage.charAt(0) === "#") { - await dom.scrollTo($(successPage)[0], { - duration: 500, - extraOffset: 0, - }); + const successAnchorEl = document.getElementById(successPage.substring(1)); + if (successAnchorEl) { + await dom.scrollTo(successAnchorEl, { + duration: 500, + extraOffset: 0, + }); + } break; } $(window.location).attr('href', successPage);