mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-10 03:45:46 +00:00
merge autoland to mozilla-central.r=merge a=merge
MozReview-Commit-ID: JRQXsnsRpCS
This commit is contained in:
commit
1a3935a05f
@ -2276,6 +2276,11 @@ CustomizeMode.prototype = {
|
||||
return aReferenceNode;
|
||||
},
|
||||
|
||||
onPaletteContextMenuShowing(event) {
|
||||
let isFlexibleSpace = event.target.triggerNode.id.includes("wrapper-customizableui-special-spring");
|
||||
event.target.querySelector(".customize-context-addToPanel").disabled = isFlexibleSpace;
|
||||
},
|
||||
|
||||
onPanelContextMenuShowing(event) {
|
||||
let inPermanentArea = !!event.target.triggerNode.closest("#widget-overflow-fixed-list");
|
||||
let doc = event.target.ownerDocument;
|
||||
|
@ -462,7 +462,8 @@
|
||||
</popupnotification>
|
||||
</panel>
|
||||
|
||||
<menupopup id="customizationPaletteItemContextMenu">
|
||||
<menupopup id="customizationPaletteItemContextMenu"
|
||||
onpopupshowing="gCustomizeMode.onPaletteContextMenuShowing(event)">
|
||||
<menuitem oncommand="gCustomizeMode.addToToolbar(document.popupNode)"
|
||||
class="customize-context-addToToolbar"
|
||||
accesskey="&customizeMenu.addToToolbar.accesskey;"
|
||||
|
@ -8324,16 +8324,11 @@ nsDocShell::CanSavePresentation(uint32_t aLoadType,
|
||||
return false;
|
||||
}
|
||||
|
||||
// Don't cache the content viewer if we're in a subframe and the subframe
|
||||
// pref is disabled.
|
||||
bool cacheFrames =
|
||||
Preferences::GetBool("browser.sessionhistory.cache_subframes", false);
|
||||
if (!cacheFrames) {
|
||||
nsCOMPtr<nsIDocShellTreeItem> root;
|
||||
GetSameTypeParent(getter_AddRefs(root));
|
||||
if (root && root != this) {
|
||||
return false; // this is a subframe load
|
||||
}
|
||||
// Don't cache the content viewer if we're in a subframe.
|
||||
nsCOMPtr<nsIDocShellTreeItem> root;
|
||||
GetSameTypeParent(getter_AddRefs(root));
|
||||
if (root && root != this) {
|
||||
return false; // this is a subframe load
|
||||
}
|
||||
|
||||
// If the document does not want its presentation cached, then don't.
|
||||
|
@ -120,6 +120,20 @@ interface nsISHistoryInternal: nsISupports
|
||||
[noscript, notxpcom] void RemoveDynEntries(in long aIndex,
|
||||
in nsISHContainer aContainer);
|
||||
|
||||
/**
|
||||
* Similar to RemoveDynEntries, but instead of specifying an index, use the
|
||||
* given BFCacheEntry to find the index and remove dynamic entries from the
|
||||
* index.
|
||||
*
|
||||
* The method takes no effect if the bfcache entry is not or no longer hold
|
||||
* by the SHistory instance.
|
||||
*
|
||||
* @param aEntry
|
||||
* The bfcache entry to look up for index to remove dynamic entries
|
||||
* from.
|
||||
*/
|
||||
[noscript, notxpcom] void RemoveDynEntriesForBFCacheEntry(in nsIBFCacheEntry aEntry);
|
||||
|
||||
/**
|
||||
* Removes entries from the history if their docshellID is in
|
||||
* aIDs array.
|
||||
|
@ -50,7 +50,18 @@ nsSHEntryShared::nsSHEntryShared()
|
||||
|
||||
nsSHEntryShared::~nsSHEntryShared()
|
||||
{
|
||||
// The destruction can be caused by either the entry is removed from session
|
||||
// history and no one holds the reference, or the whole session history is on
|
||||
// destruction. We want to ensure that we invoke
|
||||
// shistory->RemoveFromExpirationTracker for the former case.
|
||||
RemoveFromExpirationTracker();
|
||||
|
||||
// Calling RemoveDynEntriesForBFCacheEntry on destruction is unnecessary since
|
||||
// there couldn't be any SHEntry holding this shared entry, and we noticed
|
||||
// that calling RemoveDynEntriesForBFCacheEntry in the middle of
|
||||
// nsSHistory::Release can cause a crash, so set mSHistory to null explicitly
|
||||
// before RemoveFromBFCacheSync.
|
||||
mSHistory = nullptr;
|
||||
if (mContentViewer) {
|
||||
RemoveFromBFCacheSync();
|
||||
}
|
||||
@ -168,56 +179,59 @@ nsSHEntryShared::RemoveFromBFCacheSync()
|
||||
{
|
||||
MOZ_ASSERT(mContentViewer && mDocument, "we're not in the bfcache!");
|
||||
|
||||
// The call to DropPresentationState could drop the last reference, so hold
|
||||
// |this| until RemoveDynEntriesForBFCacheEntry finishes.
|
||||
RefPtr<nsSHEntryShared> kungFuDeathGrip = this;
|
||||
|
||||
// DropPresentationState would clear mContentViewer.
|
||||
nsCOMPtr<nsIContentViewer> viewer = mContentViewer;
|
||||
DropPresentationState();
|
||||
|
||||
// Warning! The call to DropPresentationState could have dropped the last
|
||||
// reference to this object, so don't access members beyond here.
|
||||
|
||||
if (viewer) {
|
||||
viewer->Destroy();
|
||||
}
|
||||
|
||||
// Now that we've dropped the viewer, we have to clear associated dynamic
|
||||
// subframe entries.
|
||||
nsCOMPtr<nsISHistoryInternal> shistory = do_QueryReferent(mSHistory);
|
||||
if (shistory) {
|
||||
shistory->RemoveDynEntriesForBFCacheEntry(this);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
class DestroyViewerEvent : public mozilla::Runnable
|
||||
{
|
||||
public:
|
||||
DestroyViewerEvent(nsIContentViewer* aViewer, nsIDocument* aDocument)
|
||||
: mozilla::Runnable("DestroyViewerEvent")
|
||||
, mViewer(aViewer)
|
||||
, mDocument(aDocument)
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHOD Run() override
|
||||
{
|
||||
if (mViewer) {
|
||||
mViewer->Destroy();
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIContentViewer> mViewer;
|
||||
nsCOMPtr<nsIDocument> mDocument;
|
||||
};
|
||||
|
||||
nsresult
|
||||
nsSHEntryShared::RemoveFromBFCacheAsync()
|
||||
{
|
||||
MOZ_ASSERT(mContentViewer && mDocument, "we're not in the bfcache!");
|
||||
|
||||
// Release the reference to the contentviewer asynchronously so that the
|
||||
// document doesn't get nuked mid-mutation.
|
||||
|
||||
// Check it again to play safe in release builds.
|
||||
if (!mDocument) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
nsCOMPtr<nsIRunnable> evt = new DestroyViewerEvent(mContentViewer, mDocument);
|
||||
nsresult rv = mDocument->Dispatch(mozilla::TaskCategory::Other, evt.forget());
|
||||
|
||||
// DropPresentationState would clear mContentViewer & mDocument. Capture and
|
||||
// release the references asynchronously so that the document doesn't get
|
||||
// nuked mid-mutation.
|
||||
nsCOMPtr<nsIContentViewer> viewer = mContentViewer;
|
||||
nsCOMPtr<nsIDocument> document = mDocument;
|
||||
RefPtr<nsSHEntryShared> self = this;
|
||||
nsresult rv = mDocument->Dispatch(mozilla::TaskCategory::Other,
|
||||
NS_NewRunnableFunction("nsSHEntryShared::RemoveFromBFCacheAsync",
|
||||
[self, viewer, document]() {
|
||||
if (viewer) {
|
||||
viewer->Destroy();
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISHistoryInternal> shistory = do_QueryReferent(self->mSHistory);
|
||||
if (shistory) {
|
||||
shistory->RemoveDynEntriesForBFCacheEntry(self);
|
||||
}
|
||||
}));
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("failed to dispatch DestroyViewerEvent");
|
||||
NS_WARNING("Failed to dispatch RemoveFromBFCacheAsync runnable.");
|
||||
} else {
|
||||
// Drop presentation. Only do this if we succeeded in posting the event
|
||||
// since otherwise the document could be torn down mid-mutation, causing
|
||||
@ -225,9 +239,6 @@ nsSHEntryShared::RemoveFromBFCacheAsync()
|
||||
DropPresentationState();
|
||||
}
|
||||
|
||||
// Careful! The call to DropPresentationState could have dropped the last
|
||||
// reference to this nsSHEntryShared, so don't access members beyond here.
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -213,7 +213,7 @@ nsSHistory::EvictContentViewerForTransaction(nsISHTransaction* aTrans)
|
||||
LOG_SHENTRY_SPEC(("Evicting content viewer 0x%p for "
|
||||
"owning SHEntry 0x%p at %s.",
|
||||
viewer.get(), ownerEntry.get(), _spec),
|
||||
ownerEntry);
|
||||
ownerEntry);
|
||||
|
||||
// Drop the presentation state before destroying the viewer, so that
|
||||
// document teardown is able to correctly persist the state.
|
||||
@ -588,7 +588,7 @@ nsSHistory::GetEntryAtIndex(int32_t aIndex, bool aModifyIndex,
|
||||
}
|
||||
|
||||
/* Get the transaction at a given index */
|
||||
NS_IMETHODIMP
|
||||
nsresult
|
||||
nsSHistory::GetTransactionAtIndex(int32_t aIndex, nsISHTransaction** aResult)
|
||||
{
|
||||
nsresult rv;
|
||||
@ -1290,8 +1290,13 @@ nsSHistory::GloballyEvictContentViewers()
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsSHistory::EvictExpiredContentViewerForEntry(nsIBFCacheEntry* aEntry)
|
||||
nsSHistory::FindTransactionForBFCache(nsIBFCacheEntry* aEntry,
|
||||
nsISHTransaction** aResult,
|
||||
int32_t* aResultIndex)
|
||||
{
|
||||
*aResult = nullptr;
|
||||
*aResultIndex = -1;
|
||||
|
||||
int32_t startIndex = std::max(0, mIndex - nsISHistory::VIEWER_WINDOW);
|
||||
int32_t endIndex = std::min(mLength - 1, mIndex + nsISHistory::VIEWER_WINDOW);
|
||||
nsCOMPtr<nsISHTransaction> trans;
|
||||
@ -1311,15 +1316,29 @@ nsSHistory::EvictExpiredContentViewerForEntry(nsIBFCacheEntry* aEntry)
|
||||
temp->GetNext(getter_AddRefs(trans));
|
||||
}
|
||||
if (i > endIndex) {
|
||||
return NS_OK;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (i == mIndex) {
|
||||
trans.forget(aResult);
|
||||
*aResultIndex = i;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsSHistory::EvictExpiredContentViewerForEntry(nsIBFCacheEntry* aEntry)
|
||||
{
|
||||
int32_t index;
|
||||
nsCOMPtr<nsISHTransaction> trans;
|
||||
FindTransactionForBFCache(aEntry, getter_AddRefs(trans), &index);
|
||||
|
||||
if (index == mIndex) {
|
||||
NS_WARNING("How did the current SHEntry expire?");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
EvictContentViewerForTransaction(trans);
|
||||
if (trans) {
|
||||
EvictContentViewerForTransaction(trans);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -1586,6 +1605,20 @@ nsSHistory::RemoveDynEntries(int32_t aIndex, nsISHContainer* aContainer)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsSHistory::RemoveDynEntriesForBFCacheEntry(nsIBFCacheEntry* aEntry)
|
||||
{
|
||||
int32_t index;
|
||||
nsCOMPtr<nsISHTransaction> trans;
|
||||
FindTransactionForBFCache(aEntry, getter_AddRefs(trans), &index);
|
||||
if (trans) {
|
||||
nsCOMPtr<nsISHEntry> entry;
|
||||
trans->GetSHEntry(getter_AddRefs(entry));
|
||||
nsCOMPtr<nsISHContainer> container(do_QueryInterface(entry));
|
||||
RemoveDynEntries(index, container);
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHistory::UpdateIndex()
|
||||
{
|
||||
@ -1703,7 +1736,7 @@ nsSHistory::LoadNextPossibleEntry(int32_t aNewIndex, long aLoadType,
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsresult
|
||||
nsSHistory::LoadEntry(int32_t aIndex, long aLoadType, uint32_t aHistCmd)
|
||||
{
|
||||
if (!mRootDocShell) {
|
||||
|
@ -83,20 +83,25 @@ private:
|
||||
friend class nsSHEnumerator;
|
||||
friend class nsSHistoryObserver;
|
||||
|
||||
// Could become part of nsIWebNavigation
|
||||
NS_IMETHOD GetTransactionAtIndex(int32_t aIndex, nsISHTransaction** aResult);
|
||||
nsresult GetTransactionAtIndex(int32_t aIndex, nsISHTransaction** aResult);
|
||||
nsresult LoadDifferingEntries(nsISHEntry* aPrevEntry, nsISHEntry* aNextEntry,
|
||||
nsIDocShell* aRootDocShell, long aLoadType,
|
||||
bool& aDifferenceFound);
|
||||
nsresult InitiateLoad(nsISHEntry* aFrameEntry, nsIDocShell* aFrameDS,
|
||||
long aLoadType);
|
||||
|
||||
NS_IMETHOD LoadEntry(int32_t aIndex, long aLoadType, uint32_t aHistCmd);
|
||||
nsresult LoadEntry(int32_t aIndex, long aLoadType, uint32_t aHistCmd);
|
||||
|
||||
#ifdef DEBUG
|
||||
nsresult PrintHistory();
|
||||
#endif
|
||||
|
||||
// Find the transaction for a given bfcache entry. It only looks up between
|
||||
// the range where alive viewers may exist (i.e nsISHistory::VIEWER_WINDOW).
|
||||
nsresult FindTransactionForBFCache(nsIBFCacheEntry* aEntry,
|
||||
nsISHTransaction** aResult,
|
||||
int32_t* aResultIndex);
|
||||
|
||||
// Evict content viewers in this window which don't lie in the "safe" range
|
||||
// around aIndex.
|
||||
void EvictOutOfRangeWindowContentViewers(int32_t aIndex);
|
||||
|
@ -1,6 +1,14 @@
|
||||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<window title="Mozilla Bug 608669 - Blank page"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
onload="notifyOpener();">
|
||||
<description flex="1" value="This window is intentionally left blank"/>
|
||||
<script type="application/javascript">
|
||||
function notifyOpener() {
|
||||
if (opener) {
|
||||
opener.postMessage("load", "*");
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</window>
|
||||
|
@ -18,27 +18,6 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=608669
|
||||
<!-- test code goes here -->
|
||||
<script type="application/javascript"><![CDATA[
|
||||
|
||||
var gOrigMaxTotalViewers = undefined;
|
||||
function setCachePref(enabled) {
|
||||
var prefBranch = Components.classes["@mozilla.org/preferences-service;1"]
|
||||
.getService(Components.interfaces.nsIPrefBranch);
|
||||
if (enabled) {
|
||||
is(typeof gOrigMaxTotalViewers, "undefined", "don't double-enable bfcache");
|
||||
prefBranch.setBoolPref("browser.sessionhistory.cache_subframes", true);
|
||||
gOrigMaxTotalViewers = prefBranch.getIntPref("browser.sessionhistory.max_total_viewers");
|
||||
prefBranch.setIntPref("browser.sessionhistory.max_total_viewers", 10);
|
||||
}
|
||||
else {
|
||||
is(typeof gOrigMaxTotalViewers, "number", "don't double-disable bfcache");
|
||||
prefBranch.setIntPref("browser.sessionhistory.max_total_viewers", gOrigMaxTotalViewers);
|
||||
gOrigMaxTotalViewers = undefined;
|
||||
try {
|
||||
prefBranch.clearUserPref("browser.sessionhistory.cache_subframes");
|
||||
} catch (e) { /* Pref didn't exist, meh */ }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** Test for Bug 608669 **/
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
@ -51,10 +30,6 @@ function nextTest() {
|
||||
}
|
||||
|
||||
function* doTest() {
|
||||
var container = document.getElementById('container');
|
||||
|
||||
setCachePref(true);
|
||||
|
||||
var notificationCount = 0;
|
||||
var observer = {
|
||||
observe: function(aSubject, aTopic, aData) {
|
||||
@ -73,44 +48,31 @@ function* doTest() {
|
||||
|
||||
is(notificationCount, 0, "initial count");
|
||||
|
||||
// create a new iframe
|
||||
var iframe = document.createElement("iframe");
|
||||
container.appendChild(iframe);
|
||||
iframe.contentWindow.x = "y";
|
||||
is(notificationCount, 1, "after created iframe");
|
||||
|
||||
// Try loading in an iframe
|
||||
iframe.setAttribute("src", "bug608669.xul");
|
||||
iframe.onload = nextTest;
|
||||
// create a new window
|
||||
var testWin = window.open("", "bug 608669", "chrome,width=600,height=600");
|
||||
testWin.x = "y";
|
||||
is(notificationCount, 1, "after created window");
|
||||
|
||||
// Try loading in the window
|
||||
testWin.location = "bug608669.xul";
|
||||
window.onmessage = nextTest;
|
||||
yield undefined;
|
||||
is(notificationCount, 1, "after first load");
|
||||
is(iframe.contentWindow.x, "y", "reused window");
|
||||
is(testWin.x, "y", "reused window");
|
||||
|
||||
// Try loading again in an iframe
|
||||
iframe.setAttribute("src", "bug608669.xul?x");
|
||||
iframe.onload = nextTest;
|
||||
// Try loading again in the window
|
||||
testWin.location = "bug608669.xul?x";
|
||||
window.onmessage = nextTest;
|
||||
yield undefined;
|
||||
is(notificationCount, 2, "after second load");
|
||||
is("x" in iframe.contentWindow, false, "didn't reuse window");
|
||||
is("x" in testWin, false, "didn't reuse window");
|
||||
|
||||
// Open a new window using window.open
|
||||
popup = window.open("bug608669.xul", "bug 608669",
|
||||
"chrome,width=600,height=600");
|
||||
popup.onload = nextTest;
|
||||
yield undefined;
|
||||
is(notificationCount, 3, "after window.open load");
|
||||
popup.close();
|
||||
testWin.close();
|
||||
|
||||
setCachePref(false);
|
||||
os.removeObserver(observer, "chrome-document-global-created");
|
||||
os.removeObserver(observer, "content-document-global-created");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
|
||||
|
||||
]]></script>
|
||||
<vbox id="container" flex="1">
|
||||
<description>Below will an iframe be added</description>
|
||||
</vbox>
|
||||
</window>
|
||||
|
33
docshell/test/navigation/file_bug1364364-1.html
Normal file
33
docshell/test/navigation/file_bug1364364-1.html
Normal file
@ -0,0 +1,33 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>title</title>
|
||||
</head>
|
||||
<body onload="loadFramesAndNavigate();">
|
||||
<p id="content"></p>
|
||||
<div id="frameContainer">
|
||||
</div>
|
||||
<script type="application/javascript">
|
||||
function waitForLoad(frame) {
|
||||
return new Promise(r => frame.onload = r);
|
||||
}
|
||||
|
||||
async function loadFramesAndNavigate() {
|
||||
let dynamicFrame = document.createElement("iframe");
|
||||
dynamicFrame.src = "data:text/html,iframe1";
|
||||
document.querySelector("#frameContainer").appendChild(dynamicFrame);
|
||||
await waitForLoad(dynamicFrame);
|
||||
dynamicFrame.src = "data:text/html,iframe2";
|
||||
await waitForLoad(dynamicFrame);
|
||||
dynamicFrame.src = "data:text/html,iframe3";
|
||||
await waitForLoad(dynamicFrame);
|
||||
dynamicFrame.src = "data:text/html,iframe4";
|
||||
await waitForLoad(dynamicFrame);
|
||||
dynamicFrame.src = "data:text/html,iframe5";
|
||||
await waitForLoad(dynamicFrame);
|
||||
location.href = "file_bug1364364-2.html";
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
14
docshell/test/navigation/file_bug1364364-2.html
Normal file
14
docshell/test/navigation/file_bug1364364-2.html
Normal file
@ -0,0 +1,14 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>title</title>
|
||||
</head>
|
||||
<body onload="notifyOpener();">
|
||||
<script type="application/javascript">
|
||||
function notifyOpener() {
|
||||
opener.postMessage("navigation-done", "*");
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -49,6 +49,8 @@ support-files =
|
||||
file_contentpolicy_block_window.html
|
||||
file_bug1326251.html
|
||||
file_bug1326251_evict_cache.html
|
||||
file_bug1364364-1.html
|
||||
file_bug1364364-2.html
|
||||
file_bug1375833.html
|
||||
file_bug1375833-frame1.html
|
||||
file_bug1375833-frame2.html
|
||||
@ -63,6 +65,7 @@ skip-if = toolkit == "android" || toolkit == "windows" # disabled on Windows bec
|
||||
[test_bug430624.html]
|
||||
[test_bug430723.html]
|
||||
skip-if = (toolkit == 'android') || (!debug && (os == 'mac' || os == 'win')) # Bug 874423
|
||||
[test_bug1364364.html]
|
||||
[test_bug1375833.html]
|
||||
[test_child.html]
|
||||
[test_grandchild.html]
|
||||
|
56
docshell/test/navigation/test_bug1364364.html
Normal file
56
docshell/test/navigation/test_bug1364364.html
Normal file
@ -0,0 +1,56 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=1364364
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test for Bug 1364364</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Bug 1364364 **/
|
||||
let testWin, testDoc;
|
||||
async function test() {
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
testWin = window.open("file_bug1364364-1.html");
|
||||
await waitForLoad(testWin);
|
||||
testDoc = testWin.document;
|
||||
|
||||
// file_bug1364364-1.html will load a few dynamic iframes and then navigate
|
||||
// top browsing context to file_bug1364364-2.html, which will postMessage
|
||||
// back.
|
||||
}
|
||||
|
||||
function waitForLoad(win) {
|
||||
return new Promise(r => win.addEventListener("load", r, { once: true}));
|
||||
}
|
||||
|
||||
window.addEventListener("message", async function(msg) {
|
||||
if (msg.data == "navigation-done") {
|
||||
is(testWin.history.length, 6, "check history.length");
|
||||
|
||||
// Modify a document in bfcache should cause the cache being dropped tho
|
||||
// RemoveFromBFCacheAsync.
|
||||
testDoc.querySelector("#content").textContent = "modified";
|
||||
await new Promise(r => setTimeout(r, 0));
|
||||
|
||||
is(testWin.history.length, 2, "check history.length after bfcache dropped");
|
||||
testWin.close();
|
||||
SimpleTest.finish();
|
||||
}
|
||||
});
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body onload="test();">
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1364364">Mozilla Bug 1364364</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -1898,6 +1898,19 @@ Element::UnbindFromTree(bool aDeep, bool aNullParent)
|
||||
DeleteProperty(nsGkAtoms::animationsProperty);
|
||||
}
|
||||
|
||||
// Computed style data isn't useful for detached nodes, and we'll need to
|
||||
// recompute it anyway if we ever insert the nodes back into a document.
|
||||
if (IsStyledByServo()) {
|
||||
if (document) {
|
||||
ClearServoData(document);
|
||||
} else {
|
||||
MOZ_ASSERT(!HasServoData());
|
||||
MOZ_ASSERT(!HasAnyOfFlags(kAllServoDescendantBits | NODE_NEEDS_FRAME));
|
||||
}
|
||||
} else {
|
||||
MOZ_ASSERT(!HasServoData());
|
||||
}
|
||||
|
||||
// Editable descendant count only counts descendants that
|
||||
// are in the uncomposed document.
|
||||
ResetEditableDescendantCount();
|
||||
@ -1992,18 +2005,21 @@ Element::UnbindFromTree(bool aDeep, bool aNullParent)
|
||||
shadowRoot->SetIsComposedDocParticipant(false);
|
||||
}
|
||||
|
||||
// Computed style data isn't useful for detached nodes, and we'll need to
|
||||
// recompute it anyway if we ever insert the nodes back into a document.
|
||||
if (IsStyledByServo()) {
|
||||
if (document) {
|
||||
ClearServoData(document);
|
||||
} else {
|
||||
MOZ_ASSERT(!HasServoData());
|
||||
MOZ_ASSERT(!HasAnyOfFlags(kAllServoDescendantBits | NODE_NEEDS_FRAME));
|
||||
}
|
||||
} else {
|
||||
MOZ_ASSERT(!HasServoData());
|
||||
}
|
||||
// Unbinding of children is the only point in time where we don't enforce the
|
||||
// "child has style data implies parent has it too" invariant.
|
||||
//
|
||||
// As such, the restyle root tracking may incorrectly end up setting dirty
|
||||
// bits on the parent chain when moving from a not yet unbound root with
|
||||
// already unbound parents to a root higher up in the tree, so we clear those
|
||||
// (again, since they're also cleared in ClearServoData) here.
|
||||
//
|
||||
// This can happen when the element changes the state of some ancestor up in
|
||||
// the tree, for example.
|
||||
//
|
||||
// Note that clearing the data itself here would have its own set of problems,
|
||||
// since the invariant we'd be breaking in that case is "HasServoData()
|
||||
// implies InComposedDoc()", which we rely on in various places.
|
||||
UnsetFlags(kAllServoDescendantBits);
|
||||
}
|
||||
|
||||
nsICSSDeclaration*
|
||||
|
@ -2,7 +2,7 @@
|
||||
<html>
|
||||
<head>
|
||||
<script>
|
||||
var request = indexedDB.open(parent.location, 1);
|
||||
var request = indexedDB.open(opener.location, 1);
|
||||
request.onupgradeneeded = function(e) {
|
||||
var db = e.target.result;
|
||||
// This should never be called
|
||||
@ -16,7 +16,7 @@
|
||||
var store = db.createObjectStore("mystore");
|
||||
store.add({ hello: "world" }, 42);
|
||||
trans.oncomplete = function() {
|
||||
parent.postMessage("go", "http://mochi.test:8888");
|
||||
opener.postMessage("go", "http://mochi.test:8888");
|
||||
}
|
||||
};
|
||||
</script>
|
@ -3,7 +3,7 @@
|
||||
<head>
|
||||
<script>
|
||||
var res = {};
|
||||
var request = indexedDB.open(parent.location, 2);
|
||||
var request = indexedDB.open(opener.location, 2);
|
||||
request.onblocked = function() {
|
||||
res.blockedFired = true;
|
||||
}
|
||||
@ -17,7 +17,7 @@
|
||||
res.value = JSON.stringify(e.target.result);
|
||||
}
|
||||
trans.oncomplete = function() {
|
||||
parent.postMessage(JSON.stringify(res), "http://mochi.test:8888");
|
||||
opener.postMessage(JSON.stringify(res), "http://mochi.test:8888");
|
||||
}
|
||||
};
|
||||
|
@ -4,8 +4,8 @@
|
||||
|
||||
[DEFAULT]
|
||||
support-files =
|
||||
bfcache_iframe1.html
|
||||
bfcache_iframe2.html
|
||||
bfcache_page1.html
|
||||
bfcache_page2.html
|
||||
blob_worker_crash_iframe.html
|
||||
error_events_abort_transactions_iframe.html
|
||||
event_propagation_iframe.html
|
||||
|
@ -10,41 +10,16 @@
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
<script type="text/javascript">
|
||||
/* import-globals-from helpers.js */
|
||||
var gOrigMaxTotalViewers = undefined;
|
||||
function setCachePref(enabled) {
|
||||
if (enabled) {
|
||||
is(typeof gOrigMaxTotalViewers, "undefined",
|
||||
"don't double-enable bfcache");
|
||||
SpecialPowers.setBoolPref("browser.sessionhistory.cache_subframes",
|
||||
true);
|
||||
gOrigMaxTotalViewers =
|
||||
SpecialPowers.getIntPref("browser.sessionhistory.max_total_viewers");
|
||||
SpecialPowers.setIntPref("browser.sessionhistory.max_total_viewers",
|
||||
10);
|
||||
}
|
||||
else {
|
||||
is(typeof gOrigMaxTotalViewers, "number",
|
||||
"don't double-disable bfcache");
|
||||
SpecialPowers.setIntPref("browser.sessionhistory.max_total_viewers",
|
||||
gOrigMaxTotalViewers);
|
||||
gOrigMaxTotalViewers = undefined;
|
||||
try {
|
||||
SpecialPowers.clearUserPref("browser.sessionhistory.cache_subframes");
|
||||
} catch (e) { /* Pref didn't exist, meh */ }
|
||||
}
|
||||
}
|
||||
|
||||
function* testSteps()
|
||||
{
|
||||
var iframe = $("iframe");
|
||||
setCachePref(true);
|
||||
window.onmessage = grabEventAndContinueHandler;
|
||||
|
||||
iframe.src = "bfcache_iframe1.html";
|
||||
let testWin = window.open("bfcache_page1.html", "testWin");
|
||||
var event = yield undefined;
|
||||
is(event.data, "go", "set up database successfully");
|
||||
|
||||
iframe.src = "bfcache_iframe2.html";
|
||||
testWin.location = "bfcache_page2.html";
|
||||
let res = JSON.parse((yield).data);
|
||||
is(res.version, 2, "version was set correctly");
|
||||
is(res.storeCount, 1, "correct set of stores");
|
||||
@ -52,7 +27,7 @@
|
||||
is(res.value, JSON.stringify({ hello: "world" }),
|
||||
"correct value found in store");
|
||||
|
||||
setCachePref(false);
|
||||
testWin.close();
|
||||
finishTest();
|
||||
}
|
||||
</script>
|
||||
@ -61,7 +36,6 @@
|
||||
</head>
|
||||
|
||||
<body onload="runTest();">
|
||||
<iframe id="iframe"></iframe>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
@ -14,8 +14,8 @@
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsWindowsHelpers.h"
|
||||
#include "prenv.h"
|
||||
#include <Shlobj.h>
|
||||
#include <Shlwapi.h>
|
||||
#include <shlobj.h>
|
||||
#include <shlwapi.h>
|
||||
#include <initguid.h>
|
||||
#include <stdint.h>
|
||||
#include "mozilla/mscom/EnsureMTA.h"
|
||||
|
@ -7,7 +7,7 @@
|
||||
var u = new SpeechSynthesisUtterance('hello');
|
||||
u.lang = 'it-IT-noend';
|
||||
u.addEventListener('start', function() {
|
||||
location = "file_bfcache_frame2.html";
|
||||
location = "file_bfcache_page2.html";
|
||||
});
|
||||
speechSynthesis.speak(u);
|
||||
});
|
@ -3,8 +3,8 @@
|
||||
var frameUnloaded = function() {
|
||||
var u = new SpeechSynthesisUtterance('hi');
|
||||
u.addEventListener('end', function () {
|
||||
parent.ok(true, 'Successfully spoke utterance from new frame.');
|
||||
parent.onDone();
|
||||
opener.ok(true, 'Successfully spoke utterance from new frame.');
|
||||
opener.onDone();
|
||||
});
|
||||
speechSynthesis.speak(u);
|
||||
};
|
@ -3,8 +3,8 @@ tags=msg
|
||||
subsuite = media
|
||||
support-files =
|
||||
common.js
|
||||
file_bfcache_frame.html
|
||||
file_bfcache_frame2.html
|
||||
file_bfcache_page1.html
|
||||
file_bfcache_page2.html
|
||||
file_setup.html
|
||||
file_speech_queue.html
|
||||
file_speech_simple.html
|
||||
|
@ -13,9 +13,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1230533
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1230533">Mozilla Bug 1230533</a>
|
||||
<p id="display"></p>
|
||||
<iframe id="testFrame"></iframe>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
@ -23,20 +22,22 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1230533
|
||||
/** Test for Bug 525444 **/
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var iframe;
|
||||
let testWin;
|
||||
|
||||
function onDone() {
|
||||
testWin.close();
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
SpecialPowers.pushPrefEnv({ set: [
|
||||
['media.webspeech.synth.enabled', true],
|
||||
['media.webspeech.synth.force_global_queue', true],
|
||||
['browser.sessionhistory.cache_subframes', true],
|
||||
['browser.sessionhistory.max_total_viewers', 10]] },
|
||||
['media.webspeech.synth.force_global_queue', true]] },
|
||||
function() {
|
||||
loadSpeechTest("file_bfcache_frame.html");
|
||||
testWin = window.open("about:blank", "testWin");
|
||||
testWin.onload = function(e) {
|
||||
waitForVoices(testWin)
|
||||
.then(() => testWin.location = "file_bfcache_page1.html")
|
||||
};
|
||||
});
|
||||
|
||||
</script>
|
||||
|
@ -5,7 +5,7 @@
|
||||
<script>
|
||||
var worker = new Worker("WorkerDebugger_frozen_worker1.js");
|
||||
worker.onmessage = function () {
|
||||
parent.postMessage("ready", "*");
|
||||
opener.postMessage("ready", "*");
|
||||
};
|
||||
</script>
|
||||
</head>
|
@ -5,7 +5,7 @@
|
||||
<script>
|
||||
var worker = new Worker("WorkerDebugger_frozen_worker2.js");
|
||||
worker.onmessage = function () {
|
||||
parent.postMessage("ready", "*");
|
||||
opener.postMessage("ready", "*");
|
||||
};
|
||||
</script>
|
||||
</head>
|
15
dom/workers/test/blank.html
Normal file
15
dom/workers/test/blank.html
Normal file
@ -0,0 +1,15 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Blank</title>
|
||||
</head>
|
||||
<body onload="notifyOnload();">
|
||||
<script type="application/javascript">
|
||||
function notifyOnload() {
|
||||
opener.postMessage({event: 'load'}, '*');
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -24,8 +24,8 @@ support-files =
|
||||
WorkerDebuggerManager_childWorker.js
|
||||
WorkerDebuggerManager_worker.js
|
||||
WorkerDebugger_childWorker.js
|
||||
WorkerDebugger_frozen_iframe1.html
|
||||
WorkerDebugger_frozen_iframe2.html
|
||||
WorkerDebugger_frozen_window1.html
|
||||
WorkerDebugger_frozen_window2.html
|
||||
WorkerDebugger_frozen_worker1.js
|
||||
WorkerDebugger_frozen_worker2.js
|
||||
WorkerDebugger_promise_debugger.js
|
||||
|
@ -2,6 +2,7 @@
|
||||
support-files =
|
||||
WorkerTest_badworker.js
|
||||
atob_worker.js
|
||||
blank.html
|
||||
bug978260_worker.js
|
||||
bug1014466_data1.txt
|
||||
bug1014466_data2.txt
|
||||
@ -56,7 +57,7 @@ support-files =
|
||||
sharedWorker_console.js
|
||||
sharedWorker_sharedWorker.js
|
||||
simpleThread_worker.js
|
||||
suspend_iframe.html
|
||||
suspend_window.html
|
||||
suspend_worker.js
|
||||
terminate_worker.js
|
||||
test_csp.html^headers^
|
||||
|
@ -7,15 +7,31 @@
|
||||
<head>
|
||||
<title>Test for SharedWorker</title>
|
||||
</head>
|
||||
<body>
|
||||
<body onload="notifyOpenerLoadEvent();">
|
||||
<script type="text/javascript">
|
||||
"use strict";
|
||||
|
||||
function postMessageToParentOrOpener(message) {
|
||||
if (parent != window) {
|
||||
parent.postMessage(message, "*");
|
||||
}
|
||||
if (opener) {
|
||||
opener.postMessage(message, "*");
|
||||
}
|
||||
}
|
||||
|
||||
// Used by test_multi_sharedWorker_lifetimes.html
|
||||
function notifyOpenerLoadEvent() {
|
||||
if (opener) {
|
||||
opener.postMessage({event: "load"}, "*");
|
||||
}
|
||||
}
|
||||
|
||||
function debug(message) {
|
||||
if (typeof(message) != "string") {
|
||||
throw new Error("debug() only accepts strings!");
|
||||
}
|
||||
parent.postMessage(message, "*");
|
||||
postMessageToParentOrOpener(message);
|
||||
}
|
||||
|
||||
let worker;
|
||||
@ -35,12 +51,12 @@
|
||||
lineno: event.lineno,
|
||||
isErrorEvent: event instanceof ErrorEvent
|
||||
};
|
||||
parent.postMessage(data, "*");
|
||||
postMessageToParentOrOpener(data);
|
||||
};
|
||||
|
||||
worker.port.onmessage = function(event) {
|
||||
debug("Worker message: " + JSON.stringify(event.data));
|
||||
parent.postMessage(event.data, "*");
|
||||
postMessageToParentOrOpener(event.data);
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -16,11 +16,8 @@
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
|
||||
const CACHE_SUBFRAMES = "browser.sessionhistory.cache_subframes";
|
||||
const MAX_TOTAL_VIEWERS = "browser.sessionhistory.max_total_viewers";
|
||||
|
||||
const IFRAME1_URL = "WorkerDebugger_frozen_iframe1.html";
|
||||
const IFRAME2_URL = "WorkerDebugger_frozen_iframe2.html";
|
||||
const WINDOW1_URL = "WorkerDebugger_frozen_window1.html";
|
||||
const WINDOW2_URL = "WorkerDebugger_frozen_window2.html";
|
||||
|
||||
const WORKER1_URL = "WorkerDebugger_frozen_worker1.js";
|
||||
const WORKER2_URL = "WorkerDebugger_frozen_worker2.js";
|
||||
@ -29,18 +26,14 @@
|
||||
(async function() {
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var oldMaxTotalViewers = SpecialPowers.getIntPref(MAX_TOTAL_VIEWERS);
|
||||
|
||||
SpecialPowers.setBoolPref(CACHE_SUBFRAMES, true);
|
||||
SpecialPowers.setIntPref(MAX_TOTAL_VIEWERS, 10);
|
||||
|
||||
let iframe = $("iframe");
|
||||
SpecialPowers.pushPrefEnv({set:
|
||||
[["browser.sessionhistory.max_total_viewers", 10]]});
|
||||
|
||||
let promise = waitForMultiple([
|
||||
waitForRegister(WORKER1_URL),
|
||||
waitForWindowMessage(window, "ready"),
|
||||
]);
|
||||
iframe.src = IFRAME1_URL;
|
||||
let testWin = window.open(WINDOW1_URL, "testWin");;
|
||||
let [dbg1] = await promise;
|
||||
is(dbg1.isClosed, false,
|
||||
"debugger for worker on page 1 should not be closed");
|
||||
@ -51,7 +44,7 @@
|
||||
waitForRegister(WORKER2_URL),
|
||||
waitForWindowMessage(window, "ready"),
|
||||
]);
|
||||
iframe.src = IFRAME2_URL;
|
||||
testWin.location = WINDOW2_URL;
|
||||
let [,, dbg2] = await promise;
|
||||
is(dbg1.isClosed, true,
|
||||
"debugger for worker on page 1 should be closed");
|
||||
@ -63,16 +56,13 @@
|
||||
waitForDebuggerClose(dbg2),
|
||||
waitForRegister(WORKER1_URL)
|
||||
]);
|
||||
iframe.contentWindow.history.back();
|
||||
testWin.history.back();
|
||||
[,, dbg1] = await promise;
|
||||
is(dbg1.isClosed, false,
|
||||
"debugger for worker on page 1 should not be closed");
|
||||
is(dbg2.isClosed, true,
|
||||
"debugger for worker on page 2 should be closed");
|
||||
|
||||
SpecialPowers.clearUserPref(CACHE_SUBFRAMES);
|
||||
SpecialPowers.setIntPref(MAX_TOTAL_VIEWERS, oldMaxTotalViewers);
|
||||
|
||||
SimpleTest.finish();
|
||||
})();
|
||||
}
|
||||
@ -84,7 +74,6 @@
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display:none;"></div>
|
||||
<pre id="test"></pre>
|
||||
<iframe id="iframe"></iframe>
|
||||
</body>
|
||||
<label id="test-result"/>
|
||||
</window>
|
||||
|
@ -12,21 +12,20 @@
|
||||
"use strict";
|
||||
|
||||
const scrollbarPref = "layout.testing.overlay-scrollbars.always-visible";
|
||||
const bfCacheEnabledPref = "browser.sessionhistory.cache_subframes";
|
||||
const bfCacheDepthPref = "browser.sessionhistory.max_total_viewers";
|
||||
const bfCacheDepth = 10;
|
||||
const viewersPref = "browser.sessionhistory.max_total_viewers";
|
||||
|
||||
const frameRelativeURL = "multi_sharedWorker_frame.html";
|
||||
const windowRelativeURL = "multi_sharedWorker_frame.html";
|
||||
const storedData = "0123456789abcdefghijklmnopqrstuvwxyz";
|
||||
|
||||
let testGenerator = (function*() {
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
// Force scrollbar to always be shown. The scrollbar setting is
|
||||
// necessary to avoid the fade-in/fade-out from evicting our document
|
||||
// from the BF cache below. If bug 1049277 is fixed, then we can
|
||||
// stop setting the scrollbar pref here.
|
||||
SpecialPowers.pushPrefEnv({ set: [[scrollbarPref, true]] },
|
||||
// Force scrollbar to always be shown. The scrollbar setting is
|
||||
// necessary to avoid the fade-in/fade-out from evicting our document
|
||||
// from the BF cache below. If bug 1049277 is fixed, then we can
|
||||
// stop setting the scrollbar pref here.
|
||||
SpecialPowers.pushPrefEnv({ set: [[scrollbarPref, true],
|
||||
[viewersPref, 10]] },
|
||||
sendToGenerator);
|
||||
yield undefined;
|
||||
|
||||
@ -38,76 +37,62 @@
|
||||
}
|
||||
});
|
||||
|
||||
let frame = document.getElementById("frame");
|
||||
frame.src = frameRelativeURL;
|
||||
frame.onload = sendToGenerator;
|
||||
|
||||
let testWin = window.open(windowRelativeURL, "testWin");
|
||||
yield undefined;
|
||||
|
||||
frame = frame.contentWindow;
|
||||
frame.postMessage({ command: "retrieve" }, "*");
|
||||
testWin.postMessage({ command: "retrieve" }, "*");
|
||||
|
||||
let event = yield undefined;
|
||||
ok(event instanceof MessageEvent, "Got a MessageEvent");
|
||||
is(event.source, frame, "Correct window got the event");
|
||||
is(event.source, testWin, "Correct window got the event");
|
||||
is(event.data.type, "result", "Got a result message");
|
||||
is(event.data.data, undefined, "No data stored yet");
|
||||
|
||||
frame.postMessage({ command: "store", data: storedData }, "*");
|
||||
frame.postMessage({ command: "retrieve" }, "*");
|
||||
testWin.postMessage({ command: "store", data: storedData }, "*");
|
||||
testWin.postMessage({ command: "retrieve" }, "*");
|
||||
|
||||
event = yield undefined;
|
||||
ok(event instanceof MessageEvent, "Got a MessageEvent");
|
||||
is(event.source, frame, "Correct window got the event");
|
||||
is(event.source, testWin, "Correct window got the event");
|
||||
is(event.data.type, "result", "Got a result message");
|
||||
is(event.data.data, storedData, "Got stored data");
|
||||
|
||||
// Navigate when the bfcache is disabled.
|
||||
info("Navigating to about:blank");
|
||||
frame = document.getElementById("frame");
|
||||
frame.onload = sendToGenerator;
|
||||
frame.src = "about:blank";
|
||||
frame.contentWindow.document.body.offsetTop;
|
||||
info("Navigating to a blank page");
|
||||
testWin.onunload = function(){};;
|
||||
testWin.location = "blank.html";
|
||||
testWin.document.body.offsetTop;
|
||||
|
||||
yield undefined;
|
||||
|
||||
info("Navigating to " + frameRelativeURL);
|
||||
frame.src = frameRelativeURL;
|
||||
frame.contentWindow.document.body.offsetTop;
|
||||
info("Navigating to " + windowRelativeURL);
|
||||
testWin.onunload = function(){};
|
||||
testWin.location = windowRelativeURL;
|
||||
testWin.document.body.offsetTop;
|
||||
|
||||
yield undefined;
|
||||
|
||||
frame = frame.contentWindow;
|
||||
frame.postMessage({ command: "retrieve" }, "*");
|
||||
testWin.postMessage({ command: "retrieve" }, "*");
|
||||
|
||||
event = yield undefined;
|
||||
ok(event instanceof MessageEvent, "Got a MessageEvent");
|
||||
is(event.source, frame, "Correct window got the event");
|
||||
is(event.source, testWin, "Correct window got the event");
|
||||
is(event.data.type, "result", "Got a result message");
|
||||
is(event.data.data, undefined, "No data stored");
|
||||
|
||||
frame.postMessage({ command: "store", data: storedData }, "*");
|
||||
frame.postMessage({ command: "retrieve" }, "*");
|
||||
testWin.postMessage({ command: "store", data: storedData }, "*");
|
||||
testWin.postMessage({ command: "retrieve" }, "*");
|
||||
|
||||
event = yield undefined;
|
||||
ok(event instanceof MessageEvent, "Got a MessageEvent");
|
||||
is(event.source, frame, "Correct window got the event");
|
||||
is(event.source, testWin, "Correct window got the event");
|
||||
is(event.data.type, "result", "Got a result message");
|
||||
is(event.data.data, storedData, "Got stored data");
|
||||
|
||||
info("Enabling '" + bfCacheEnabledPref + "' pref");
|
||||
SpecialPowers.pushPrefEnv({ set: [[bfCacheEnabledPref, true],
|
||||
[bfCacheDepthPref, bfCacheDepth]] },
|
||||
sendToGenerator);
|
||||
yield undefined;
|
||||
|
||||
// Navigate when the bfcache is enabled.
|
||||
frame = document.getElementById("frame");
|
||||
frame.onload = sendToGenerator;
|
||||
|
||||
info("Navigating to about:blank");
|
||||
frame.src = "about:blank";
|
||||
frame.contentWindow.document.body.offsetTop;
|
||||
info("Navigating to a blank page");
|
||||
testWin.location = "blank.html";
|
||||
testWin.document.body.offsetTop;
|
||||
|
||||
yield undefined;
|
||||
|
||||
@ -116,32 +101,33 @@
|
||||
SpecialPowers.exactGC(sendToGenerator);
|
||||
yield undefined;
|
||||
|
||||
// It seems using SpecialPowers.executeSoon() would make the
|
||||
// entryGlobal being the TabChildGlobal (and that would make the
|
||||
// baseURI in the location assignment below being incorrect);
|
||||
// setTimeout on the otherhand ensures the entryGlobal is this
|
||||
// window.
|
||||
info("Waiting the event queue to clear");
|
||||
SpecialPowers.executeSoon(sendToGenerator);
|
||||
setTimeout(sendToGenerator, 0);
|
||||
yield undefined;
|
||||
}
|
||||
|
||||
info("Navigating to " + frameRelativeURL);
|
||||
frame.src = frameRelativeURL;
|
||||
frame.contentWindow.document.body.offsetTop;
|
||||
info("Navigating to " + windowRelativeURL);
|
||||
testWin.location = windowRelativeURL;
|
||||
testWin.document.body.offsetTop;
|
||||
|
||||
yield undefined;
|
||||
|
||||
frame = frame.contentWindow;
|
||||
frame.postMessage({ command: "retrieve" }, "*");
|
||||
testWin.postMessage({ command: "retrieve" }, "*");
|
||||
|
||||
event = yield undefined;
|
||||
ok(event instanceof MessageEvent, "Got a MessageEvent");
|
||||
is(event.source, frame, "Correct window got the event");
|
||||
is(event.source, testWin, "Correct window got the event");
|
||||
is(event.data.type, "result", "Got a result message");
|
||||
is(event.data.data, storedData, "Still have data stored");
|
||||
|
||||
info("Resetting '" + bfCacheEnabledPref + "' pref");
|
||||
SpecialPowers.popPrefEnv(sendToGenerator);
|
||||
yield undefined;
|
||||
|
||||
window.removeEventListener("message", sendToGenerator);
|
||||
|
||||
testWin.close();
|
||||
SimpleTest.finish();
|
||||
})();
|
||||
|
||||
@ -150,6 +136,5 @@
|
||||
</script>
|
||||
</head>
|
||||
<body onload="testGenerator.next();">
|
||||
<iframe id="frame"></iframe>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -26,7 +26,16 @@ addLoadEvent(function() {
|
||||
|
||||
w.onmessage = function(e) {
|
||||
if (e.data.type === 'ready') {
|
||||
doTest();
|
||||
// XXX Important trick here.
|
||||
//
|
||||
// Setting iosvc.offline would trigger a sync notifyObservers call, and if
|
||||
// there exists a preloaded about:newtab (see tabbrowser._handleNewTab),
|
||||
// that tab will be notified.
|
||||
//
|
||||
// This implies a sync call across different tabGroups, and will hit the
|
||||
// assertion in SchedulerGroup::ValidateAccess(). So use executeSoon to
|
||||
// re-dispatch an unlabeled runnable to the event queue.
|
||||
SpecialPowers.executeSoon(doTest);
|
||||
} else if (e.data.type === 'ok') {
|
||||
ok(e.data.test, e.data.message);
|
||||
} else if (e.data.type === 'finished') {
|
||||
|
@ -14,13 +14,12 @@
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
<iframe id="workerFrame" src="suspend_iframe.html" onload="subframeLoaded();">
|
||||
</iframe>
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var iframe;
|
||||
const BLANK_URI = location.href.replace("test_suspend.html", "blank.html");
|
||||
|
||||
var lastCount;
|
||||
|
||||
var suspended = false;
|
||||
@ -31,29 +30,39 @@
|
||||
var oldMessageCount;
|
||||
var waitCount = 0;
|
||||
|
||||
var testWin = window.open("suspend_window.html", "testWin");
|
||||
testWin.onload = testWinLoaded;
|
||||
|
||||
window.addEventListener("message", msg => {
|
||||
if (suspended) {
|
||||
badOnloadCallback();
|
||||
} else {
|
||||
suspendCallback();
|
||||
}
|
||||
})
|
||||
|
||||
function finishTest() {
|
||||
if (finished) {
|
||||
return;
|
||||
}
|
||||
finished = true;
|
||||
SpecialPowers.flushPrefEnv(function () {
|
||||
iframe.terminateWorker();
|
||||
SimpleTest.finish();
|
||||
});
|
||||
testWin.terminateWorker();
|
||||
testWin.close();
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
function waitInterval() {
|
||||
if (finished) {
|
||||
return;
|
||||
}
|
||||
is(String(iframe.location), "about:blank", "Wrong url!");
|
||||
is(testWin.location.href, BLANK_URI, "Wrong url!");
|
||||
is(suspended, true, "Not suspended?");
|
||||
is(resumed, false, "Already resumed?!");
|
||||
is(lastCount, oldMessageCount, "Received a message while suspended!");
|
||||
if (++waitCount == 5) {
|
||||
clearInterval(interval);
|
||||
resumed = true;
|
||||
iframe.history.back();
|
||||
testWin.history.back();
|
||||
}
|
||||
}
|
||||
|
||||
@ -61,7 +70,7 @@
|
||||
if (finished) {
|
||||
return;
|
||||
}
|
||||
ok(false, "We don't want suspend_iframe.html to fire a new load event, we want it to come out of the bfcache!");
|
||||
ok(false, "We don't want suspend_window.html to fire a new load event, we want it to come out of the bfcache!");
|
||||
finishTest();
|
||||
}
|
||||
|
||||
@ -69,16 +78,12 @@
|
||||
if (finished) {
|
||||
return;
|
||||
}
|
||||
is(String(iframe.location), "about:blank", "Wrong url!");
|
||||
is(testWin.location.href, BLANK_URI, "Wrong url!");
|
||||
is(suspended, false, "Already suspended?");
|
||||
is(resumed, false, "Already resumed?");
|
||||
SpecialPowers.popPrefEnv(function () {
|
||||
suspended = true;
|
||||
var iframeElement = document.getElementById("workerFrame");
|
||||
iframeElement.onload = badOnloadCallback;
|
||||
oldMessageCount = lastCount;
|
||||
interval = setInterval(waitInterval, 1000);
|
||||
});
|
||||
suspended = true;
|
||||
oldMessageCount = lastCount;
|
||||
interval = setInterval(waitInterval, 1000);
|
||||
}
|
||||
|
||||
function messageCallback(data) {
|
||||
@ -91,21 +96,18 @@
|
||||
"Got good data, lastCount = " + lastCount + ", data = " + data);
|
||||
lastCount = data;
|
||||
if (lastCount == 25) {
|
||||
SpecialPowers.pushPrefEnv({"set": [["browser.sessionhistory.cache_subframes", true]]}, function () {
|
||||
iframe.location = "about:blank";
|
||||
// We want suspend_iframe.html to go into bfcache, so we need to flush
|
||||
// out all pending notifications. Otherwise, if they're flushed too
|
||||
// late, they could kick us out of the bfcache again.
|
||||
iframe.document.body.offsetTop;
|
||||
});
|
||||
testWin.location = "blank.html";
|
||||
// We want suspend_window.html to go into bfcache, so we need to flush
|
||||
// out all pending notifications. Otherwise, if they're flushed too
|
||||
// late, they could kick us out of the bfcache again.
|
||||
testWin.document.body.offsetTop;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
var newLocation =
|
||||
window.location.toString().replace("test_suspend.html",
|
||||
"suspend_iframe.html");
|
||||
is(newLocation.indexOf(iframe.location.toString()), 0, "Wrong url!");
|
||||
var newLocation = location.href.replace("test_suspend.html",
|
||||
"suspend_window.html");
|
||||
is(testWin.location.href, newLocation, "Wrong url!");
|
||||
is(resumed, true, "Got message before resumed!");
|
||||
is(lastCount, data - 1, "Missed a message, suspend failed!");
|
||||
finishTest();
|
||||
@ -115,21 +117,15 @@
|
||||
if (finished) {
|
||||
return;
|
||||
}
|
||||
ok(false, "Iframe had an error: '" + data + "'");
|
||||
ok(false, "testWin had an error: '" + data + "'");
|
||||
finishTest();
|
||||
}
|
||||
|
||||
function subframeLoaded() {
|
||||
function testWinLoaded() {
|
||||
if (finished) {
|
||||
return;
|
||||
}
|
||||
var iframeElement = document.getElementById("workerFrame");
|
||||
iframeElement.onload = suspendCallback;
|
||||
|
||||
iframe = iframeElement.contentWindow;
|
||||
ok(iframe, "No iframe?!");
|
||||
|
||||
iframe.startWorker(messageCallback, errorCallback);
|
||||
testWin.startWorker(messageCallback, errorCallback);
|
||||
}
|
||||
|
||||
</script>
|
||||
|
@ -464,7 +464,9 @@ PaintItemByDrawTarget(nsDisplayItem* aItem,
|
||||
DrawTarget* aDT,
|
||||
const LayerRect& aImageRect,
|
||||
const LayerPoint& aOffset,
|
||||
nsDisplayListBuilder* aDisplayListBuilder)
|
||||
nsDisplayListBuilder* aDisplayListBuilder,
|
||||
RefPtr<BasicLayerManager>& aManager,
|
||||
WebRenderLayerManager* aWrManager)
|
||||
{
|
||||
MOZ_ASSERT(aDT);
|
||||
|
||||
@ -479,21 +481,43 @@ PaintItemByDrawTarget(nsDisplayItem* aItem,
|
||||
break;
|
||||
case DisplayItemType::TYPE_FILTER:
|
||||
{
|
||||
RefPtr<BasicLayerManager> tempManager = new BasicLayerManager(BasicLayerManager::BLM_INACTIVE);
|
||||
if (aManager == nullptr) {
|
||||
aManager = new BasicLayerManager(BasicLayerManager::BLM_INACTIVE);
|
||||
}
|
||||
|
||||
FrameLayerBuilder* layerBuilder = new FrameLayerBuilder();
|
||||
layerBuilder->Init(aDisplayListBuilder, tempManager);
|
||||
layerBuilder->Init(aDisplayListBuilder, aManager);
|
||||
layerBuilder->DidBeginRetainedLayerTransaction(aManager);
|
||||
|
||||
aManager->BeginTransactionWithTarget(context);
|
||||
|
||||
tempManager->BeginTransactionWithTarget(context);
|
||||
ContainerLayerParameters param;
|
||||
RefPtr<Layer> layer = aItem->BuildLayer(aDisplayListBuilder, tempManager, param);
|
||||
RefPtr<Layer> layer =
|
||||
static_cast<nsDisplayFilter*>(aItem)->BuildLayer(aDisplayListBuilder,
|
||||
aManager, param);
|
||||
|
||||
if (layer) {
|
||||
tempManager->SetRoot(layer);
|
||||
static_cast<nsDisplayFilter*>(aItem)->PaintAsLayer(aDisplayListBuilder, context, tempManager);
|
||||
UniquePtr<LayerProperties> props;
|
||||
props = Move(LayerProperties::CloneFrom(aManager->GetRoot()));
|
||||
|
||||
aManager->SetRoot(layer);
|
||||
layerBuilder->WillEndTransaction();
|
||||
|
||||
nsIntRegion invalid;
|
||||
props->ComputeDifferences(layer, invalid, nullptr);
|
||||
|
||||
static_cast<nsDisplayFilter*>(aItem)->PaintAsLayer(aDisplayListBuilder,
|
||||
context, aManager);
|
||||
|
||||
if (!invalid.IsEmpty()) {
|
||||
aWrManager->SetNotifyInvalidation(true);
|
||||
}
|
||||
}
|
||||
|
||||
if (tempManager->InTransaction()) {
|
||||
tempManager->AbortTransaction();
|
||||
if (aManager->InTransaction()) {
|
||||
aManager->AbortTransaction();
|
||||
}
|
||||
aManager->SetTarget(nullptr);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -554,11 +578,18 @@ WebRenderLayerManager::GenerateFallbackData(nsDisplayItem* aItem,
|
||||
}
|
||||
|
||||
aOffset = RoundedToInt(bounds.TopLeft());
|
||||
nsRegion invalidRegion;
|
||||
|
||||
bool needPaint = true;
|
||||
nsAutoPtr<nsDisplayItemGeometry> geometry = fallbackData->GetGeometry();
|
||||
|
||||
if (geometry) {
|
||||
|
||||
// nsDisplayFilter is rendered via BasicLayerManager which means the invalidate
|
||||
// region is unknown until we traverse the displaylist contained by it.
|
||||
if (geometry && !fallbackData->IsInvalid() &&
|
||||
aItem->GetType() != DisplayItemType::TYPE_FILTER) {
|
||||
nsRect invalid;
|
||||
nsRegion invalidRegion;
|
||||
|
||||
if (aItem->IsInvalid(invalid)) {
|
||||
invalidRegion.OrWith(clippedBounds);
|
||||
} else {
|
||||
@ -574,11 +605,12 @@ WebRenderLayerManager::GenerateFallbackData(nsDisplayItem* aItem,
|
||||
invalidRegion.OrWith(clippedBounds);
|
||||
}
|
||||
}
|
||||
needPaint = !invalidRegion.IsEmpty();
|
||||
}
|
||||
|
||||
gfx::SurfaceFormat format = aItem->GetType() == DisplayItemType::TYPE_MASK ?
|
||||
gfx::SurfaceFormat::A8 : gfx::SurfaceFormat::B8G8R8A8;
|
||||
if (!geometry || !invalidRegion.IsEmpty() || fallbackData->IsInvalid()) {
|
||||
if (needPaint) {
|
||||
gfx::SurfaceFormat format = aItem->GetType() == DisplayItemType::TYPE_MASK ?
|
||||
gfx::SurfaceFormat::A8 : gfx::SurfaceFormat::B8G8R8A8;
|
||||
if (gfxPrefs::WebRenderBlobImages()) {
|
||||
bool snapped;
|
||||
bool isOpaque = aItem->GetOpaqueRegion(aDisplayListBuilder, &snapped).Contains(clippedBounds);
|
||||
@ -588,7 +620,8 @@ WebRenderLayerManager::GenerateFallbackData(nsDisplayItem* aItem,
|
||||
RefPtr<gfx::DrawTarget> dummyDt =
|
||||
gfx::Factory::CreateDrawTarget(gfx::BackendType::SKIA, gfx::IntSize(1, 1), gfx::SurfaceFormat::B8G8R8A8);
|
||||
RefPtr<gfx::DrawTarget> dt = gfx::Factory::CreateRecordingDrawTarget(recorder, dummyDt, imageSize.ToUnknownSize());
|
||||
PaintItemByDrawTarget(aItem, dt, aImageRect, aOffset, aDisplayListBuilder);
|
||||
PaintItemByDrawTarget(aItem, dt, aImageRect, aOffset, aDisplayListBuilder,
|
||||
fallbackData->mBasicLayerManager, this);
|
||||
recorder->Finish();
|
||||
|
||||
Range<uint8_t> bytes((uint8_t*)recorder->mOutputStream.mData, recorder->mOutputStream.mLength);
|
||||
@ -608,7 +641,9 @@ WebRenderLayerManager::GenerateFallbackData(nsDisplayItem* aItem,
|
||||
if (!dt) {
|
||||
return nullptr;
|
||||
}
|
||||
PaintItemByDrawTarget(aItem, dt, aImageRect, aOffset, aDisplayListBuilder);
|
||||
PaintItemByDrawTarget(aItem, dt, aImageRect, aOffset,
|
||||
aDisplayListBuilder,
|
||||
fallbackData->mBasicLayerManager, this);
|
||||
}
|
||||
if (!helper.UpdateImage()) {
|
||||
return nullptr;
|
||||
|
@ -246,6 +246,7 @@ public:
|
||||
}
|
||||
|
||||
bool ShouldNotifyInvalidation() const { return mShouldNotifyInvalidation; }
|
||||
void SetNotifyInvalidation(bool aShouldNotifyInvalidation) { mShouldNotifyInvalidation = aShouldNotifyInvalidation; }
|
||||
|
||||
private:
|
||||
/**
|
||||
|
@ -6,6 +6,7 @@
|
||||
#ifndef GFX_WEBRENDERUSERDATA_H
|
||||
#define GFX_WEBRENDERUSERDATA_H
|
||||
|
||||
#include "BasicLayers.h" // for BasicLayerManager
|
||||
#include "mozilla/layers/StackingContextHelper.h"
|
||||
#include "mozilla/webrender/WebRenderAPI.h"
|
||||
#include "mozilla/layers/AnimationInfo.h"
|
||||
@ -127,6 +128,7 @@ public:
|
||||
void SetInvalid(bool aInvalid) { mInvalid = aInvalid; }
|
||||
bool IsInvalid() { return mInvalid; }
|
||||
|
||||
RefPtr<BasicLayerManager> mBasicLayerManager;
|
||||
protected:
|
||||
nsAutoPtr<nsDisplayItemGeometry> mGeometry;
|
||||
nsRect mBounds;
|
||||
|
@ -1507,6 +1507,8 @@ nsDocumentViewer::Open(nsISupports *aState, nsISHEntry *aSHEntry)
|
||||
SyncParentSubDocMap();
|
||||
|
||||
if (mFocusListener && mDocument) {
|
||||
// The focus listener may have been disconnected.
|
||||
mFocusListener->Init(this);
|
||||
mDocument->AddEventListener(NS_LITERAL_STRING("focus"), mFocusListener,
|
||||
false, false);
|
||||
mDocument->AddEventListener(NS_LITERAL_STRING("blur"), mFocusListener,
|
||||
|
@ -9256,7 +9256,6 @@ nsDisplayFilter::BuildLayer(nsDisplayListBuilder* aBuilder,
|
||||
RefPtr<ContainerLayer> container = aManager->GetLayerBuilder()->
|
||||
BuildContainerLayerFor(aBuilder, aManager, mFrame, this, &mList,
|
||||
newContainerParameters, nullptr);
|
||||
|
||||
LayerState state = this->GetLayerState(aBuilder, aManager, newContainerParameters);
|
||||
if (container && state != LAYER_SVG_EFFECTS) {
|
||||
const nsTArray<nsStyleFilter>& filters = mFrame->StyleEffects()->mFilters;
|
||||
|
@ -1749,7 +1749,7 @@ fuzzy-if(true,17,5886) fuzzy-if(skiaContent,9,5894) == 759036-2.html 759036-2-re
|
||||
== 776443-2.html 776443-2-ref.html
|
||||
== 786254-1.html 786254-1-ref.html
|
||||
== 787947-1.html 787947-1-ref.html
|
||||
== 796847-1.svg 796847-1-ref.svg
|
||||
pref(gfx.webrender.layers-free,true) == 796847-1.svg 796847-1-ref.svg
|
||||
fuzzy(40,875) fuzzy-if(skiaContent,1,2500) == 797797-1.html 797797-1-ref.html # 'opacity:N' and rgba(,,,N) text don't match precisely
|
||||
fuzzy(40,850) fuzzy-if(skiaContent,2,2310) == 797797-2.html 797797-2-ref.html # 'opacity:N' and rgba(,,,N) text don't match precisely
|
||||
== 801994-1.html 801994-1-ref.html
|
||||
|
Loading…
Reference in New Issue
Block a user