Bug 1116037 part 2 - Use frame state bit to mark rtc of span. r=dbaron

--HG--
extra : source : ae8d3b155c8ac5f73992fdb5f23e6be48c884c78
This commit is contained in:
Xidorn Quan 2014-12-29 13:34:07 +11:00
parent 7368bd2654
commit 1175e8d1f5
5 changed files with 81 additions and 7 deletions

View File

@ -18,6 +18,7 @@
#include "nsInlineFrame.h"
#include "nsPlaceholderFrame.h"
#include "nsRubyTextFrame.h"
#include "nsRubyTextContainerFrame.h"
#include "nsSVGContainerFrame.h"
#include "nsTableCellFrame.h"
#include "nsTableRowFrame.h"

View File

@ -523,6 +523,13 @@ FRAME_STATE_GROUP(RubyText, nsRubyTextFrame)
FRAME_STATE_BIT(RubyText, 24, NS_RUBY_TEXT_FRAME_AUTOHIDE)
// == Frame state bits that apply to ruby text container frames ===============
FRAME_STATE_GROUP(RubyTextContainer, nsRubyTextContainerFrame)
FRAME_STATE_BIT(RubyTextContainer, 20, NS_RUBY_TEXT_CONTAINER_IS_SPAN)
// == Frame state bits that apply to placeholder frames =======================
FRAME_STATE_GROUP(Placeholder, nsPlaceholderFrame)

View File

@ -195,13 +195,8 @@ void nsRubyBaseContainerFrame::AppendTextContainer(nsIFrame* aFrame)
MOZ_ASSERT(rtcFrame, "Must provide a ruby text container.");
nsTArray<nsRubyTextContainerFrame*>* containers = &mTextContainers;
if (!GetPrevContinuation() && !GetNextContinuation()) {
nsIFrame* onlyChild = rtcFrame->PrincipalChildList().OnlyChild();
if (onlyChild && onlyChild->IsPseudoFrame(rtcFrame->GetContent())) {
// Per CSS Ruby spec, if the only child of an rtc frame is
// a pseudo rt frame, it spans all bases in the segment.
containers = &mSpanContainers;
}
if (rtcFrame->IsSpanContainer()) {
containers = &mSpanContainers;
}
containers->AppendElement(rtcFrame);
}

View File

@ -61,6 +61,60 @@ nsRubyTextContainerFrame::IsFrameOfType(uint32_t aFlags) const
return nsRubyTextContainerFrameSuper::IsFrameOfType(aFlags);
}
/* virtual */ void
nsRubyTextContainerFrame::SetInitialChildList(ChildListID aListID,
nsFrameList& aChildList)
{
nsRubyTextContainerFrameSuper::SetInitialChildList(aListID, aChildList);
UpdateSpanFlag();
}
/* virtual */ void
nsRubyTextContainerFrame::AppendFrames(ChildListID aListID,
nsFrameList& aFrameList)
{
nsRubyTextContainerFrameSuper::AppendFrames(aListID, aFrameList);
UpdateSpanFlag();
}
/* virtual */ void
nsRubyTextContainerFrame::InsertFrames(ChildListID aListID,
nsIFrame* aPrevFrame,
nsFrameList& aFrameList)
{
nsRubyTextContainerFrameSuper::InsertFrames(aListID, aPrevFrame, aFrameList);
UpdateSpanFlag();
}
/* virtual */ void
nsRubyTextContainerFrame::RemoveFrame(ChildListID aListID,
nsIFrame* aOldFrame)
{
nsRubyTextContainerFrameSuper::RemoveFrame(aListID, aOldFrame);
UpdateSpanFlag();
}
void
nsRubyTextContainerFrame::UpdateSpanFlag()
{
bool isSpan = false;
// The continuation checks are safe here because spans never break.
if (!GetPrevContinuation() && !GetNextContinuation()) {
nsIFrame* onlyChild = mFrames.OnlyChild();
if (onlyChild && onlyChild->IsPseudoFrame(GetContent())) {
// Per CSS Ruby spec, if the only child of an rtc frame is
// a pseudo rt frame, it spans all bases in the segment.
isSpan = true;
}
}
if (isSpan) {
AddStateBits(NS_RUBY_TEXT_CONTAINER_IS_SPAN);
} else {
RemoveStateBits(NS_RUBY_TEXT_CONTAINER_IS_SPAN);
}
}
/* virtual */ void
nsRubyTextContainerFrame::Reflow(nsPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,

View File

@ -42,6 +42,21 @@ public:
virtual nsresult GetFrameName(nsAString& aResult) const MOZ_OVERRIDE;
#endif
// nsContainerFrame overrides
virtual void SetInitialChildList(ChildListID aListID,
nsFrameList& aChildList) MOZ_OVERRIDE;
virtual void AppendFrames(ChildListID aListID,
nsFrameList& aFrameList) MOZ_OVERRIDE;
virtual void InsertFrames(ChildListID aListID, nsIFrame* aPrevFrame,
nsFrameList& aFrameList) MOZ_OVERRIDE;
virtual void RemoveFrame(ChildListID aListID,
nsIFrame* aOldFrame) MOZ_OVERRIDE;
bool IsSpanContainer() const
{
return GetStateBits() & NS_RUBY_TEXT_CONTAINER_IS_SPAN;
}
protected:
friend nsContainerFrame*
NS_NewRubyTextContainerFrame(nsIPresShell* aPresShell,
@ -50,6 +65,8 @@ protected:
: nsRubyTextContainerFrameSuper(aContext)
, mLineSize(mozilla::WritingMode(aContext)) {}
void UpdateSpanFlag();
friend class nsRubyBaseContainerFrame;
void SetLineSize(const mozilla::LogicalSize& aSize) { mLineSize = aSize; }