зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1668106 - Store subdocument intrinsic size and ratio on content rather than frame. r=dholbert
This avoids a problem where we receive the IPC message from the child with updated intrinsics before an <embed> or <object> has had its frame constructed in the parent, and drop the update. Differential Revision: https://phabricator.services.mozilla.com/D99304
This commit is contained in:
Родитель
11c32bb13e
Коммит
5e3e854648
|
@ -3545,6 +3545,25 @@ bool nsObjectLoadingContent::BlockEmbedOrObjectContentLoading() {
|
|||
return false;
|
||||
}
|
||||
|
||||
void nsObjectLoadingContent::SubdocumentIntrinsicSizeOrRatioChanged(
|
||||
const Maybe<IntrinsicSize>& aIntrinsicSize,
|
||||
const Maybe<AspectRatio>& aIntrinsicRatio) {
|
||||
if (aIntrinsicSize == mSubdocumentIntrinsicSize &&
|
||||
aIntrinsicRatio == mSubdocumentIntrinsicRatio) {
|
||||
return;
|
||||
}
|
||||
|
||||
mSubdocumentIntrinsicSize = aIntrinsicSize;
|
||||
mSubdocumentIntrinsicRatio = aIntrinsicRatio;
|
||||
|
||||
nsCOMPtr<nsIContent> thisContent =
|
||||
do_QueryInterface(static_cast<nsIImageLoadingContent*>(this));
|
||||
|
||||
if (nsSubDocumentFrame* sdf = do_QueryFrame(thisContent->GetPrimaryFrame())) {
|
||||
sdf->SubdocumentIntrinsicSizeOrRatioChanged();
|
||||
}
|
||||
}
|
||||
|
||||
// SetupProtoChainRunner implementation
|
||||
nsObjectLoadingContent::SetupProtoChainRunner::SetupProtoChainRunner(
|
||||
nsObjectLoadingContent* aContent)
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#define NSOBJECTLOADINGCONTENT_H_
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "mozilla/dom/BindingDeclarations.h"
|
||||
#include "nsIFrame.h" // for WeakFrame only
|
||||
#include "nsImageLoadingContent.h"
|
||||
|
@ -235,6 +236,20 @@ class nsObjectLoadingContent : public nsImageLoadingContent,
|
|||
mozilla::dom::WindowProxyHolder>& aOpenerWindow,
|
||||
mozilla::ErrorResult& aRv);
|
||||
|
||||
const mozilla::Maybe<mozilla::IntrinsicSize>& GetSubdocumentIntrinsicSize()
|
||||
const {
|
||||
return mSubdocumentIntrinsicSize;
|
||||
}
|
||||
|
||||
const mozilla::Maybe<mozilla::AspectRatio>& GetSubdocumentIntrinsicRatio()
|
||||
const {
|
||||
return mSubdocumentIntrinsicRatio;
|
||||
}
|
||||
|
||||
void SubdocumentIntrinsicSizeOrRatioChanged(
|
||||
const mozilla::Maybe<mozilla::IntrinsicSize>& aIntrinsicSize,
|
||||
const mozilla::Maybe<mozilla::AspectRatio>& aIntrinsicRatio);
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Begins loading the object when called
|
||||
|
@ -693,6 +708,16 @@ class nsObjectLoadingContent : public nsImageLoadingContent,
|
|||
RefPtr<nsPluginInstanceOwner> mInstanceOwner;
|
||||
nsTArray<mozilla::dom::MozPluginParameter> mCachedAttributes;
|
||||
nsTArray<mozilla::dom::MozPluginParameter> mCachedParameters;
|
||||
|
||||
// The intrinsic size and aspect ratio from a child SVG document that
|
||||
// we should use. These are only set when we are an <object> or <embed>
|
||||
// and the inner document is SVG.
|
||||
//
|
||||
// We store these here rather than on nsSubDocumentFrame since we are
|
||||
// sometimes notified of our child's intrinsics before we've constructed
|
||||
// our own frame.
|
||||
mozilla::Maybe<mozilla::IntrinsicSize> mSubdocumentIntrinsicSize;
|
||||
mozilla::Maybe<mozilla::AspectRatio> mSubdocumentIntrinsicRatio;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "nsFocusManager.h"
|
||||
#include "nsFrameLoader.h"
|
||||
#include "nsFrameLoaderOwner.h"
|
||||
#include "nsObjectLoadingContent.h"
|
||||
#include "nsQueryObject.h"
|
||||
#include "nsSubDocumentFrame.h"
|
||||
#include "nsView.h"
|
||||
|
@ -248,11 +249,10 @@ mozilla::ipc::IPCResult BrowserBridgeChild::RecvIntrinsicSizeOrRatioChanged(
|
|||
const Maybe<IntrinsicSize>& aIntrinsicSize,
|
||||
const Maybe<AspectRatio>& aIntrinsicRatio) {
|
||||
if (RefPtr<Element> owner = mFrameLoader->GetOwnerContent()) {
|
||||
if (nsIFrame* f = owner->GetPrimaryFrame()) {
|
||||
if (nsSubDocumentFrame* sdf = do_QueryFrame(f)) {
|
||||
sdf->SubdocumentIntrinsicSizeOrRatioChanged(aIntrinsicSize,
|
||||
aIntrinsicRatio);
|
||||
}
|
||||
if (nsCOMPtr<nsIObjectLoadingContent> olc = do_QueryInterface(owner)) {
|
||||
static_cast<nsObjectLoadingContent*>(olc.get())
|
||||
->SubdocumentIntrinsicSizeOrRatioChanged(aIntrinsicSize,
|
||||
aIntrinsicRatio);
|
||||
}
|
||||
}
|
||||
return IPC_OK();
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
#include "nsServiceManagerUtils.h"
|
||||
#include "nsQueryObject.h"
|
||||
#include "RetainedDisplayListBuilder.h"
|
||||
#include "nsObjectLoadingContent.h"
|
||||
|
||||
#include "Layers.h"
|
||||
#include "BasicLayers.h"
|
||||
|
@ -585,7 +586,10 @@ nscoord nsSubDocumentFrame::GetMinISize(gfxContext* aRenderingContext) {
|
|||
nscoord result;
|
||||
DISPLAY_MIN_INLINE_SIZE(this, result);
|
||||
|
||||
if (mSubdocumentIntrinsicSize) {
|
||||
nsCOMPtr<nsIObjectLoadingContent> iolc = do_QueryInterface(mContent);
|
||||
auto olc = static_cast<nsObjectLoadingContent*>(iolc.get());
|
||||
|
||||
if (olc && olc->GetSubdocumentIntrinsicSize()) {
|
||||
// The subdocument is an SVG document, so technically we should call
|
||||
// SVGOuterSVGFrame::GetMinISize() on its root frame. That method always
|
||||
// returns 0, though, so we can just do that & don't need to bother with
|
||||
|
@ -621,9 +625,13 @@ IntrinsicSize nsSubDocumentFrame::GetIntrinsicSize() {
|
|||
return IntrinsicSize(0, 0);
|
||||
}
|
||||
|
||||
if (mSubdocumentIntrinsicSize) {
|
||||
// Use the intrinsic size from the child SVG document, if available.
|
||||
return *mSubdocumentIntrinsicSize;
|
||||
if (nsCOMPtr<nsIObjectLoadingContent> iolc = do_QueryInterface(mContent)) {
|
||||
auto olc = static_cast<nsObjectLoadingContent*>(iolc.get());
|
||||
|
||||
if (auto size = olc->GetSubdocumentIntrinsicSize()) {
|
||||
// Use the intrinsic size from the child SVG document, if available.
|
||||
return *size;
|
||||
}
|
||||
}
|
||||
|
||||
if (!IsInline()) {
|
||||
|
@ -643,9 +651,15 @@ AspectRatio nsSubDocumentFrame::GetIntrinsicRatio() const {
|
|||
// FIXME(emilio): This should probably respect contain: size and return no
|
||||
// ratio in the case subDocRoot is non-null. Otherwise we do it by virtue of
|
||||
// using a zero-size below and reusing GetIntrinsicSize().
|
||||
if (mSubdocumentIntrinsicRatio && *mSubdocumentIntrinsicRatio) {
|
||||
// Use the intrinsic aspect ratio from the child SVG document, if available.
|
||||
return *mSubdocumentIntrinsicRatio;
|
||||
if (nsCOMPtr<nsIObjectLoadingContent> iolc = do_QueryInterface(mContent)) {
|
||||
auto olc = static_cast<nsObjectLoadingContent*>(iolc.get());
|
||||
|
||||
auto ratio = olc->GetSubdocumentIntrinsicRatio();
|
||||
if (ratio && *ratio) {
|
||||
// Use the intrinsic aspect ratio from the child SVG document, if
|
||||
// available.
|
||||
return *ratio;
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE(emilio): Even though we have an intrinsic size, we may not have an
|
||||
|
@ -1156,16 +1170,7 @@ nsPoint nsSubDocumentFrame::GetExtraOffset() const {
|
|||
return mInnerView->GetPosition();
|
||||
}
|
||||
|
||||
void nsSubDocumentFrame::SubdocumentIntrinsicSizeOrRatioChanged(
|
||||
const Maybe<IntrinsicSize>& aIntrinsicSize,
|
||||
const Maybe<AspectRatio>& aIntrinsicRatio) {
|
||||
if (mSubdocumentIntrinsicSize == aIntrinsicSize &&
|
||||
mSubdocumentIntrinsicRatio == aIntrinsicRatio) {
|
||||
return;
|
||||
}
|
||||
mSubdocumentIntrinsicSize = aIntrinsicSize;
|
||||
mSubdocumentIntrinsicRatio = aIntrinsicRatio;
|
||||
|
||||
void nsSubDocumentFrame::SubdocumentIntrinsicSizeOrRatioChanged() {
|
||||
if (MOZ_UNLIKELY(HasAllStateBits(NS_FRAME_IS_DIRTY))) {
|
||||
// We will be reflowed soon anyway.
|
||||
return;
|
||||
|
|
|
@ -135,9 +135,7 @@ class nsSubDocumentFrame final : public nsAtomicContainerFrame,
|
|||
|
||||
void ClearDisplayItems();
|
||||
|
||||
void SubdocumentIntrinsicSizeOrRatioChanged(
|
||||
const mozilla::Maybe<mozilla::IntrinsicSize>& aIntrinsicSize,
|
||||
const mozilla::Maybe<mozilla::AspectRatio>& aIntrinsicRatio);
|
||||
void SubdocumentIntrinsicSizeOrRatioChanged();
|
||||
|
||||
protected:
|
||||
friend class AsyncFrameInit;
|
||||
|
@ -171,12 +169,6 @@ class nsSubDocumentFrame final : public nsAtomicContainerFrame,
|
|||
nsView* mOuterView;
|
||||
nsView* mInnerView;
|
||||
|
||||
// The intrinsic size and aspect ratio from a child SVG document that
|
||||
// we should use. These are only set when we are an <object> or <embed>
|
||||
// and the inner document is SVG.
|
||||
mozilla::Maybe<mozilla::IntrinsicSize> mSubdocumentIntrinsicSize;
|
||||
mozilla::Maybe<mozilla::AspectRatio> mSubdocumentIntrinsicRatio;
|
||||
|
||||
bool mIsInline;
|
||||
bool mPostedReflowCallback;
|
||||
bool mDidCreateDoc;
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
#include "gfxContext.h"
|
||||
#include "nsDisplayList.h"
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
#include "nsIObjectLoadingContent.h"
|
||||
#include "nsObjectLoadingContent.h"
|
||||
#include "nsSubDocumentFrame.h"
|
||||
#include "mozilla/PresShell.h"
|
||||
#include "mozilla/SVGForeignObjectFrame.h"
|
||||
|
@ -923,13 +923,12 @@ void SVGOuterSVGFrame::MaybeSendIntrinsicSizeAndRatioToEmbedder(
|
|||
|
||||
if (bc->GetParent()->IsInProcess()) {
|
||||
if (Element* embedder = bc->GetEmbedderElement()) {
|
||||
nsSubDocumentFrame* sdf = do_QueryFrame(embedder->GetPrimaryFrame());
|
||||
if (!sdf) {
|
||||
return;
|
||||
if (nsCOMPtr<nsIObjectLoadingContent> olc = do_QueryInterface(embedder)) {
|
||||
static_cast<nsObjectLoadingContent*>(olc.get())
|
||||
->SubdocumentIntrinsicSizeOrRatioChanged(aIntrinsicSize,
|
||||
aIntrinsicRatio);
|
||||
}
|
||||
|
||||
sdf->SubdocumentIntrinsicSizeOrRatioChanged(aIntrinsicSize,
|
||||
aIntrinsicRatio);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче