[FIX] website: restore google map UI for special google map snippet
Since [1], the google map UI to search for locations thanks to the google map API was not working anymore. Indeed, the lib was loaded inside the iframe (as it should) but not outside of it, preventing to use the `google` object in the related editor panel widget. The autocomplete UI style was also broken as the CSS is not available outside the iframe. As a fix, the code outside the iframe now use the `google` object from inside the iframe (no problem seems to come out of it) and the style is restored via custom CSS (custom CSS already existed and was already changing most default style anyway). As a reminder, this snippet is only available in debug mode or if your google map key is setup, which we do not allow to enter anymore via standard flow since 16.0 (15.3). [1]: https://github.com/odoo/odoo/commit/31cc10b91dc7762e23b4bde9b945be0c4ce3fe3b closes odoo/odoo#106103 X-original-commit: 7d60d0ae4ea195edc4a12e57bf1c3b7c661bcf82 Signed-off-by: Quentin Smetz (qsm) <qsm@odoo.com>
This commit is contained in:
@@ -1,4 +1,3 @@
|
||||
/* globals google*/
|
||||
odoo.define('website.editor.snippets.options', function (require) {
|
||||
'use strict';
|
||||
|
||||
@@ -316,6 +315,11 @@ const GPSPicker = InputUserValueWidget.extend({
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
this._gmapCacheGPSToPlace = {};
|
||||
|
||||
// The google API will be loaded inside the website iframe. Let's try
|
||||
// not having to load it in the backend too and just using the iframe
|
||||
// google object instead.
|
||||
this.contentWindow = this.$target[0].ownerDocument.defaultView;
|
||||
},
|
||||
/**
|
||||
* @override
|
||||
@@ -354,8 +358,23 @@ const GPSPicker = InputUserValueWidget.extend({
|
||||
return;
|
||||
}
|
||||
|
||||
this._gmapAutocomplete = new google.maps.places.Autocomplete(this.inputEl, {types: ['geocode']});
|
||||
google.maps.event.addListener(this._gmapAutocomplete, 'place_changed', this._onPlaceChanged.bind(this));
|
||||
this._gmapAutocomplete = new this.contentWindow.google.maps.places.Autocomplete(this.inputEl, {types: ['geocode']});
|
||||
this.contentWindow.google.maps.event.addListener(this._gmapAutocomplete, 'place_changed', this._onPlaceChanged.bind(this));
|
||||
},
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
destroy() {
|
||||
this._super(...arguments);
|
||||
|
||||
// Without this, the google library injects elements inside the backend
|
||||
// DOM but do not remove them once the editor is left. Notice that
|
||||
// this is also done when the widget is destroyed for another reason
|
||||
// than leaving the editor, but if the google API needs that container
|
||||
// again afterwards, it will simply recreate it.
|
||||
for (const el of document.body.querySelectorAll('.pac-container')) {
|
||||
el.remove();
|
||||
}
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
@@ -400,9 +419,9 @@ const GPSPicker = InputUserValueWidget.extend({
|
||||
}
|
||||
|
||||
const p = gps.substring(1).slice(0, -1).split(',');
|
||||
const location = new google.maps.LatLng(p[0] || 0, p[1] || 0);
|
||||
const location = new this.contentWindow.google.maps.LatLng(p[0] || 0, p[1] || 0);
|
||||
return new Promise(resolve => {
|
||||
const service = new google.maps.places.PlacesService(document.createElement('div'));
|
||||
const service = new this.contentWindow.google.maps.places.PlacesService(document.createElement('div'));
|
||||
service.nearbySearch({
|
||||
// Do a 'nearbySearch' followed by 'getDetails' to avoid using
|
||||
// GMap Geocoder which the user may not have enabled... but
|
||||
@@ -411,13 +430,16 @@ const GPSPicker = InputUserValueWidget.extend({
|
||||
location: location,
|
||||
radius: 1,
|
||||
}, (results, status) => {
|
||||
const GMAP_CRITICAL_ERRORS = [google.maps.places.PlacesServiceStatus.REQUEST_DENIED, google.maps.places.PlacesServiceStatus.UNKNOWN_ERROR];
|
||||
if (status === google.maps.places.PlacesServiceStatus.OK) {
|
||||
const GMAP_CRITICAL_ERRORS = [
|
||||
this.contentWindow.google.maps.places.PlacesServiceStatus.REQUEST_DENIED,
|
||||
this.contentWindow.google.maps.places.PlacesServiceStatus.UNKNOWN_ERROR
|
||||
];
|
||||
if (status === this.contentWindow.google.maps.places.PlacesServiceStatus.OK) {
|
||||
service.getDetails({
|
||||
placeId: results[0].place_id,
|
||||
fields: ['geometry', 'formatted_address'],
|
||||
}, (place, status) => {
|
||||
if (status === google.maps.places.PlacesServiceStatus.OK) {
|
||||
if (status === this.contentWindow.google.maps.places.PlacesServiceStatus.OK) {
|
||||
this._gmapCacheGPSToPlace[gps] = place;
|
||||
resolve(place);
|
||||
} else if (GMAP_CRITICAL_ERRORS.includes(status)) {
|
||||
|
||||
@@ -231,29 +231,54 @@ $i: 1;
|
||||
border-bottom: none !important;
|
||||
}
|
||||
|
||||
.pac-container { // google map autosuggestion
|
||||
.pac-container { // google map autosuggestion (note: their CSS lib is not used)
|
||||
z-index: $zindex-modal-backdrop; // > $o-we-zindex
|
||||
width: $o-we-sidebar-width !important;
|
||||
width: ceil($o-we-sidebar-width * 0.9) !important;
|
||||
font-size: $o-we-sidebar-font-size;
|
||||
margin-left: -$o-we-sidebar-width/2;
|
||||
border: $o-we-sidebar-content-field-border-width solid $o-we-sidebar-content-field-dropdown-border-color;
|
||||
border-top: none;
|
||||
border-radius: $o-we-item-border-radius;
|
||||
overflow: hidden;
|
||||
background-color: $o-we-sidebar-content-field-dropdown-bg;
|
||||
box-shadow: $o-we-sidebar-content-field-dropdown-shadow;
|
||||
margin-top: $o-we-sidebar-content-field-dropdown-spacing;
|
||||
transform: translate(41px);
|
||||
|
||||
&:after {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.pac-item {
|
||||
@include o-text-overflow(block);
|
||||
line-height: $o-we-sidebar-content-field-dropdown-item-height;
|
||||
color: $o-we-sidebar-content-field-clickable-color;
|
||||
padding: 0 1em 0 (2 * $o-we-sidebar-content-field-control-item-spacing + $o-we-sidebar-content-field-control-item-size);
|
||||
border-top: $o-we-sidebar-content-field-border-width solid lighten($o-we-sidebar-content-field-dropdown-border-color, 15%);
|
||||
border-radius: $o-we-sidebar-content-field-border-radius;
|
||||
background-color: $o-we-sidebar-content-field-clickable-bg;
|
||||
color: $o-we-sidebar-content-field-clickable-color;
|
||||
&:hover {
|
||||
font-size: $o-we-sidebar-font-size;
|
||||
|
||||
&:hover, &:focus, &.pac-item-selected {
|
||||
background-color: $o-we-sidebar-content-field-dropdown-item-bg-hover;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
.pac-item-query {
|
||||
color: $o-we-sidebar-content-field-clickable-color;
|
||||
|
||||
.pac-icon-marker {
|
||||
position: absolute;
|
||||
margin-left: -1em;
|
||||
|
||||
&::after {
|
||||
content: '\f041';
|
||||
font-family: FontAwesome;
|
||||
}
|
||||
}
|
||||
|
||||
.pac-item-query {
|
||||
margin-right: 0.4em;
|
||||
color: inherit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user