зеркало из https://github.com/mozilla/gecko-dev.git
Do not prevent the creation of multiple captions, but display only the first one, bug 309322 r/sr=bzbarsky
This commit is contained in:
Родитель
48fd426131
Коммит
5663eeaaaa
|
@ -8415,6 +8415,7 @@ nsCSSFrameConstructor::IsValidSibling(nsIFrame* aParentFrame,
|
|||
{
|
||||
if ((NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP == aSiblingDisplay) ||
|
||||
(NS_STYLE_DISPLAY_TABLE_COLUMN == aSiblingDisplay) ||
|
||||
(NS_STYLE_DISPLAY_TABLE_CAPTION == aSiblingDisplay) ||
|
||||
(NS_STYLE_DISPLAY_TABLE_HEADER_GROUP == aSiblingDisplay) ||
|
||||
(NS_STYLE_DISPLAY_TABLE_ROW_GROUP == aSiblingDisplay) ||
|
||||
(NS_STYLE_DISPLAY_TABLE_FOOTER_GROUP == aSiblingDisplay)) {
|
||||
|
@ -8431,6 +8432,8 @@ nsCSSFrameConstructor::IsValidSibling(nsIFrame* aParentFrame,
|
|||
return (NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP == aDisplay);
|
||||
case NS_STYLE_DISPLAY_TABLE_COLUMN:
|
||||
return (NS_STYLE_DISPLAY_TABLE_COLUMN == aDisplay);
|
||||
case NS_STYLE_DISPLAY_TABLE_CAPTION:
|
||||
return (NS_STYLE_DISPLAY_TABLE_CAPTION == aDisplay);
|
||||
default: // all of the row group types
|
||||
return (NS_STYLE_DISPLAY_TABLE_HEADER_GROUP == aDisplay) ||
|
||||
(NS_STYLE_DISPLAY_TABLE_ROW_GROUP == aDisplay) ||
|
||||
|
@ -8438,22 +8441,14 @@ nsCSSFrameConstructor::IsValidSibling(nsIFrame* aParentFrame,
|
|||
(NS_STYLE_DISPLAY_TABLE_CAPTION == aDisplay);
|
||||
}
|
||||
}
|
||||
else if (NS_STYLE_DISPLAY_TABLE_CAPTION == aSiblingDisplay) {
|
||||
// Nothing can be a sibling of a caption since there can only be one caption.
|
||||
// But this check is necessary since a row group and caption are siblings
|
||||
// from a content perspective (they share the table content as parent)
|
||||
return PR_FALSE;
|
||||
}
|
||||
else {
|
||||
if (nsLayoutAtoms::fieldSetFrame == aParentFrame->GetType()) {
|
||||
// Legends can be sibling of legends but not of other content in the fieldset
|
||||
nsIAtom* sibType = aSibling.GetType();
|
||||
nsCOMPtr<nsIDOMHTMLLegendElement> legendContent(do_QueryInterface(&aContent));
|
||||
else if (nsLayoutAtoms::fieldSetFrame == aParentFrame->GetType()) {
|
||||
// Legends can be sibling of legends but not of other content in the fieldset
|
||||
nsIAtom* sibType = aSibling.GetType();
|
||||
nsCOMPtr<nsIDOMHTMLLegendElement> legendContent(do_QueryInterface(&aContent));
|
||||
|
||||
if ((legendContent && (nsLayoutAtoms::legendFrame != sibType)) ||
|
||||
(!legendContent && (nsLayoutAtoms::legendFrame == sibType)))
|
||||
return PR_FALSE;
|
||||
}
|
||||
if ((legendContent && (nsLayoutAtoms::legendFrame != sibType)) ||
|
||||
(!legendContent && (nsLayoutAtoms::legendFrame == sibType)))
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
return PR_TRUE;
|
||||
|
@ -8879,15 +8874,6 @@ nsCSSFrameConstructor::ContentAppended(nsIContent* aContainer,
|
|||
// the outer table frame's additional child list.
|
||||
nsFrameItems captionItems;
|
||||
|
||||
PRBool hasCaption = PR_FALSE;
|
||||
if (nsLayoutAtoms::tableFrame == frameType) {
|
||||
nsIFrame* outerTable = parentFrame->GetParent();
|
||||
if (outerTable) {
|
||||
if (outerTable->GetFirstChild(nsLayoutAtoms::captionList)) {
|
||||
hasCaption = PR_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
PRUint32 i;
|
||||
count = aContainer->GetChildCount();
|
||||
for (i = aNewIndexInContainer; i < count; i++) {
|
||||
|
@ -8895,19 +8881,10 @@ nsCSSFrameConstructor::ContentAppended(nsIContent* aContainer,
|
|||
// lookup the table child frame type as it is much more difficult to remove a frame
|
||||
// and all it descendants (abs. pos. for instance) than to prevent the frame creation.
|
||||
if (nsLayoutAtoms::tableFrame == frameType) {
|
||||
if (hasCaption) {
|
||||
// Resolve the style context and get its display
|
||||
nsRefPtr<nsStyleContext> childStyleContext;
|
||||
childStyleContext = ResolveStyleContext(parentFrame, childContent);
|
||||
if (childStyleContext->GetStyleDisplay()->mDisplay == NS_STYLE_DISPLAY_TABLE_CAPTION)
|
||||
continue; //don't create a table caption frame and its descendants
|
||||
}
|
||||
nsFrameItems tempItems;
|
||||
ConstructFrame(state, childContent, parentFrame, tempItems);
|
||||
if (tempItems.childList) {
|
||||
if (nsLayoutAtoms::tableCaptionFrame == tempItems.childList->GetType()) {
|
||||
NS_ASSERTION(!captionItems.childList, "don't append twice a caption");
|
||||
hasCaption = PR_TRUE; // remember that we have a caption now
|
||||
captionItems.AddChild(tempItems.childList);
|
||||
}
|
||||
else {
|
||||
|
@ -9031,7 +9008,8 @@ nsCSSFrameConstructor::NeedSpecialFrameReframe(nsIContent* aParent1,
|
|||
if (aChild->IsContentOfType(nsIContent::eELEMENT)) {
|
||||
nsRefPtr<nsStyleContext> styleContext;
|
||||
styleContext = ResolveStyleContext(aParentFrame, aChild);
|
||||
childIsBlock = styleContext->GetStyleDisplay()->IsBlockLevel();
|
||||
const nsStyleDisplay* display = styleContext->GetStyleDisplay();
|
||||
childIsBlock = display->IsBlockLevel() || IsTableRelated(display->mDisplay, PR_TRUE);
|
||||
}
|
||||
nsIFrame* prevParent; // parent of prev sibling
|
||||
nsIFrame* nextParent; // parent of next sibling
|
||||
|
@ -9368,15 +9346,6 @@ nsCSSFrameConstructor::ContentInserted(nsIContent* aContainer,
|
|||
GetFloatContainingBlock(parentFrame),
|
||||
aFrameState);
|
||||
|
||||
PRBool hasCaption = PR_FALSE;
|
||||
if (nsLayoutAtoms::tableFrame == parentFrame->GetType()) {
|
||||
nsIFrame* outerTable = parentFrame->GetParent();
|
||||
if (outerTable) {
|
||||
if (outerTable->GetFirstChild(nsLayoutAtoms::captionList)) {
|
||||
hasCaption = PR_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Recover state for the containing block - we need to know if
|
||||
// it has :first-letter or :first-line style applied to it. The
|
||||
|
@ -9464,13 +9433,6 @@ nsCSSFrameConstructor::ContentInserted(nsIContent* aContainer,
|
|||
if (childStyleContext->GetStyleDisplay()->mDisplay != NS_STYLE_DISPLAY_TABLE_COLUMN)
|
||||
return NS_OK; //don't create anything else than columns below a colgroup
|
||||
}
|
||||
else if (parentFrame->GetType() == nsLayoutAtoms::tableFrame && hasCaption) {
|
||||
// Resolve the style context and get its display
|
||||
nsRefPtr<nsStyleContext> childStyleContext;
|
||||
childStyleContext = ResolveStyleContext(parentFrame, aChild);
|
||||
if (childStyleContext->GetStyleDisplay()->mDisplay == NS_STYLE_DISPLAY_TABLE_CAPTION)
|
||||
return NS_OK; //don't create a second table caption frame and its descendants
|
||||
}
|
||||
|
||||
// if the container is a table and a caption will be appended, it needs to be
|
||||
// put in the outer table frame's additional child list.
|
||||
|
@ -9549,13 +9511,16 @@ nsCSSFrameConstructor::ContentInserted(nsIContent* aContainer,
|
|||
// will get lost
|
||||
NS_ASSERTION(nsLayoutAtoms::tableOuterFrame == outerTableFrame->GetType(),
|
||||
"Pseudo frame construction failure, a caption can be only a child of a outer table frame");
|
||||
// the double caption creation was prevented above, so we are sure
|
||||
// that we can append
|
||||
NS_ASSERTION(!outerTableFrame->GetFirstChild(nsLayoutAtoms::captionList),
|
||||
"No double captions please");
|
||||
state.mFrameManager->AppendFrames(outerTableFrame,
|
||||
nsLayoutAtoms::captionList,
|
||||
newCaptionFrame);
|
||||
if (isAppend) {
|
||||
state.mFrameManager->AppendFrames(outerTableFrame,
|
||||
nsLayoutAtoms::captionList,
|
||||
newCaptionFrame);
|
||||
}
|
||||
else {
|
||||
state.mFrameManager->InsertFrames(outerTableFrame,
|
||||
nsLayoutAtoms::captionList,
|
||||
prevSibling, newCaptionFrame);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10710,40 +10675,12 @@ nsCSSFrameConstructor::CreateContinuingOuterTableFrame(nsIPresShell* aPresShe
|
|||
nsFrameItems newChildFrames;
|
||||
|
||||
nsIFrame* childFrame = aFrame->GetFirstChild(nsnull);
|
||||
while (childFrame) {
|
||||
// See if it's the inner table frame
|
||||
if (nsLayoutAtoms::tableFrame == childFrame->GetType()) {
|
||||
nsIFrame* continuingTableFrame;
|
||||
|
||||
// It's the inner table frame, so create a continuing frame
|
||||
CreateContinuingFrame(aPresContext, childFrame, newFrame, &continuingTableFrame);
|
||||
newChildFrames.AddChild(continuingTableFrame);
|
||||
} else {
|
||||
// XXX remove this code and the above checks. We don't want to replicate
|
||||
// the caption (that is what the thead is for). This code is not executed
|
||||
// anyway, because the caption was put in a different child list.
|
||||
nsStyleContext* captionStyle = childFrame->GetStyleContext();
|
||||
nsIContent* caption = childFrame->GetContent();
|
||||
NS_ASSERTION(NS_STYLE_DISPLAY_TABLE_CAPTION ==
|
||||
captionStyle->GetStyleDisplay()->mDisplay,
|
||||
"expected caption");
|
||||
|
||||
// Replicate the caption frame
|
||||
// XXX We have to do it this way instead of calling ConstructFrameByDisplayType(),
|
||||
// because of a bug in the way ConstructTableFrame() handles the initial child
|
||||
// list...
|
||||
nsIFrame* captionFrame = NS_NewTableCaptionFrame(aPresShell);
|
||||
nsFrameItems childItems;
|
||||
nsFrameConstructorState state(mPresShell, mFixedContainingBlock,
|
||||
GetAbsoluteContainingBlock(newFrame),
|
||||
captionFrame);
|
||||
captionFrame->Init(aPresContext, caption, newFrame, captionStyle, nsnull);
|
||||
ProcessChildren(state, caption, captionFrame, PR_TRUE, childItems,
|
||||
PR_TRUE);
|
||||
captionFrame->SetInitialChildList(aPresContext, nsnull, childItems.childList);
|
||||
newChildFrames.AddChild(captionFrame);
|
||||
}
|
||||
childFrame = childFrame->GetNextSibling();
|
||||
if (childFrame) {
|
||||
nsIFrame* continuingTableFrame;
|
||||
CreateContinuingFrame(aPresContext, childFrame, newFrame, &continuingTableFrame);
|
||||
newChildFrames.AddChild(continuingTableFrame);
|
||||
|
||||
NS_ASSERTION(!childFrame->GetNextSibling(),"there can be only one inner table frame");
|
||||
}
|
||||
|
||||
// Set the outer table's initial child list
|
||||
|
|
|
@ -74,10 +74,7 @@ nsTableCaptionFrame::~nsTableCaptionFrame()
|
|||
NS_IMETHODIMP
|
||||
nsTableOuterFrame::Destroy(nsPresContext* aPresContext)
|
||||
{
|
||||
if (mCaptionFrame) {
|
||||
mCaptionFrame->Destroy(aPresContext);
|
||||
}
|
||||
|
||||
mCaptionFrames.DestroyFrames(aPresContext);
|
||||
return nsHTMLContainerFrame::Destroy(aPresContext);
|
||||
}
|
||||
|
||||
|
@ -168,7 +165,7 @@ nsIFrame*
|
|||
nsTableOuterFrame::GetFirstChild(nsIAtom* aListName) const
|
||||
{
|
||||
if (nsLayoutAtoms::captionList == aListName) {
|
||||
return mCaptionFrame;
|
||||
return mCaptionFrames.FirstChild();
|
||||
}
|
||||
if (!aListName) {
|
||||
return mFrames.FirstChild();
|
||||
|
@ -192,7 +189,8 @@ nsTableOuterFrame::SetInitialChildList(nsPresContext* aPresContext,
|
|||
{
|
||||
if (nsLayoutAtoms::captionList == aListName) {
|
||||
// the frame constructor already checked for table-caption display type
|
||||
mCaptionFrame = aChildList;
|
||||
mCaptionFrames.SetFrames(aChildList);
|
||||
mCaptionFrame = mCaptionFrames.FirstChild();
|
||||
}
|
||||
else {
|
||||
mFrames.SetFrames(aChildList);
|
||||
|
@ -213,23 +211,18 @@ nsTableOuterFrame::AppendFrames(nsIAtom* aListName,
|
|||
{
|
||||
nsresult rv;
|
||||
|
||||
// We only have two child frames: the inner table and one caption frame.
|
||||
// We only have two child frames: the inner table and a caption frame.
|
||||
// The inner frame is provided when we're initialized, and it cannot change
|
||||
if (nsLayoutAtoms::captionList == aListName) {
|
||||
NS_PRECONDITION(!mCaptionFrame, "already have a caption frame");
|
||||
// We only support having a single caption frame
|
||||
if (mCaptionFrame || (LengthOf(aFrameList) > 1)) {
|
||||
rv = NS_ERROR_UNEXPECTED;
|
||||
} else {
|
||||
// Insert the caption frame into the child list
|
||||
mCaptionFrame = aFrameList;
|
||||
mCaptionFrames.AppendFrames(this, aFrameList);
|
||||
mCaptionFrame = mCaptionFrames.FirstChild();
|
||||
|
||||
// Reflow the new caption frame. It's already marked dirty, so generate a reflow
|
||||
// command that tells us to reflow our dirty child frames
|
||||
rv = GetPresContext()->
|
||||
PresShell()->AppendReflowCommand(this, eReflowType_ReflowDirty,
|
||||
// Reflow the new caption frame. It's already marked dirty, so generate a reflow
|
||||
// command that tells us to reflow our dirty child frames
|
||||
rv = GetPresContext()->
|
||||
PresShell()->AppendReflowCommand(this, eReflowType_ReflowDirty,
|
||||
nsnull);
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
NS_PRECONDITION(PR_FALSE, "unexpected child frame type");
|
||||
|
@ -244,8 +237,14 @@ nsTableOuterFrame::InsertFrames(nsIAtom* aListName,
|
|||
nsIFrame* aPrevFrame,
|
||||
nsIFrame* aFrameList)
|
||||
{
|
||||
NS_PRECONDITION(!aPrevFrame, "invalid previous frame");
|
||||
return AppendFrames(aListName, aFrameList);
|
||||
if (nsLayoutAtoms::captionList == aListName) {
|
||||
mCaptionFrames.InsertFrames(nsnull, aPrevFrame, aFrameList);
|
||||
mCaptionFrame = mCaptionFrames.FirstChild();
|
||||
}
|
||||
else {
|
||||
NS_PRECONDITION(!aPrevFrame, "invalid previous frame");
|
||||
return AppendFrames(aListName, aFrameList);
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -255,7 +254,6 @@ nsTableOuterFrame::RemoveFrame(nsIAtom* aListName,
|
|||
// We only have two child frames: the inner table and one caption frame.
|
||||
// The inner frame can't be removed so this should be the caption
|
||||
NS_PRECONDITION(nsLayoutAtoms::captionList == aListName, "can't remove inner frame");
|
||||
NS_PRECONDITION(aOldFrame == mCaptionFrame, "invalid caption frame");
|
||||
|
||||
PRUint8 captionSide = GetCaptionSide();
|
||||
|
||||
|
@ -268,12 +266,11 @@ nsTableOuterFrame::RemoveFrame(nsIAtom* aListName,
|
|||
mInnerTableFrame->AddStateBits(NS_FRAME_IS_DIRTY);
|
||||
}
|
||||
|
||||
// Remove the caption frame and destroy it
|
||||
if (mCaptionFrame && (mCaptionFrame == aOldFrame)) {
|
||||
mCaptionFrame->Destroy(GetPresContext());
|
||||
mCaptionFrame = nsnull;
|
||||
mMinCaptionWidth = 0;
|
||||
}
|
||||
// Remove the frame and destroy it
|
||||
mCaptionFrames.DestroyFrame(GetPresContext(), aOldFrame);
|
||||
mCaptionFrame = mCaptionFrames.FirstChild();
|
||||
|
||||
mMinCaptionWidth = 0;
|
||||
|
||||
// Generate a reflow command so we get reflowed
|
||||
GetPresContext()->PresShell()->AppendReflowCommand(this,
|
||||
|
|
|
@ -401,6 +401,7 @@ protected:
|
|||
private:
|
||||
// used to keep track of this frame's children. They are redundant with mFrames, but more convient
|
||||
nsTableFrame* mInnerTableFrame;
|
||||
nsFrameList mCaptionFrames;
|
||||
nsIFrame* mCaptionFrame;
|
||||
|
||||
// used to track caption max element size
|
||||
|
|
Загрузка…
Ссылка в новой задаче