fix(va-host): bound the early replay even when the frame is not postable
The interval tested its deadline only after the contentWindow guard, so a frame
that never became postable (detached, mid-navigation, or a load that never
fires) returned on every tick and the timer ran for the life of the page.
The capture check and the deadline now both run before the guard, so the replay
always stops. Capture keeps precedence, so a message caught on the last tick is
still reported as a capture, and it only counts once something has been posted
in this replay - a buffer left by the previous load of the same frame cannot be
read as one that belongs to this mount.
attempts keeps counting posts rather than ticks, because that is what the lines
quote ("after N post(s)"); a tick skipped for want of a frame sent nothing. The
zero case is now stated separately, since "0 post(s)" otherwise reads as a
broken probe rather than a frame that never appeared.
This commit is contained in:
1 parent
7d4155dc6c
commit
f6d5a0495e
1 file changed
+19
-6
+19
-6
@@ -191,21 +191,34 @@
|
||||
log('early replay: posting every ' + interval + 'ms until the app captures it')
|
||||
|
||||
earlyTimer = setInterval(function () {
|
||||
if (!FRAME.contentWindow) return
|
||||
attempts++
|
||||
postToFrame(payload)
|
||||
|
||||
if (frameBuffered()) {
|
||||
// The capture and the deadline are both tested before the frame guard: a
|
||||
// detached or mid-navigation frame leaves contentWindow null, and a bare
|
||||
// return there would skip them and keep this timer alive for the life of
|
||||
// the page. A capture only counts once something has been posted in this
|
||||
// replay, so a buffer left by the previous load of the same frame cannot
|
||||
// be read as one that belongs to this mount.
|
||||
if (attempts > 0 && frameBuffered()) {
|
||||
log('early replay: the app captured the message after ' + attempts + ' post(s)')
|
||||
stopEarlyReplay()
|
||||
} else if (Date.now() > deadline) {
|
||||
return
|
||||
}
|
||||
|
||||
if (Date.now() > deadline) {
|
||||
log(
|
||||
captureProbeVisible()
|
||||
? 'early replay: gave up after ' + attempts + ' post(s), no capture seen'
|
||||
: 'early replay: gave up after ' + attempts + ' post(s) - the app does not expose window.__vaLastMessage, so this replay cannot tell whether it captured'
|
||||
)
|
||||
if (attempts === 0) {
|
||||
log('early replay: the frame was never postable, so nothing was sent')
|
||||
}
|
||||
stopEarlyReplay()
|
||||
return
|
||||
}
|
||||
|
||||
if (!FRAME.contentWindow) return
|
||||
attempts++
|
||||
postToFrame(payload)
|
||||
}, interval)
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user