diff --git a/src/lib/index.js b/src/lib/index.js index e696a2068ab..0cbb71bf129 100644 --- a/src/lib/index.js +++ b/src/lib/index.js @@ -715,6 +715,18 @@ lib.isIOS = function() { return IS_IOS_REGEX.test(window.navigator.userAgent); }; +var FIREFOX_VERSION_REGEX = /Firefox\/(\d+)\.\d+/; +lib.getFirefoxVersion = function() { + var match = FIREFOX_VERSION_REGEX.exec(window.navigator.userAgent); + if(match && match.length === 2) { + var versionInt = parseInt(match[1]); + if(!isNaN(versionInt)) { + return versionInt; + } + } + return null; +}; + lib.isD3Selection = function(obj) { return obj instanceof d3.selection; }; @@ -1267,3 +1279,27 @@ lib.join2 = function(arr, mainSeparator, lastSeparator) { lib.bigFont = function(size) { return Math.round(1.2 * size); }; + +var firefoxVersion = lib.getFirefoxVersion(); +// see https://bugzilla.mozilla.org/show_bug.cgi?id=1684973 +var isProblematicFirefox = firefoxVersion !== null && firefoxVersion < 86; + +/** + * Return the mouse position from the last event registered by D3. + * @returns An array with two numbers, representing the x and y coordinates of the mouse pointer + * at the event relative to the targeted node. + */ +lib.getPositionFromD3Event = function() { + if(isProblematicFirefox) { + // layerX and layerY are non-standard, so we only fallback to them when we have to: + return [ + d3.event.layerX, + d3.event.layerY + ]; + } else { + return [ + d3.event.offsetX, + d3.event.offsetY + ]; + } +}; diff --git a/src/plots/geo/geo.js b/src/plots/geo/geo.js index c5789f600f2..5ed53ca379f 100644 --- a/src/plots/geo/geo.js +++ b/src/plots/geo/geo.js @@ -506,7 +506,7 @@ proto.updateFx = function(fullLayout, geoLayout) { } bgRect.on('mousemove', function() { - var lonlat = _this.projection.invert(d3.mouse(this)); + var lonlat = _this.projection.invert(Lib.getPositionFromD3Event()); if(!lonlat || isNaN(lonlat[0]) || isNaN(lonlat[1])) { return dragElement.unhover(gd, d3.event);