Backed out 2 changesets (bug 1576188) for causing browser-chrome failures on browser_persist_cross_origin_iframe.js

CLOSED TREE

Backed out changeset d2c102f8d898 (bug 1576188)
Backed out changeset 9ddd9a63d178 (bug 1576188)
This commit is contained in:
Arthur Iakab 2020-04-23 19:38:58 +03:00
parent 15756c2e25
commit c278cf13d3
32 changed files with 51 additions and 621 deletions

View File

@ -567,7 +567,6 @@ class ContextMenuChild extends JSWindowActorChild {
} = doc;
docLocation = docLocation && docLocation.spec;
let frameOuterWindowID = WebNavigationFrames.getFrameId(doc.defaultView);
let frameBrowsingContextID = doc.defaultView.docShell.browsingContext.id;
let loginFillInfo = LoginManagerChild.forWindow(
doc.defaultView
).getFieldContext(aEvent.composedTarget);
@ -684,7 +683,6 @@ class ContextMenuChild extends JSWindowActorChild {
customMenuItems,
contentDisposition,
frameOuterWindowID,
frameBrowsingContextID,
disableSetDesktopBackground,
parentAllowsMixedContent,
};
@ -904,9 +902,6 @@ class ContextMenuChild extends JSWindowActorChild {
context.target.ownerGlobal
);
context.frameBrowsingContextID =
context.target.ownerGlobal.docShell.browsingContext.id;
// Check if we are in the PDF Viewer.
context.inPDFViewer =
context.target.ownerDocument.nodePrincipal.origin == "resource://pdf.js";

View File

@ -52,7 +52,6 @@ function openContextMenu(aMessage, aBrowser, aActor) {
contentType: data.contentType,
contentDisposition: data.contentDisposition,
frameOuterWindowID: data.frameOuterWindowID,
frameBrowsingContext: BrowsingContext.get(data.frameBrowsingContextID),
selectionInfo: data.selectionInfo,
disableSetDesktopBackground: data.disableSetDesktopBackground,
loginFillInfo: data.loginFillInfo,
@ -232,9 +231,6 @@ class nsContextMenu {
this.principal = context.principal;
this.storagePrincipal = context.storagePrincipal;
this.frameOuterWindowID = context.frameOuterWindowID;
this.frameBrowsingContext = BrowsingContext.get(
context.frameBrowsingContextID
);
this.inSyntheticDoc = context.inSyntheticDoc;
this.inAboutDevtoolsToolbox = context.inAboutDevtoolsToolbox;
@ -1399,7 +1395,7 @@ class nsContextMenu {
// Save URL of clicked-on frame.
saveFrame() {
saveBrowser(this.browser, false, this.frameBrowsingContext);
saveBrowser(this.browser, false, this.frameOuterWindowID);
}
// Helper function to wait for appropriate MIME-type headers and

View File

@ -1320,7 +1320,7 @@ const JsonView = {
// principal is from the child. Null principals don't survive crossing
// over IPC, so there's no other principal that'll work.
const persistable = browser.frameLoader;
persistable.startPersistence(null, {
persistable.startPersistence(0, {
onDocumentReady(doc) {
const uri = chrome.makeURI(doc.documentURI, doc.characterSet);
const filename = chrome.getDefaultFileName(undefined, uri, doc, null);

View File

@ -93,16 +93,6 @@ static void Register(BrowsingContext* aBrowsingContext) {
aBrowsingContext->Group()->Register(aBrowsingContext);
}
bool BrowsingContext::IsInSubtreeOf(BrowsingContext* aContext) {
BrowsingContext* bc = this;
do {
if (bc == aContext) {
return true;
}
} while ((bc = bc->mParent));
return false;
}
BrowsingContext* BrowsingContext::Top() {
BrowsingContext* bc = this;
while (bc->mParent) {

View File

@ -214,12 +214,6 @@ class BrowsingContext : public nsILoadContext, public nsWrapperCache {
void SetDocShell(nsIDocShell* aDocShell);
void ClearDocShell() { mDocShell = nullptr; }
// Get the Document for this BrowsingContext if it is in-process, or
// null if it's not.
Document* GetDocument() const {
return mDocShell ? mDocShell->GetDocument() : nullptr;
}
// This cleans up remote outer window proxies that might have been left behind
// when the browsing context went from being remote to local. It does this by
// turning them into cross-compartment wrappers to aOuter. If there is already
@ -298,8 +292,6 @@ class BrowsingContext : public nsILoadContext, public nsWrapperCache {
bool IsTopContent() const { return IsContent() && !GetParent(); }
bool IsInSubtreeOf(BrowsingContext* aContext);
bool IsContentSubframe() const { return IsContent() && GetParent(); }
uint64_t Id() const { return mBrowsingContextId; }

View File

@ -3209,27 +3209,25 @@ void nsFrameLoader::DestroyBrowserFrameScripts() {
}
void nsFrameLoader::StartPersistence(
BrowsingContext* aContext, nsIWebBrowserPersistDocumentReceiver* aRecv,
uint64_t aOuterWindowID, nsIWebBrowserPersistDocumentReceiver* aRecv,
ErrorResult& aRv) {
MOZ_ASSERT(aRecv);
RefPtr<BrowsingContext> context = aContext ? aContext : GetBrowsingContext();
if (!context || !context->IsInSubtreeOf(GetBrowsingContext())) {
aRecv->OnError(NS_ERROR_NO_CONTENT);
if (auto* browserParent = GetBrowserParent()) {
browserParent->StartPersistence(aOuterWindowID, aRecv, aRv);
return;
}
if (!context->GetDocShell() && XRE_IsParentProcess()) {
CanonicalBrowsingContext* canonical =
CanonicalBrowsingContext::Cast(context);
RefPtr<BrowserParent> browserParent =
canonical->GetCurrentWindowGlobal()->GetBrowserParent();
browserParent->StartPersistence(canonical, aRecv, aRv);
return;
nsCOMPtr<Document> rootDoc =
GetDocShell() ? GetDocShell()->GetDocument() : nullptr;
nsCOMPtr<Document> foundDoc;
if (aOuterWindowID) {
foundDoc = nsContentUtils::GetSubdocumentWithOuterWindowId(rootDoc,
aOuterWindowID);
} else {
foundDoc = rootDoc;
}
nsCOMPtr<Document> foundDoc = context->GetDocument();
if (!foundDoc) {
aRecv->OnError(NS_ERROR_NO_CONTENT);
} else {

View File

@ -219,7 +219,7 @@ class nsFrameLoader final : public nsStubMutationObserver,
nsIWebProgressListener* aProgressListener,
mozilla::ErrorResult& aRv);
void StartPersistence(BrowsingContext* aContext,
void StartPersistence(uint64_t aOuterWindowID,
nsIWebBrowserPersistDocumentReceiver* aRecv,
mozilla::ErrorResult& aRv);

View File

@ -1,210 +0,0 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
interface LoadContext;
interface RemoteTab;
interface URI;
interface nsIDocShell;
interface nsIPrintSettings;
interface nsIWebBrowserPersistDocumentReceiver;
interface nsIWebProgressListener;
[ChromeOnly,
Exposed=Window]
interface FrameLoader {
/**
* Get the docshell from the frame loader.
*/
[GetterThrows]
readonly attribute nsIDocShell? docShell;
/**
* Get this frame loader's RemoteTab, if it has a remote frame. Otherwise,
* returns null.
*/
readonly attribute RemoteTab? remoteTab;
/**
* Get an nsILoadContext for the top-level docshell. For remote
* frames, a shim is returned that contains private browsing and app
* information.
*/
readonly attribute LoadContext loadContext;
/**
* Get the root BrowsingContext within the frame.
* This may be null immediately after creating a remote frame.
*/
readonly attribute BrowsingContext? browsingContext;
/**
* Find out whether the loader's frame is at too great a depth in
* the frame tree. This can be used to decide what operations may
* or may not be allowed on the loader's docshell.
*/
[Pure]
readonly attribute boolean depthTooGreat;
/**
* Find out whether the loader's frame is a remote frame.
*/
readonly attribute boolean isRemoteFrame;
/**
* Activate remote frame.
* Throws an exception with non-remote frames.
*/
[Throws]
void activateRemoteFrame();
/**
* Deactivate remote frame.
* Throws an exception with non-remote frames.
*/
[Throws]
void deactivateRemoteFrame();
/**
* @see nsIDOMWindowUtils sendMouseEvent.
*/
[Throws]
void sendCrossProcessMouseEvent(DOMString aType,
float aX,
float aY,
long aButton,
long aClickCount,
long aModifiers,
optional boolean aIgnoreRootScrollFrame = false);
/**
* Activate event forwarding from client (remote frame) to parent.
*/
[Throws]
void activateFrameEvent(DOMString aType, boolean capture);
// Note, when frameloaders are swapped, also messageManagers are swapped.
readonly attribute MessageSender? messageManager;
/**
* Request that the next time a remote layer transaction has been
* received by the Compositor, a MozAfterRemoteFrame event be sent
* to the window.
*/
void requestNotifyAfterRemotePaint();
/**
* Force a remote browser to recompute its dimension and screen position.
*/
[Throws]
void requestUpdatePosition();
/**
* Force a TabStateFlush from native sessionStoreListeners.
* Return true if the flush requires async ipc call.
*/
boolean requestTabStateFlush(unsigned long aFlushId);
/**
* Force Epoch update in native sessionStoreListeners.
*/
void requestEpochUpdate(unsigned long aEpoch);
/**
* Request a session history update in native sessionStoreListeners.
*/
void requestSHistoryUpdate(boolean aImmediately);
/**
* Print the current document.
*
* @param aOuterWindowID the ID of the outer window to print
* @param aPrintSettings optional print settings to use; printSilent can be
* set to prevent prompting.
* @param aProgressListener optional print progress listener.
*/
[Throws]
void print(unsigned long long aOuterWindowID,
nsIPrintSettings aPrintSettings,
optional nsIWebProgressListener? aProgressListener = null);
/**
* The element which owns this frame loader.
*
* For example, if this is a frame loader for an <iframe>, this attribute
* returns the iframe element.
*/
[Pure]
readonly attribute Element? ownerElement;
/**
* Cached childID of the ContentParent owning the RemoteTab in this frame
* loader. This can be used to obtain the childID after the RemoteTab died.
*/
[Pure]
readonly attribute unsigned long long childID;
/**
* Find out whether the owner content really is a mozbrowser. <xul:browser>
* is not considered to be a mozbrowser frame.
*/
[Pure]
readonly attribute boolean ownerIsMozBrowserFrame;
/**
* The last known width of the frame. Reading this property will not trigger
* a reflow, and therefore may not reflect the current state of things. It
* should only be used in asynchronous APIs where values are not guaranteed
* to be up-to-date when received.
*/
[Pure]
readonly attribute unsigned long lazyWidth;
/**
* The last known height of the frame. Reading this property will not trigger
* a reflow, and therefore may not reflect the current state of things. It
* should only be used in asynchronous APIs where values are not guaranteed
* to be up-to-date when received.
*/
[Pure]
readonly attribute unsigned long lazyHeight;
/**
* Is `true` if the frameloader is dead (destroy has been called on it)
*/
[Pure]
readonly attribute boolean isDead;
};
/**
* Interface for objects which represent a document that can be
* serialized with nsIWebBrowserPersist. This interface is
* asynchronous because the actual document can be in another process
* (e.g., if this object is a FrameLoader for an out-of-process
* frame).
*
* @see nsIWebBrowserPersistDocumentReceiver
* @see nsIWebBrowserPersistDocument
* @see nsIWebBrowserPersist
*
* @param aContext
* The browsing context of the subframe we'd like to persist.
* If set to nullptr, WebBrowserPersistable will attempt to persist
* the top-level document. If the browsing context is for a subframe
* that is not held beneath the WebBrowserPersistable, aRecv's onError
* method will be called with NS_ERROR_NO_CONTENT.
* @param aRecv
* The nsIWebBrowserPersistDocumentReceiver is a callback that
* will be fired once the document is ready for persisting.
*/
interface mixin WebBrowserPersistable
{
[Throws]
void startPersistence(BrowsingContext? aContext,
nsIWebBrowserPersistDocumentReceiver aRecv);
};
FrameLoader includes WebBrowserPersistable;

View File

@ -45,7 +45,6 @@ WEBIDL_FILES = [
'DOMLocalization.webidl',
'Flex.webidl',
'Fluent.webidl',
'FrameLoader.webidl',
'HeapSnapshot.webidl',
'InspectorUtils.webidl',
'IteratorResult.webidl',

View File

@ -3896,12 +3896,12 @@ bool BrowserParent::AsyncPanZoomEnabled() const {
}
void BrowserParent::StartPersistence(
CanonicalBrowsingContext* aContext,
nsIWebBrowserPersistDocumentReceiver* aRecv, ErrorResult& aRv) {
uint64_t aOuterWindowID, nsIWebBrowserPersistDocumentReceiver* aRecv,
ErrorResult& aRv) {
auto* actor = new WebBrowserPersistDocumentParent();
actor->SetOnReady(aRecv);
bool ok = Manager()->SendPWebBrowserPersistDocumentConstructor(actor, this,
aContext);
bool ok = Manager()->SendPWebBrowserPersistDocumentConstructor(
actor, this, aOuterWindowID);
if (!ok) {
aRv.Throw(NS_ERROR_FAILURE);
}

View File

@ -612,7 +612,7 @@ class BrowserParent final : public PBrowserParent,
bool GetGlobalJSObject(JSContext* cx, JSObject** globalp);
void StartPersistence(CanonicalBrowsingContext* aContext,
void StartPersistence(uint64_t aOuterWindowID,
nsIWebBrowserPersistDocumentReceiver* aRecv,
ErrorResult& aRv);

View File

@ -2949,24 +2949,26 @@ bool ContentChild::DeallocPContentPermissionRequestChild(
PWebBrowserPersistDocumentChild*
ContentChild::AllocPWebBrowserPersistDocumentChild(
PBrowserChild* aBrowser, const MaybeDiscarded<BrowsingContext>& aContext) {
PBrowserChild* aBrowser, const uint64_t& aOuterWindowID) {
return new WebBrowserPersistDocumentChild();
}
mozilla::ipc::IPCResult ContentChild::RecvPWebBrowserPersistDocumentConstructor(
PWebBrowserPersistDocumentChild* aActor, PBrowserChild* aBrowser,
const MaybeDiscarded<BrowsingContext>& aContext) {
const uint64_t& aOuterWindowID) {
if (NS_WARN_IF(!aBrowser)) {
return IPC_FAIL_NO_REASON(this);
}
if (aContext.IsNullOrDiscarded()) {
aActor->SendInitFailure(NS_ERROR_NO_CONTENT);
return IPC_OK();
nsCOMPtr<Document> rootDoc =
static_cast<BrowserChild*>(aBrowser)->GetTopLevelDocument();
nsCOMPtr<Document> foundDoc;
if (aOuterWindowID) {
foundDoc = nsContentUtils::GetSubdocumentWithOuterWindowId(rootDoc,
aOuterWindowID);
} else {
foundDoc = rootDoc;
}
nsCOMPtr<Document> foundDoc = aContext.get()->GetDocument();
if (!foundDoc) {
aActor->SendInitFailure(NS_ERROR_NO_CONTENT);
} else {

View File

@ -216,11 +216,11 @@ class ContentChild final
const FileDescriptor& aGCLog, const FileDescriptor& aCCLog) override;
PWebBrowserPersistDocumentChild* AllocPWebBrowserPersistDocumentChild(
PBrowserChild* aBrowser, const MaybeDiscarded<BrowsingContext>& aContext);
PBrowserChild* aBrowser, const uint64_t& aOuterWindowID);
virtual mozilla::ipc::IPCResult RecvPWebBrowserPersistDocumentConstructor(
PWebBrowserPersistDocumentChild* aActor, PBrowserChild* aBrowser,
const MaybeDiscarded<BrowsingContext>& aContext) override;
const uint64_t& aOuterWindowID) override;
bool DeallocPWebBrowserPersistDocumentChild(
PWebBrowserPersistDocumentChild* aActor);

View File

@ -4544,7 +4544,7 @@ bool ContentParent::DeallocPContentPermissionRequestParent(
PWebBrowserPersistDocumentParent*
ContentParent::AllocPWebBrowserPersistDocumentParent(
PBrowserParent* aBrowser, const MaybeDiscarded<BrowsingContext>& aContext) {
PBrowserParent* aBrowser, const uint64_t& aOuterWindowID) {
return new WebBrowserPersistDocumentParent();
}

View File

@ -972,8 +972,7 @@ class ContentParent final
#endif
PWebBrowserPersistDocumentParent* AllocPWebBrowserPersistDocumentParent(
PBrowserParent* aBrowser,
const MaybeDiscarded<BrowsingContext>& aContext);
PBrowserParent* aBrowser, const uint64_t& aOuterWindowID);
bool DeallocPWebBrowserPersistDocumentParent(
PWebBrowserPersistDocumentParent* aActor);

View File

@ -429,12 +429,12 @@ child:
both:
async PFileDescriptorSet(FileDescriptor fd);
// For parent->child, aBrowser must be non-null; aContext can
// be null to indicate the browser's current root document, or non-null
// For parent->child, aBrowser must be non-null; aOuterWindowID can
// be 0 to indicate the browser's current root document, or nonzero
// to persist a subdocument. For child->parent, arguments are
// ignored and should be null.
// ignored and should be null/zero.
async PWebBrowserPersistDocument(nullable PBrowser aBrowser,
MaybeDiscardedBrowsingContext aContext);
uint64_t aOuterWindowID);
child:
async InitGMPService(Endpoint<PGMPServiceChild> service);

View File

@ -10,7 +10,6 @@ support-files =
worker_bug1004814.js
geo_leak_test.html
dummy.html
dummy.png
test_largeAllocation.html
test_largeAllocation.html^headers^
test_largeAllocation2.html
@ -72,10 +71,12 @@ skip-if =
support-files =
set-samesite-cookies-and-redirect.sjs
mimeme.sjs
skip-if = fission
[browser_persist_image_accept.js]
[browser_persist_mixed_content_image.js]
support-files =
test_mixed_content_image.html
dummy.png
[browser_pointerlock_warning.js]
[browser_test_focus_after_modal_state.js]
skip-if = verify
@ -108,6 +109,3 @@ skip-if = webrender
support-files =
file_postMessage_parent.html
[browser_navigate_replace_browsingcontext.js]
[browser_persist_cross_origin_iframe.js]
support-files =
image.html

View File

@ -98,7 +98,7 @@ add_task(async function() {
info("done showCallback");
};
saveBrowser(browser);
await new Promise(async (resolve, reject) => {
await new Promise(async resolve => {
let dls = await Downloads.getList(Downloads.PUBLIC);
dls.addView({
onDownloadChanged(download) {
@ -106,8 +106,6 @@ add_task(async function() {
dls.removeView(this);
dls.removeFinished();
resolve();
} else if (download.error) {
reject("Download failed");
}
},
});

View File

@ -1,193 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
const TEST_PATH = getRootDirectory(gTestPath).replace(
"chrome://mochitests/content",
"https://example.org"
);
const TEST_PATH2 = getRootDirectory(gTestPath).replace(
"chrome://mochitests/content",
"https://example.com"
);
var MockFilePicker = SpecialPowers.MockFilePicker;
MockFilePicker.init(window);
registerCleanupFunction(async function() {
info("Running the cleanup code");
MockFilePicker.cleanup();
if (gTestDir && gTestDir.exists()) {
// On Windows, sometimes nsIFile.remove() throws, probably because we're
// still writing to the directory we're trying to remove, despite
// waiting for the download to complete. Just retry a bit later...
let succeeded = false;
while (!succeeded) {
try {
gTestDir.remove(true);
succeeded = true;
} catch (ex) {
await new Promise(requestAnimationFrame);
}
}
}
});
let gTestDir = null;
function createTemporarySaveDirectory() {
var saveDir = Services.dirsvc.get("TmpD", Ci.nsIFile);
saveDir.append("testsavedir");
if (!saveDir.exists()) {
saveDir.create(Ci.nsIFile.DIRECTORY_TYPE, 0o755);
}
return saveDir;
}
function checkContents(dir, expected, str) {
let stack = [dir];
let files = [];
while (stack.length) {
for (let file of stack.pop().directoryEntries) {
if (file.isDirectory()) {
stack.push(file);
}
files.push(file.path);
}
}
SimpleTest.isDeeply(
files.sort(),
expected.sort(),
str + "Should contain downloaded files in correct place."
);
}
async function addFrame(browser, path, selector) {
await SpecialPowers.spawn(browser, [path, selector], async function(
path,
selector
) {
let document = content.document;
let target = document.querySelector(selector);
if (target instanceof content.HTMLIFrameElement) {
document = target.contentDocument;
target = document.body;
}
let element = document.createElement("iframe");
element.src = path;
await new Promise(resolve => {
element.onload = resolve;
target.appendChild(element);
});
});
}
async function handleResult(expected, str) {
let dls = await Downloads.getList(Downloads.PUBLIC);
return new Promise((resolve, reject) => {
dls.addView({
onDownloadChanged(download) {
if (download.succeeded) {
checkContents(gTestDir, expected, str);
dls.removeView(this);
dls.removeFinished();
resolve();
} else if (download.error) {
reject("Download failed");
}
},
});
});
}
add_task(async function() {
await BrowserTestUtils.withNewTab(TEST_PATH + "image.html", async function(
browser
) {
await addFrame(browser, TEST_PATH + "image.html", "body");
await addFrame(browser, TEST_PATH2 + "image.html", "body>iframe");
gTestDir = createTemporarySaveDirectory();
MockFilePicker.displayDirectory = gTestDir;
MockFilePicker.showCallback = function(fp) {
let destFile = gTestDir.clone();
destFile.append("first.html");
MockFilePicker.setFiles([destFile]);
MockFilePicker.filterIndex = 0; // kSaveAsType_Complete
};
let expected = [
"/tmp/testsavedir/first.html",
"/tmp/testsavedir/first_files",
"/tmp/testsavedir/first_files/image.html",
"/tmp/testsavedir/first_files/dummy.png",
"/tmp/testsavedir/first_files/image_data",
"/tmp/testsavedir/first_files/image_data/image.html",
"/tmp/testsavedir/first_files/image_data/image_data",
"/tmp/testsavedir/first_files/image_data/image_data/dummy.png",
];
// This saves the top-level document contained in `browser`
saveBrowser(browser);
await handleResult(expected, "Check toplevel: ");
// Instead of deleting previously saved files, we update our list
// of expected files for the next part of the test. To not clash
// we make sure to save to a different file name.
expected = expected.concat([
"/tmp/testsavedir/second.html",
"/tmp/testsavedir/second_files",
"/tmp/testsavedir/second_files/dummy.png",
"/tmp/testsavedir/second_files/image.html",
"/tmp/testsavedir/second_files/image_data",
"/tmp/testsavedir/second_files/image_data/dummy.png",
]);
MockFilePicker.displayDirectory = gTestDir;
MockFilePicker.showCallback = function(fp) {
let destFile = gTestDir.clone();
destFile.append("second.html");
MockFilePicker.setFiles([destFile]);
MockFilePicker.filterIndex = 0; // kSaveAsType_Complete
};
// This saves the sub-document of the iframe contained in the
// top-level document, as indicated by passing a child browsing
// context as target for the save.
saveBrowser(browser, false, browser.browsingContext.children[0]);
await handleResult(expected, "Check subframe: ");
// Instead of deleting previously saved files, we update our list
// of expected files for the next part of the test. To not clash
// we make sure to save to a different file name.
expected = expected.concat([
"/tmp/testsavedir/third.html",
"/tmp/testsavedir/third_files",
"/tmp/testsavedir/third_files/dummy.png",
]);
MockFilePicker.displayDirectory = gTestDir;
MockFilePicker.showCallback = function(fp) {
let destFile = gTestDir.clone();
destFile.append("third.html");
MockFilePicker.setFiles([destFile]);
MockFilePicker.filterIndex = 0; // kSaveAsType_Complete
};
// This saves the sub-document of the iframe contained in the
// first sub-document, as indicated by passing a child browsing
// context as target for the save. That frame is special, because
// it's cross-process.
saveBrowser(
browser,
false,
browser.browsingContext.children[0].children[0]
);
await handleResult(expected, "Check subframe: ");
});
});

View File

@ -1,2 +0,0 @@
<!doctype html>
<img src="dummy.png"></img>

View File

@ -5,8 +5,6 @@
include protocol PWebBrowserPersistDocument;
using mozilla::dom::MaybeDiscardedBrowsingContext from "mozilla/dom/BrowsingContext.h";
namespace mozilla {
// == nsIWebBrowserPersistResourceVisitor
@ -21,8 +19,6 @@ parent:
// before exposing it with a visitDocument call.
async VisitDocument(PWebBrowserPersistDocument aSubDocument);
async VisitBrowsingContext(MaybeDiscardedBrowsingContext aContext);
// This reflects the endVisit method.
async __delete__(nsresult aStatus);
};

View File

@ -7,7 +7,6 @@
#include "WebBrowserPersistDocumentParent.h"
#include "mozilla/dom/Attr.h"
#include "mozilla/dom/BrowsingContext.h"
#include "mozilla/dom/Comment.h"
#include "mozilla/dom/Element.h"
#include "mozilla/dom/HTMLAnchorElement.h"
@ -288,17 +287,12 @@ nsresult ResourceReader::OnWalkSubframe(nsINode* aNode) {
RefPtr<nsFrameLoader> loader = loaderOwner->GetFrameLoader();
NS_ENSURE_STATE(loader);
RefPtr<dom::BrowsingContext> context = loader->GetBrowsingContext();
NS_ENSURE_STATE(context);
if (loader->IsRemoteFrame()) {
mVisitor->VisitBrowsingContext(mParent, context);
return NS_OK;
}
++mOutstandingDocuments;
// Pass in 0 as the outer window ID so that we start
// persisting the root of this subframe, and not some other
// subframe child of this subframe.
ErrorResult err;
loader->StartPersistence(context, this, err);
loader->StartPersistence(0, this, err);
nsresult rv = err.StealNSResult();
if (NS_FAILED(rv)) {
if (rv == NS_ERROR_NO_CONTENT) {

View File

@ -38,7 +38,7 @@ WebBrowserPersistResourcesChild::VisitDocument(
// persistence started does not necessarily exist at this point;
// see bug 1203602.
if (!Manager()->Manager()->SendPWebBrowserPersistDocumentConstructor(
subActor, nullptr, nullptr)) {
subActor, nullptr, 0)) {
// NOTE: subActor is freed at this point.
return NS_ERROR_FAILURE;
}
@ -57,14 +57,6 @@ WebBrowserPersistResourcesChild::VisitDocument(
return NS_OK;
}
NS_IMETHODIMP
WebBrowserPersistResourcesChild::VisitBrowsingContext(
nsIWebBrowserPersistDocument* aDocument,
dom::BrowsingContext* aBrowsingContext) {
SendVisitBrowsingContext(aBrowsingContext);
return NS_OK;
}
NS_IMETHODIMP
WebBrowserPersistResourcesChild::EndVisit(
nsIWebBrowserPersistDocument* aDocument, nsresult aStatus) {

View File

@ -8,11 +8,6 @@
#include "nsThreadUtils.h"
#include "mozilla/dom/BrowserParent.h"
#include "mozilla/dom/CanonicalBrowsingContext.h"
#include "mozilla/dom/ContentParent.h"
#include "mozilla/dom/WindowGlobalParent.h"
namespace mozilla {
NS_IMPL_ISUPPORTS(WebBrowserPersistResourcesParent,
@ -63,18 +58,6 @@ mozilla::ipc::IPCResult WebBrowserPersistResourcesParent::RecvVisitDocument(
return IPC_OK();
}
mozilla::ipc::IPCResult
WebBrowserPersistResourcesParent::RecvVisitBrowsingContext(
const dom::MaybeDiscarded<dom::BrowsingContext>& aContext) {
if (aContext.IsNullOrDiscarded()) {
// Nothing useful to do but ignore the discarded context.
return IPC_OK();
}
mVisitor->VisitBrowsingContext(mDocument, aContext.get());
return IPC_OK();
}
NS_IMETHODIMP
WebBrowserPersistResourcesParent::OnDocumentReady(
nsIWebBrowserPersistDocument* aSubDocument) {

View File

@ -30,9 +30,6 @@ class WebBrowserPersistResourcesParent final
virtual mozilla::ipc::IPCResult RecvVisitDocument(
PWebBrowserPersistDocumentParent* aSubDocument) override;
virtual mozilla::ipc::IPCResult RecvVisitBrowsingContext(
const dom::MaybeDiscarded<dom::BrowsingContext>& aContext) override;
virtual mozilla::ipc::IPCResult Recv__delete__(
const nsresult& aStatus) override;

View File

@ -16,8 +16,6 @@ interface nsIWebBrowserPersistWriteCompletion;
interface nsIReferrerInfo;
interface nsISHEntry;
webidl BrowsingContext;
native SHEntryRef(already_AddRefed<nsISHEntry>);
/**
@ -149,7 +147,6 @@ interface nsIWebBrowserPersistResourceVisitor : nsISupports
void visitResource(in nsIWebBrowserPersistDocument aDocument,
in AUTF8String aURI,
in nsContentPolicyType aContentPolicyType);
/**
* Indicates a subdocument resource; e.g., a frame or iframe.
*
@ -159,16 +156,6 @@ interface nsIWebBrowserPersistResourceVisitor : nsISupports
void visitDocument(in nsIWebBrowserPersistDocument aDocument,
in nsIWebBrowserPersistDocument aSubDocument);
/**
* Indicates a cross origin subdocument resource; e.g., a frame
* or iframe loaded in another process.
*
* @param aDocument The document containing the reference.
* @param aContext The referenced document's browsing context.
*/
void visitBrowsingContext(in nsIWebBrowserPersistDocument aDocument,
in BrowsingContext aContext);
/**
* Indicates that the document traversal is complete.
*

View File

@ -139,11 +139,7 @@ class nsWebBrowserPersist::OnWalk final
: public nsIWebBrowserPersistResourceVisitor {
public:
OnWalk(nsWebBrowserPersist* aParent, nsIURI* aFile, nsIFile* aDataPath)
: mParent(aParent),
mFile(aFile),
mDataPath(aDataPath),
mPendingDocuments(1),
mStatus(NS_OK) {}
: mParent(aParent), mFile(aFile), mDataPath(aDataPath) {}
NS_DECL_NSIWEBBROWSERPERSISTRESOURCEVISITOR
NS_DECL_ISUPPORTS
@ -152,34 +148,12 @@ class nsWebBrowserPersist::OnWalk final
nsCOMPtr<nsIURI> mFile;
nsCOMPtr<nsIFile> mDataPath;
uint32_t mPendingDocuments;
nsresult mStatus;
virtual ~OnWalk() = default;
};
NS_IMPL_ISUPPORTS(nsWebBrowserPersist::OnWalk,
nsIWebBrowserPersistResourceVisitor)
class nsWebBrowserPersist::OnRemoteWalk final
: public nsIWebBrowserPersistDocumentReceiver {
public:
OnRemoteWalk(nsIWebBrowserPersistResourceVisitor* aVisitor,
nsIWebBrowserPersistDocument* aDocument)
: mVisitor(aVisitor), mDocument(aDocument) {}
NS_DECL_NSIWEBBROWSERPERSISTDOCUMENTRECEIVER
NS_DECL_ISUPPORTS
private:
nsCOMPtr<nsIWebBrowserPersistResourceVisitor> mVisitor;
nsCOMPtr<nsIWebBrowserPersistDocument> mDocument;
virtual ~OnRemoteWalk() = default;
};
NS_IMPL_ISUPPORTS(nsWebBrowserPersist::OnRemoteWalk,
nsIWebBrowserPersistDocumentReceiver)
class nsWebBrowserPersist::OnWrite final
: public nsIWebBrowserPersistWriteCompletion {
public:
@ -1594,73 +1568,18 @@ nsWebBrowserPersist::OnWalk::VisitDocument(
return mParent->SaveSubframeContent(aSubDoc, aDoc, uriSpec, data);
}
NS_IMETHODIMP
nsWebBrowserPersist::OnWalk::VisitBrowsingContext(
nsIWebBrowserPersistDocument* aDoc, BrowsingContext* aContext) {
RefPtr<dom::CanonicalBrowsingContext> context = aContext->Canonical();
UniquePtr<WebBrowserPersistDocumentParent> actor(
new WebBrowserPersistDocumentParent());
nsCOMPtr<nsIWebBrowserPersistDocumentReceiver> receiver =
new OnRemoteWalk(this, aDoc);
actor->SetOnReady(receiver);
RefPtr<dom::BrowserParent> browserParent =
context->GetCurrentWindowGlobal()->GetBrowserParent();
bool ok =
context->GetContentParent()->SendPWebBrowserPersistDocumentConstructor(
actor.release(), browserParent, context);
if (NS_WARN_IF(!ok)) {
// (The actor will be destroyed on constructor failure.)
EndVisit(nullptr, NS_ERROR_FAILURE);
return NS_ERROR_FAILURE;
}
++mPendingDocuments;
return NS_OK;
}
NS_IMETHODIMP
nsWebBrowserPersist::OnWalk::EndVisit(nsIWebBrowserPersistDocument* aDoc,
nsresult aStatus) {
if (NS_FAILED(mStatus)) {
return mStatus;
}
if (NS_FAILED(aStatus)) {
mStatus = aStatus;
mParent->SendErrorStatusChange(true, aStatus, nullptr, mFile);
mParent->EndDownload(aStatus);
return aStatus;
}
if (--mPendingDocuments) {
// We're not done yet, wait for more.
return NS_OK;
}
mParent->FinishSaveDocumentInternal(mFile, mDataPath);
return NS_OK;
}
NS_IMETHODIMP
nsWebBrowserPersist::OnRemoteWalk::OnDocumentReady(
nsIWebBrowserPersistDocument* aSubDocument) {
mVisitor->VisitDocument(mDocument, aSubDocument);
mVisitor->EndVisit(mDocument, NS_OK);
return NS_OK;
}
NS_IMETHODIMP
nsWebBrowserPersist::OnRemoteWalk::OnError(nsresult aFailure) {
mVisitor->EndVisit(nullptr, aFailure);
return NS_OK;
}
void nsWebBrowserPersist::FinishSaveDocumentInternal(nsIURI* aFile,
nsIFile* aDataPath) {
// If there are things to persist, create a directory to hold them

View File

@ -74,7 +74,6 @@ class nsWebBrowserPersist final : public nsIInterfaceRequestor,
struct WalkData;
class OnWalk;
class OnRemoteWalk;
class OnWrite;
class FlatURIMap;
friend class OnWalk;

View File

@ -540,6 +540,7 @@ WEBIDL_FILES = [
'FontFaceSet.webidl',
'FontFaceSource.webidl',
'FormData.webidl',
'FrameLoader.webidl',
'Function.webidl',
'GainNode.webidl',
'Gamepad.webidl',

View File

@ -13,7 +13,7 @@ function one_test(delay, continuation) {
BrowserTestUtils.openNewForegroundTab(gBrowser, testPageURL).then(tab => {
browser = tab.linkedBrowser;
let persistable = browser.frameLoader;
persistable.startPersistence(null, {
persistable.startPersistence(/* outer window ID: */ 0, {
onDocumentReady,
onError(status) {
ok(false, new Components.Exception("startPersistence failed", status));

View File

@ -22,7 +22,7 @@ add_task(async function checkFormStateSaved() {
await SpecialPowers.spawn(browser, [{ textareas, textboxes }], fillform);
let fileURISpec = await new Promise((resolve, reject) => {
let stack = Components.stack.caller;
browser.frameLoader.startPersistence(null, {
browser.frameLoader.startPersistence(0, {
onDocumentReady(document) {
// Note that 'document' here is going to be an nsIWebBrowserPersistDocument,
// not a regular DOM document.

View File

@ -84,7 +84,7 @@ function saveURL(
// Save the current document inside any browser/frame-like element,
// whether in-process or out-of-process.
function saveBrowser(aBrowser, aSkipPrompt, aBrowsingContext = null) {
function saveBrowser(aBrowser, aSkipPrompt, aOuterWindowID = 0) {
if (!aBrowser) {
throw new Error("Must have a browser when calling saveBrowser");
}
@ -119,7 +119,7 @@ function saveBrowser(aBrowser, aSkipPrompt, aBrowsingContext = null) {
return;
}
let stack = Components.stack.caller;
persistable.startPersistence(aBrowsingContext, {
persistable.startPersistence(aOuterWindowID, {
onDocumentReady(document) {
if (!document || !(document instanceof Ci.nsIWebBrowserPersistDocument)) {
throw new Error("Must have an nsIWebBrowserPersistDocument!");