mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1141337 - Update nsIWebBrowserPersistable to allow subframe targeting for Save Frame As. r=jld
This alters nsIWebBrowserPersistable so that startPersistence takes an outerWindowID. This allows us to target a particular subframe from beneath an nsFrameLoader, which is useful when attempting to Save Frame As a remote browser.
This commit is contained in:
parent
6e7ec6c889
commit
cfd5c1fa5a
@ -1186,7 +1186,7 @@ nsContextMenu.prototype = {
|
||||
|
||||
// Save URL of clicked-on frame.
|
||||
saveFrame: function () {
|
||||
saveDocument(this.target.ownerDocument);
|
||||
saveBrowser(this.browser, false, this.frameOuterWindowID);
|
||||
},
|
||||
|
||||
// Helper function to wait for appropriate MIME-type headers and
|
||||
|
@ -3849,6 +3849,30 @@ nsContentUtils::MatchElementId(nsIContent *aContent, const nsAString& aId)
|
||||
return MatchElementId(aContent, id);
|
||||
}
|
||||
|
||||
/* static */
|
||||
nsIDocument*
|
||||
nsContentUtils::GetSubdocumentWithOuterWindowId(nsIDocument *aDocument,
|
||||
uint64_t aOuterWindowId)
|
||||
{
|
||||
if (!aDocument || !aOuterWindowId) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsPIDOMWindow> window = nsGlobalWindow::GetOuterWindowWithId(aOuterWindowId);
|
||||
if (!window) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocument> foundDoc = window->GetDoc();
|
||||
if (nsContentUtils::ContentIsCrossDocDescendantOf(foundDoc, aDocument)) {
|
||||
// Note that ContentIsCrossDocDescendantOf will return true if
|
||||
// foundDoc == aDocument.
|
||||
return foundDoc;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Convert the string from the given encoding to Unicode.
|
||||
/* static */
|
||||
nsresult
|
||||
|
@ -325,6 +325,23 @@ public:
|
||||
*/
|
||||
static uint16_t ReverseDocumentPosition(uint16_t aDocumentPosition);
|
||||
|
||||
/**
|
||||
* Returns a subdocument for aDocument with a particular outer window ID.
|
||||
*
|
||||
* @param aDocument
|
||||
* The document whose subdocuments will be searched.
|
||||
* @param aOuterWindowID
|
||||
* The outer window ID for the subdocument to be found. This must
|
||||
* be a value greater than 0.
|
||||
* @return nsIDocument*
|
||||
* A pointer to the found nsIDocument. nullptr if the subdocument
|
||||
* cannot be found, or if either aDocument or aOuterWindowId were
|
||||
* invalid. If the outer window ID belongs to aDocument itself, this
|
||||
* will return a pointer to aDocument.
|
||||
*/
|
||||
static nsIDocument* GetSubdocumentWithOuterWindowId(nsIDocument *aDocument,
|
||||
uint64_t aOuterWindowId);
|
||||
|
||||
static uint32_t CopyNewlineNormalizedUnicodeTo(const nsAString& aSource,
|
||||
uint32_t aSrcOffset,
|
||||
char16_t* aDest,
|
||||
|
@ -2885,18 +2885,31 @@ nsFrameLoader::InitializeBrowserAPI()
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFrameLoader::StartPersistence(nsIWebBrowserPersistDocumentReceiver* aRecv)
|
||||
nsFrameLoader::StartPersistence(uint64_t aOuterWindowID,
|
||||
nsIWebBrowserPersistDocumentReceiver* aRecv)
|
||||
{
|
||||
if (!aRecv) {
|
||||
return NS_ERROR_INVALID_POINTER;
|
||||
}
|
||||
|
||||
if (mRemoteBrowser) {
|
||||
return mRemoteBrowser->StartPersistence(aRecv);
|
||||
return mRemoteBrowser->StartPersistence(aOuterWindowID, aRecv);
|
||||
}
|
||||
if (mDocShell) {
|
||||
nsCOMPtr<nsIDocument> doc = do_GetInterface(mDocShell);
|
||||
NS_ENSURE_STATE(doc);
|
||||
|
||||
nsCOMPtr<nsIDocument> rootDoc = do_GetInterface(mDocShell);
|
||||
nsCOMPtr<nsIDocument> foundDoc;
|
||||
if (aOuterWindowID) {
|
||||
foundDoc = nsContentUtils::GetSubdocumentWithOuterWindowId(rootDoc, aOuterWindowID);
|
||||
} else {
|
||||
foundDoc = rootDoc;
|
||||
}
|
||||
|
||||
if (!foundDoc) {
|
||||
aRecv->OnError(NS_ERROR_NO_CONTENT);
|
||||
} else {
|
||||
nsCOMPtr<nsIWebBrowserPersistDocument> pdoc =
|
||||
new mozilla::WebBrowserPersistLocalDocument(doc);
|
||||
new mozilla::WebBrowserPersistLocalDocument(foundDoc);
|
||||
aRecv->OnDocumentReady(pdoc);
|
||||
return NS_OK;
|
||||
}
|
||||
return NS_ERROR_NO_CONTENT;
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -121,7 +121,7 @@ both:
|
||||
*/
|
||||
PRenderFrame();
|
||||
|
||||
PWebBrowserPersistDocument();
|
||||
PWebBrowserPersistDocument(uint64_t aOuterWindowID);
|
||||
|
||||
parent:
|
||||
/**
|
||||
@ -524,6 +524,7 @@ parent:
|
||||
child:
|
||||
NativeSynthesisResponse(uint64_t aObserverId, nsCString aResponse);
|
||||
|
||||
|
||||
parent:
|
||||
|
||||
/**
|
||||
|
@ -3118,16 +3118,28 @@ TabChildGlobal::GetGlobalJSObject()
|
||||
}
|
||||
|
||||
PWebBrowserPersistDocumentChild*
|
||||
TabChild::AllocPWebBrowserPersistDocumentChild()
|
||||
TabChild::AllocPWebBrowserPersistDocumentChild(const uint64_t& aOuterWindowID)
|
||||
{
|
||||
return new WebBrowserPersistDocumentChild();
|
||||
}
|
||||
|
||||
bool
|
||||
TabChild::RecvPWebBrowserPersistDocumentConstructor(PWebBrowserPersistDocumentChild *aActor)
|
||||
TabChild::RecvPWebBrowserPersistDocumentConstructor(PWebBrowserPersistDocumentChild *aActor,
|
||||
const uint64_t& aOuterWindowID)
|
||||
{
|
||||
nsCOMPtr<nsIDocument> doc = GetDocument();
|
||||
static_cast<WebBrowserPersistDocumentChild*>(aActor)->Start(doc);
|
||||
nsCOMPtr<nsIDocument> rootDoc = GetDocument();
|
||||
nsCOMPtr<nsIDocument> foundDoc;
|
||||
if (aOuterWindowID) {
|
||||
foundDoc = nsContentUtils::GetSubdocumentWithOuterWindowId(rootDoc, aOuterWindowID);
|
||||
} else {
|
||||
foundDoc = rootDoc;
|
||||
}
|
||||
|
||||
if (!foundDoc) {
|
||||
aActor->SendInitFailure(NS_ERROR_NO_CONTENT);
|
||||
} else {
|
||||
static_cast<WebBrowserPersistDocumentChild*>(aActor)->Start(foundDoc);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -495,8 +495,9 @@ public:
|
||||
|
||||
virtual ScreenIntSize GetInnerSize() override;
|
||||
|
||||
virtual PWebBrowserPersistDocumentChild* AllocPWebBrowserPersistDocumentChild() override;
|
||||
virtual bool RecvPWebBrowserPersistDocumentConstructor(PWebBrowserPersistDocumentChild *aActor) override;
|
||||
virtual PWebBrowserPersistDocumentChild* AllocPWebBrowserPersistDocumentChild(const uint64_t& aOuterWindowID) override;
|
||||
virtual bool RecvPWebBrowserPersistDocumentConstructor(PWebBrowserPersistDocumentChild *aActor,
|
||||
const uint64_t& aOuterWindowID) override;
|
||||
virtual bool DeallocPWebBrowserPersistDocumentChild(PWebBrowserPersistDocumentChild* aActor) override;
|
||||
|
||||
protected:
|
||||
|
@ -3368,7 +3368,7 @@ TabParent::AsyncPanZoomEnabled() const
|
||||
}
|
||||
|
||||
PWebBrowserPersistDocumentParent*
|
||||
TabParent::AllocPWebBrowserPersistDocumentParent()
|
||||
TabParent::AllocPWebBrowserPersistDocumentParent(const uint64_t& aOuterWindowID)
|
||||
{
|
||||
return new WebBrowserPersistDocumentParent();
|
||||
}
|
||||
@ -3381,11 +3381,12 @@ TabParent::DeallocPWebBrowserPersistDocumentParent(PWebBrowserPersistDocumentPar
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
TabParent::StartPersistence(nsIWebBrowserPersistDocumentReceiver* aRecv)
|
||||
TabParent::StartPersistence(uint64_t aOuterWindowID,
|
||||
nsIWebBrowserPersistDocumentReceiver* aRecv)
|
||||
{
|
||||
auto* actor = new WebBrowserPersistDocumentParent();
|
||||
actor->SetOnReady(aRecv);
|
||||
return SendPWebBrowserPersistDocumentConstructor(actor)
|
||||
return SendPWebBrowserPersistDocumentConstructor(actor, aOuterWindowID)
|
||||
? NS_OK : NS_ERROR_FAILURE;
|
||||
// (The actor will be destroyed on constructor failure.)
|
||||
}
|
||||
|
@ -435,7 +435,7 @@ public:
|
||||
int32_t& aDragAreaX, int32_t& aDragAreaY);
|
||||
layout::RenderFrameParent* GetRenderFrame();
|
||||
|
||||
virtual PWebBrowserPersistDocumentParent* AllocPWebBrowserPersistDocumentParent() override;
|
||||
virtual PWebBrowserPersistDocumentParent* AllocPWebBrowserPersistDocumentParent(const uint64_t& aOuterWindowID) override;
|
||||
virtual bool DeallocPWebBrowserPersistDocumentParent(PWebBrowserPersistDocumentParent* aActor) override;
|
||||
|
||||
protected:
|
||||
|
@ -346,7 +346,10 @@ ResourceReader::OnWalkSubframe(nsIDOMNode* aNode)
|
||||
NS_ENSURE_STATE(loader);
|
||||
|
||||
++mOutstandingDocuments;
|
||||
nsresult rv = loader->StartPersistence(this);
|
||||
// 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.
|
||||
nsresult rv = loader->StartPersistence(0, this);
|
||||
if (NS_FAILED(rv)) {
|
||||
if (rv == NS_ERROR_NO_CONTENT) {
|
||||
// Just ignore frames with no content document.
|
||||
|
@ -37,7 +37,11 @@ WebBrowserPersistResourcesChild::VisitDocument(nsIWebBrowserPersistDocument* aDo
|
||||
{
|
||||
auto* subActor = new WebBrowserPersistDocumentChild();
|
||||
dom::PBrowserChild* grandManager = Manager()->Manager();
|
||||
if (!grandManager->SendPWebBrowserPersistDocumentConstructor(subActor)) {
|
||||
// As a consequence of how PWebBrowserPersistDocumentConstructor can be
|
||||
// sent by both the parent and the child, we must pass the outerWindowID
|
||||
// argument here. We pass 0, though note that this argument is actually
|
||||
// just ignored when passed up to the parent from the child.
|
||||
if (!grandManager->SendPWebBrowserPersistDocumentConstructor(subActor, 0)) {
|
||||
// NOTE: subActor is freed at this point.
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
@ -22,9 +22,20 @@ interface nsIWebBrowserPersistDocumentReceiver;
|
||||
* @see nsIWebBrowserPersistDocumentReceiver
|
||||
* @see nsIWebBrowserPersistDocument
|
||||
* @see nsIWebBrowserPersist
|
||||
*
|
||||
* @param aOuterWindowID
|
||||
* The outer window ID of the subframe we'd like to persist.
|
||||
* If set at 0, nsIWebBrowserPersistable will attempt to persist
|
||||
* the top-level document. If the outer window ID is for a subframe
|
||||
* that does not exist, or is not held beneath the nsIWebBrowserPersistable,
|
||||
* 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.
|
||||
*/
|
||||
[scriptable, function, uuid(24d0dc9e-b970-4cca-898f-cbba03abaa73)]
|
||||
[scriptable, uuid(f4c3fa8e-83e9-49f8-ac6f-951fc7541fe4)]
|
||||
interface nsIWebBrowserPersistable : nsISupports
|
||||
{
|
||||
void startPersistence(in nsIWebBrowserPersistDocumentReceiver aRecv);
|
||||
void startPersistence(in unsigned long long aOuterWindowID,
|
||||
in nsIWebBrowserPersistDocumentReceiver aRecv);
|
||||
};
|
||||
|
@ -129,7 +129,7 @@ function saveImageURL(aURL, aFileName, aFilePickerTitleKey, aShouldBypassCache,
|
||||
// This is like saveDocument, but takes any browser/frame-like element
|
||||
// (nsIFrameLoaderOwner) and saves the current document inside it,
|
||||
// whether in-process or out-of-process.
|
||||
function saveBrowser(aBrowser, aSkipPrompt)
|
||||
function saveBrowser(aBrowser, aSkipPrompt, aOuterWindowID=0)
|
||||
{
|
||||
if (!aBrowser) {
|
||||
throw "Must have a browser when calling saveBrowser";
|
||||
@ -138,7 +138,7 @@ function saveBrowser(aBrowser, aSkipPrompt)
|
||||
.frameLoader
|
||||
.QueryInterface(Ci.nsIWebBrowserPersistable);
|
||||
let stack = Components.stack.caller;
|
||||
persistable.startPersistence({
|
||||
persistable.startPersistence(aOuterWindowID, {
|
||||
onDocumentReady: function (document) {
|
||||
saveDocument(document, aSkipPrompt);
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user