fix(runtime-dom): fix event listeners call in firefox <= 53 (#3501)
fix #3485
This commit is contained in:
parent
42b68c773d
commit
33ba0e3229
@ -15,19 +15,24 @@ type EventValue = Function | Function[]
|
|||||||
// Async edge case fix requires storing an event listener's attach timestamp.
|
// Async edge case fix requires storing an event listener's attach timestamp.
|
||||||
let _getNow: () => number = Date.now
|
let _getNow: () => number = Date.now
|
||||||
|
|
||||||
|
let skipTimestampCheck = false
|
||||||
|
|
||||||
|
if (typeof window !== 'undefined') {
|
||||||
// Determine what event timestamp the browser is using. Annoyingly, the
|
// Determine what event timestamp the browser is using. Annoyingly, the
|
||||||
// timestamp can either be hi-res (relative to page load) or low-res
|
// timestamp can either be hi-res (relative to page load) or low-res
|
||||||
// (relative to UNIX epoch), so in order to compare time we have to use the
|
// (relative to UNIX epoch), so in order to compare time we have to use the
|
||||||
// same timestamp type when saving the flush timestamp.
|
// same timestamp type when saving the flush timestamp.
|
||||||
if (
|
if (_getNow() > document.createEvent('Event').timeStamp) {
|
||||||
typeof document !== 'undefined' &&
|
|
||||||
_getNow() > document.createEvent('Event').timeStamp
|
|
||||||
) {
|
|
||||||
// if the low-res timestamp which is bigger than the event timestamp
|
// if the low-res timestamp which is bigger than the event timestamp
|
||||||
// (which is evaluated AFTER) it means the event is using a hi-res timestamp,
|
// (which is evaluated AFTER) it means the event is using a hi-res timestamp,
|
||||||
// and we need to use the hi-res version for event listeners as well.
|
// and we need to use the hi-res version for event listeners as well.
|
||||||
_getNow = () => performance.now()
|
_getNow = () => performance.now()
|
||||||
}
|
}
|
||||||
|
// #3485: Firefox <= 53 has incorrect Event.timeStamp implementation
|
||||||
|
// and does not fire microtasks in between event propagation, so safe to exclude.
|
||||||
|
const ffMatch = navigator.userAgent.match(/firefox\/(\d+)/i)
|
||||||
|
skipTimestampCheck = !!(ffMatch && Number(ffMatch[1]) <= 53)
|
||||||
|
}
|
||||||
|
|
||||||
// To avoid the overhead of repeatedly calling performance.now(), we cache
|
// To avoid the overhead of repeatedly calling performance.now(), we cache
|
||||||
// and use the same timestamp for all event listeners attached in the same tick.
|
// and use the same timestamp for all event listeners attached in the same tick.
|
||||||
@ -111,7 +116,8 @@ function createInvoker(
|
|||||||
// and the handler would only fire if the event passed to it was fired
|
// and the handler would only fire if the event passed to it was fired
|
||||||
// AFTER it was attached.
|
// AFTER it was attached.
|
||||||
const timeStamp = e.timeStamp || _getNow()
|
const timeStamp = e.timeStamp || _getNow()
|
||||||
if (timeStamp >= invoker.attached - 1) {
|
|
||||||
|
if (skipTimestampCheck || timeStamp >= invoker.attached - 1) {
|
||||||
callWithAsyncErrorHandling(
|
callWithAsyncErrorHandling(
|
||||||
patchStopImmediatePropagation(e, invoker.value),
|
patchStopImmediatePropagation(e, invoker.value),
|
||||||
instance,
|
instance,
|
||||||
|
Loading…
Reference in New Issue
Block a user