Bug 1299753 Part 3 - Reuse ConstructScrollableBlock to build scrollable DetailsFrame. draft
authorTing-Yu Lin <tlin@mozilla.com>
Thu, 08 Sep 2016 15:38:06 +0800
changeset 412033 727cc383bd24ca54deb88c8844ae14be51451888
parent 412032 3485cdd3f52f8e4b195e236ac8d7ae5b0dcdc028
child 412055 6941794d047936fb226fda4933e84dda31fd09eb
child 412057 20797a07c37aac71ebbff1ff820a1107431a69ab
push id29027
push userbmo:tlin@mozilla.com
push dateFri, 09 Sep 2016 04:20:42 +0000
bugs1299753
milestone51.0a1
Bug 1299753 Part 3 - Reuse ConstructScrollableBlock to build scrollable DetailsFrame. MozReview-Commit-ID: 1yAhuKqurHf
layout/base/nsCSSFrameConstructor.cpp
layout/base/nsCSSFrameConstructor.h
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -3363,46 +3363,20 @@ nsCSSFrameConstructor::ConstructDetailsF
                                              nsFrameItems& aFrameItems)
 {
   if (!aStyleDisplay->IsScrollableOverflow()) {
     return ConstructNonScrollableBlockWithConstructor(aState, aItem, aParentFrame,
                                                       aStyleDisplay, aFrameItems,
                                                       NS_NewDetailsFrame);
   }
 
-  nsIContent* const content = aItem.mContent;
-  nsStyleContext* const styleContext = aItem.mStyleContext;
-  nsContainerFrame* geometricParent =
-    aState.GetGeometricParent(aStyleDisplay, aParentFrame);
-
-  nsContainerFrame* detailsFrame = NS_NewDetailsFrame(mPresShell, styleContext);
-
   // Build a scroll frame to wrap details frame if necessary.
-  nsContainerFrame* scrollFrame = nullptr;
-
-  RefPtr<nsStyleContext> detailsStyle =
-    BeginBuildingScrollFrame(aState, content, styleContext, geometricParent ,
-                             nsCSSAnonBoxes::scrolledContent, false,
-                             scrollFrame);
-
-  aState.AddChild(scrollFrame, aFrameItems, content, styleContext,
-                  aParentFrame);
-
-  nsFrameItems scrollFrameItems;
-  ConstructBlock(aState, content, scrollFrame, scrollFrame,
-                 detailsStyle, &detailsFrame, scrollFrameItems,
-                 aStyleDisplay->IsAbsPosContainingBlock(scrollFrame) ?
-                   scrollFrame : nullptr,
-                 aItem.mPendingBinding);
-
-  MOZ_ASSERT(scrollFrameItems.OnlyChild() == detailsFrame);
-
-  FinishBuildingScrollFrame(scrollFrame, detailsFrame);
-
-  return scrollFrame;
+  return ConstructScrollableBlockWithConstructor(aState, aItem, aParentFrame,
+                                                 aStyleDisplay, aFrameItems,
+                                                 NS_NewDetailsFrame);
 }
 
 static nsIFrame*
 FindAncestorWithGeneratedContentPseudo(nsIFrame* aFrame)
 {
   for (nsIFrame* f = aFrame->GetParent(); f; f = f->GetParent()) {
     NS_ASSERTION(f->IsGeneratedContentFrame(),
                  "should not have exited generated content");
@@ -4834,43 +4808,56 @@ nsCSSFrameConstructor::FindDisplayData(c
 
 nsIFrame*
 nsCSSFrameConstructor::ConstructScrollableBlock(nsFrameConstructorState& aState,
                                                 FrameConstructionItem&   aItem,
                                                 nsContainerFrame*        aParentFrame,
                                                 const nsStyleDisplay*    aDisplay,
                                                 nsFrameItems&            aFrameItems)
 {
+  return ConstructScrollableBlockWithConstructor(aState, aItem, aParentFrame,
+                                                 aDisplay, aFrameItems,
+                                                 NS_NewBlockFormattingContext);
+}
+
+nsIFrame*
+nsCSSFrameConstructor::ConstructScrollableBlockWithConstructor(
+  nsFrameConstructorState& aState,
+  FrameConstructionItem& aItem,
+  nsContainerFrame* aParentFrame,
+  const nsStyleDisplay* aDisplay,
+  nsFrameItems& aFrameItems,
+  BlockFrameCreationFunc aConstructor)
+{
   nsIContent* const content = aItem.mContent;
   nsStyleContext* const styleContext = aItem.mStyleContext;
 
   nsContainerFrame* newFrame = nullptr;
   RefPtr<nsStyleContext> scrolledContentStyle
     = BeginBuildingScrollFrame(aState, content, styleContext,
                                aState.GetGeometricParent(aDisplay, aParentFrame),
                                nsCSSAnonBoxes::scrolledContent,
                                false, newFrame);
 
   // Create our block frame
   // pass a temporary stylecontext, the correct one will be set later
-  nsContainerFrame* scrolledFrame =
-    NS_NewBlockFormattingContext(mPresShell, styleContext);
+  nsContainerFrame* scrolledFrame = aConstructor(mPresShell, styleContext);
 
   // Make sure to AddChild before we call ConstructBlock so that we
   // end up before our descendants in fixed-pos lists as needed.
   aState.AddChild(newFrame, aFrameItems, content, styleContext, aParentFrame);
 
   nsFrameItems blockItem;
   ConstructBlock(aState, content, newFrame, newFrame, scrolledContentStyle,
                  &scrolledFrame, blockItem,
                  aDisplay->IsAbsPosContainingBlock(newFrame) ? newFrame : nullptr,
                  aItem.mPendingBinding);
 
-  NS_ASSERTION(blockItem.FirstChild() == scrolledFrame,
-               "Scrollframe's frameItems should be exactly the scrolled frame");
+  MOZ_ASSERT(blockItem.OnlyChild() == scrolledFrame,
+             "Scrollframe's frameItems should be exactly the scrolled frame!");
   FinishBuildingScrollFrame(newFrame, scrolledFrame);
 
   return newFrame;
 }
 
 nsIFrame*
 nsCSSFrameConstructor::ConstructNonScrollableBlock(nsFrameConstructorState& aState,
                                                    FrameConstructionItem&   aItem,
--- a/layout/base/nsCSSFrameConstructor.h
+++ b/layout/base/nsCSSFrameConstructor.h
@@ -1553,16 +1553,28 @@ private:
    */
   nsIFrame* ConstructScrollableBlock(nsFrameConstructorState& aState,
                                      FrameConstructionItem&   aItem,
                                      nsContainerFrame*        aParentFrame,
                                      const nsStyleDisplay*    aDisplay,
                                      nsFrameItems&            aFrameItems);
 
   /**
+   * Construct a scrollable block frame using the given block frame creation
+   * function.
+   */
+  nsIFrame* ConstructScrollableBlockWithConstructor(
+    nsFrameConstructorState& aState,
+    FrameConstructionItem& aItem,
+    nsContainerFrame* aParentFrame,
+    const nsStyleDisplay* aDisplay,
+    nsFrameItems& aFrameItems,
+    BlockFrameCreationFunc aConstructor);
+
+  /**
    * Construct a non-scrollable block frame
    */
   nsIFrame* ConstructNonScrollableBlock(nsFrameConstructorState& aState,
                                         FrameConstructionItem&   aItem,
                                         nsContainerFrame*        aParentFrame,
                                         const nsStyleDisplay*    aDisplay,
                                         nsFrameItems&            aFrameItems);