[FIX] website: make s_map work in sanitized fields

Before this commit, the `<iframe/>` element of the `s_map` snippet would
be removed from the field value if the field was sanitized.
The map would then not be displayed, obviously.

The way that `s_map` snippet work is simple:
1. The snippet is defined with a hidden `<iframe/>` element
2. The snippet options are stored as data attributes on the `<section/>`
   element.
3. When those options are changed, the iframe `src` is updated and it is
   shown if needed.

The fix is simple, as we already have all the data attributes available,
we just need to recreate that iframe when the snippet is started without
one. It most likely means it got deleted through the sanitization during
the save.

opw-2844010

closes odoo/odoo#91866

X-original-commit: c2e9bd0e60014b6a42931cf300e0f89f8cf7c225
Signed-off-by: Quentin Smetz (qsm) <qsm@odoo.com>
This commit is contained in:
Romain Derie
2022-05-23 23:31:53 +02:00
committed by qsm-odoo
parent 482b539351
commit 88194dd941
5 changed files with 74 additions and 8 deletions
+1 -3
View File
@@ -107,9 +107,7 @@
'views/res_partner_views.xml',
'wizard/base_language_install_views.xml',
'wizard/website_robots.xml',
# Old snippets
],
],
'demo': [
'data/website_demo.xml',
'data/website_visitor_demo.xml',
+33
View File
@@ -351,6 +351,37 @@ async function svgToPNG(src) {
}).then(loadedImgEl => toPNGViaCanvas(loadedImgEl));
}
/**
* Bootstraps an "empty" Google Maps iframe.
*
* @returns {HTMLIframeElement}
*/
function generateGMapIframe() {
const iframeEl = document.createElement('iframe');
iframeEl.classList.add('s_map_embedded', 'o_not_editable');
iframeEl.setAttribute('width', '100%');
iframeEl.setAttribute('height', '100%');
iframeEl.setAttribute('frameborder', '0');
iframeEl.setAttribute('scrolling', 'no');
iframeEl.setAttribute('marginheight', '0');
iframeEl.setAttribute('marginwidth', '0');
iframeEl.setAttribute('src', 'about:blank');
return iframeEl;
}
/**
* Generates a Google Maps URL based on the given parameter.
*
* @param {DOMStringMap} dataset
* @returns {string} a Google Maps URL
*/
function generateGMapLink(dataset) {
return 'https://maps.google.com/maps?q=' + encodeURIComponent(dataset.mapAddress)
+ '&t=' + encodeURIComponent(dataset.mapType)
+ '&z=' + encodeURIComponent(dataset.mapZoom)
+ '&ie=UTF8&iwloc=&output=embed';
}
return {
loadAnchors: loadAnchors,
autocompleteWithPages: autocompleteWithPages,
@@ -359,5 +390,7 @@ return {
sendRequest: sendRequest,
websiteDomain: websiteDomain,
svgToPNG: svgToPNG,
generateGMapIframe: generateGMapIframe,
generateGMapLink: generateGMapLink,
};
});
@@ -0,0 +1,29 @@
/** @odoo-module **/
import publicWidget from 'web.public.widget';
import {generateGMapLink, generateGMapIframe} from 'website.utils';
publicWidget.registry.Map = publicWidget.Widget.extend({
selector: '.s_map',
/**
* @override
*/
start() {
if (!this.el.querySelector('.s_map_embedded')) {
// The iframe is not found inside the snippet. This is probably due
// the sanitization of a field during the save, like in a product
// description field.
// In such cases, reconstruct the iframe.
const dataset = this.el.dataset;
if (dataset.mapAddress) {
const iframeEl = generateGMapIframe();
iframeEl.setAttribute('src', generateGMapLink(dataset));
this.el.querySelector('.s_map_color_filter').before(iframeEl);
}
}
return this._super(...arguments);
},
});
export default publicWidget.registry.Map;
@@ -2,12 +2,15 @@
import {_t} from 'web.core';
import options from 'web_editor.snippets.options';
import {generateGMapIframe, generateGMapLink} from 'website.utils';
options.registry.Map = options.Class.extend({
/**
* @override
*/
onBuilt() {
const iframeEl = generateGMapIframe();
this.$target[0].querySelector('.s_map_color_filter').before(iframeEl);
this._updateSource();
},
@@ -62,10 +65,7 @@ options.registry.Map = options.Class.extend({
const $embedded = this.$target.find('.s_map_embedded');
const $info = this.$target.find('.missing_option_warning');
if (dataset.mapAddress) {
const url = 'https://maps.google.com/maps?q=' + encodeURIComponent(dataset.mapAddress)
+ '&t=' + encodeURIComponent(dataset.mapType)
+ '&z=' + encodeURIComponent(dataset.mapZoom)
+ '&ie=UTF8&iwloc=&output=embed';
const url = generateGMapLink(dataset);
if (url !== $embedded.attr('src')) {
$embedded.attr('src', url);
}
+7 -1
View File
@@ -9,7 +9,7 @@
An address must be specified for a map to be embedded
</div>
</div>
<iframe class="d-none s_map_embedded o_not_editable" width="100%" height="100%" src="about:blank" frameborder="0" scrolling="no" marginheight="0" marginwidth="0"></iframe>
<!-- GMap iframe will be injected in JS -->
<div class="s_map_color_filter"/>
</div>
</section>
@@ -59,4 +59,10 @@
<field name="path">website/static/src/snippets/s_map/000.scss</field>
</record>
<record id="website.s_map_000_js" model="ir.asset">
<field name="name">Map 000 JS</field>
<field name="bundle">web.assets_frontend</field>
<field name="path">website/static/src/snippets/s_map/000.js</field>
</record>
</odoo>