If you load a map with a marker in Safari, having the map inside a Shadow DOM, it seems to get hung up in an infinite page reload loop, until that infinite loop is stopped by the browser, which then shows the following error (translated from Spanish):
There has been a problem repeatedly with http://localhost:8000/index.html. Try loading the web page again.
I created the following very simple Polymer project to reproduce the problem.
Index.html
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<meta charset="utf-8">
<title>Markers test</title>
<style>
/* Always set the map height explicitly to define the size of the div
* element that contains the map. */
#map {
height: 300px;
width: 300px;
}
/* Optional: Makes the sample page fill the window. */
html, body {
height: 100%;
margin: 0;
padding: 0;
}
</style>
<script src="bower_components/webcomponentsjs/webcomponents-loader.js"></script>
<!-- Load your application shell -->
<link rel="import" href="test-el.html">
</head>
<body>
<test-el></test-el>
<div id="map"></div>
<script>
function initMap() {
const mapsEvent = new CustomEvent('map-ready');
document.dispatchEvent(mapsEvent);
window.MAP_READY = true;
}
</script>
<script async defer
src="https://maps.googleapis.com/maps/api/js?key=YOUR_MAPS_API_KEY_HERE&callback=initMap">
</script>
</body>
</html>
test-el.html, which is the Poylmer test element I created to encapsulate the map inside a Shadow DOM
<link rel="import" href="bower_components/polymer/polymer-element.html">
<dom-module id="test-el">
<template>
<style>
#map {
width: 300px;
height: 300px;
}
</style>
<div id="map"></div>
</template>
<script>
class TestEl extends Polymer.Element {
static get is() { return 'test-el'; }
static get properties() {
return {
// This shouldn't be neccessary, but the Analyzer isn't picking up
// Polymer.Element#rootPath
rootPath: String,
};
}
ready() {
super.ready();
if (window.MAP_READY) {
this.loadMap();
} else {
document.addEventListener('map-ready', () => this.loadMap());
}
}
loadMap() {
var myLatLng = {lat: -25.363, lng: 131.044};
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 4,
center: myLatLng
});
var marker = new google.maps.Marker({
position: myLatLng,
map: map,
title: 'Hello World!'
});
var mapShadowDom = new google.maps.Map(this.$.map, {
zoom: 4,
center: myLatLng
});
var markerShadowDom = new google.maps.Marker({
position: myLatLng,
map: mapShadowDom,
title: 'Hello World!'
});
}
}
window.customElements.define(TestEl.is, TestEl);
</script>
</dom-module>
If you want to run the same test I did, you would need the following small bower.json file, and running bower install
in the folder where you save these three documents, for bower to install webcomponents and Polymer dependencies.
{
"name": "markers_test",
"dependencies": {
"polymer": "Polymer/polymer#^2.5.0",
"webcomponentsjs": "webcomponents/webcomponentsjs#^1.0.0"
},
"resolutions": {
"polymer": "^2.0.0"
},
"private": true
}
Finally, serve index.html with a local server.
The test
As you can see, there is actually a <div id="map"></div>
right below the test-el
instantiation <test-el></test-el>
in index.html. That div
is not inside a Shadow DOM, so it is only there to show that the map and marker work perfectly fine if not inside a Shadow DOM.
In the <script>
section of the test-el.html file, inside the loadMap()
function, you can see I create 2 Google Maps with a marker each. The first Google Maps instantiation is assigned to the non-Shadow DOM div located in index.html, while the mapShadowDom
is assigned to the <div id="map"></div>
that is inside test-el's Shadow DOM.
Running this example code in Google Chrome, for instance, should render two maps of Australia, each with a marker right on its center.
Running this same code on Safari (I have tested on Safari 11.1) should lead to the error scenario I described at the top.
However, if you were to comment the following lines in test-el.html
var markerShadowDom = new google.maps.Marker({
position: myLatLng,
map: mapShadowDom,
title: 'Hello World!'
});
the result in Safari should look something like this:
So it seems like the problem is related to painting a Google Marker in a Google Map located inside a Shadow DOM.
To reload the markers, when you create then, push them to an array. Then create a function where you iterate through the array, setting the markers map as null. After this, erase the array.
Add different color markerspng at the end of the URL to get a blue marker. To add a green marker simply change it to green-dot. png so that the URL will be http://maps.google.com/mapfiles/ms/icons/green-dot.png .
Had the same problem. This is what I ended up doing for a temporary fix
var markerShadowDom = new google.maps.Marker({
icon: 'https://maps.gstatic.com/mapfiles/api-3/images/spotlight-poi.png',
position: myLatLng,
map: mapShadowDom,
title: 'Hello World!'
});
Custom markers seems to be ok with safari
Thank you for the very detailed info and repro steps!
Here's an issue that was reported on a Google Maps web component that seems to represent the same problem. Like you said, it only manifests when a marker is added to a map in shadow DOM.
It happens in Safari 11.1 (I still had Safari 11.0 this morning and couldn't repro with that version). It seems to be fixed in Tech Preview (Safari 12).
If you need a workaround quickly you could try forcing Safari 11.1 to use the shady DOM polyfill. Something like
<script>
// Force Safari 11.1.* to use shady DOM because of a bug
// See https://github.com/GoogleWebComponents/google-map/issues/419
// i don't know how to parse user agents
// this is probably bad
var s1 = 'Version/11.1';
var s2 = 'Safari/605.1.15';
var agent=navigator.userAgent;
if ((agent.search(s1) >= 0 ) && (agent.search(s2) >= 0 )) {
ShadyDOM = { force: true };
}
</script>
<script src="/bower_components/webcomponentsjs/webcomponents-loader.js"></script>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With