From 689819e12b5f5ae60ea7e3f7ae5e17c8392cce8a Mon Sep 17 00:00:00 2001 From: Cameron Kaiser Date: Sun, 14 Jun 2020 14:23:43 -0700 Subject: [PATCH] #612: M969874 M1525628 --- layout/generic/nsFrame.cpp | 5 +++++ layout/generic/nsGfxScrollFrame.cpp | 23 +++++++++++++++++++++++ layout/generic/nsGfxScrollFrame.h | 2 ++ layout/generic/nsIFrame.h | 12 ++++++++++++ 4 files changed, 42 insertions(+) diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index 4a51286e1..98a8d15c3 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -5889,6 +5889,11 @@ nsIFrame::IsBlockWrapper() const pseudoType == nsCSSAnonBoxes::cellContent); } +bool nsIFrame::IsBlockFrameOrSubclass() { + nsBlockFrame* thisAsBlock = do_QueryFrame(this); + return !!thisAsBlock; +} + static nsIFrame* GetNearestBlockContainer(nsIFrame* frame) { diff --git a/layout/generic/nsGfxScrollFrame.cpp b/layout/generic/nsGfxScrollFrame.cpp index 03cc4c947..4ef9b6515 100644 --- a/layout/generic/nsGfxScrollFrame.cpp +++ b/layout/generic/nsGfxScrollFrame.cpp @@ -972,6 +972,29 @@ nsHTMLScrollFrame::AccessibleType() } #endif +nscoord nsHTMLScrollFrame::GetLogicalBaseline(WritingMode aWritingMode) const { + // This function implements some of the spec text here: + // https://drafts.csswg.org/css-align/#baseline-export + // + // Specifically: if our scrolled frame is a block, we just use the inherited + // GetLogicalBaseline() impl, which synthesizes a baseline from the + // margin-box. Otherwise, we defer to our scrolled frame, considering it + // to be scrolled to its initial scroll position. + if (mHelper.mScrolledFrame->IsBlockFrameOrSubclass()) { + return nsContainerFrame::GetLogicalBaseline(aWritingMode); + } + + // OK, here's where we defer to our scrolled frame. We have to add our + // border BStart thickness to whatever it returns, to produce an offset in + // our frame-rect's coordinate system. (We don't have to add padding, + // because the scrolled frame handles our padding.) + LogicalMargin border = GetLogicalUsedBorder(aWritingMode); + + return border.BStart(aWritingMode) + + mHelper.mScrolledFrame->GetLogicalBaseline(aWritingMode); +} + + NS_QUERYFRAME_HEAD(nsHTMLScrollFrame) NS_QUERYFRAME_ENTRY(nsIAnonymousContentCreator) NS_QUERYFRAME_ENTRY(nsIScrollableFrame) diff --git a/layout/generic/nsGfxScrollFrame.h b/layout/generic/nsGfxScrollFrame.h index 7f6301559..5bbd1ca9f 100644 --- a/layout/generic/nsGfxScrollFrame.h +++ b/layout/generic/nsGfxScrollFrame.h @@ -943,6 +943,8 @@ public: virtual mozilla::a11y::AccType AccessibleType() override; #endif + nscoord GetLogicalBaseline(mozilla::WritingMode aWritingMode) const override; + protected: nsHTMLScrollFrame(nsStyleContext* aContext, bool aIsRoot); void SetSuppressScrollbarUpdate(bool aSuppress) { diff --git a/layout/generic/nsIFrame.h b/layout/generic/nsIFrame.h index e1d756850..39c4b9789 100644 --- a/layout/generic/nsIFrame.h +++ b/layout/generic/nsIFrame.h @@ -2162,6 +2162,18 @@ public: */ bool IsBlockWrapper() const; + /** + * Returns true if the frame is an instance of nsBlockFrame or one of its + * subclasses. + * + * XXXdholbert this is non-const because it uses nsIFrame::QueryFrame which + * is non-const. If we need this accessor to be 'const' down the road, the + * right way to do it would be to make the QueryFrame machinery + * const-friendly. But it may not be worth the trouble, because we rarely + * handle const frame pointers anyway. + */ + bool IsBlockFrameOrSubclass(); + /** * Get this frame's CSS containing block. *