Bug 1346983 - Add ColumnSetWrapperFrame to wrap nsColumnSetFrames and column span frames. r=dbaron
authorTing-Yu Lin <tlin@mozilla.com>
Thu, 06 Sep 2018 17:58:24 +0000
changeset 490872 2ffd781dd9a1e8c7da6e0289c3edc446344f6448
parent 490871 1d860063c47790e6ce4cca993a3818c7b79c6bd6
child 490873 1b602c278c16afc215dd18c3e36296339aea9217
push id9984
push userffxbld-merge
push dateMon, 15 Oct 2018 21:07:35 +0000
treeherdermozilla-beta@183d27ea8570 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdbaron
bugs1346983, 1421105
milestone64.0a1
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
Bug 1346983 - Add ColumnSetWrapperFrame to wrap nsColumnSetFrames and column span frames. r=dbaron ColumnSetWrapperFrame is needed to implement column-span. Patches in bug 1421105 will utilize this frame. Co-authored-by: Neerja Pancholi <npancholi@mozilla.com> Differential Revision: https://phabricator.services.mozilla.com/D5092
layout/base/nsCSSFrameConstructor.cpp
layout/generic/ColumnSetWrapperFrame.cpp
layout/generic/ColumnSetWrapperFrame.h
layout/generic/FrameTypeList.h
layout/generic/moz.build
layout/generic/nsFrameIdList.h
layout/generic/nsHTMLParts.h
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -8357,16 +8357,19 @@ nsCSSFrameConstructor::CreateContinuingF
                "no support for fragmenting table captions yet");
     newFrame = NS_NewBlockFrame(shell, computedStyle);
     newFrame->Init(content, aParentFrame, aFrame);
 #ifdef MOZ_XUL
   } else if (LayoutFrameType::XULLabel == frameType) {
     newFrame = NS_NewXULLabelFrame(shell, computedStyle);
     newFrame->Init(content, aParentFrame, aFrame);
 #endif
+  } else if (LayoutFrameType::ColumnSetWrapper == frameType) {
+    newFrame = NS_NewColumnSetWrapperFrame(shell, computedStyle, nsFrameState(0));
+    newFrame->Init(content, aParentFrame, aFrame);
   } else if (LayoutFrameType::ColumnSet == frameType) {
     MOZ_ASSERT(!aFrame->IsTableCaption(),
                "no support for fragmenting table captions yet");
     newFrame = NS_NewColumnSetFrame(shell, computedStyle, nsFrameState(0));
     newFrame->Init(content, aParentFrame, aFrame);
   } else if (LayoutFrameType::Page == frameType) {
     nsContainerFrame* canvasFrame;
     newFrame = ConstructPageFrame(shell, aParentFrame, aFrame, canvasFrame);
new file mode 100644
--- /dev/null
+++ b/layout/generic/ColumnSetWrapperFrame.cpp
@@ -0,0 +1,69 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
+
+#include "ColumnSetWrapperFrame.h"
+
+using namespace mozilla;
+
+nsBlockFrame*
+NS_NewColumnSetWrapperFrame(nsIPresShell* aPresShell,
+                            ComputedStyle* aStyle,
+                            nsFrameState aStateFlags)
+{
+  ColumnSetWrapperFrame* frame = new (aPresShell) ColumnSetWrapperFrame(aStyle);
+
+  // CSS Multi-column level 1 section 2: A multi-column container
+  // establishes a new block formatting context, as per CSS 2.1 section
+  // 9.4.1.
+  frame->AddStateBits(aStateFlags | NS_BLOCK_FORMATTING_CONTEXT_STATE_BITS);
+  return frame;
+}
+
+NS_IMPL_FRAMEARENA_HELPERS(ColumnSetWrapperFrame)
+
+NS_QUERYFRAME_HEAD(ColumnSetWrapperFrame)
+  NS_QUERYFRAME_ENTRY(ColumnSetWrapperFrame)
+NS_QUERYFRAME_TAIL_INHERITING(nsBlockFrame)
+
+ColumnSetWrapperFrame::ColumnSetWrapperFrame(ComputedStyle* aStyle)
+  : nsBlockFrame(aStyle, kClassID)
+{
+}
+
+#ifdef DEBUG_FRAME_DUMP
+nsresult
+ColumnSetWrapperFrame::GetFrameName(nsAString& aResult) const
+{
+  return MakeFrameName(NS_LITERAL_STRING("ColumnSetWrapper"), aResult);
+}
+#endif
+
+// Disallow any append, insert, or remove operations after building the
+// column hierarchy since any change to the column hierarchy in the column
+// sub-tree need to be re-created.
+void
+ColumnSetWrapperFrame::AppendFrames(ChildListID aListID,
+                                    nsFrameList& aFrameList)
+{
+  MOZ_ASSERT_UNREACHABLE("Unsupported operation!");
+  nsBlockFrame::AppendFrames(aListID, aFrameList);
+}
+
+void
+ColumnSetWrapperFrame::InsertFrames(ChildListID aListID,
+                                    nsIFrame* aPrevFrame,
+                                    nsFrameList& aFrameList)
+{
+  MOZ_ASSERT_UNREACHABLE("Unsupported operation!");
+  nsBlockFrame::InsertFrames(aListID, aPrevFrame, aFrameList);
+}
+
+void
+ColumnSetWrapperFrame::RemoveFrame(ChildListID aListID, nsIFrame* aOldFrame)
+{
+  MOZ_ASSERT_UNREACHABLE("Unsupported operation!");
+  nsBlockFrame::RemoveFrame(aListID, aOldFrame);
+}
new file mode 100644
--- /dev/null
+++ b/layout/generic/ColumnSetWrapperFrame.h
@@ -0,0 +1,55 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
+
+// A frame for CSS multi-column layout that wraps nsColumnSetFrames and
+// column-span frames.
+
+#ifndef mozilla_ColumnSetWrapperFrame_h
+#define mozilla_ColumnSetWrapperFrame_h
+
+#include "nsBlockFrame.h"
+
+namespace mozilla {
+
+// This class is a wrapper for nsColumnSetFrames and column-span frame.
+// Essentially, we divide the *original* nsColumnSetFrame into multiple
+// nsColumnSetFrames on the basis of the number and position of spanning
+// elements.
+//
+// This wrapper is necessary for implementing column-span as it allows us to
+// maintain each nsColumnSetFrame as an independent set of columns, and each
+// column-span element then becomes just a block level element.
+//
+class ColumnSetWrapperFrame final : public nsBlockFrame
+{
+public:
+  NS_DECL_FRAMEARENA_HELPERS(ColumnSetWrapperFrame)
+  NS_DECL_QUERYFRAME
+
+  friend nsBlockFrame* ::NS_NewColumnSetWrapperFrame(nsIPresShell* aPresShell,
+                                                     ComputedStyle* aStyle,
+                                                     nsFrameState aStateFlags);
+
+#ifdef DEBUG_FRAME_DUMP
+  nsresult GetFrameName(nsAString& aResult) const override;
+#endif
+
+  void AppendFrames(ChildListID aListID, nsFrameList& aFrameList) override;
+
+  void InsertFrames(ChildListID aListID,
+                    nsIFrame* aPrevFrame,
+                    nsFrameList& aFrameList) override;
+
+  void RemoveFrame(ChildListID aListID, nsIFrame* aOldFrame) override;
+
+private:
+  explicit ColumnSetWrapperFrame(ComputedStyle* aStyle);
+  ~ColumnSetWrapperFrame() override = default;
+};
+
+} // namespace mozilla
+
+#endif // mozilla_ColumnSetWrapperFrame_h
--- a/layout/generic/FrameTypeList.h
+++ b/layout/generic/FrameTypeList.h
@@ -13,16 +13,17 @@ FRAME_TYPE(Block)
 FRAME_TYPE(Box)
 FRAME_TYPE(Br)
 FRAME_TYPE(Bullet)
 FRAME_TYPE(BCTableCell)
 FRAME_TYPE(Canvas)
 FRAME_TYPE(CheckboxRadio)
 FRAME_TYPE(ColorControl)
 FRAME_TYPE(ColumnSet)
+FRAME_TYPE(ColumnSetWrapper)
 FRAME_TYPE(ComboboxControl)
 FRAME_TYPE(ComboboxDisplay)
 FRAME_TYPE(Deck)
 FRAME_TYPE(DateTimeControl)
 FRAME_TYPE(Details)
 FRAME_TYPE(FieldSet)
 FRAME_TYPE(FlexContainer)
 FRAME_TYPE(FrameSet)
--- a/layout/generic/moz.build
+++ b/layout/generic/moz.build
@@ -7,16 +7,22 @@
 with Files('nsBlock*'):
     # Parts of these files are really Layout: Floats
     BUG_COMPONENT = ('Core', 'Layout: Block and Inline')
 
 with Files('Block*'):
     # Parts of these files are really Layout: Floats
     BUG_COMPONENT = ('Core', 'Layout: Block and Inline')
 
+with Files('nsColumn*'):
+    BUG_COMPONENT = ('Core', 'Layout: Columns')
+
+with Files('Column*'):
+    BUG_COMPONENT = ('Core', 'Layout: Columns')
+
 with Files('nsLine*'):
     # Parts of these files are really Layout: Floats
     BUG_COMPONENT = ('Core', 'Layout: Block and Inline')
 
 with Files('nsInlineFrame.*'):
     BUG_COMPONENT = ('Core', 'Layout: Block and Inline')
 
 with Files('BRFrame.*'):
@@ -139,16 +145,17 @@ EXPORTS.mozilla += [
 
 EXPORTS.mozilla.layout += [
     'FrameChildList.h',
 ]
 
 UNIFIED_SOURCES += [
     'BlockReflowInput.cpp',
     'BRFrame.cpp',
+    'ColumnSetWrapperFrame.cpp',
     'CSSAlignUtils.cpp',
     'CSSOrderAwareFrameIterator.cpp',
     'DetailsFrame.cpp',
     'FrameChildList.cpp',
     'MathMLTextRunFactory.cpp',
     'nsAbsoluteContainingBlock.cpp',
     'nsBackdropFrame.cpp',
     'nsBlockFrame.cpp',
--- a/layout/generic/nsFrameIdList.h
+++ b/layout/generic/nsFrameIdList.h
@@ -12,16 +12,17 @@ FRAME_ID(nsBlockFrame, Block, NotLeaf)
 FRAME_ID(nsBox, None, NotLeaf)
 FRAME_ID(nsBoxFrame, Box, NotLeaf)
 FRAME_ID(nsBulletFrame, Bullet, Leaf)
 FRAME_ID(nsButtonBoxFrame, Box, NotLeaf)
 FRAME_ID(nsCanvasFrame, Canvas, NotLeaf)
 FRAME_ID(nsCheckboxRadioFrame, CheckboxRadio, Leaf)
 FRAME_ID(nsColorControlFrame, ColorControl, Leaf)
 FRAME_ID(nsColumnSetFrame, ColumnSet, NotLeaf)
+FRAME_ID(ColumnSetWrapperFrame, ColumnSetWrapper, NotLeaf)
 FRAME_ID(nsComboboxControlFrame, ComboboxControl, NotLeaf)
 FRAME_ID(nsComboboxDisplayFrame, ComboboxDisplay, NotLeaf)
 FRAME_ID(nsContinuingTextFrame, Text, Leaf)
 FRAME_ID(nsDateTimeControlFrame, DateTimeControl, Leaf)
 FRAME_ID(nsDeckFrame, Deck, NotLeaf)
 FRAME_ID(nsDocElementBoxFrame, Box, NotLeaf)
 FRAME_ID(nsFieldSetFrame, FieldSet, NotLeaf)
 FRAME_ID(nsFileControlFrame, Block, Leaf)
--- a/layout/generic/nsHTMLParts.h
+++ b/layout/generic/nsHTMLParts.h
@@ -103,16 +103,18 @@ nsIFrame*
 NS_NewContinuingTextFrame(nsIPresShell* aPresShell, mozilla::ComputedStyle* aStyle);
 nsIFrame*
 NS_NewEmptyFrame(nsIPresShell* aPresShell, mozilla::ComputedStyle* aStyle);
 inline nsIFrame*
 NS_NewWBRFrame(nsIPresShell* aPresShell, mozilla::ComputedStyle* aStyle) {
   return NS_NewEmptyFrame(aPresShell, aStyle);
 }
 
+nsBlockFrame*
+NS_NewColumnSetWrapperFrame(nsIPresShell* aPresShell, mozilla::ComputedStyle* aStyle, nsFrameState aStateFlags);
 nsContainerFrame*
 NS_NewColumnSetFrame(nsIPresShell* aPresShell, mozilla::ComputedStyle* aStyle, nsFrameState aStateFlags);
 
 class nsSimplePageSequenceFrame;
 nsSimplePageSequenceFrame*
 NS_NewSimplePageSequenceFrame(nsIPresShell* aPresShell, mozilla::ComputedStyle* aStyle);
 class nsPageFrame;
 nsPageFrame*