mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-30 00:01:50 +00:00
Bug 63895 (Part 2) - Support table parts as absolute containing blocks. r=dbaron
This commit is contained in:
parent
b222d248ef
commit
874e445c7b
@ -7,3 +7,5 @@ ImageMapCircleWrongNumberOfCoords=The "coords" attribute of the <area shape="cir
|
||||
ImageMapCircleNegativeRadius=The "coords" attribute of the <area shape="circle"> tag has a negative radius.
|
||||
ImageMapPolyWrongNumberOfCoords=The "coords" attribute of the <area shape="poly"> tag is not in the "x1,y1,x2,y2 …" format.
|
||||
ImageMapPolyOddNumberOfCoords=The "coords" attribute of the <area shape="poly"> tag is missing the last "y" coordinate (the correct format is "x1,y1,x2,y2 …").
|
||||
|
||||
TablePartRelPosWarning=Relative positioning of table rows and row groups is now supported. This site may need to be updated because it may depend on this feature having no effect.
|
||||
|
@ -1984,27 +1984,64 @@ nsCSSFrameConstructor::ConstructTable(nsFrameConstructorState& aState,
|
||||
return newFrame;
|
||||
}
|
||||
|
||||
nsIFrame*
|
||||
nsCSSFrameConstructor::ConstructTableRow(nsFrameConstructorState& aState,
|
||||
FrameConstructionItem& aItem,
|
||||
nsIFrame* aParentFrame,
|
||||
const nsStyleDisplay* aDisplay,
|
||||
nsFrameItems& aFrameItems)
|
||||
static void
|
||||
MakeTablePartAbsoluteContainingBlockIfNeeded(nsFrameConstructorState& aState,
|
||||
const nsStyleDisplay* aDisplay,
|
||||
nsFrameConstructorSaveState& aAbsSaveState,
|
||||
nsIFrame* aFrame)
|
||||
{
|
||||
NS_PRECONDITION(aDisplay->mDisplay == NS_STYLE_DISPLAY_TABLE_ROW,
|
||||
// If we're positioned, then we need to become an absolute containing block
|
||||
// for any absolutely positioned children and register for post-reflow fixup.
|
||||
//
|
||||
// Note that usually if a frame type can be an absolute containing block, we
|
||||
// always set NS_FRAME_CAN_HAVE_ABSPOS_CHILDREN, whether it actually is or not.
|
||||
// However, in this case flag serves the additional purpose of indicating that
|
||||
// the frame was registered with its table frame. This allows us to avoid the
|
||||
// overhead of unregistering the frame in most cases.
|
||||
if (aDisplay->IsRelativelyPositionedStyle() ||
|
||||
aDisplay->IsAbsolutelyPositionedStyle() ||
|
||||
aDisplay->HasTransform(aFrame)) {
|
||||
aFrame->AddStateBits(NS_FRAME_CAN_HAVE_ABSPOS_CHILDREN);
|
||||
aState.PushAbsoluteContainingBlock(aFrame, aFrame, aAbsSaveState);
|
||||
nsTableFrame::RegisterPositionedTablePart(aFrame);
|
||||
}
|
||||
}
|
||||
|
||||
nsIFrame*
|
||||
nsCSSFrameConstructor::ConstructTableRowOrRowGroup(nsFrameConstructorState& aState,
|
||||
FrameConstructionItem& aItem,
|
||||
nsIFrame* aParentFrame,
|
||||
const nsStyleDisplay* aDisplay,
|
||||
nsFrameItems& aFrameItems)
|
||||
{
|
||||
NS_PRECONDITION(aDisplay->mDisplay == NS_STYLE_DISPLAY_TABLE_ROW ||
|
||||
aDisplay->mDisplay == NS_STYLE_DISPLAY_TABLE_ROW_GROUP ||
|
||||
aDisplay->mDisplay == NS_STYLE_DISPLAY_TABLE_FOOTER_GROUP ||
|
||||
aDisplay->mDisplay == NS_STYLE_DISPLAY_TABLE_HEADER_GROUP,
|
||||
"Unexpected call");
|
||||
MOZ_ASSERT(aItem.mStyleContext->StyleDisplay() == aDisplay,
|
||||
"Display style doesn't match style context");
|
||||
nsIContent* const content = aItem.mContent;
|
||||
nsStyleContext* const styleContext = aItem.mStyleContext;
|
||||
const uint32_t nameSpaceID = aItem.mNameSpaceID;
|
||||
|
||||
nsIFrame* newFrame;
|
||||
if (kNameSpaceID_MathML == nameSpaceID)
|
||||
newFrame = NS_NewMathMLmtrFrame(mPresShell, styleContext);
|
||||
else
|
||||
newFrame = NS_NewTableRowFrame(mPresShell, styleContext);
|
||||
if (aDisplay->mDisplay == NS_STYLE_DISPLAY_TABLE_ROW) {
|
||||
if (kNameSpaceID_MathML == nameSpaceID)
|
||||
newFrame = NS_NewMathMLmtrFrame(mPresShell, styleContext);
|
||||
else
|
||||
newFrame = NS_NewTableRowFrame(mPresShell, styleContext);
|
||||
} else {
|
||||
newFrame = NS_NewTableRowGroupFrame(mPresShell, styleContext);
|
||||
}
|
||||
|
||||
InitAndRestoreFrame(aState, content, aParentFrame, newFrame);
|
||||
|
||||
nsFrameConstructorSaveState absoluteSaveState;
|
||||
MakeTablePartAbsoluteContainingBlockIfNeeded(aState, aDisplay,
|
||||
absoluteSaveState,
|
||||
newFrame);
|
||||
|
||||
nsFrameItems childItems;
|
||||
NS_ASSERTION(aItem.mAnonChildren.IsEmpty(),
|
||||
"nsIAnonymousContentCreator::CreateAnonymousContent "
|
||||
@ -2107,6 +2144,11 @@ nsCSSFrameConstructor::ConstructTableCell(nsFrameConstructorState& aState,
|
||||
|
||||
InitAndRestoreFrame(aState, content, newFrame, cellInnerFrame);
|
||||
|
||||
nsFrameConstructorSaveState absoluteSaveState;
|
||||
MakeTablePartAbsoluteContainingBlockIfNeeded(aState, aDisplay,
|
||||
absoluteSaveState,
|
||||
newFrame);
|
||||
|
||||
nsFrameItems childItems;
|
||||
NS_ASSERTION(aItem.mAnonChildren.IsEmpty(),
|
||||
"nsIAnonymousContentCreator::CreateAnonymousContent "
|
||||
@ -4393,20 +4435,17 @@ nsCSSFrameConstructor::FindDisplayData(const nsStyleDisplay* aDisplay,
|
||||
FCDATA_DESIRED_PARENT_TYPE_TO_BITS(eTypeTable),
|
||||
NS_NewTableCaptionFrame) },
|
||||
{ NS_STYLE_DISPLAY_TABLE_ROW_GROUP,
|
||||
FCDATA_DECL(FCDATA_IS_TABLE_PART | FCDATA_DISALLOW_OUT_OF_FLOW |
|
||||
FCDATA_SKIP_ABSPOS_PUSH |
|
||||
FCDATA_DESIRED_PARENT_TYPE_TO_BITS(eTypeTable),
|
||||
NS_NewTableRowGroupFrame) },
|
||||
FULL_CTOR_FCDATA(FCDATA_IS_TABLE_PART |
|
||||
FCDATA_DESIRED_PARENT_TYPE_TO_BITS(eTypeTable),
|
||||
&nsCSSFrameConstructor::ConstructTableRowOrRowGroup) },
|
||||
{ NS_STYLE_DISPLAY_TABLE_HEADER_GROUP,
|
||||
FCDATA_DECL(FCDATA_IS_TABLE_PART | FCDATA_DISALLOW_OUT_OF_FLOW |
|
||||
FCDATA_SKIP_ABSPOS_PUSH |
|
||||
FCDATA_DESIRED_PARENT_TYPE_TO_BITS(eTypeTable),
|
||||
NS_NewTableRowGroupFrame) },
|
||||
FULL_CTOR_FCDATA(FCDATA_IS_TABLE_PART |
|
||||
FCDATA_DESIRED_PARENT_TYPE_TO_BITS(eTypeTable),
|
||||
&nsCSSFrameConstructor::ConstructTableRowOrRowGroup) },
|
||||
{ NS_STYLE_DISPLAY_TABLE_FOOTER_GROUP,
|
||||
FCDATA_DECL(FCDATA_IS_TABLE_PART | FCDATA_DISALLOW_OUT_OF_FLOW |
|
||||
FCDATA_SKIP_ABSPOS_PUSH |
|
||||
FCDATA_DESIRED_PARENT_TYPE_TO_BITS(eTypeTable),
|
||||
NS_NewTableRowGroupFrame) },
|
||||
FULL_CTOR_FCDATA(FCDATA_IS_TABLE_PART |
|
||||
FCDATA_DESIRED_PARENT_TYPE_TO_BITS(eTypeTable),
|
||||
&nsCSSFrameConstructor::ConstructTableRowOrRowGroup) },
|
||||
{ NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP,
|
||||
FCDATA_DECL(FCDATA_IS_TABLE_PART | FCDATA_DISALLOW_OUT_OF_FLOW |
|
||||
FCDATA_SKIP_ABSPOS_PUSH |
|
||||
@ -4419,7 +4458,7 @@ nsCSSFrameConstructor::FindDisplayData(const nsStyleDisplay* aDisplay,
|
||||
{ NS_STYLE_DISPLAY_TABLE_ROW,
|
||||
FULL_CTOR_FCDATA(FCDATA_IS_TABLE_PART |
|
||||
FCDATA_DESIRED_PARENT_TYPE_TO_BITS(eTypeRowGroup),
|
||||
&nsCSSFrameConstructor::ConstructTableRow) },
|
||||
&nsCSSFrameConstructor::ConstructTableRowOrRowGroup) },
|
||||
{ NS_STYLE_DISPLAY_TABLE_CELL,
|
||||
FULL_CTOR_FCDATA(FCDATA_IS_TABLE_PART |
|
||||
FCDATA_DESIRED_PARENT_TYPE_TO_BITS(eTypeRow),
|
||||
@ -7993,8 +8032,16 @@ nsCSSFrameConstructor::CreateContinuingTableFrame(nsIPresShell* aPresShell,
|
||||
nullptr);
|
||||
state.mCreatingExtraFrames = true;
|
||||
|
||||
nsStyleContext* const headerFooterStyleContext = rowGroupFrame->StyleContext();
|
||||
headerFooterFrame = static_cast<nsTableRowGroupFrame*>
|
||||
(NS_NewTableRowGroupFrame(aPresShell, rowGroupFrame->StyleContext()));
|
||||
(NS_NewTableRowGroupFrame(aPresShell, headerFooterStyleContext));
|
||||
|
||||
nsFrameConstructorSaveState absoluteSaveState;
|
||||
MakeTablePartAbsoluteContainingBlockIfNeeded(state,
|
||||
headerFooterStyleContext->StyleDisplay(),
|
||||
absoluteSaveState,
|
||||
headerFooterFrame);
|
||||
|
||||
nsIContent* headerFooter = rowGroupFrame->GetContent();
|
||||
headerFooterFrame->Init(headerFooter, newFrame, nullptr);
|
||||
ProcessChildren(state, headerFooter, rowGroupFrame->StyleContext(),
|
||||
@ -8071,10 +8118,16 @@ nsCSSFrameConstructor::CreateContinuingFrame(nsPresContext* aPresContext,
|
||||
} else if (nsGkAtoms::tableRowGroupFrame == frameType) {
|
||||
newFrame = NS_NewTableRowGroupFrame(shell, styleContext);
|
||||
newFrame->Init(content, aParentFrame, aFrame);
|
||||
if (newFrame->GetStateBits() & NS_FRAME_CAN_HAVE_ABSPOS_CHILDREN) {
|
||||
nsTableFrame::RegisterPositionedTablePart(newFrame);
|
||||
}
|
||||
} else if (nsGkAtoms::tableRowFrame == frameType) {
|
||||
newFrame = NS_NewTableRowFrame(shell, styleContext);
|
||||
|
||||
newFrame->Init(content, aParentFrame, aFrame);
|
||||
if (newFrame->GetStateBits() & NS_FRAME_CAN_HAVE_ABSPOS_CHILDREN) {
|
||||
nsTableFrame::RegisterPositionedTablePart(newFrame);
|
||||
}
|
||||
|
||||
// Create a continuing frame for each table cell frame
|
||||
nsFrameItems newChildList;
|
||||
@ -8099,6 +8152,9 @@ nsCSSFrameConstructor::CreateContinuingFrame(nsPresContext* aPresContext,
|
||||
newFrame = NS_NewTableCellFrame(shell, styleContext, IsBorderCollapse(aParentFrame));
|
||||
|
||||
newFrame->Init(content, aParentFrame, aFrame);
|
||||
if (newFrame->GetStateBits() & NS_FRAME_CAN_HAVE_ABSPOS_CHILDREN) {
|
||||
nsTableFrame::RegisterPositionedTablePart(newFrame);
|
||||
}
|
||||
|
||||
// Create a continuing area frame
|
||||
nsIFrame* blockFrame = aFrame->GetFirstPrincipalChild();
|
||||
@ -8799,15 +8855,14 @@ nsCSSFrameConstructor::sPseudoParentData[eParentTypeCount] = {
|
||||
FULL_CTOR_FCDATA(FCDATA_IS_TABLE_PART | FCDATA_SKIP_FRAMESET |
|
||||
FCDATA_USE_CHILD_ITEMS |
|
||||
FCDATA_DESIRED_PARENT_TYPE_TO_BITS(eTypeRowGroup),
|
||||
&nsCSSFrameConstructor::ConstructTableRow),
|
||||
&nsCSSFrameConstructor::ConstructTableRowOrRowGroup),
|
||||
&nsCSSAnonBoxes::tableRow
|
||||
},
|
||||
{ // Row group
|
||||
FCDATA_DECL(FCDATA_IS_TABLE_PART | FCDATA_SKIP_FRAMESET |
|
||||
FCDATA_DISALLOW_OUT_OF_FLOW | FCDATA_USE_CHILD_ITEMS |
|
||||
FCDATA_SKIP_ABSPOS_PUSH |
|
||||
FCDATA_DESIRED_PARENT_TYPE_TO_BITS(eTypeTable),
|
||||
NS_NewTableRowGroupFrame),
|
||||
FULL_CTOR_FCDATA(FCDATA_IS_TABLE_PART | FCDATA_SKIP_FRAMESET |
|
||||
FCDATA_USE_CHILD_ITEMS |
|
||||
FCDATA_DESIRED_PARENT_TYPE_TO_BITS(eTypeTable),
|
||||
&nsCSSFrameConstructor::ConstructTableRowOrRowGroup),
|
||||
&nsCSSAnonBoxes::tableRowGroup
|
||||
},
|
||||
{ // Column group
|
||||
|
@ -383,13 +383,13 @@ private:
|
||||
nsFrameItems& aFrameItems);
|
||||
|
||||
/**
|
||||
* FrameConstructionData callback used for constructing table rows.
|
||||
* FrameConstructionData callback for constructing table rows and row groups.
|
||||
*/
|
||||
nsIFrame* ConstructTableRow(nsFrameConstructorState& aState,
|
||||
FrameConstructionItem& aItem,
|
||||
nsIFrame* aParentFrame,
|
||||
const nsStyleDisplay* aStyleDisplay,
|
||||
nsFrameItems& aFrameItems);
|
||||
nsIFrame* ConstructTableRowOrRowGroup(nsFrameConstructorState& aState,
|
||||
FrameConstructionItem& aItem,
|
||||
nsIFrame* aParentFrame,
|
||||
const nsStyleDisplay* aStyleDisplay,
|
||||
nsFrameItems& aFrameItems);
|
||||
|
||||
/**
|
||||
* FrameConstructionData callback used for constructing table columns.
|
||||
|
@ -1023,6 +1023,14 @@ public:
|
||||
|
||||
bool IsDeviceSizePageSize();
|
||||
|
||||
bool HasWarnedAboutPositionedTableParts() const {
|
||||
return mHasWarnedAboutPositionedTableParts;
|
||||
}
|
||||
|
||||
void SetHasWarnedAboutPositionedTableParts() {
|
||||
mHasWarnedAboutPositionedTableParts = true;
|
||||
}
|
||||
|
||||
protected:
|
||||
friend class nsRunnableMethod<nsPresContext>;
|
||||
NS_HIDDEN_(void) ThemeChangedInternal();
|
||||
@ -1326,6 +1334,8 @@ protected:
|
||||
mutable unsigned mPaintFlashing : 1;
|
||||
mutable unsigned mPaintFlashingInitialized : 1;
|
||||
|
||||
unsigned mHasWarnedAboutPositionedTableParts : 1;
|
||||
|
||||
#ifdef DEBUG
|
||||
bool mInitialized;
|
||||
#endif
|
||||
|
@ -87,6 +87,16 @@ nsTableCellFrame::Init(nsIContent* aContent,
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsTableCellFrame::DestroyFrom(nsIFrame* aDestructRoot)
|
||||
{
|
||||
if (GetStateBits() & NS_FRAME_CAN_HAVE_ABSPOS_CHILDREN) {
|
||||
nsTableFrame::UnregisterPositionedTablePart(this, aDestructRoot);
|
||||
}
|
||||
|
||||
nsContainerFrame::DestroyFrom(aDestructRoot);
|
||||
}
|
||||
|
||||
// nsIPercentHeightObserver methods
|
||||
|
||||
void
|
||||
|
@ -47,6 +47,8 @@ public:
|
||||
nsIFrame* aParent,
|
||||
nsIFrame* aPrevInFlow) MOZ_OVERRIDE;
|
||||
|
||||
virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE;
|
||||
|
||||
#ifdef ACCESSIBILITY
|
||||
virtual mozilla::a11y::AccType AccessibleType() MOZ_OVERRIDE;
|
||||
#endif
|
||||
|
@ -27,12 +27,14 @@
|
||||
#include "FixedTableLayoutStrategy.h"
|
||||
|
||||
#include "nsPresContext.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsCSSRendering.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsCSSAnonBoxes.h"
|
||||
#include "nsIPresShell.h"
|
||||
#include "nsIDOMElement.h"
|
||||
#include "nsIDOMHTMLElement.h"
|
||||
#include "nsIScriptError.h"
|
||||
#include "nsFrameManager.h"
|
||||
#include "nsError.h"
|
||||
#include "nsAutoPtr.h"
|
||||
@ -41,6 +43,7 @@
|
||||
#include "nsDisplayList.h"
|
||||
#include "nsIScrollableFrame.h"
|
||||
#include "nsCSSProps.h"
|
||||
#include "RestyleTracker.h"
|
||||
#include <algorithm>
|
||||
|
||||
using namespace mozilla;
|
||||
@ -252,6 +255,81 @@ nsTableFrame::PageBreakAfter(nsIFrame* aSourceFrame,
|
||||
return false;
|
||||
}
|
||||
|
||||
typedef nsTArray<nsIFrame*> FrameTArray;
|
||||
|
||||
/* static */ void
|
||||
nsTableFrame::DestroyPositionedTablePartArray(void* aPropertyValue)
|
||||
{
|
||||
auto positionedObjs = static_cast<FrameTArray*>(aPropertyValue);
|
||||
delete positionedObjs;
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
nsTableFrame::RegisterPositionedTablePart(nsIFrame* aFrame)
|
||||
{
|
||||
// Supporting relative positioning for table parts other than table cells has
|
||||
// the potential to break sites that apply 'position: relative' to those
|
||||
// parts, expecting nothing to happen. We warn at the console to make tracking
|
||||
// down the issue easy.
|
||||
if (nsGkAtoms::tableCellFrame != aFrame->GetType()) {
|
||||
nsIContent* content = aFrame->GetContent();
|
||||
nsPresContext* presContext = aFrame->PresContext();
|
||||
if (content && !presContext->HasWarnedAboutPositionedTableParts()) {
|
||||
presContext->SetHasWarnedAboutPositionedTableParts();
|
||||
nsContentUtils::ReportToConsole(nsIScriptError::warningFlag,
|
||||
NS_LITERAL_CSTRING("Layout: Tables"),
|
||||
content->OwnerDoc(),
|
||||
nsContentUtils::eLAYOUT_PROPERTIES,
|
||||
"TablePartRelPosWarning");
|
||||
}
|
||||
}
|
||||
|
||||
nsTableFrame* tableFrame = nsTableFrame::GetTableFrame(aFrame);
|
||||
MOZ_ASSERT(tableFrame, "Should have a table frame here");
|
||||
tableFrame = static_cast<nsTableFrame*>(tableFrame->FirstContinuation());
|
||||
|
||||
// Retrieve the positioned parts array for this table.
|
||||
FrameProperties props = tableFrame->Properties();
|
||||
auto positionedParts =
|
||||
static_cast<FrameTArray*>(props.Get(PositionedTablePartArray()));
|
||||
|
||||
// Lazily create the array if it doesn't exist yet.
|
||||
if (!positionedParts) {
|
||||
positionedParts = new FrameTArray;
|
||||
props.Set(PositionedTablePartArray(), positionedParts);
|
||||
}
|
||||
|
||||
// Add this frame to the list.
|
||||
positionedParts->AppendElement(aFrame);
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
nsTableFrame::UnregisterPositionedTablePart(nsIFrame* aFrame,
|
||||
nsIFrame* aDestructRoot)
|
||||
{
|
||||
// Retrieve the table frame, and ensure that we hit aDestructRoot on the way.
|
||||
// If we don't, that means that the table frame will be destroyed, so we don't
|
||||
// need to bother with unregistering this frame.
|
||||
nsTableFrame* tableFrame = GetTableFramePassingThrough(aDestructRoot, aFrame);
|
||||
if (!tableFrame) {
|
||||
return;
|
||||
}
|
||||
tableFrame = static_cast<nsTableFrame*>(tableFrame->FirstContinuation());
|
||||
|
||||
// Retrieve the positioned parts array for this table.
|
||||
FrameProperties props = tableFrame->Properties();
|
||||
auto positionedParts =
|
||||
static_cast<FrameTArray*>(props.Get(PositionedTablePartArray()));
|
||||
|
||||
// Remove the frame.
|
||||
MOZ_ASSERT(positionedParts &&
|
||||
positionedParts->IndexOf(aFrame) != FrameTArray::NoIndex,
|
||||
"Asked to unregister a positioned table part that wasn't registered");
|
||||
if (positionedParts) {
|
||||
positionedParts->RemoveElement(aFrame);
|
||||
}
|
||||
}
|
||||
|
||||
// XXX this needs to be cleaned up so that the frame constructor breaks out col group
|
||||
// frames into a separate child list, bug 343048.
|
||||
nsresult
|
||||
@ -1814,6 +1892,10 @@ nsresult nsTableFrame::Reflow(nsPresContext* aPresContext,
|
||||
AdjustForCollapsingRowsCols(aDesiredSize, borderPadding);
|
||||
}
|
||||
|
||||
// If there are any relatively-positioned table parts, we need to reflow their
|
||||
// absolutely-positioned descendants now that their dimensions are final.
|
||||
FixupPositionedTableParts(aPresContext, aReflowState);
|
||||
|
||||
// make sure the table overflow area does include the table rect.
|
||||
nsRect tableRect(0, 0, aDesiredSize.Width(), aDesiredSize.Height()) ;
|
||||
|
||||
@ -1834,6 +1916,57 @@ nsresult nsTableFrame::Reflow(nsPresContext* aPresContext,
|
||||
return rv;
|
||||
}
|
||||
|
||||
void
|
||||
nsTableFrame::FixupPositionedTableParts(nsPresContext* aPresContext,
|
||||
const nsHTMLReflowState& aReflowState)
|
||||
{
|
||||
auto positionedParts =
|
||||
static_cast<FrameTArray*>(Properties().Get(PositionedTablePartArray()));
|
||||
if (!positionedParts) {
|
||||
return;
|
||||
}
|
||||
|
||||
OverflowChangedTracker overflowTracker;
|
||||
overflowTracker.SetSubtreeRoot(this);
|
||||
|
||||
for (size_t i = 0; i < positionedParts->Length(); ++i) {
|
||||
nsIFrame* positionedPart = positionedParts->ElementAt(i);
|
||||
|
||||
// As we've already finished reflow, positionedParts's size and overflow
|
||||
// areas have already been assigned, so we just pull them back out.
|
||||
nsSize size(positionedPart->GetSize());
|
||||
nsHTMLReflowMetrics desiredSize(aReflowState.GetWritingMode());
|
||||
desiredSize.Width() = size.width;
|
||||
desiredSize.Height() = size.height;
|
||||
desiredSize.mOverflowAreas = positionedPart->GetOverflowAreasRelativeToSelf();
|
||||
|
||||
// Construct a dummy reflow state and reflow status.
|
||||
// XXX(seth): Note that the dummy reflow state doesn't have a correct
|
||||
// chain of parent reflow states. It also doesn't necessarily have a
|
||||
// correct containing block.
|
||||
nsHTMLReflowState reflowState(aPresContext, positionedPart,
|
||||
aReflowState.rendContext,
|
||||
nsSize(size.width, NS_UNCONSTRAINEDSIZE),
|
||||
nsHTMLReflowState::DUMMY_PARENT_REFLOW_STATE);
|
||||
nsReflowStatus reflowStatus = NS_FRAME_COMPLETE;
|
||||
|
||||
// Reflow absolutely-positioned descendants of the positioned part.
|
||||
// FIXME: Unconditionally using NS_UNCONSTRAINEDSIZE for the height and
|
||||
// ignoring any change to the reflow status aren't correct. We'll never
|
||||
// paginate absolutely positioned frames.
|
||||
overflowTracker.AddFrame(positionedPart);
|
||||
nsFrame* positionedFrame = static_cast<nsFrame*>(positionedPart);
|
||||
positionedFrame->FinishReflowWithAbsoluteFrames(PresContext(),
|
||||
desiredSize,
|
||||
reflowState,
|
||||
reflowStatus,
|
||||
true);
|
||||
}
|
||||
|
||||
// Propagate updated overflow areas up the tree.
|
||||
overflowTracker.Flush();
|
||||
}
|
||||
|
||||
bool
|
||||
nsTableFrame::UpdateOverflow()
|
||||
{
|
||||
@ -3444,6 +3577,32 @@ nsTableFrame::GetTableFrame(nsIFrame* aFrame)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsTableFrame*
|
||||
nsTableFrame::GetTableFramePassingThrough(nsIFrame* aMustPassThrough,
|
||||
nsIFrame* aFrame)
|
||||
{
|
||||
MOZ_ASSERT(aMustPassThrough == aFrame ||
|
||||
nsLayoutUtils::IsProperAncestorFrame(aMustPassThrough, aFrame),
|
||||
"aMustPassThrough should be an ancestor");
|
||||
|
||||
// Retrieve the table frame, and ensure that we hit aMustPassThrough on the
|
||||
// way. If we don't, just return null.
|
||||
bool hitPassThroughFrame = false;
|
||||
nsTableFrame* tableFrame = nullptr;
|
||||
for (nsIFrame* ancestor = aFrame; ancestor; ancestor = ancestor->GetParent()) {
|
||||
if (ancestor == aMustPassThrough) {
|
||||
hitPassThroughFrame = true;
|
||||
}
|
||||
if (nsGkAtoms::tableFrame == ancestor->GetType()) {
|
||||
tableFrame = static_cast<nsTableFrame*>(ancestor);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
MOZ_ASSERT(tableFrame, "Should have a table frame here");
|
||||
return hitPassThroughFrame ? tableFrame : nullptr;
|
||||
}
|
||||
|
||||
bool
|
||||
nsTableFrame::IsAutoHeight()
|
||||
{
|
||||
|
@ -111,6 +111,9 @@ class nsTableFrame : public nsContainerFrame
|
||||
public:
|
||||
NS_DECL_FRAMEARENA_HELPERS
|
||||
|
||||
static void DestroyPositionedTablePartArray(void* aPropertyValue);
|
||||
NS_DECLARE_FRAME_PROPERTY(PositionedTablePartArray, DestroyPositionedTablePartArray)
|
||||
|
||||
/** nsTableOuterFrame has intimate knowledge of the inner table frame */
|
||||
friend class nsTableOuterFrame;
|
||||
|
||||
@ -146,6 +149,15 @@ public:
|
||||
|
||||
static bool PageBreakAfter(nsIFrame* aSourceFrame,
|
||||
nsIFrame* aNextFrame);
|
||||
|
||||
// Register a positioned table part with its nsTableFrame. These objects will
|
||||
// be visited by FixupPositionedTableParts after reflow is complete. (See that
|
||||
// function for more explanation.) Should be called during frame construction.
|
||||
static void RegisterPositionedTablePart(nsIFrame* aFrame);
|
||||
|
||||
// Unregister a positioned table part with its nsTableFrame.
|
||||
static void UnregisterPositionedTablePart(nsIFrame* aFrame,
|
||||
nsIFrame* aDestructRoot);
|
||||
|
||||
nsPoint GetFirstSectionOrigin(const nsHTMLReflowState& aReflowState) const;
|
||||
/*
|
||||
@ -179,6 +191,12 @@ public:
|
||||
/** helper method to find the table parent of any table frame object */
|
||||
static nsTableFrame* GetTableFrame(nsIFrame* aSourceFrame);
|
||||
|
||||
/* Like GetTableFrame, but will return nullptr if we don't pass through
|
||||
* aMustPassThrough on the way to the table.
|
||||
*/
|
||||
static nsTableFrame* GetTableFramePassingThrough(nsIFrame* aMustPassThrough,
|
||||
nsIFrame* aSourceFrame);
|
||||
|
||||
typedef void (* DisplayGenericTablePartTraversal)
|
||||
(nsDisplayListBuilder* aBuilder, nsFrame* aFrame,
|
||||
const nsRect& aDirtyRect, const nsDisplayListSet& aLists);
|
||||
@ -549,6 +567,18 @@ protected:
|
||||
void AdjustForCollapsingRowsCols(nsHTMLReflowMetrics& aDesiredSize,
|
||||
nsMargin aBorderPadding);
|
||||
|
||||
/** FixupPositionedTableParts is called at the end of table reflow to reflow
|
||||
* the absolutely positioned descendants of positioned table parts. This is
|
||||
* necessary because the dimensions of table parts may change after they've
|
||||
* been reflowed (e.g. in AdjustForCollapsingRowsCols).
|
||||
*/
|
||||
|
||||
void FixupPositionedTableParts(nsPresContext* aPresContext,
|
||||
const nsHTMLReflowState& aReflowState);
|
||||
|
||||
// Clears the list of positioned table parts.
|
||||
void ClearAllPositionedTableParts();
|
||||
|
||||
nsITableLayoutStrategy* LayoutStrategy() const {
|
||||
return static_cast<nsTableFrame*>(FirstInFlow())->
|
||||
mTableLayoutStrategy;
|
||||
|
@ -150,6 +150,16 @@ nsTableRowFrame::Init(nsIContent* aContent,
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsTableRowFrame::DestroyFrom(nsIFrame* aDestructRoot)
|
||||
{
|
||||
if (GetStateBits() & NS_FRAME_CAN_HAVE_ABSPOS_CHILDREN) {
|
||||
nsTableFrame::UnregisterPositionedTablePart(this, aDestructRoot);
|
||||
}
|
||||
|
||||
nsContainerFrame::DestroyFrom(aDestructRoot);
|
||||
}
|
||||
|
||||
/* virtual */ void
|
||||
nsTableRowFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
|
||||
{
|
||||
|
@ -36,6 +36,9 @@ public:
|
||||
virtual void Init(nsIContent* aContent,
|
||||
nsIFrame* aParent,
|
||||
nsIFrame* aPrevInFlow) MOZ_OVERRIDE;
|
||||
|
||||
virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE;
|
||||
|
||||
/** @see nsIFrame::DidSetStyleContext */
|
||||
virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext) MOZ_OVERRIDE;
|
||||
|
||||
|
@ -34,6 +34,16 @@ nsTableRowGroupFrame::~nsTableRowGroupFrame()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
nsTableRowGroupFrame::DestroyFrom(nsIFrame* aDestructRoot)
|
||||
{
|
||||
if (GetStateBits() & NS_FRAME_CAN_HAVE_ABSPOS_CHILDREN) {
|
||||
nsTableFrame::UnregisterPositionedTablePart(this, aDestructRoot);
|
||||
}
|
||||
|
||||
nsContainerFrame::DestroyFrom(aDestructRoot);
|
||||
}
|
||||
|
||||
NS_QUERYFRAME_HEAD(nsTableRowGroupFrame)
|
||||
NS_QUERYFRAME_ENTRY(nsTableRowGroupFrame)
|
||||
NS_QUERYFRAME_TAIL_INHERITING(nsContainerFrame)
|
||||
|
@ -67,6 +67,9 @@ public:
|
||||
*/
|
||||
friend nsIFrame* NS_NewTableRowGroupFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
|
||||
virtual ~nsTableRowGroupFrame();
|
||||
|
||||
virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE;
|
||||
|
||||
/** @see nsIFrame::DidSetStyleContext */
|
||||
virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext) MOZ_OVERRIDE;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user