diff --git a/addons/website/models/ir_http.py b/addons/website/models/ir_http.py index 6a675a1245079cd22dcd913b2288994e45b14866..f217e79eab4990cf4ee0d9872fcac7e30a904969 100644 --- a/addons/website/models/ir_http.py +++ b/addons/website/models/ir_http.py @@ -422,6 +422,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'), }) if request.env.user.has_group('website.group_website_publisher'): session_info.update({ diff --git a/addons/website/static/src/js/content/snippets.animation.js b/addons/website/static/src/js/content/snippets.animation.js index cab2a8f5e04a6ebd68273f3208f8057158a7aef5..de044fba3d7b1b67d04712ec571b10d7f48120a2 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; @@ -982,9 +981,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 @@ -999,9 +995,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 dbafdff3f9f8248fc58b91401a2cf037bf31d6fb..2c271c7e36e58837988198c28b8b85bbf1fce8f0 100644 --- a/addons/website/static/src/js/editor/snippets.options.js +++ b/addons/website/static/src/js/editor/snippets.options.js @@ -2302,10 +2302,9 @@ 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()); this.displayNotification({ type: 'success', - message: _.str.sprintf(_t("Anchor copied to clipboard<br>Link: %s"), anchor), + message: _.str.sprintf(_t("Anchor copied to clipboard<br>Link: %s"), this._getAnchorLink()), buttons: [{text: _t("Edit"), click: () => this.openAnchorDialog(), primary: true}], }); }); diff --git a/addons/website_form/static/src/snippets/s_website_form/000.js b/addons/website_form/static/src/snippets/s_website_form/000.js index 64e39400b3ee9c6439a8c718f24977df0051cd85..b61a3297864674318535738c302a1c7dfc6e3b9f 100644 --- a/addons/website_form/static/src/snippets/s_website_form/000.js +++ b/addons/website_form/static/src/snippets/s_website_form/000.js @@ -7,6 +7,7 @@ odoo.define('website_form.s_website_form', function (require) { var ajax = require('web.ajax'); var publicWidget = require('web.public.widget'); const dom = require('web.dom'); + const session = require('web.session'); var _t = core._t; var qweb = core.qweb; @@ -192,17 +193,35 @@ odoo.define('website_form.s_website_form', function (require) { successMode = successPage ? 'redirect' : 'nothing'; } switch (successMode) { - case 'redirect': - successPage = successPage.startsWith("/#") ? successPage.slice(1) : successPage; + case 'redirect': { + const 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. + let currentUrlPath = window.location.pathname; + if (!currentUrlPath.endsWith("/")) { + currentUrlPath = currentUrlPath + "/"; + } + if ([successPage, "/" + session.lang_url_code + successPage].some(link => link.startsWith(currentUrlPath + '#'))) { + successPage = successPage.substring(hashIndex); + } + } if (successPage.charAt(0) === "#") { - dom.scrollTo($(successPage)[0], { - duration: 500, - extraOffset: 0, - }); + const successAnchorEl = document.getElementById(successPage.substring(1)); + if (successAnchorEl) { + dom.scrollTo(successAnchorEl, { + duration: 500, + extraOffset: 0, + }); + } } else { $(window.location).attr('href', successPage); } break; + } case 'message': self.$target[0].classList.add('d-none'); self.$target[0].parentElement.querySelector('.s_website_form_end_message').classList.remove('d-none');