Bug 368554 - "[quirks] Image inside table inside table-cell with small width is wrapped" [p=chris@pearce.org.nz (Chris Pearce [cpearce]) r+sr=roc a=blocking1.9+]
authorreed@reedloden.com
Mon, 03 Dec 2007 01:24:49 -0800
changeset 8578 caff1dd167565da51ef3af80b938bd8517b4d1dc
parent 8577 3c8b980d028ff2dfd32d27ce5bc93eaaacc5e67d
child 8579 537dc64c90a8abb5ced9ca96ee19c1902f11b758
push idunknown
push userunknown
push dateunknown
reviewersblocking1.9
bugs368554
milestone1.9b2pre
Bug 368554 - "[quirks] Image inside table inside table-cell with small width is wrapped" [p=chris@pearce.org.nz (Chris Pearce [cpearce]) r+sr=roc a=blocking1.9+]
layout/base/nsCSSFrameConstructor.cpp
layout/generic/nsImageFrame.cpp
layout/generic/nsImageFrame.h
layout/reftests/bugs/384322-1-ref.html
layout/reftests/bugs/384322-1.html
layout/reftests/bugs/reftest.list
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -4035,16 +4035,19 @@ nsCSSFrameConstructor::ConstructTableCel
   // This won't break us because MathML table frames are all subclasses of the default
   // table code, and so we can freely mix <mtable> with <mtr> or <tr>, <mtd> or <td>.
   // What will happen is just that non-MathML frames won't understand MathML attributes
   // and will therefore miss the special handling that the MathML code does.
   if (kNameSpaceID_MathML == aNameSpaceID && !IsBorderCollapse(parentFrame))
     aNewCellOuterFrame = NS_NewMathMLmtdFrame(mPresShell, aStyleContext);
   else
 #endif
+    // Warning: If you change this and add a wrapper frame around table cell
+    // frames, make sure Bug 368554 doesn't regress!
+    // See IsInAutoWidthTableCellForQuirk() in nsImageFrame.cpp.    
     aNewCellOuterFrame = NS_NewTableCellFrame(mPresShell, aStyleContext,
                                               IsBorderCollapse(parentFrame));
 
   if (NS_UNLIKELY(!aNewCellOuterFrame)) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
   // Initialize the table cell frame
@@ -10641,16 +10644,19 @@ nsCSSFrameConstructor::CreateContinuingF
         cellFrame = cellFrame->GetNextSibling();
       }
       
       // Set the table cell's initial child list
       newFrame->SetInitialChildList(nsnull, newChildList.childList);
     }
 
   } else if (IS_TABLE_CELL(frameType)) {
+    // Warning: If you change this and add a wrapper frame around table cell
+    // frames, make sure Bug 368554 doesn't regress!
+    // See IsInAutoWidthTableCellForQuirk() in nsImageFrame.cpp.
     newFrame = NS_NewTableCellFrame(shell, styleContext, IsBorderCollapse(aParentFrame));
 
     if (newFrame) {
       newFrame->Init(content, aParentFrame, aFrame);
       // XXXbz should we be passing in a non-null aContentParentFrame?
       nsHTMLContainerFrame::CreateViewForFrame(newFrame, nsnull, PR_FALSE);
 
       // Create a continuing area frame
--- a/layout/generic/nsImageFrame.cpp
+++ b/layout/generic/nsImageFrame.cpp
@@ -48,16 +48,17 @@
 #include "nsIRenderingContext.h"
 #include "nsIPresShell.h"
 #include "nsIImage.h"
 #include "nsIWidget.h"
 #include "nsGkAtoms.h"
 #include "nsIDocument.h"
 #include "nsINodeInfo.h"
 #include "nsContentUtils.h"
+#include "nsCSSAnonBoxes.h"
 #include "nsStyleContext.h"
 #include "nsStyleConsts.h"
 #include "nsImageMap.h"
 #include "nsILinkHandler.h"
 #include "nsIURL.h"
 #include "nsIIOService.h"
 #include "nsIURL.h"
 #include "nsILoadGroup.h"
@@ -1862,8 +1863,50 @@ NS_IMETHODIMP nsImageListener::FrameChan
                                             nsRect * dirtyRect)
 {
   if (!mFrame)
     return NS_ERROR_FAILURE;
 
   return mFrame->FrameChanged(aContainer, newframe, dirtyRect);
 }
 
+static PRBool
+IsInAutoWidthTableCellForQuirk(nsIFrame *aFrame)
+{
+  if (eCompatibility_NavQuirks != aFrame->PresContext()->CompatibilityMode())
+    return PR_FALSE;
+  // Check if the parent of the closest nsBlockFrame has auto width.
+  nsBlockFrame *ancestor = nsLayoutUtils::FindNearestBlockAncestor(aFrame);
+  if (ancestor->GetStyleContext()->GetPseudoType() == nsCSSAnonBoxes::cellContent) {
+    // Assume direct parent is a table cell frame.
+    nsFrame *grandAncestor = static_cast<nsFrame*>(ancestor->GetParent());
+    return grandAncestor &&
+      grandAncestor->GetStylePosition()->mWidth.GetUnit() == eStyleUnit_Auto;
+  }
+  return PR_FALSE;
+}
+
+/* virtual */ void
+nsImageFrame::AddInlineMinWidth(nsIRenderingContext *aRenderingContext,
+                                nsIFrame::InlineMinWidthData *aData)
+{
+
+  NS_ASSERTION(GetParent(), "Must have a parent if we get here!");
+  
+  PRBool canBreak =
+    !CanContinueTextRun() &&
+    GetParent()->GetStyleText()->WhiteSpaceCanWrap() &&
+    !IsInAutoWidthTableCellForQuirk(this);
+
+  if (canBreak)
+    aData->OptionallyBreak(aRenderingContext);
+ 
+  aData->trailingWhitespace = 0;
+  aData->skipWhitespace = PR_FALSE;
+  aData->trailingTextFrame = nsnull;
+  aData->currentLine += nsLayoutUtils::IntrinsicForContainer(aRenderingContext,
+                            this, nsLayoutUtils::MIN_WIDTH);
+  aData->atStartOfLine = PR_FALSE;
+
+  if (canBreak)
+    aData->OptionallyBreak(aRenderingContext);
+
+}
--- a/layout/generic/nsImageFrame.h
+++ b/layout/generic/nsImageFrame.h
@@ -168,16 +168,19 @@ public:
                           const nsRect&        aDirtyRect,
                           imgIRequest*         aRequest,
                           nsPoint              aPt);
 
   nsRect GetInnerArea() const;
 
   nsImageMap* GetImageMap(nsPresContext* aPresContext);
 
+  virtual void AddInlineMinWidth(nsIRenderingContext *aRenderingContext,
+                                 InlineMinWidthData *aData);
+
 protected:
   // nsISupports
   NS_IMETHOD_(nsrefcnt) AddRef(void);
   NS_IMETHOD_(nsrefcnt) Release(void);
 
   virtual ~nsImageFrame();
 
   void EnsureIntrinsicSize(nsPresContext* aPresContext);
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/384322-1-ref.html
@@ -0,0 +1,55 @@
+<html>
+<head><title>[384322] Testcase</title>
+</head>
+<body bgcolor="white">
+
+ <p>&lt;img&gt;&lt;img&gt;Hello&lt;img&gt;&lt;img&gt;
+
+  <table bgcolor="lightgray" border="0" cellpadding="0" cellspacing="0">
+    <tbody>
+      <tr>
+        <td bgcolor="red">
+          <img width="50" height="50"><img width="50" height="50">Hello<img width="50" height="50"><img width="50" height="50">
+        </td>
+      </tr>
+    </tbody>
+  </table>
+  
+  <p>&lt;img&gt;&lt;img&gt;Hello</p>
+  
+  <table bgcolor="lightgray" border="0" cellpadding="0" cellspacing="0">
+    <tbody>
+      <tr>
+        <td bgcolor="red">
+          <img width="50" height="50"><img width="50" height="50">Hello
+        </td>
+      </tr>
+    </tbody>
+  </table>
+  
+  <p>Hello&lt;img&gt;&lt;img&gt;</p>
+  
+    <table bgcolor="lightgray" border="0" cellpadding="0" cellspacing="0">
+    <tbody>
+      <tr>
+        <td bgcolor="red">
+          Hello<img width="50" height="50"><img width="50" height="50">
+        </td>
+      </tr>
+    </tbody>
+  </table>
+  
+  <p>&lt;img&gt;Hello</p>
+  
+  <table bgcolor="lightgray" border="0" cellpadding="0" cellspacing="0">
+    <tbody>
+      <tr>
+        <td bgcolor="red">
+          <img width="50" height="50">Hello
+        </td>
+      </tr>
+    </tbody>
+  </table>
+  
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/384322-1.html
@@ -0,0 +1,55 @@
+<html>
+<head><title>[384322] Testcase</title>
+</head>
+<body bgcolor="white">
+
+ <p>&lt;img&gt;&lt;img&gt;Hello&lt;img&gt;&lt;img&gt;
+
+  <table bgcolor="lightgray" width="70" border="0" cellpadding="0" cellspacing="0">
+    <tbody>
+      <tr>
+        <td bgcolor="red">
+          <img width="50" height="50"><img width="50" height="50">Hello<img width="50" height="50"><img width="50" height="50">
+        </td>
+      </tr>
+    </tbody>
+  </table>
+  
+  <p>&lt;img&gt;&lt;img&gt;Hello</p>
+  
+  <table bgcolor="lightgray" width="70" border="0" cellpadding="0" cellspacing="0">
+    <tbody>
+      <tr>
+        <td bgcolor="red">
+          <img width="50" height="50"><img width="50" height="50">Hello
+        </td>
+      </tr>
+    </tbody>
+  </table>
+  
+  <p>Hello&lt;img&gt;&lt;img&gt;</p>
+  
+    <table bgcolor="lightgray" width="70" border="0" cellpadding="0" cellspacing="0">
+    <tbody>
+      <tr>
+        <td bgcolor="red">
+          Hello<img width="50" height="50"><img width="50" height="50">
+        </td>
+      </tr>
+    </tbody>
+  </table>
+  
+  <p>&lt;img&gt;Hello</p>
+  
+  <table bgcolor="lightgray" width="70" border="0" cellpadding="0" cellspacing="0">
+    <tbody>
+      <tr>
+        <td bgcolor="red">
+          <img width="50" height="50">Hello
+        </td>
+      </tr>
+    </tbody>
+  </table>
+
+</body>
+</html>
--- a/layout/reftests/bugs/reftest.list
+++ b/layout/reftests/bugs/reftest.list
@@ -372,16 +372,17 @@ random-if(MOZ_WIDGET_TOOLKIT=="cocoa") =
 == 382600-1.html 382600-1-ref.html
 == 383551-1.html 383551-1-ref.html
 == 383883-1.html 383883-1-ref.html
 == 383883-2.html 383883-2-ref.html
 == 383883-3.html 383883-3-ref.html
 == 383883-4.html 383883-4-ref.html
 == 383884-1.html 383884-1-ref.html
 == 383885-1.html 383885-1-ref.html
+== 384322-1.html 384322-1-ref.html
 == 384576-1.html 384576-1-ref.html
 == 384762-1.html about:blank
 == 384876-1.html 384876-1-ref.html
 == 385533-1.html about:blank # assertion test
 == 385823-1.html 385823-1-ref.html 
 == 385823-2a.html 385823-2-ref.html 
 fails == 385823-2b.html 385823-2-ref.html 
 == 385823-2c.html 385823-2-ref.html