: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
* Adds a new script to the page
iMapsBuilder.addGeoFileSeries = function (src, clback) {
var scriptPromise = new Promise(function (resolve, reject) {
var script = document.createElement('script');
document.body.appendChild(script);
scriptPromise.then(function () {
iMapsBuilder.initAvailableRegions();
iMapsBuilder.eventGeocoding = function (e) {
// e.target is the clicked element!
if (e.target && e.target.classList.contains('geocoding-input')) {
iMapsBuilder.geocoder = new google.maps.Geocoder();
iMapsBuilder.searchInput = e.target;
iMapsBuilder.searchInput.addEventListener('keypress', function (e) {
var key = e.which || e.keyCode;
iMapsBuilder.geocodeAddress();
// blur (remove focus) event
iMapsBuilder.searchInput.addEventListener('blur', function (e) {
iMapsBuilder.geocodeAddress();
iMapsBuilder.initGeocoding = function () {
// Get the element, add a click listener...
var container = document.getElementById('map_info');
container.addEventListener('click', iMapsBuilder.eventGeocoding);
container.addEventListener('focus', iMapsBuilder.eventGeocoding, true);
iMapsBuilder.eventGoogleAutocomplete = function (e) {
// e.target is the clicked element!
if (e.target && e.target.classList.contains('geocoding-input')) {
// Create the autocomplete object, restricting the search predictions to
// geographical location types.
iMapsBuilder.autocomplete = new google.maps.places.Autocomplete(e.target, {
iMapsBuilder.searchInput = e.target;
// Avoid paying for data that you don't need by restricting the set of
// place fields that are returned to just the address components.
iMapsBuilder.autocomplete.setFields(['geometry']);
// When the user selects an address from the drop-down, populate the
// address fields in the form.
iMapsBuilder.autocomplete.addListener('place_changed', iMapsBuilder.fillInAddress);
iMapsBuilder.initGoogleAutocomplete = function () {
// Get the element, add a click listener...
var container = document.getElementById('map_info');
container.addEventListener('click', iMapsBuilder.eventGoogleAutocomplete);
container.addEventListener('focus', iMapsBuilder.eventGoogleAutocomplete, true);
iMapsBuilder.fillInAddress = function (i) {
var autocomplete = iMapsBuilder.autocomplete;
var input = iMapsBuilder.searchInput;
var parent = iMapsBuilder.getClosest(input, '.csf-fieldset-content');
var changeEvent = new Event('change');
console.log(iMapsBuilder.autocomplete);
// Get the place details from the autocomplete object.
var place = autocomplete.getPlace();
var latfield = parent.querySelector('[data-depend-id="latitude"]');
var lonfield = parent.querySelector('[data-depend-id="longitude"]');
latfield.value = place.geometry.location.lat();
lonfield.value = place.geometry.location.lng();
latfield.dispatchEvent(changeEvent);
iMapsBuilder.geocodeAddress = function () {
var addressInput = iMapsBuilder.searchInput,
address = addressInput.value,
geocoder = iMapsBuilder.geocoder,
parent = iMapsBuilder.getClosest(iMapsBuilder.searchInput, '.csf-fieldset-content'),
latfield = parent.querySelector('[data-depend-id="latitude"]'),
lonfield = parent.querySelector('[data-depend-id="longitude"]'),
changeEvent = new Event('change');
addressInput.setAttribute('readonly', 'readonly');
function (results, status) {
latfield.value = place.geometry.location.lat();
lonfield.value = place.geometry.location.lng();
latfield.dispatchEvent(changeEvent);
console.log('geocode error: ' + status);
addressInput.removeAttribute('readonly');
iMapsBuilder.getClosest = function (elem, selector) {
// Element.matches() polyfill
if (!Element.prototype.matches) {
Element.prototype.matches =
Element.prototype.matchesSelector ||
Element.prototype.mozMatchesSelector ||
Element.prototype.msMatchesSelector ||
Element.prototype.oMatchesSelector ||
Element.prototype.webkitMatchesSelector ||
var matches = (this.document || this.ownerDocument).querySelectorAll(s),
while (--i >= 0 && matches.item(i) !== this) {}
// Get the closest matching element
for (; elem && elem !== document; elem = elem.parentNode) {
if (elem.matches(selector)) return elem;
iMapsBuilder.swap = function (json) {
iMapsBuilder.eventThrottle = function (fn, threshold, scope) {
threshold = typeof threshold !== 'undefined' ? threshold : 250;
var context = scope || this;
if (last && now < last + threshold) {
clearTimeout(deferTimer);
deferTimer = setTimeout(function () {
iMapsBuilder.addRegion = function (regionCode, regionName) {
addButton = document.querySelector('.regions_tab .csf-cloneable-add');
regionTab = document.querySelector('#map_info .csf-nav-metabox ul li:nth-of-type(3)');
if (!regionTab.classList.contains('csf-section-active')) {
regionTab.querySelector('a').click();
// check if region already exists
regionCollection = document.querySelector('.region-code-autocomplete');
if (regionCollection.length > 0) {
regionCollection.forEach(function (field) {
if (field.value === regionCode) {
// if it doesn't exist yet
newEntry = document.querySelector(
'div[data-field-id="[regions]"] .csf-cloneable-item:last-of-type'
titleField = newEntry.querySelector('[data-depend-id="name"]');
titleField.value = regionName;
titleField.dispatchEvent(new Event('keyup'));
regionCodeField = newEntry.querySelector('[data-depend-id="id"]');
regionCodeField.value = regionCode;
tooltipField = newEntry.querySelector('[data-depend-id="tooltipContent"]');
tooltipField.value = regionName;
iMapsBuilder.updateRegionsUsed();
iMapsBuilder.populateAvailableRegions();
iMapsBuilder.addMarker = function (latitude, longitude) {
previewContainer = document.querySelector('.map_wrapper'),
addButton = document.querySelector('.markers_tab .csf-cloneable-add');
markersTab = document.querySelector('#map_info .csf-nav-metabox ul li:nth-of-type(4)');
if (!markersTab.classList.contains('csf-section-active')) {
markersTab.querySelector('a').click();
newEntry = document.querySelector(
'div[data-field-id="[roundMarkers]"] .csf-cloneable-item:last-of-type'
titleField = newEntry.querySelector('[data-depend-id="id"]');
thisID = titleField.getAttribute('name');
thisID = thisID.replace('map_info[roundMarkers]', '');
thisID = thisID.replace('[id]', '');
titleField.value = 'Custom Marker ' + thisID;
titleField.dispatchEvent(new Event('keyup'));
tooltipField = newEntry.querySelector('[data-depend-id="tooltipContent"]');
tooltipField.value = 'Custom Marker ' + thisID;
latitudeField = newEntry.querySelector('[data-depend-id="latitude"]');
longitudeField = newEntry.querySelector('[data-depend-id="longitude"]');
if (latitudeField && longitudeField) {
latitudeField.value = latitude;
longitudeField.value = longitude;
// probably using openstreetmap
latitudeField = newEntry.querySelector('.csf--latitude');
longitudeField = newEntry.querySelector('.csf--longitude');
latitudeField.value = latitude;
longitudeField.value = longitude;
latitudeField.dispatchEvent(new Event('change'));
iMapsBuilder.needsUpdate = true;
previewContainer.classList.add('map_updating');
if (!iMapsBuilder.isInViewport(previewContainer)) {
form = iMapsBuilder.form;
iMapsBuilder.updatePreview(form, false);
* Determine if an element is in the viewport
* (c) 2017 Chris Ferdinandi, MIT License, https://gomakethings.com
* @param {Node} elem The element
* @return {Boolean} Returns true if element is in the viewport
iMapsBuilder.isInViewport = function (elem) {
var distance = elem.getBoundingClientRect();
distance.bottom >= 250 &&
distance.bottom <= (window.innerHeight || document.documentElement.clientHeight)
// code for geolocate metabox
iMapsBuilder.geoLocateInit = function () {
// fix map field not rendering properly when initially hidden
let trigger = document.querySelector('[data-depend-id="enabled"]').closest('.csf--switcher');
trigger.addEventListener('click', function () {
window.dispatchEvent(new Event('resize'));
// if we have the options available, we're in the edit map screen
if (typeof iMapsOptions !== 'undefined') {
iMapsBuilder.geoLocateInit();