The frame model depends on the span attribute, so changing span should reconstruct frames. Bug 403249, r=bernd, sr=roc
authorbzbarsky@mit.edu
Sun, 18 Nov 2007 10:56:49 -0800
changeset 8151 82d49c055fd05067119143ffeac7e966d56f029a
parent 8150 78e8d17d75299cf505ae171406e94fd85cd41264
child 8152 dda44fa0dcfdbd40a56a2e9c31ba7fbf884f8e07
push idunknown
push userunknown
push dateunknown
reviewersbernd, roc
bugs403249
milestone1.9b2pre
The frame model depends on the span attribute, so changing span should reconstruct frames. Bug 403249, r=bernd, sr=roc
content/html/content/src/nsHTMLTableColElement.cpp
layout/base/nsCSSFrameConstructor.cpp
layout/generic/nsHTMLParts.h
layout/style/nsStyleStruct.cpp
layout/tables/nsTableColFrame.cpp
layout/tables/nsTableColFrame.h
--- 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();