Last active
April 5, 2022 21:06
-
-
Save artginzburg/791ea42fb687bc7ca0144e7cc4a1f925 to your computer and use it in GitHub Desktop.
A drop-in patch for Firefox "dragend" and other DragEvent events.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* eslint-disable func-names, no-underscore-dangle, no-useless-escape, no-mixed-operators */ | |
/** | |
* A drop-in patch for Firefox "dragend" and other {@link DragEvent} events. | |
* @author Codesmith <https://bugzilla.mozilla.org/show_bug.cgi?id=505521#c87> | |
* @see {@link https://bugzilla.mozilla.org/show_bug.cgi?id=505521 Bugzilla: Bug #505521} | |
* | |
* @version 0.1.0 | |
* @link https://gist.github.com/artginzburg/791ea42fb687bc7ca0144e7cc4a1f925 | |
* @example React.useEffect(firefoxDragEventPatch, []); | |
*/ | |
export function firefoxDragEventPatch() { | |
if ( | |
/Firefox\/\d+[\d\.]*/.test(navigator.userAgent) && | |
typeof window.DragEvent === 'function' && | |
typeof window.addEventListener === 'function' | |
) { | |
(function () { | |
// patch for Firefox bug https://bugzilla.mozilla.org/show_bug.cgi?id=505521 | |
let cx; | |
let cy; | |
let px; | |
let py; | |
let ox; | |
let oy; | |
let sx; | |
let sy; | |
let lx; | |
let ly; | |
function update(e) { | |
cx = e.clientX; | |
cy = e.clientY; | |
px = e.pageX; | |
py = e.pageY; | |
ox = e.offsetX; | |
oy = e.offsetY; | |
sx = e.screenX; | |
sy = e.screenY; | |
lx = e.layerX; | |
ly = e.layerY; | |
} | |
function assign(e) { | |
e._ffix_cx = cx; | |
e._ffix_cy = cy; | |
e._ffix_px = px; | |
e._ffix_py = py; | |
e._ffix_ox = ox; | |
e._ffix_oy = oy; | |
e._ffix_sx = sx; | |
e._ffix_sy = sy; | |
e._ffix_lx = lx; | |
e._ffix_ly = ly; | |
} | |
window.addEventListener('mousemove', update, true); | |
window.addEventListener('dragover', update, true); | |
// bug #505521 identifies these three listeners as problematic: | |
// (although tests show 'dragstart' seems to work now, keep to be compatible) | |
window.addEventListener('dragstart', assign, true); | |
window.addEventListener('drag', assign, true); | |
window.addEventListener('dragend', assign, true); | |
const me = Object.getOwnPropertyDescriptors(window.MouseEvent.prototype); | |
const ue = Object.getOwnPropertyDescriptors(window.UIEvent.prototype); | |
function getter(prop, repl) { | |
return function () { | |
return ( | |
(me[prop] && me[prop].get.call(this)) || Number(this[repl]) || 0 | |
); | |
}; | |
} | |
function layerGetter(prop, repl) { | |
return function () { | |
return this.type === 'dragover' && ue[prop] | |
? ue[prop].get.call(this) | |
: Number(this[repl]) || 0; | |
}; | |
} | |
const descriptorClientX = Object.getOwnPropertyDescriptor( | |
window.DragEvent.prototype, | |
'clientX', | |
); | |
if (!descriptorClientX || descriptorClientX.configurable) { | |
Object.defineProperties(window.DragEvent.prototype, { | |
clientX: { get: getter('clientX', '_ffix_cx') }, | |
clientY: { get: getter('clientY', '_ffix_cy') }, | |
pageX: { get: getter('pageX', '_ffix_px') }, | |
pageY: { get: getter('pageY', '_ffix_py') }, | |
offsetX: { get: getter('offsetX', '_ffix_ox') }, | |
offsetY: { get: getter('offsetY', '_ffix_oy') }, | |
screenX: { get: getter('screenX', '_ffix_sx') }, | |
screenY: { get: getter('screenY', '_ffix_sy') }, | |
x: { get: getter('x', '_ffix_cx') }, | |
y: { get: getter('y', '_ffix_cy') }, | |
layerX: { get: layerGetter('layerX', '_ffix_lx') }, | |
layerY: { get: layerGetter('layerY', '_ffix_ly') }, | |
}); | |
} | |
})(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment