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 id1
push userbsmedberg@mozilla.com
push dateThu, 20 Mar 2008 16:49:24 +0000
treeherdermozilla-central@61007906a1f8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
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();