diff --git a/dom/base/nsFrameLoader.cpp b/dom/base/nsFrameLoader.cpp index a0e11a38846a..92c51b76109e 100644 --- a/dom/base/nsFrameLoader.cpp +++ b/dom/base/nsFrameLoader.cpp @@ -80,8 +80,11 @@ #include "mozilla/dom/ChromeMessageSender.h" #include "mozilla/dom/Element.h" #include "mozilla/dom/FrameLoaderBinding.h" +#include "mozilla/gfx/CrossProcessPaint.h" #include "mozilla/jsipc/CrossProcessObjectWrappers.h" #include "mozilla/layout/RenderFrameParent.h" +#include "mozilla/ServoCSSParser.h" +#include "mozilla/ServoStyleSet.h" #include "nsGenericHTMLFrameElement.h" #include "GeckoProfiler.h" @@ -3103,6 +3106,64 @@ nsFrameLoader::Print(uint64_t aOuterWindowID, #endif } +already_AddRefed +nsFrameLoader::DrawSnapshot(double aX, + double aY, + double aW, + double aH, + double aScale, + const nsAString& aBackgroundColor, + mozilla::ErrorResult& aRv) +{ + RefPtr global = GetOwnerContent()->GetOwnerGlobal(); + RefPtr promise = Promise::Create(global, aRv); + if (NS_WARN_IF(aRv.Failed())) { + return nullptr; + } + + RefPtr document = GetOwnerContent()->GetOwnerDocument(); + if (NS_WARN_IF(!document)) { + aRv = NS_ERROR_FAILURE; + return nullptr; + } + nsIPresShell* presShell = document->GetShell(); + if (NS_WARN_IF(!presShell)) { + aRv = NS_ERROR_FAILURE; + return nullptr; + } + + nscolor color; + css::Loader* loader = document->CSSLoader(); + ServoStyleSet* set = presShell->StyleSet(); + if (NS_WARN_IF(!ServoCSSParser::ComputeColor(set, + NS_RGB(0, 0, 0), + aBackgroundColor, + &color, + nullptr, + loader))) { + aRv = NS_ERROR_FAILURE; + return nullptr; + } + + gfx::IntRect rect = gfx::IntRect::RoundOut(gfx::Rect(aX, aY, aW, aH)); + + if (IsRemoteFrame()) { + gfx::CrossProcessPaint::StartRemote(mRemoteBrowser->GetTabId(), + rect, + aScale, + color, + promise); + } else { + gfx::CrossProcessPaint::StartLocal(mDocShell, + rect, + aScale, + color, + promise); + } + + return promise.forget(); +} + already_AddRefed nsFrameLoader::GetTabParent() { diff --git a/dom/base/nsFrameLoader.h b/dom/base/nsFrameLoader.h index f6510bcd923f..e43cebcf811d 100644 --- a/dom/base/nsFrameLoader.h +++ b/dom/base/nsFrameLoader.h @@ -171,6 +171,15 @@ public: nsIWebProgressListener* aProgressListener, mozilla::ErrorResult& aRv); + already_AddRefed + DrawSnapshot(double aX, + double aY, + double aW, + double aH, + double aScale, + const nsAString& aBackgroundColor, + mozilla::ErrorResult& aRv); + void StartPersistence(uint64_t aOuterWindowID, nsIWebBrowserPersistDocumentReceiver* aRecv, mozilla::ErrorResult& aRv); diff --git a/dom/webidl/FrameLoader.webidl b/dom/webidl/FrameLoader.webidl index c8137488504e..9f1b0df7bc52 100644 --- a/dom/webidl/FrameLoader.webidl +++ b/dom/webidl/FrameLoader.webidl @@ -108,6 +108,30 @@ interface FrameLoader { nsIPrintSettings aPrintSettings, optional nsIWebProgressListener? aProgressListener = null); + /** + * Renders a region of the frame into an image bitmap. + * + * @param x + * @param y + * @param w + * @param h Specify the area of the window to render, in CSS + * pixels. This is relative to the current scroll position. + * @param scale The scale to render the window at. Use devicePixelRatio + * to have comparable rendering to the OS. + * @param backgroundColor The background color to use. + * + * This API can only be used in the parent process, as content processes + * cannot access the rendering of out of process iframes. This API works + * with remote and local frames. + */ + [Throws] + Promise drawSnapshot(double x, + double y, + double w, + double h, + double scale, + DOMString backgroundColor); + /** * If false, then the subdocument is not clipped to its CSS viewport, and the * subdocument's viewport scrollbar(s) are not rendered. diff --git a/toolkit/content/widgets/browser.xml b/toolkit/content/widgets/browser.xml index 07ad6604de37..8d80588be021 100644 --- a/toolkit/content/widgets/browser.xml +++ b/toolkit/content/widgets/browser.xml @@ -1904,6 +1904,24 @@ + + + + + + + + + + + +