Don't propagate text-decoration in quirks-mode across inline-block, inline-table, and HTML table elements. Also, prepare quirks-mode text-decoration propagation code for use in standards mode (for bug 403524). (Bug 572713) r=roc a2.0=blocking
authorL. David Baron <dbaron@dbaron.org>
Sun, 21 Nov 2010 15:50:28 -0800
changeset 57980 4847e1cf6cf4725b9a36da1a94788374b0cab397
parent 57979 6b3f7a3a6a7f68d5bb630534f22c002601a0469b
child 57982 4c7d41fe4e8fc63638f9d86d4d254a0aaae1085a
push idunknown
push userunknown
push dateunknown
reviewersroc
bugs403524, 572713
milestone2.0b8pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Don't propagate text-decoration in quirks-mode across inline-block, inline-table, and HTML table elements. Also, prepare quirks-mode text-decoration propagation code for use in standards mode (for bug 403524). (Bug 572713) r=roc a2.0=blocking
layout/generic/nsTextFrameThebes.cpp
layout/reftests/text-decoration/reftest.list
layout/reftests/text-decoration/table-quirk-1-ref.html
layout/reftests/text-decoration/table-quirk-1.html
layout/reftests/text-decoration/table-quirk-2-ref.html
layout/reftests/text-decoration/table-quirk-2.html
layout/reftests/text-decoration/text-decoration-propagation-1-quirks-ref.html
layout/reftests/text-decoration/text-decoration-propagation-1-quirks.html
layout/reftests/text-decoration/text-decoration-propagation-1-standards-ref.html
layout/reftests/text-decoration/text-decoration-propagation-1-standards.html
--- a/layout/generic/nsTextFrameThebes.cpp
+++ b/layout/generic/nsTextFrameThebes.cpp
@@ -4151,59 +4151,101 @@ FillClippedRect(gfxContext* aCtx, nsPres
 nsTextFrame::TextDecorations
 nsTextFrame::GetTextDecorations(nsPresContext* aPresContext)
 {
   TextDecorations decorations;
 
   // Quirks mode text decoration are rendered by children; see bug 1777
   // In non-quirks mode, nsHTMLContainer::Paint and nsBlockFrame::Paint
   // does the painting of text decorations.
-  if (eCompatibility_NavQuirks != aPresContext->CompatibilityMode())
+  // FIXME Bug 403524: We'd like to unify standards-mode and quirks-mode
+  // text-decoration drawing, using what's currently the quirks mode
+  // codepath.  But for now this code is only used for quirks mode.
+  const nsCompatibility compatMode = aPresContext->CompatibilityMode();
+  if (compatMode != eCompatibility_NavQuirks)
     return decorations;
 
   PRBool useOverride = PR_FALSE;
   nscolor overrideColor;
 
   // A mask of all possible decorations.
+  // FIXME: Per spec, we still need to draw all relevant decorations
+  // from ancestors, not just the nearest one from each.
   PRUint8 decorMask = NS_STYLE_TEXT_DECORATION_UNDERLINE | 
                       NS_STYLE_TEXT_DECORATION_OVERLINE |
                       NS_STYLE_TEXT_DECORATION_LINE_THROUGH;
 
-  for (nsStyleContext* context = GetStyleContext();
-       decorMask && context && context->HasTextDecorations();
-       context = context->GetParent()) {
+  PRBool isChild; // ignored
+  for (nsIFrame* f = this; decorMask && f;
+       NS_SUCCEEDED(f->GetParentStyleContextFrame(aPresContext, &f, &isChild))
+         || (f = nsnull)) {
+    nsStyleContext* context = f->GetStyleContext();
+    if (!context->HasTextDecorations()) {
+      break;
+    }
     const nsStyleTextReset* styleText = context->GetStyleTextReset();
     if (!useOverride && 
         (NS_STYLE_TEXT_DECORATION_OVERRIDE_ALL & styleText->mTextDecoration)) {
       // This handles the <a href="blah.html"><font color="green">La 
       // la la</font></a> case. The link underline should be green.
       useOverride = PR_TRUE;
       overrideColor = context->GetVisitedDependentColor(eCSSProperty_color);
     }
 
+    // FIXME: see above (remove this check)
     PRUint8 useDecorations = decorMask & styleText->mTextDecoration;
     if (useDecorations) {// a decoration defined here
       nscolor color = context->GetVisitedDependentColor(eCSSProperty_color);
 
+      // FIXME: We also need to record the thickness and position
+      // metrics appropriate to this element (at least in standards
+      // mode).  This will require adjusting the visual overflow region
+      // of this frame and maybe its ancestors.  The positions should
+      // probably be relative to the line's baseline (when text
+      // decorations are specified on inlines we should look for their
+      // containing line; otherwise use the element's font); when
+      // drawing it should always be relative to the line baseline.
+      // This way we move the decorations for relative positioning.
       if (NS_STYLE_TEXT_DECORATION_UNDERLINE & useDecorations) {
         decorations.mUnderColor = useOverride ? overrideColor : color;
         decorMask &= ~NS_STYLE_TEXT_DECORATION_UNDERLINE;
         decorations.mDecorations |= NS_STYLE_TEXT_DECORATION_UNDERLINE;
       }
       if (NS_STYLE_TEXT_DECORATION_OVERLINE & useDecorations) {
         decorations.mOverColor = useOverride ? overrideColor : color;
         decorMask &= ~NS_STYLE_TEXT_DECORATION_OVERLINE;
         decorations.mDecorations |= NS_STYLE_TEXT_DECORATION_OVERLINE;
       }
       if (NS_STYLE_TEXT_DECORATION_LINE_THROUGH & useDecorations) {
         decorations.mStrikeColor = useOverride ? overrideColor : color;
         decorMask &= ~NS_STYLE_TEXT_DECORATION_LINE_THROUGH;
         decorations.mDecorations |= NS_STYLE_TEXT_DECORATION_LINE_THROUGH;
       }
     }
+
+    // In all modes, if we're on an inline-block or inline-table (or
+    // inline-stack, inline-box, inline-grid), we're done.
+    const nsStyleDisplay *disp = context->GetStyleDisplay();
+    if (disp->mDisplay != NS_STYLE_DISPLAY_INLINE &&
+        disp->IsInlineOutside()) {
+      break;
+    }
+
+    if (compatMode == eCompatibility_NavQuirks) {
+      // In quirks mode, if we're on an HTML table element, we're done.
+      if (f->GetContent()->IsHTML(nsGkAtoms::table)) {
+        break;
+      }
+    } else {
+      // In standards/almost-standards mode, if we're on an
+      // absolutely-positioned element or a floating element, we're done.
+      if (disp->IsFloating() || disp->IsAbsolutelyPositioned()) {
+        break;
+      }
+    }
   }
 
   return decorations;
 }
 
 void
 nsTextFrame::UnionTextDecorationOverflow(nsPresContext* aPresContext,
                                          PropertyProvider& aProvider,
--- a/layout/reftests/text-decoration/reftest.list
+++ b/layout/reftests/text-decoration/reftest.list
@@ -15,8 +15,12 @@ fails == underline-block-propagation-2-q
 == underline-table-caption-standards.html underline-table-caption-standards-ref.html
 != underline-table-caption-standards.html underline-table-caption-standards-notref.html
 == underline-table-cell-standards.html underline-table-cell-standards-ref.html
 != underline-table-cell-standards.html underline-table-cell-standards-notref.html
 fails == underline-block-propagation-standards.html underline-block-propagation-standards-ref.html # bug that decoration is drawn through non-text child (bug 428599)
 fails-if(d2d) == underline-block-propagation-2-standards.html underline-block-propagation-2-standards-ref.html # bug 585684
 == text-decoration-zorder-1-standards.html text-decoration-zorder-1-ref.html
 fails == text-decoration-zorder-1-quirks.html text-decoration-zorder-1-ref.html # bug 403524
+== table-quirk-1.html table-quirk-1-ref.html
+== table-quirk-2.html table-quirk-2-ref.html
+== text-decoration-propagation-1-quirks.html text-decoration-propagation-1-quirks-ref.html
+fails == text-decoration-propagation-1-standards.html text-decoration-propagation-1-standards-ref.html
new file mode 100644
--- /dev/null
+++ b/layout/reftests/text-decoration/table-quirk-1-ref.html
@@ -0,0 +1,7 @@
+<title>text-decoration quirk on tables (Bug 572713)</title>
+
+<div><table><tbody><tr><td>text-decoration on container of table</td></tr></tbody></table></div>
+<div><table><tbody><tr><td style="text-decoration: underline">text-decoration on table</td></tr></tbody></table></div>
+<div><table><tbody><tr><td style="text-decoration: underline">text-decoration on tbody</td></tr></tbody></table></div>
+<div><table><tbody><tr><td style="text-decoration: underline">text-decoration on tr</td></tr></tbody></table></div>
+<div><table><tbody><tr><td style="text-decoration: underline">text-decoration on td</td></tr></tbody></table></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/text-decoration/table-quirk-1.html
@@ -0,0 +1,7 @@
+<title>text-decoration quirk on tables (Bug 572713)</title>
+
+<div style="text-decoration: underline"><table><tbody><tr><td>text-decoration on container of table</td></tr></tbody></table></div>
+<div><table style="text-decoration: underline"><tbody><tr><td>text-decoration on table</td></tr></tbody></table></div>
+<div><table><tbody style="text-decoration: underline"><tr><td>text-decoration on tbody</td></tr></tbody></table></div>
+<div><table><tbody><tr style="text-decoration: underline"><td>text-decoration on tr</td></tr></tbody></table></div>
+<div><table><tbody><tr><td style="text-decoration: underline">text-decoration on td</td></tr></tbody></table></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/text-decoration/table-quirk-2-ref.html
@@ -0,0 +1,26 @@
+<title>text-decoration quirk on tables (Bug 572713)</title>
+
+<h1>text-decoration on a block</h1>
+
+<u>text in the block</u>
+
+<div><u>text in a block in the block</u></div>
+
+<table><tbody><tr><td>an HTML table</td></tr></tbody></table>
+
+<table style="display:block"><tbody style="display:block"><tr style="display:block"><td style="display:block">an HTML table that's not table-display</td></tr></tbody></table>
+
+<div style="display: table"><div style="display: table-row-group"><div style="display: table-row"><div style="display: table-cell"><u>a div with table display types</u></div></div></div></div>
+
+<h1>text-decoration on an inline</h1>
+
+<u>text in the block</u>
+
+<div><u>text in a block in the block</u></div>
+
+<table><tbody><tr><td>an HTML table</td></tr></tbody></table>
+
+<table style="display:block"><tbody style="display:block"><tr style="display:block"><td style="display:block">an HTML table that's not table-display</td></tr></tbody></table>
+
+<div style="display: table"><div style="display: table-row-group"><div style="display: table-row"><div style="display: table-cell"><u>a div with table display types</u></div></div></div></div>
+
new file mode 100644
--- /dev/null
+++ b/layout/reftests/text-decoration/table-quirk-2.html
@@ -0,0 +1,35 @@
+<title>text-decoration quirk on tables (Bug 572713)</title>
+
+<h1>text-decoration on a block</h1>
+
+<div style="text-decoration: underline">
+
+text in the block
+
+<div>text in a block in the block</div>
+
+<table><tbody><tr><td>an HTML table</td></tr></tbody></table>
+
+<table style="display:block"><tbody style="display:block"><tr style="display:block"><td style="display:block">an HTML table that's not table-display</td></tr></tbody></table>
+
+<div style="display: table"><div style="display: table-row-group"><div style="display: table-row"><div style="display: table-cell">a div with table display types</div></div></div></div>
+
+
+</div>
+
+<h1>text-decoration on an inline</h1>
+
+<div style="text-decoration: underline; display: inline">
+
+text in the block
+
+<div>text in a block in the block</div>
+
+<table><tbody><tr><td>an HTML table</td></tr></tbody></table>
+
+<table style="display:block"><tbody style="display:block"><tr style="display:block"><td style="display:block">an HTML table that's not table-display</td></tr></tbody></table>
+
+<div style="display: table"><div style="display: table-row-group"><div style="display: table-row"><div style="display: table-cell">a div with table display types</div></div></div></div>
+
+
+</div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/text-decoration/text-decoration-propagation-1-quirks-ref.html
@@ -0,0 +1,34 @@
+<title>text-decoration</title>
+
+<h1>text-decoration on a block</h1>
+
+  <u>text directly in parent</u>
+
+  <div><u>text in block</u></div>
+
+  <div style="float:left; clear: left"><u>text in float</u></div>
+  <div style="clear:left"></div>
+
+  <div style="display:inline-block">text in<br>inline-block</div><u>
+  </u><div style="display:inline-table">text in<br>inline-table</div>
+
+  <div style="height: 2em">
+    <div style="position: absolute"><u>text in abs-pos</u></div>
+  </div>
+
+<h1>text-decoration on an inline</h1>
+
+  <u>text directly in parent</u>
+
+  <div><u>text in block</u></div>
+
+  <div style="float:left; clear: left"><u>text in float</u></div>
+  <div style="clear:left"></div>
+
+  <div style="display:inline-block">text in<br>inline-block</div><u>
+  </u><div style="display:inline-table">text in<br>inline-table</div>
+
+  <div style="height: 2em">
+    <div style="position: absolute"><u>text in abs-pos</u></div>
+  </div>
+
new file mode 100644
--- /dev/null
+++ b/layout/reftests/text-decoration/text-decoration-propagation-1-quirks.html
@@ -0,0 +1,42 @@
+<title>text-decoration</title>
+
+<h1>text-decoration on a block</h1>
+
+<div style="text-decoration: underline">
+
+  text directly in parent
+
+  <div>text in block</div>
+
+  <div style="float:left; clear: left">text in float</div>
+  <div style="clear:left"></div>
+
+  <div style="display:inline-block">text in<br>inline-block</div>
+  <div style="display:inline-table">text in<br>inline-table</div>
+
+  <div style="height: 2em">
+    <div style="position: absolute">text in abs-pos</div>
+  </div>
+
+</div>
+
+<h1>text-decoration on an inline</h1>
+
+<div style="text-decoration: underline; display: inline">
+
+  text directly in parent
+
+  <div>text in block</div>
+
+  <div style="float:left; clear: left">text in float</div>
+  <div style="clear:left"></div>
+
+  <div style="display:inline-block">text in<br>inline-block</div>
+  <div style="display:inline-table">text in<br>inline-table</div>
+
+  <div style="height: 2em">
+    <div style="position: absolute">text in abs-pos</div>
+  </div>
+
+</div>
+
new file mode 100644
--- /dev/null
+++ b/layout/reftests/text-decoration/text-decoration-propagation-1-standards-ref.html
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML>
+<title>text-decoration</title>
+
+<h1>text-decoration on a block</h1>
+
+  <u>text directly in parent</u>
+
+  <div><u>text in block</u></div>
+
+  <div style="float:left; clear: left">text in float</div>
+  <div style="clear:left"></div>
+
+  <div style="display:inline-block">text in<br>inline-block</div><u>
+  </u><div style="display:inline-table">text in<br>inline-table</div>
+
+  <div style="height: 2em">
+    <div style="position: absolute">text in abs-pos</div>
+  </div>
+
+<h1>text-decoration on an inline</h1>
+
+  <u>text directly in parent</u>
+
+  <div><u>text in block</u></div>
+
+  <div style="float:left; clear: left">text in float</div>
+  <div style="clear:left"></div>
+
+  <div style="display:inline-block">text in<br>inline-block</div><u>
+  </u><div style="display:inline-table">text in<br>inline-table</div>
+
+  <div style="height: 2em">
+    <div style="position: absolute">text in abs-pos</div>
+  </div>
+
new file mode 100644
--- /dev/null
+++ b/layout/reftests/text-decoration/text-decoration-propagation-1-standards.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<title>text-decoration</title>
+
+<h1>text-decoration on a block</h1>
+
+<div style="text-decoration: underline">
+
+  text directly in parent
+
+  <div>text in block</div>
+
+  <div style="float:left; clear: left">text in float</div>
+  <div style="clear:left"></div>
+
+  <div style="display:inline-block">text in<br>inline-block</div>
+  <div style="display:inline-table">text in<br>inline-table</div>
+
+  <div style="height: 2em">
+    <div style="position: absolute">text in abs-pos</div>
+  </div>
+
+</div>
+
+<h1>text-decoration on an inline</h1>
+
+<div style="text-decoration: underline; display: inline">
+
+  text directly in parent
+
+  <div>text in block</div>
+
+  <div style="float:left; clear: left">text in float</div>
+  <div style="clear:left"></div>
+
+  <div style="display:inline-block">text in<br>inline-block</div>
+  <div style="display:inline-table">text in<br>inline-table</div>
+
+  <div style="height: 2em">
+    <div style="position: absolute">text in abs-pos</div>
+  </div>
+
+</div>
+