Bug 1109571 part 4 - Frame construction bits to create the appropriate frame tree for table captions. r=roc
authorMats Palmgren <mats@mozilla.com>
Fri, 26 Dec 2014 07:21:32 +0000
changeset 238112 79eb639db611e4276f9561c5c6d3e2decd043967
parent 238111 b539dc005423ed54bcf32f13753c62f69d1b4892
child 238113 b67489a65e49751b2b8f5c0d0fae26ef4f225c83
push id7472
push userraliiev@mozilla.com
push dateMon, 12 Jan 2015 20:36:27 +0000
treeherdermozilla-aurora@300ca104f8fb [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs1109571
milestone37.0a1
Bug 1109571 part 4 - Frame construction bits to create the appropriate frame tree for table captions. r=roc Note that this also makes IsPositioned() table captions be abs.pos. containers, which was broken before.
layout/base/nsCSSFrameConstructor.cpp
layout/style/nsStyleContext.cpp
layout/style/nsStyleStruct.h
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -4520,46 +4520,52 @@ nsCSSFrameConstructor::FindDisplayData(c
     propagatedScrollToViewport =
       PropagateScrollToViewport() == aElement;
   }
 
   NS_ASSERTION(!propagatedScrollToViewport ||
                !mPresShell->GetPresContext()->IsPaginated(),
                "Shouldn't propagate scroll in paginated contexts");
 
-  // If the frame is a block-level frame and is scrollable, then wrap it in a
-  // scroll frame.
-  // XXX Ignore tables for the time being
-  // XXXbz it would be nice to combine this with the other block
-  // case... Think about how do do this?
-  if (aDisplay->IsBlockInsideStyle() &&
-      aDisplay->IsScrollableOverflow() &&
-      !propagatedScrollToViewport) {
-    // Except we don't want to do that for paginated contexts for
-    // frames that are block-outside and aren't frames for native
-    // anonymous stuff.
-    if (mPresShell->GetPresContext()->IsPaginated() &&
-        aDisplay->IsBlockOutsideStyle() &&
-        !aElement->IsInNativeAnonymousSubtree()) {
-      static const FrameConstructionData sForcedNonScrollableBlockData =
-        FULL_CTOR_FCDATA(FCDATA_FORCED_NON_SCROLLABLE_BLOCK,
-                         &nsCSSFrameConstructor::ConstructNonScrollableBlock);
-      return &sForcedNonScrollableBlockData;
-    }
-
-    static const FrameConstructionData sScrollableBlockData =
-      FULL_CTOR_FCDATA(0, &nsCSSFrameConstructor::ConstructScrollableBlock);
-    return &sScrollableBlockData;
-  }
-
-  // Handle various non-scrollable blocks
   if (aDisplay->IsBlockInsideStyle()) {
-    static const FrameConstructionData sNonScrollableBlockData =
-      FULL_CTOR_FCDATA(0, &nsCSSFrameConstructor::ConstructNonScrollableBlock);
-    return &sNonScrollableBlockData;
+    // If the frame is a block-level frame and is scrollable, then wrap it in a
+    // scroll frame.  Except we don't want to do that for paginated contexts for
+    // frames that are block-outside and aren't frames for native anonymous stuff.
+    // XXX Ignore tables for the time being (except caption)
+    const uint32_t kCaptionCtorFlags =
+      FCDATA_IS_TABLE_PART | FCDATA_DESIRED_PARENT_TYPE_TO_BITS(eTypeTable);
+    bool caption = aDisplay->mDisplay == NS_STYLE_DISPLAY_TABLE_CAPTION;
+    bool suppressScrollFrame = false;
+    bool needScrollFrame = aDisplay->IsScrollableOverflow() &&
+                           !propagatedScrollToViewport;
+    if (needScrollFrame) {
+      suppressScrollFrame = mPresShell->GetPresContext()->IsPaginated() &&
+                            aDisplay->IsBlockOutsideStyle() &&
+                            !aElement->IsInNativeAnonymousSubtree();
+      if (!suppressScrollFrame) {
+        static const FrameConstructionData sScrollableBlockData[2] =
+          { FULL_CTOR_FCDATA(0, &nsCSSFrameConstructor::ConstructScrollableBlock),
+            FULL_CTOR_FCDATA(kCaptionCtorFlags,
+                             &nsCSSFrameConstructor::ConstructScrollableBlock) };
+        return &sScrollableBlockData[caption];
+      }
+    }
+
+    // Handle various non-scrollable blocks.
+    static const FrameConstructionData sNonScrollableBlockData[2][2] {
+      { FULL_CTOR_FCDATA(0,
+                         &nsCSSFrameConstructor::ConstructNonScrollableBlock),
+        FULL_CTOR_FCDATA(kCaptionCtorFlags,
+                         &nsCSSFrameConstructor::ConstructNonScrollableBlock) },
+      { FULL_CTOR_FCDATA(FCDATA_FORCED_NON_SCROLLABLE_BLOCK,
+                         &nsCSSFrameConstructor::ConstructNonScrollableBlock),
+        FULL_CTOR_FCDATA(FCDATA_FORCED_NON_SCROLLABLE_BLOCK | kCaptionCtorFlags,
+                         &nsCSSFrameConstructor::ConstructNonScrollableBlock) }
+    };
+    return &sNonScrollableBlockData[suppressScrollFrame][caption];
   }
 
   // If this is for a <body> node and we've propagated the scroll-frame to the
   // viewport, we need to make sure not to add another layer of scrollbars, so
   // we use a different FCData struct without FCDATA_MAY_NEED_SCROLLFRAME.
   if (propagatedScrollToViewport && aDisplay->IsScrollableOverflow()) {
     if (aDisplay->mDisplay == NS_STYLE_DISPLAY_FLEX) {
       static const FrameConstructionData sNonScrollableFlexData =
@@ -4609,21 +4615,16 @@ nsCSSFrameConstructor::FindDisplayData(c
                   NS_NewRubyTextContainerFrame) },
     { NS_STYLE_DISPLAY_TABLE,
       FULL_CTOR_FCDATA(0, &nsCSSFrameConstructor::ConstructTable) },
     { NS_STYLE_DISPLAY_INLINE_TABLE,
       FULL_CTOR_FCDATA(0, &nsCSSFrameConstructor::ConstructTable) },
     // NOTE: In the unlikely event that we add another table-part here that has
     // a desired-parent-type (& hence triggers table fixup), we'll need to also
     // update the flexbox chunk in nsStyleContext::ApplyStyleFixups().
-    { NS_STYLE_DISPLAY_TABLE_CAPTION,
-      FCDATA_DECL(FCDATA_IS_TABLE_PART | FCDATA_ALLOW_BLOCK_STYLES |
-                  FCDATA_DISALLOW_OUT_OF_FLOW | FCDATA_SKIP_ABSPOS_PUSH |
-                  FCDATA_DESIRED_PARENT_TYPE_TO_BITS(eTypeTable),
-                  NS_NewTableCaptionFrame) },
     { NS_STYLE_DISPLAY_TABLE_ROW_GROUP,
       FULL_CTOR_FCDATA(FCDATA_IS_TABLE_PART |
                        FCDATA_DESIRED_PARENT_TYPE_TO_BITS(eTypeTable),
                        &nsCSSFrameConstructor::ConstructTableRowOrRowGroup) },
     { NS_STYLE_DISPLAY_TABLE_HEADER_GROUP,
       FULL_CTOR_FCDATA(FCDATA_IS_TABLE_PART |
                        FCDATA_DESIRED_PARENT_TYPE_TO_BITS(eTypeTable),
                        &nsCSSFrameConstructor::ConstructTableRowOrRowGroup) },
--- a/layout/style/nsStyleContext.cpp
+++ b/layout/style/nsStyleContext.cpp
@@ -524,19 +524,19 @@ nsStyleContext::ApplyStyleFixups(bool aS
       containerContext = containerContext->GetParent();
       containerDisp = containerContext->StyleDisplay();
     }
     if (containerDisp->IsFlexOrGridDisplayType() &&
         GetPseudo() != nsCSSAnonBoxes::mozNonElement) {
       uint8_t displayVal = disp->mDisplay;
       // Skip table parts.
       // NOTE: This list needs to be kept in sync with
-      // nsCSSFrameConstructor.cpp's "sDisplayData" array -- specifically,
-      // this should be the list of display-values that have
-      // FCDATA_DESIRED_PARENT_TYPE_TO_BITS specified in that array.
+      // nsCSSFrameConstructor::FindDisplayData() -- specifically,
+      // this should be the list of display-values that returns
+      // FCDATA_DESIRED_PARENT_TYPE_TO_BITS from that method.
       if (NS_STYLE_DISPLAY_TABLE_CAPTION      != displayVal &&
           NS_STYLE_DISPLAY_TABLE_ROW_GROUP    != displayVal &&
           NS_STYLE_DISPLAY_TABLE_HEADER_GROUP != displayVal &&
           NS_STYLE_DISPLAY_TABLE_FOOTER_GROUP != displayVal &&
           NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP != displayVal &&
           NS_STYLE_DISPLAY_TABLE_COLUMN       != displayVal &&
           NS_STYLE_DISPLAY_TABLE_ROW          != displayVal &&
           NS_STYLE_DISPLAY_TABLE_CELL         != displayVal) {
--- a/layout/style/nsStyleStruct.h
+++ b/layout/style/nsStyleStruct.h
@@ -2071,18 +2071,19 @@ struct nsStyleDisplay {
            mAnimationDirectionCount,
            mAnimationFillModeCount,
            mAnimationPlayStateCount,
            mAnimationIterationCountCount;
 
   bool IsBlockInsideStyle() const {
     return NS_STYLE_DISPLAY_BLOCK == mDisplay ||
            NS_STYLE_DISPLAY_LIST_ITEM == mDisplay ||
-           NS_STYLE_DISPLAY_INLINE_BLOCK == mDisplay;
-    // Should TABLE_CELL and TABLE_CAPTION go here?  They have
+           NS_STYLE_DISPLAY_INLINE_BLOCK == mDisplay ||
+           NS_STYLE_DISPLAY_TABLE_CAPTION == mDisplay;
+    // Should TABLE_CELL be included here?  They have
     // block frames nested inside of them.
     // (But please audit all callers before changing.)
   }
 
   bool IsBlockOutsideStyle() const {
     return NS_STYLE_DISPLAY_BLOCK == mDisplay ||
            NS_STYLE_DISPLAY_FLEX == mDisplay ||
            NS_STYLE_DISPLAY_GRID == mDisplay ||