зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1726364 - Scroll events stop working after synchronous XHR request while scrolling an iframe, r=edgar
I tried to keep the changes minimal in this case. We may need some more changes to Document::UnsuppressEventHandlingAndFireEvents to make it work well with Fission (but that Fission work is totally unrelated to this fix). Differential Revision: https://phabricator.services.mozilla.com/D123389
This commit is contained in:
Родитель
d5cefe3b4a
Коммит
50a110f8af
|
@ -12418,6 +12418,35 @@ void Document::UnsuppressEventHandlingAndFireEvents(bool aFireEvents) {
|
|||
nsTArray<nsCOMPtr<Document>> documents;
|
||||
GetAndUnsuppressSubDocuments(*this, documents);
|
||||
|
||||
for (nsCOMPtr<Document>& doc : documents) {
|
||||
if (!doc->EventHandlingSuppressed()) {
|
||||
WindowGlobalChild* wgc = doc->GetWindowGlobalChild();
|
||||
if (wgc) {
|
||||
wgc->UnblockBFCacheFor(BFCacheStatus::EVENT_HANDLING_SUPPRESSED);
|
||||
}
|
||||
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
nsTArray<RefPtr<net::ChannelEventQueue>> queues =
|
||||
std::move(doc->mSuspendedQueues);
|
||||
for (net::ChannelEventQueue* queue : queues) {
|
||||
queue->Resume();
|
||||
}
|
||||
|
||||
// If there have been any events driven by the refresh driver which were
|
||||
// delayed due to events being suppressed in this document, make sure
|
||||
// there is a refresh scheduled soon so the events will run.
|
||||
if (doc->mHasDelayedRefreshEvent) {
|
||||
doc->mHasDelayedRefreshEvent = false;
|
||||
|
||||
if (doc->mPresShell) {
|
||||
nsRefreshDriver* rd =
|
||||
doc->mPresShell->GetPresContext()->RefreshDriver();
|
||||
rd->RunDelayedEventsSoon();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (aFireEvents) {
|
||||
MOZ_RELEASE_ASSERT(NS_IsMainThread());
|
||||
nsCOMPtr<nsIRunnable> ded =
|
||||
|
@ -12426,32 +12455,6 @@ void Document::UnsuppressEventHandlingAndFireEvents(bool aFireEvents) {
|
|||
} else {
|
||||
FireOrClearDelayedEvents(documents, false);
|
||||
}
|
||||
|
||||
if (!EventHandlingSuppressed()) {
|
||||
WindowGlobalChild* wgc = GetWindowGlobalChild();
|
||||
if (wgc) {
|
||||
wgc->UnblockBFCacheFor(BFCacheStatus::EVENT_HANDLING_SUPPRESSED);
|
||||
}
|
||||
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
nsTArray<RefPtr<net::ChannelEventQueue>> queues =
|
||||
std::move(mSuspendedQueues);
|
||||
for (net::ChannelEventQueue* queue : queues) {
|
||||
queue->Resume();
|
||||
}
|
||||
|
||||
// If there have been any events driven by the refresh driver which were
|
||||
// delayed due to events being suppressed in this document, make sure there
|
||||
// is a refresh scheduled soon so the events will run.
|
||||
if (mHasDelayedRefreshEvent) {
|
||||
mHasDelayedRefreshEvent = false;
|
||||
|
||||
if (mPresShell) {
|
||||
nsRefreshDriver* rd = mPresShell->GetPresContext()->RefreshDriver();
|
||||
rd->RunDelayedEventsSoon();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Document::AreClipboardCommandsUnconditionallyEnabled() const {
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<body><iframe srcdoc="
|
||||
<html>
|
||||
<head>
|
||||
<script>
|
||||
onload = function() {
|
||||
// Ensure the layout is up-to-date and painted.
|
||||
requestAnimationFrame(function() {
|
||||
setTimeout(run);
|
||||
})
|
||||
}
|
||||
|
||||
function run() {
|
||||
parent.opener.postMessage('doscroll', '*');
|
||||
window.onscroll = function() {
|
||||
parent.opener.postMessage('didscroll', '*');
|
||||
}
|
||||
let xhr = new XMLHttpRequest();
|
||||
xhr.open('GET', 'slow.sjs', false);
|
||||
xhr.send();
|
||||
parent.opener.postMessage('xhr_done', '*');
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body style='height: 3000px; border: 1px solid black;'>
|
||||
</body>
|
||||
</html>
|
||||
"></iframe></body>
|
||||
</html>
|
|
@ -771,6 +771,9 @@ skip-if = debug == false
|
|||
[test_shared_compartment2.html]
|
||||
[test_structuredclone_backref.html]
|
||||
[test_style_cssText.html]
|
||||
[test_suppressed_events_and_scrolling.html]
|
||||
support-files =
|
||||
file_suppressed_events_and_scrolling.html
|
||||
[test_suppressed_microtasks.html]
|
||||
skip-if = debug || asan || verify || toolkit == 'android' # The test needs to run reasonably fast.
|
||||
[test_text_wholeText.html]
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test event suppression and scrolling</title>
|
||||
<script src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" href="/tests/SimpleTest/test.css"/>
|
||||
<script>
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
function run() {
|
||||
let testWin = window.open("file_suppressed_events_and_scrolling.html");
|
||||
// The order of xhrDone and didScroll is random.
|
||||
let xhrDone = false;
|
||||
let didScroll = false;
|
||||
window.onmessage = function(e) {
|
||||
let iframeWindow = testWin.document.body.firstChild.contentWindow;
|
||||
info(e.data);
|
||||
if (e.data == "doscroll") {
|
||||
iframeWindow.scrollTo(0, 1500);
|
||||
} else if (e.data == "xhr_done") {
|
||||
xhrDone = true;
|
||||
if (didScroll) {
|
||||
iframeWindow.scrollTo(0, 3000);
|
||||
}
|
||||
} else if (e.data == "didscroll") {
|
||||
if (didScroll && xhrDone) {
|
||||
// We got the second scroll event.
|
||||
ok(true, "Should have got two scroll events");
|
||||
testWin.close();
|
||||
SimpleTest.finish();
|
||||
}
|
||||
didScroll = true;
|
||||
if (xhrDone) {
|
||||
iframeWindow.scrollTo(0, 3000);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body onload="run()">
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test"></pre>
|
||||
</body>
|
||||
</html>
|
Загрузка…
Ссылка в новой задаче