[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:
@@ -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',
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user