The frame model depends on the span attribute, so changing span should reconstruct frames.
Bug 403249, r=bernd, sr=roc
--- a/content/html/content/src/nsHTMLTableColElement.cpp
+++ b/content/html/content/src/nsHTMLTableColElement.cpp
@@ -190,19 +190,23 @@ void MapAttributesIntoRule(const nsMappe
static
void ColMapAttributesIntoRule(const nsMappedAttributes* aAttributes,
nsRuleData* aData)
{
if (aData->mSIDs & NS_STYLE_INHERIT_BIT(Table) &&
aData->mTableData->mSpan.GetUnit() == eCSSUnit_Null) {
// span: int
const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::span);
- if (value && value->Type() == nsAttrValue::eInteger)
- aData->mTableData->mSpan.SetIntValue(value->GetIntegerValue(),
- eCSSUnit_Integer);
+ if (value && value->Type() == nsAttrValue::eInteger) {
+ PRInt32 val = value->GetIntegerValue();
+ if (val >= 1) {
+ aData->mTableData->mSpan.SetIntValue(value->GetIntegerValue(),
+ eCSSUnit_Integer);
+ }
+ }
}
MapAttributesIntoRule(aAttributes, aData);
}
NS_IMETHODIMP_(PRBool)
nsHTMLTableColElement::IsAttributeMapped(const nsIAtom* aAttribute) const
{
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -3952,42 +3952,39 @@ nsCSSFrameConstructor::ConstructTableCol
GetParentFrame(aNameSpaceID, *aParentFrameIn,
nsGkAtoms::tableColFrame, aState, parentFrame,
aIsPseudoParent);
if (!aIsPseudoParent && !aState.mPseudoFrames.IsEmpty()) {
ProcessPseudoFrames(aState, aChildItems);
}
}
- aNewFrame = NS_NewTableColFrame(mPresShell, aStyleContext);
+ nsTableColFrame* colFrame = NS_NewTableColFrame(mPresShell, aStyleContext);
+ aNewFrame = colFrame;
if (NS_UNLIKELY(!aNewFrame)) {
return NS_ERROR_OUT_OF_MEMORY;
}
InitAndRestoreFrame(aState, aContent, parentFrame, nsnull, aNewFrame);
// construct additional col frames if the col frame has a span > 1
- PRInt32 span = 1;
- nsCOMPtr<nsIDOMHTMLTableColElement> cgContent(do_QueryInterface(aContent));
- if (cgContent) {
- cgContent->GetSpan(&span);
- nsIFrame* lastCol = aNewFrame;
- nsStyleContext* styleContext = nsnull;
- for (PRInt32 spanX = 1; spanX < span; spanX++) {
- // The same content node should always resolve to the same style context.
- if (1 == spanX)
- styleContext = aNewFrame->GetStyleContext();
- nsIFrame* newCol = NS_NewTableColFrame(mPresShell, styleContext);
- if (NS_UNLIKELY(!newCol)) {
- return NS_ERROR_OUT_OF_MEMORY;
- }
- InitAndRestoreFrame(aState, aContent, parentFrame, nsnull, newCol, PR_FALSE);
- ((nsTableColFrame*)newCol)->SetColType(eColAnonymousCol);
- lastCol->SetNextSibling(newCol);
- lastCol = newCol;
- }
+ PRInt32 span = colFrame->GetSpan();
+ nsIFrame* lastCol = aNewFrame;
+ nsStyleContext* styleContext = nsnull;
+ for (PRInt32 spanX = 1; spanX < span; spanX++) {
+ // The same content node should always resolve to the same style context.
+ if (1 == spanX)
+ styleContext = aNewFrame->GetStyleContext();
+ nsTableColFrame* newCol = NS_NewTableColFrame(mPresShell, styleContext);
+ if (NS_UNLIKELY(!newCol)) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+ InitAndRestoreFrame(aState, aContent, parentFrame, nsnull, newCol, PR_FALSE);
+ newCol->SetColType(eColAnonymousCol);
+ lastCol->SetNextSibling(newCol);
+ lastCol = newCol;
}
if (!aIsPseudo && aIsPseudoParent) {
aState.mPseudoFrames.mColGroup.mChildList.AddChild(aNewFrame);
}
return rv;
}
--- a/layout/generic/nsHTMLParts.h
+++ b/layout/generic/nsHTMLParts.h
@@ -51,16 +51,17 @@ class nsIFrame;
class nsIHTMLContentSink;
class nsIFragmentContentSink;
class nsPresContext;
class nsStyleContext;
class nsIURI;
class nsString;
class nsIPresShell;
class nsIChannel;
+class nsTableColFrame;
/**
* Additional frame-state bits used by nsBlockFrame
* See the meanings at http://www.mozilla.org/newlayout/doc/block-and-line.html
*/
#define NS_BLOCK_NO_AUTO_MARGINS 0x00200000
#define NS_BLOCK_MARGIN_ROOT 0x00400000
#define NS_BLOCK_SPACE_MGR 0x00800000
@@ -223,17 +224,17 @@ NS_NewIsIndexFrame(nsIPresShell* aPresSh
// Table frame factories
nsIFrame*
NS_NewTableOuterFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
nsIFrame*
NS_NewTableFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
nsIFrame*
NS_NewTableCaptionFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
-nsIFrame*
+nsTableColFrame*
NS_NewTableColFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
nsIFrame*
NS_NewTableColGroupFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
nsIFrame*
NS_NewTableRowFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
nsIFrame*
NS_NewTableRowGroupFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
nsIFrame*
--- a/layout/style/nsStyleStruct.cpp
+++ b/layout/style/nsStyleStruct.cpp
@@ -956,23 +956,22 @@ nsStyleTable::~nsStyleTable(void)
nsStyleTable::nsStyleTable(const nsStyleTable& aSource)
{
memcpy((nsStyleTable*)this, &aSource, sizeof(nsStyleTable));
}
nsChangeHint nsStyleTable::CalcDifference(const nsStyleTable& aOther) const
{
// Changes in mRules may require reframing (if border-collapse stuff changes, for example).
- if (mRules != aOther.mRules)
+ if (mRules != aOther.mRules || mSpan != aOther.mSpan)
return NS_STYLE_HINT_FRAMECHANGE;
if ((mLayoutStrategy == aOther.mLayoutStrategy) &&
(mFrame == aOther.mFrame) &&
- (mCols == aOther.mCols) &&
- (mSpan == aOther.mSpan))
+ (mCols == aOther.mCols))
return NS_STYLE_HINT_NONE;
return NS_STYLE_HINT_REFLOW;
}
#ifdef DEBUG
/* static */
nsChangeHint nsStyleTable::MaxDifference()
{
--- a/layout/tables/nsTableColFrame.cpp
+++ b/layout/tables/nsTableColFrame.cpp
@@ -155,17 +155,17 @@ void nsTableColFrame::Dump(PRInt32 aInde
mSpanPrefPercent,
GetFinalWidth());
printf("\n%s**END COL DUMP** ", indent);
delete [] indent;
}
#endif
/* ----- global methods ----- */
-nsIFrame*
+nsTableColFrame*
NS_NewTableColFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
{
return new (aPresShell) nsTableColFrame(aContext);
}
NS_IMETHODIMP
nsTableColFrame::Init(nsIContent* aContent,
nsIFrame* aParent,
--- a/layout/tables/nsTableColFrame.h
+++ b/layout/tables/nsTableColFrame.h
@@ -62,17 +62,18 @@ public:
nsTableColType GetColType() const;
void SetColType(nsTableColType aType);
/** instantiate a new instance of nsTableRowFrame.
* @param aPresShell the pres shell for this frame
*
* @return the frame that was created
*/
- friend nsIFrame* NS_NewTableColFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
+ friend nsTableColFrame* NS_NewTableColFrame(nsIPresShell* aPresShell,
+ nsStyleContext* aContext);
PRInt32 GetColIndex() const;
void SetColIndex (PRInt32 aColIndex);
nsTableColFrame* GetNextCol() const;
NS_IMETHOD Init(nsIContent* aContent,
@@ -97,18 +98,18 @@ public:
* @see nsGkAtoms::tableColFrame
*/
virtual nsIAtom* GetType() const;
#ifdef DEBUG
NS_IMETHOD GetFrameName(nsAString& aResult) const;
#endif
- /** return the number of the columns the col represents. always >= 0 */
- virtual PRInt32 GetSpan ();
+ /** return the number of the columns the col represents. always >= 1 */
+ PRInt32 GetSpan();
/** convenience method, calls into cellmap */
nsVoidArray * GetCells();
/** convenience method, calls into cellmap */
PRInt32 Count() const;
nscoord GetLeftBorderWidth();