diff --git a/dom/base/Document.cpp b/dom/base/Document.cpp index f8871825c7f2..b24b4c8b5392 100644 --- a/dom/base/Document.cpp +++ b/dom/base/Document.cpp @@ -7250,8 +7250,7 @@ void Document::SetScriptGlobalObject( // still test false at this point and no state change will happen) or we're // doing the initial document load and don't want to fire the event for this // change. - dom::VisibilityState oldState = mVisibilityState; - mVisibilityState = ComputeVisibilityState(); + // // When the visibility is changed, notify it to observers. // Some observers need the notification, for example HTMLMediaElement uses // it to update internal media resource allocation. @@ -7264,9 +7263,7 @@ void Document::SetScriptGlobalObject( // not yet necessary. But soon after Document::SetScriptGlobalObject() // call, the document becomes not hidden. At the time, MediaDecoder needs // to know it and needs to start updating decoding. - if (oldState != mVisibilityState) { - EnumerateActivityObservers(NotifyActivityChanged); - } + UpdateVisibilityState(DispatchVisibilityChange::No); // The global in the template contents owner document should be the same. if (mTemplateContentsOwner && mTemplateContentsOwner != this) { @@ -14879,13 +14876,15 @@ void Document::UnlockPointer(Document* aDoc) { asyncDispatcher->RunDOMEventWhenSafe(); } -void Document::UpdateVisibilityState() { +void Document::UpdateVisibilityState(DispatchVisibilityChange aDispatchEvent) { dom::VisibilityState oldState = mVisibilityState; mVisibilityState = ComputeVisibilityState(); if (oldState != mVisibilityState) { - nsContentUtils::DispatchTrustedEvent(this, ToSupports(this), - u"visibilitychange"_ns, - CanBubble::eYes, Cancelable::eNo); + if (aDispatchEvent == DispatchVisibilityChange::Yes) { + nsContentUtils::DispatchTrustedEvent(this, ToSupports(this), + u"visibilitychange"_ns, + CanBubble::eYes, Cancelable::eNo); + } EnumerateActivityObservers(NotifyActivityChanged); } @@ -14911,9 +14910,9 @@ VisibilityState Document::ComputeVisibilityState() const { } void Document::PostVisibilityUpdateEvent() { - nsCOMPtr event = - NewRunnableMethod("Document::UpdateVisibilityState", this, - &Document::UpdateVisibilityState); + nsCOMPtr event = NewRunnableMethod( + "Document::UpdateVisibilityState", this, &Document::UpdateVisibilityState, + DispatchVisibilityChange::Yes); Dispatch(TaskCategory::Other, event.forget()); } diff --git a/dom/base/Document.h b/dom/base/Document.h index cc8b83ad4a43..875444e1ef3a 100644 --- a/dom/base/Document.h +++ b/dom/base/Document.h @@ -3205,7 +3205,11 @@ class Document : public nsINode, // This method may fire a DOM event; if it does so it will happen // synchronously. - void UpdateVisibilityState(); + // + // Whether the event fires is controlled by the argument. + enum class DispatchVisibilityChange { No, Yes }; + void UpdateVisibilityState( + DispatchVisibilityChange = DispatchVisibilityChange::Yes); // Posts an event to call UpdateVisibilityState. void PostVisibilityUpdateEvent(); diff --git a/toolkit/content/tests/browser/browser.ini b/toolkit/content/tests/browser/browser.ini index f76f3ce7a919..927178c3a972 100644 --- a/toolkit/content/tests/browser/browser.ini +++ b/toolkit/content/tests/browser/browser.ini @@ -47,6 +47,10 @@ skip-if = (os == "win" && processor == "aarch64") || (os == "mac") || (os == "li [browser_delay_autoplay_webAudio.js] tags = audiochannel skip-if = (os == "win" && processor == "aarch64") # aarch64 due to 1536573 +[browser_bug1572798.js] +tags = audiochannel +skip-if = (os == "win" && processor == "aarch64") # aarch64 due to 1536573 +support-files = file_document_open_audio.html [browser_bug1170531.js] skip-if = os == "linux" && !debug && !ccov # Bug 1647973 diff --git a/toolkit/content/tests/browser/browser_bug1572798.js b/toolkit/content/tests/browser/browser_bug1572798.js new file mode 100644 index 000000000000..8b5dffd432de --- /dev/null +++ b/toolkit/content/tests/browser/browser_bug1572798.js @@ -0,0 +1,29 @@ +add_task(async function test_bug_1572798() { + let tab = BrowserTestUtils.addTab(window.gBrowser, "about:blank"); + BrowserTestUtils.loadURI( + tab.linkedBrowser, + "https://example.com/browser/toolkit/content/tests/browser/file_document_open_audio.html" + ); + await BrowserTestUtils.browserLoaded(tab.linkedBrowser); + let windowLoaded = BrowserTestUtils.waitForNewWindow(); + info("- clicking button to spawn a new window -"); + await ContentTask.spawn(tab.linkedBrowser, null, function() { + content.document.querySelector("button").click(); + }); + info("- waiting for the new window -"); + let newWin = await windowLoaded; + info("- checking that the new window plays the audio -"); + let documentOpenedBrowser = newWin.gBrowser.selectedBrowser; + await ContentTask.spawn(documentOpenedBrowser, null, async function() { + try { + await content.document.querySelector("audio").play(); + ok(true, "Could play the audio"); + } catch (e) { + ok(false, "Rejected audio promise" + e); + } + }); + + info("- Cleaning up -"); + await BrowserTestUtils.closeWindow(newWin); + await BrowserTestUtils.removeTab(tab); +}); diff --git a/toolkit/content/tests/browser/file_document_open_audio.html b/toolkit/content/tests/browser/file_document_open_audio.html new file mode 100644 index 000000000000..1234299c673d --- /dev/null +++ b/toolkit/content/tests/browser/file_document_open_audio.html @@ -0,0 +1,11 @@ + +Test for bug 1572798 + +