Bug 1342801 - Store the 'writing-mode' used value on nsIFrame and make GetWritingMode non-virtual. r=jfkthame

MozReview-Commit-ID: HPhuxjDbOdh
This commit is contained in:
Mats Palmgren 2017-02-28 18:58:30 +01:00
Родитель f4d88a4bee
Коммит e8c6fd3388
20 изменённых файлов: 126 добавлений и 105 удалений

Просмотреть файл

@ -38,15 +38,6 @@ public:
nsContainerFrame* aParent,
nsIFrame* aPrevInFlow) override;
virtual mozilla::WritingMode GetWritingMode() const override
{
nsIFrame* firstChild = mFrames.FirstChild();
if (firstChild) {
return firstChild->GetWritingMode();
}
return nsIFrame::GetWritingMode();
}
#ifdef DEBUG
virtual void AppendFrames(ChildListID aListID,
nsFrameList& aFrameList) override;

Просмотреть файл

@ -182,7 +182,6 @@ nsCanvasFrame::SetHasFocus(bool aHasFocus)
return NS_OK;
}
#ifdef DEBUG
void
nsCanvasFrame::SetInitialChildList(ChildListID aListID,
nsFrameList& aChildList)
@ -191,12 +190,14 @@ nsCanvasFrame::SetInitialChildList(ChildListID aListID,
aChildList.IsEmpty() || aChildList.OnlyChild(),
"Primary child list can have at most one frame in it");
nsContainerFrame::SetInitialChildList(aListID, aChildList);
MaybePropagateRootElementWritingMode();
}
void
nsCanvasFrame::AppendFrames(ChildListID aListID,
nsFrameList& aFrameList)
{
#ifdef DEBUG
MOZ_ASSERT(aListID == kPrincipalList, "unexpected child list");
if (!mFrames.IsEmpty()) {
for (nsFrameList::Enumerator e(aFrameList); !e.AtEnd(); e.Next()) {
@ -207,7 +208,9 @@ nsCanvasFrame::AppendFrames(ChildListID aListID,
}
}
nsFrame::VerifyDirtyBitSet(aFrameList);
#endif
nsContainerFrame::AppendFrames(aListID, aFrameList);
MaybePropagateRootElementWritingMode();
}
void
@ -219,8 +222,10 @@ nsCanvasFrame::InsertFrames(ChildListID aListID,
// as appending
MOZ_ASSERT(!aPrevFrame, "unexpected previous sibling frame");
AppendFrames(aListID, aFrameList);
MaybePropagateRootElementWritingMode();
}
#ifdef DEBUG
void
nsCanvasFrame::RemoveFrame(ChildListID aListID,
nsIFrame* aOldFrame)
@ -802,6 +807,17 @@ nsCanvasFrame::GetContentForEvent(WidgetEvent* aEvent,
return rv;
}
void
nsCanvasFrame::MaybePropagateRootElementWritingMode()
{
nsIFrame* child = PrincipalChildList().FirstChild();
if (child && child->GetContent() &&
child->GetContent() == PresContext()->Document()->GetRootElement()) {
nsIFrame* childPrimary = child->GetContent()->GetPrimaryFrame();
PropagateRootElementWritingMode(childPrimary->GetWritingMode());
}
}
#ifdef DEBUG_FRAME_DUMP
nsresult
nsCanvasFrame::GetFrameName(nsAString& aResult) const

Просмотреть файл

@ -44,12 +44,6 @@ public:
virtual void DestroyFrom(nsIFrame* aDestructRoot) override;
mozilla::WritingMode GetWritingMode() const override
{
return nsFrame::GetWritingModeDeferringToRootElem();
}
#ifdef DEBUG
virtual void SetInitialChildList(ChildListID aListID,
nsFrameList& aChildList) override;
virtual void AppendFrames(ChildListID aListID,
@ -57,6 +51,7 @@ public:
virtual void InsertFrames(ChildListID aListID,
nsIFrame* aPrevFrame,
nsFrameList& aFrameList) override;
#ifdef DEBUG
virtual void RemoveFrame(ChildListID aListID,
nsIFrame* aOldFrame) override;
#endif
@ -125,6 +120,10 @@ public:
nsRect CanvasArea() const;
protected:
// Utility function to propagate the WritingMode from our first child to
// 'this' and all its ancestors.
void MaybePropagateRootElementWritingMode();
// Data members
bool mDoPaintFocus;
bool mAddedScrollPositionListener;

Просмотреть файл

@ -434,6 +434,7 @@ nsFrame::nsFrame(nsStyleContext* aContext)
mState = NS_FRAME_FIRST_REFLOW | NS_FRAME_IS_DIRTY;
mStyleContext = aContext;
mWritingMode = WritingMode(mStyleContext);
mStyleContext->AddRef();
#ifdef DEBUG
mStyleContext->FrameAddRef();
@ -559,6 +560,8 @@ nsFrame::Init(nsIContent* aContent,
}
if (aPrevInFlow) {
mWritingMode = aPrevInFlow->GetWritingMode();
// Make sure the general flags bits are the same
nsFrameState state = aPrevInFlow->GetStateBits();
@ -3083,19 +3086,6 @@ nsFrame::FireDOMEvent(const nsAString& aDOMEventName, nsIContent *aContent)
}
}
WritingMode
nsFrame::GetWritingModeDeferringToRootElem() const
{
Element* rootElem = PresContext()->Document()->GetRootElement();
if (rootElem) {
nsIFrame* primaryFrame = rootElem->GetPrimaryFrame();
if (primaryFrame) {
return primaryFrame->GetWritingMode();
}
}
return nsIFrame::GetWritingMode();
}
nsresult
nsFrame::HandleEvent(nsPresContext* aPresContext,
WidgetGUIEvent* aEvent,

Просмотреть файл

@ -688,8 +688,6 @@ protected:
// Fire DOM event. If no aContent argument use frame's mContent.
void FireDOMEvent(const nsAString& aDOMEventName, nsIContent *aContent = nullptr);
mozilla::WritingMode GetWritingModeDeferringToRootElem() const;
private:
void BoxReflow(nsBoxLayoutState& aState,
nsPresContext* aPresContext,

Просмотреть файл

@ -157,7 +157,7 @@ nsHTMLScrollFrame::SetInitialChildList(ChildListID aListID,
nsFrameList& aChildList)
{
nsContainerFrame::SetInitialChildList(aListID, aChildList);
mHelper.ReloadChildFrames();
ReloadChildFrames();
}
@ -167,7 +167,7 @@ nsHTMLScrollFrame::AppendFrames(ChildListID aListID,
{
NS_ASSERTION(aListID == kPrincipalList, "Only main list supported");
mFrames.AppendFrames(nullptr, aFrameList);
mHelper.ReloadChildFrames();
ReloadChildFrames();
}
void
@ -179,7 +179,7 @@ nsHTMLScrollFrame::InsertFrames(ChildListID aListID,
NS_ASSERTION(!aPrevFrame || aPrevFrame->GetParent() == this,
"inserting after sibling frame with different parent");
mFrames.InsertFrames(nullptr, aPrevFrame, aFrameList);
mHelper.ReloadChildFrames();
ReloadChildFrames();
}
void
@ -188,7 +188,7 @@ nsHTMLScrollFrame::RemoveFrame(ChildListID aListID,
{
NS_ASSERTION(aListID == kPrincipalList, "Only main list supported");
mFrames.DestroyFrame(aOldFrame);
mHelper.ReloadChildFrames();
ReloadChildFrames();
}
nsSplittableType

Просмотреть файл

@ -676,14 +676,6 @@ public:
NS_DECL_QUERYFRAME
NS_DECL_FRAMEARENA_HELPERS
virtual mozilla::WritingMode GetWritingMode() const override
{
if (mHelper.mScrolledFrame) {
return mHelper.mScrolledFrame->GetWritingMode();
}
return nsIFrame::GetWritingMode();
}
virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder,
const nsRect& aDirtyRect,
const nsDisplayListSet& aLists) override {
@ -1076,6 +1068,14 @@ protected:
*/
virtual bool ShouldPropagateComputedBSizeToScrolledContent() const { return true; }
void ReloadChildFrames()
{
mHelper.ReloadChildFrames();
if (mHelper.mScrolledFrame) {
mWritingMode = mHelper.mScrolledFrame->GetWritingMode();
}
}
private:
friend class mozilla::ScrollFrameHelper;
ScrollFrameHelper mHelper;

Просмотреть файл

@ -787,10 +787,15 @@ public:
/**
* The frame's writing-mode, used for logical layout computations.
* It's usually the 'writing-mode' computed value, but there are exceptions:
* * inner table frames copy the value from the table frame
* (@see nsTableRowGroupFrame::Init, nsTableRowFrame::Init etc)
* * the root element frame propagates its value to its ancestors
* (@see nsCanvasFrame::MaybePropagateRootElementWritingMode)
* * a scrolled frame propagates its value to its ancestor scroll frame
* (@see nsHTMLScrollFrame::ReloadChildFrames)
*/
virtual mozilla::WritingMode GetWritingMode() const {
return mozilla::WritingMode(StyleContext());
}
mozilla::WritingMode GetWritingMode() const { return mWritingMode; }
/**
* Construct a writing mode for line layout in this frame. This is
@ -3589,6 +3594,11 @@ private:
}
protected:
/**
* Copies aRootElemWM to mWritingMode on 'this' and all its ancestors.
*/
inline void PropagateRootElementWritingMode(mozilla::WritingMode aRootElemWM);
void MarkInReflow() {
#ifdef DEBUG_dbaron_off
// bug 81268
@ -3628,6 +3638,9 @@ protected:
VisualDeltas mVisualDeltas;
} mOverflow;
/** @see GetWritingMode() */
mozilla::WritingMode mWritingMode;
// Helpers
/**
* Can we stop inside this frame when we're skipping non-rendered whitespace?

Просмотреть файл

@ -160,4 +160,13 @@ nsIFrame::BaselineBOffset(mozilla::WritingMode aWM,
return SynthesizeBaselineBOffsetFromBorderBox(aWM, aBaselineGroup);
}
void
nsIFrame::PropagateRootElementWritingMode(mozilla::WritingMode aRootElemWM)
{
MOZ_ASSERT(GetType() == nsGkAtoms::canvasFrame);
for (auto f = this; f; f = f->GetParent()) {
f->mWritingMode = aRootElemWM;
}
}
#endif

Просмотреть файл

@ -44,11 +44,6 @@ public:
*/
virtual nsIAtom* GetType() const override;
mozilla::WritingMode GetWritingMode() const override
{
return nsFrame::GetWritingModeDeferringToRootElem();
}
#ifdef DEBUG_FRAME_DUMP
// Debugging
virtual nsresult GetFrameName(nsAString& aResult) const override;

Просмотреть файл

@ -32,11 +32,6 @@ public:
const nsRect& aDirtyRect,
const nsDisplayListSet& aLists) override;
mozilla::WritingMode GetWritingMode() const override
{
return nsFrame::GetWritingModeDeferringToRootElem();
}
/**
* Get the "type" of the frame
*

Просмотреть файл

@ -60,11 +60,6 @@ public:
NS_DECL_QUERYFRAME
NS_DECL_FRAMEARENA_HELPERS
mozilla::WritingMode GetWritingMode() const override
{
return nsFrame::GetWritingModeDeferringToRootElem();
}
// nsIFrame
void Reflow(nsPresContext* aPresContext,
ReflowOutput& aDesiredSize,

Просмотреть файл

@ -3610,6 +3610,8 @@ nsStyleVisibility::CalcDifference(const nsStyleVisibility& aNewData) const
// It's important that a change in mWritingMode results in frame
// reconstruction, because it may affect intrinsic size (see
// nsSubDocumentFrame::GetIntrinsicISize/BSize).
// Also, the used writing-mode value is now a field on nsIFrame and some
// classes (e.g. table rows/cells) copy their value from an ancestor.
hint |= nsChangeHint_ReconstructFrame;
} else {
if ((mImageOrientation != aNewData.mImageOrientation)) {

Просмотреть файл

@ -92,6 +92,13 @@ nsTableCellFrame::Init(nsIContent* aContent,
int32_t colIndex;
cellFrame->GetColIndex(colIndex);
SetColIndex(colIndex);
} else {
// Although the spec doesn't say that writing-mode is not applied to
// table-cells, we still override style value here because we want to
// make effective writing mode of table structure frames consistent
// within a table. The content inside table cells is reflowed by an
// anonymous block, hence their writing mode is not affected.
mWritingMode = GetTableFrame()->GetWritingMode();
}
}

Просмотреть файл

@ -136,14 +136,6 @@ public:
virtual nsresult GetFrameName(nsAString& aResult) const override;
#endif
// Although the spec doesn't say that writing-mode is not applied to
// table-cells, we still override this method here because we want to
// make effective writing mode of table structure frames consistent
// within a table. The content inside table cells is reflowed by an
// anonymous block, hence their writing mode is not affected.
virtual mozilla::WritingMode GetWritingMode() const override
{ return GetTableFrame()->GetWritingMode(); }
void BlockDirAlignChild(mozilla::WritingMode aWM, nscoord aMaxAscent);
/*

Просмотреть файл

@ -33,27 +33,20 @@ public:
friend nsTableColFrame* NS_NewTableColFrame(nsIPresShell* aPresShell,
nsStyleContext* aContext);
nsTableColGroupFrame* GetTableColGroupFrame() const
// nsIFrame overrides
virtual void Init(nsIContent* aContent,
nsContainerFrame* aParent,
nsIFrame* aPrevInFlow) override
{
nsIFrame* parent = GetParent();
MOZ_ASSERT(parent && parent->GetType() == nsGkAtoms::tableColGroupFrame);
return static_cast<nsTableColGroupFrame*>(parent);
}
nsTableFrame* GetTableFrame() const
{
return GetTableColGroupFrame()->GetTableFrame();
nsSplittableFrame::Init(aContent, aParent, aPrevInFlow);
if (!aPrevInFlow) {
mWritingMode = GetTableFrame()->GetWritingMode();
}
}
/** @see nsIFrame::DidSetStyleContext */
virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext) override;
int32_t GetColIndex() const;
void SetColIndex (int32_t aColIndex);
nsTableColFrame* GetNextCol() const;
virtual void Reflow(nsPresContext* aPresContext,
ReflowOutput& aDesiredSize,
const ReflowInput& aReflowInput,
@ -79,8 +72,23 @@ public:
virtual nsSplittableType GetSplittableType() const override;
virtual mozilla::WritingMode GetWritingMode() const override
{ return GetTableFrame()->GetWritingMode(); }
nsTableColGroupFrame* GetTableColGroupFrame() const
{
nsIFrame* parent = GetParent();
MOZ_ASSERT(parent && parent->GetType() == nsGkAtoms::tableColGroupFrame);
return static_cast<nsTableColGroupFrame*>(parent);
}
nsTableFrame* GetTableFrame() const
{
return GetTableColGroupFrame()->GetTableFrame();
}
int32_t GetColIndex() const;
void SetColIndex (int32_t aColIndex);
nsTableColFrame* GetNextCol() const;
/** return the number of the columns the col represents. always >= 1 */
int32_t GetSpan();

Просмотреть файл

@ -16,16 +16,12 @@ class nsTableColFrame;
/**
* nsTableColGroupFrame
* data structure to maintain information about a single table cell's frame
*
* @author sclark
*/
class nsTableColGroupFrame final : public nsContainerFrame
{
public:
NS_DECL_FRAMEARENA_HELPERS
// default constructor supplied by the compiler
/** instantiate a new instance of nsTableRowFrame.
* @param aPresShell the pres shell for this frame
*
@ -34,6 +30,17 @@ public:
friend nsTableColGroupFrame* NS_NewTableColGroupFrame(nsIPresShell* aPresShell,
nsStyleContext* aContext);
// nsIFrame overrides
virtual void Init(nsIContent* aContent,
nsContainerFrame* aParent,
nsIFrame* aPrevInFlow) override
{
nsContainerFrame::Init(aContent, aParent, aPrevInFlow);
if (!aPrevInFlow) {
mWritingMode = GetTableFrame()->GetWritingMode();
}
}
nsTableFrame* GetTableFrame() const
{
nsIFrame* parent = GetParent();
@ -116,9 +123,6 @@ public:
*/
virtual nsIAtom* GetType() const override;
virtual mozilla::WritingMode GetWritingMode() const override
{ return GetTableFrame()->GetWritingMode(); }
/** Add column frames to the table storages: colframe cache and cellmap
* this doesn't change the mFrames of the colgroup frame.
* @param aFirstColIndex - the index at which aFirstFrame should be inserted

Просмотреть файл

@ -169,6 +169,8 @@ nsTableRowFrame::Init(nsIContent* aContent,
nsTableRowFrame* rowFrame = (nsTableRowFrame*)aPrevInFlow;
SetRowIndex(rowFrame->GetRowIndex());
} else {
mWritingMode = GetTableFrame()->GetWritingMode();
}
}

Просмотреть файл

@ -116,9 +116,6 @@ public:
virtual nsresult GetFrameName(nsAString& aResult) const override;
#endif
virtual mozilla::WritingMode GetWritingMode() const override
{ return GetTableFrame()->GetWritingMode(); }
void UpdateBSize(nscoord aBSize,
nscoord aAscent,
nscoord aDescent,

Просмотреть файл

@ -51,11 +51,15 @@ public:
nsStyleContext* aContext);
virtual ~nsTableRowGroupFrame();
nsTableFrame* GetTableFrame() const
// nsIFrame overrides
virtual void Init(nsIContent* aContent,
nsContainerFrame* aParent,
nsIFrame* aPrevInFlow) override
{
nsIFrame* parent = GetParent();
MOZ_ASSERT(parent && parent->GetType() == nsGkAtoms::tableFrame);
return static_cast<nsTableFrame*>(parent);
nsContainerFrame::Init(aContent, aParent, aPrevInFlow);
if (!aPrevInFlow) {
mWritingMode = GetTableFrame()->GetWritingMode();
}
}
virtual void DestroyFrom(nsIFrame* aDestructRoot) override;
@ -102,15 +106,19 @@ public:
*/
virtual nsIAtom* GetType() const override;
nsTableRowFrame* GetFirstRow();
nsTableRowFrame* GetLastRow();
#ifdef DEBUG_FRAME_DUMP
virtual nsresult GetFrameName(nsAString& aResult) const override;
#endif
virtual mozilla::WritingMode GetWritingMode() const override
{ return GetTableFrame()->GetWritingMode(); }
nsTableRowFrame* GetFirstRow();
nsTableRowFrame* GetLastRow();
nsTableFrame* GetTableFrame() const
{
nsIFrame* parent = GetParent();
MOZ_ASSERT(parent && parent->GetType() == nsGkAtoms::tableFrame);
return static_cast<nsTableFrame*>(parent);
}
/** return the number of child rows (not necessarily == number of child frames) */
int32_t GetRowCount();