From c6767e24f5d8d9624f79b6ac952b576008c5845a Mon Sep 17 00:00:00 2001 From: Michael Diego <6419886+itsmichaeldiego@users.noreply.github.com> Date: Wed, 3 Apr 2019 10:19:42 -0300 Subject: [PATCH] Revert "Google Map loader respecting the app language change (#726)" (#738) This reverts commit 55fd1b06a375e2126e8dea95d5f32943f4009553. --- package.json | 3 +- src/loaders/google_map_loader.js | 132 +++++++++++++++---------------- yarn.lock | 4 + 3 files changed, 71 insertions(+), 68 deletions(-) diff --git a/package.json b/package.json index 1dbf088..5a25b54 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,8 @@ }, "dependencies": { "@mapbox/point-geometry": "^0.1.0", - "eventemitter3": "^1.1.0" + "eventemitter3": "^1.1.0", + "scriptjs": "^2.5.7" }, "devDependencies": { "autoprefixer": "^6.3.6", diff --git a/src/loaders/google_map_loader.js b/src/loaders/google_map_loader.js index 676d758..ce29d73 100644 --- a/src/loaders/google_map_loader.js +++ b/src/loaders/google_map_loader.js @@ -1,89 +1,87 @@ const BASE_URL = 'https://maps'; const DEFAULT_URL = `${BASE_URL}.googleapis.com`; -const API_PATH = '/maps/api/js?callback=googleMapsAPILoadedPromise'; -const EVENT_GMAPS_LOADED = 'EVENT_GMAPS_LOADED'; +const API_PATH = '/maps/api/js?callback=_$_google_map_initialize_$_'; -const getBaseUrl = region => { +const getUrl = region => { if (region && region.toLowerCase() === 'cn') { return `${BASE_URL}.google.cn`; } return DEFAULT_URL; }; -let currentResolver = null; -let lastBaseUrl = ''; -let lastScriptUrl = ''; -let googleMapsPromise; +let $script_ = null; -const destroyOldGoogleMapsInstance = url => { - document - .querySelectorAll(`script[src^='${url}']`) - .forEach(script => script.remove()); - if (window.google) delete window.google.maps; -}; +let loadPromise_; -// Callback for the Google Maps API src -window.googleMapsAPILoadedPromise = () => - window.dispatchEvent(new CustomEvent(EVENT_GMAPS_LOADED)); +let resolveCustomPromise_; -const getScriptUrl = bootstrapURLKeys => { - const baseUrl = getBaseUrl(bootstrapURLKeys.region); - const params = Object.keys(bootstrapURLKeys).reduce( - (r, key) => `${r}&${key}=${bootstrapURLKeys[key]}`, - '' - ); - return `${baseUrl}${API_PATH}${params}`; -}; +const _customPromise = new Promise(resolve => { + resolveCustomPromise_ = resolve; +}); -const loadScript = url => { - const script = document.createElement('script'); +// TODO add libraries language and other map options +export default (bootstrapURLKeys, heatmapLibrary) => { + if (!$script_) { + $script_ = require('scriptjs'); // eslint-disable-line + } - script.type = 'text/javascript'; - script.async = true; - script.src = url; - document.querySelector('head').appendChild(script); + // call from outside google-map-react + // will be as soon as loadPromise_ resolved + if (!bootstrapURLKeys) { + return _customPromise; + } - return new Promise(resolve => { - if (currentResolver) { - window.removeEventListener(EVENT_GMAPS_LOADED, currentResolver); + if (loadPromise_) { + return loadPromise_; + } + + loadPromise_ = new Promise((resolve, reject) => { + if (typeof window === 'undefined') { + reject(new Error('google map cannot be loaded outside browser env')); + return; } - currentResolver = () => { - resolve(); + + if (window.google && window.google.maps) { + resolve(window.google.maps); + return; + } + + if (typeof window._$_google_map_initialize_$_ !== 'undefined') { + reject(new Error('google map initialization error')); + } + + window._$_google_map_initialize_$_ = () => { + delete window._$_google_map_initialize_$_; + resolve(window.google.maps); }; - window.addEventListener(EVENT_GMAPS_LOADED, currentResolver); - }); -}; -const loadGoogleMaps = bootstrapURLKeys => - new Promise(async resolve => { - lastScriptUrl = getScriptUrl(bootstrapURLKeys); - await loadScript(lastScriptUrl); - resolve(window.google.maps); + if (process.env.NODE_ENV !== 'production') { + if (Object.keys(bootstrapURLKeys).indexOf('callback') > -1) { + const message = `"callback" key in bootstrapURLKeys is not allowed, + use onGoogleApiLoaded property instead`; + // eslint-disable-next-line no-console + console.error(message); + throw new Error(message); + } + } + + const params = Object.keys(bootstrapURLKeys).reduce( + (r, key) => `${r}&${key}=${bootstrapURLKeys[key]}`, + '' + ); + + const baseUrl = getUrl(bootstrapURLKeys.region); + const libraries = heatmapLibrary ? '&libraries=visualization' : ''; + + $script_( + `${baseUrl}${API_PATH}${params}${libraries}`, + () => + typeof window.google === 'undefined' && + reject(new Error('google map initialization error (not loaded)')) + ); }); -export default bootstrapURLKeys => { - if (typeof window === 'undefined') { - throw new Error('google map cannot be loaded outside browser env'); - } + resolveCustomPromise_(loadPromise_); - if (process.env.NODE_ENV !== 'production') { - if (Object.keys(bootstrapURLKeys).includes('callback')) { - const message = `'callback' key in bootstrapURLKeys is not allowed, use onGoogleapiLoadedPromise property instead`; - // eslint-disable-next-line no-console - console.error(message); - throw new Error(message); - } - } - if (googleMapsPromise) { - if (lastScriptUrl !== getScriptUrl(bootstrapURLKeys)) { - destroyOldGoogleMapsInstance(lastBaseUrl); - googleMapsPromise = loadGoogleMaps(bootstrapURLKeys); - } - return googleMapsPromise; - } - - googleMapsPromise = loadGoogleMaps(bootstrapURLKeys); - lastBaseUrl = getBaseUrl(bootstrapURLKeys.region); - - return googleMapsPromise; + return loadPromise_; }; diff --git a/yarn.lock b/yarn.lock index 6c768ce..378cdd0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4989,6 +4989,10 @@ sax@^1.2.4, sax@~1.2.1: version "1.2.4" resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" +scriptjs@^2.5.7: + version "2.5.8" + resolved "https://registry.yarnpkg.com/scriptjs/-/scriptjs-2.5.8.tgz#d0c43955c2e6bad33b6e4edf7b53b8965aa7ca5f" + scss-tokenizer@^0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz#8eb06db9a9723333824d3f5530641149847ce5d1"