summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorathenian200 <athenian200@outlook.com>2020-09-03 18:55:28 -0500
committerathenian200 <athenian200@outlook.com>2020-09-03 18:55:28 -0500
commit6b2c3b61b1c338ddec723482bd2c83427ef2e431 (patch)
treebd30f18df9a1d98b88a24c5e9482551ec84ff8ec
parent0ac50227e22599b62ddfb1e4a889032837925178 (diff)
downloaduxp-6b2c3b61b1c338ddec723482bd2c83427ef2e431.tar.gz
Issue #1641 - Implement CSS flow-root keyword
This is just a clean port of 1322191 and follow-up 1325970. It really seems to add create a new way to access existing code relating to block formatting and floating elements rather than implementing new functionality, and it is mercifully straightforwards.
-rw-r--r--layout/base/nsCSSFrameConstructor.cpp8
-rw-r--r--layout/base/nsLayoutUtils.cpp34
-rw-r--r--layout/forms/nsLegendFrame.cpp4
-rw-r--r--layout/generic/ReflowInput.cpp1
-rw-r--r--layout/generic/nsBlockFrame.cpp7
-rw-r--r--layout/generic/nsFrameStateBits.h3
-rw-r--r--layout/generic/nsHTMLParts.h3
-rw-r--r--layout/style/nsCSSKeywordList.h1
-rw-r--r--layout/style/nsCSSProps.cpp3
-rw-r--r--layout/style/nsRuleNode.cpp2
-rw-r--r--layout/style/nsStyleConsts.h1
-rw-r--r--layout/style/nsStyleStruct.h6
-rw-r--r--layout/style/test/property_database.js4
-rw-r--r--layout/xul/nsXULLabelFrame.cpp4
-rw-r--r--modules/libpref/init/all.js3
15 files changed, 68 insertions, 16 deletions
diff --git a/layout/base/nsCSSFrameConstructor.cpp b/layout/base/nsCSSFrameConstructor.cpp
index fc458b5ebf..21068b6736 100644
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -2618,7 +2618,8 @@ nsCSSFrameConstructor::ConstructDocElementFrame(Element* aDocEle
newFrame = frameItems.FirstChild();
NS_ASSERTION(frameItems.OnlyChild(), "multiple root element frames");
} else {
- MOZ_ASSERT(display->mDisplay == StyleDisplay::Block,
+ MOZ_ASSERT(display->mDisplay == StyleDisplay::Block ||
+ display->mDisplay == StyleDisplay::FlowRoot,
"Unhandled display type for root element");
contentFrame = NS_NewBlockFormattingContext(mPresShell, styleContext);
nsFrameItems frameItems;
@@ -4741,6 +4742,7 @@ nsCSSFrameConstructor::FindDisplayData(const nsStyleDisplay* aDisplay,
static const FrameConstructionDataByDisplay sDisplayData[] = {
FCDATA_FOR_DISPLAY(StyleDisplay::None, UNREACHABLE_FCDATA()),
FCDATA_FOR_DISPLAY(StyleDisplay::Block, UNREACHABLE_FCDATA()),
+ FCDATA_FOR_DISPLAY(StyleDisplay::FlowRoot, UNREACHABLE_FCDATA()),
// To keep the hash table small don't add inline frames (they're
// typically things like FONT and B), because we can quickly
// find them if we need to.
@@ -4926,7 +4928,7 @@ nsCSSFrameConstructor::ConstructNonScrollableBlockWithConstructor(
StyleDisplay::InlineBlock == aDisplay->mDisplay ||
clipPaginatedOverflow) &&
!aParentFrame->IsSVGText()) {
- flags = NS_BLOCK_FLOAT_MGR | NS_BLOCK_MARGIN_ROOT;
+ flags = NS_BLOCK_FORMATTING_CONTEXT_STATE_BITS;
if (clipPaginatedOverflow) {
flags |= NS_BLOCK_CLIP_PAGINATED_OVERFLOW;
}
@@ -5119,7 +5121,7 @@ nsCSSFrameConstructor::FlushAccumulatedBlock(nsFrameConstructorState& aState,
// is not a suitable block.
nsContainerFrame* blockFrame =
NS_NewMathMLmathBlockFrame(mPresShell, blockContext);
- blockFrame->AddStateBits(NS_BLOCK_FLOAT_MGR | NS_BLOCK_MARGIN_ROOT);
+ blockFrame->AddStateBits(NS_BLOCK_FORMATTING_CONTEXT_STATE_BITS);
InitAndRestoreFrame(aState, aContent, aParentFrame, blockFrame);
ReparentFrames(this, blockFrame, aBlockItems);
diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp
index 74dbd63e67..c8455c1c9f 100644
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -149,6 +149,7 @@ using namespace mozilla::gfx;
#define GRID_ENABLED_PREF_NAME "layout.css.grid.enabled"
#define GRID_TEMPLATE_SUBGRID_ENABLED_PREF_NAME "layout.css.grid-template-subgrid-value.enabled"
#define WEBKIT_PREFIXES_ENABLED_PREF_NAME "layout.css.prefixes.webkit"
+#define DISPLAY_FLOW_ROOT_ENABLED_PREF_NAME "layout.css.display-flow-root.enabled"
#define DISPLAY_CONTENTS_ENABLED_PREF_NAME "layout.css.display-contents.enabled"
#define TEXT_ALIGN_UNSAFE_ENABLED_PREF_NAME "layout.css.text-align-unsafe-value.enabled"
#define FLOAT_LOGICAL_VALUES_ENABLED_PREF_NAME "layout.css.float-logical-values.enabled"
@@ -314,6 +315,37 @@ WebkitPrefixEnabledPrefChangeCallback(const char* aPrefName, void* aClosure)
}
}
+// When the pref "layout.css.display-flow-root.enabled" changes, this function is
+// invoked to let us update kDisplayKTable, to selectively disable or restore
+// the entries for "flow-root" in that table.
+static void
+DisplayFlowRootEnabledPrefChangeCallback(const char* aPrefName, void* aClosure)
+{
+ NS_ASSERTION(strcmp(aPrefName, DISPLAY_FLOW_ROOT_ENABLED_PREF_NAME) == 0,
+ "Did you misspell " DISPLAY_FLOW_ROOT_ENABLED_PREF_NAME " ?");
+
+ static bool sIsDisplayFlowRootKeywordIndexInitialized;
+ static int32_t sIndexOfFlowRootInDisplayTable;
+ bool isDisplayFlowRootEnabled =
+ Preferences::GetBool(DISPLAY_FLOW_ROOT_ENABLED_PREF_NAME, false);
+
+ if (!sIsDisplayFlowRootKeywordIndexInitialized) {
+ // First run: find the position of "flow-root" in kDisplayKTable.
+ sIndexOfFlowRootInDisplayTable =
+ nsCSSProps::FindIndexOfKeyword(eCSSKeyword_flow_root,
+ nsCSSProps::kDisplayKTable);
+ sIsDisplayFlowRootKeywordIndexInitialized = true;
+ }
+
+ // OK -- now, stomp on or restore the "flow-root" entry in kDisplayKTable,
+ // depending on whether the pref is enabled vs. disabled.
+ if (sIndexOfFlowRootInDisplayTable >= 0) {
+ nsCSSProps::kDisplayKTable[sIndexOfFlowRootInDisplayTable].mKeyword =
+ isDisplayFlowRootEnabled ? eCSSKeyword_flow_root : eCSSKeyword_UNKNOWN;
+ }
+}
+
+
// When the pref "layout.css.display-contents.enabled" changes, this function is
// invoked to let us update kDisplayKTable, to selectively disable or restore
// the entries for "contents" in that table.
@@ -7555,6 +7587,8 @@ static const PrefCallbacks kPrefCallbacks[] = {
WebkitPrefixEnabledPrefChangeCallback },
{ TEXT_ALIGN_UNSAFE_ENABLED_PREF_NAME,
TextAlignUnsafeEnabledPrefChangeCallback },
+ { DISPLAY_FLOW_ROOT_ENABLED_PREF_NAME,
+ DisplayFlowRootEnabledPrefChangeCallback },
{ DISPLAY_CONTENTS_ENABLED_PREF_NAME,
DisplayContentsEnabledPrefChangeCallback },
{ FLOAT_LOGICAL_VALUES_ENABLED_PREF_NAME,
diff --git a/layout/forms/nsLegendFrame.cpp b/layout/forms/nsLegendFrame.cpp
index 95efc2c878..b985ed8fc3 100644
--- a/layout/forms/nsLegendFrame.cpp
+++ b/layout/forms/nsLegendFrame.cpp
@@ -24,9 +24,7 @@ NS_NewLegendFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
#endif
nsIFrame* f = new (aPresShell) nsLegendFrame(aContext);
- if (f) {
- f->AddStateBits(NS_BLOCK_FLOAT_MGR | NS_BLOCK_MARGIN_ROOT);
- }
+ f->AddStateBits(NS_BLOCK_FORMATTING_CONTEXT_STATE_BITS);
return f;
}
diff --git a/layout/generic/ReflowInput.cpp b/layout/generic/ReflowInput.cpp
index 9f7b4368c3..077c68b5be 100644
--- a/layout/generic/ReflowInput.cpp
+++ b/layout/generic/ReflowInput.cpp
@@ -844,6 +844,7 @@ ReflowInput::InitFrameType(nsIAtom* aFrameType)
case StyleDisplay::Flex:
case StyleDisplay::WebkitBox:
case StyleDisplay::Grid:
+ case StyleDisplay::FlowRoot:
case StyleDisplay::RubyTextContainer:
frameType = NS_CSS_FRAME_TYPE_BLOCK;
break;
diff --git a/layout/generic/nsBlockFrame.cpp b/layout/generic/nsBlockFrame.cpp
index 4742db07e6..152b3d06ad 100644
--- a/layout/generic/nsBlockFrame.cpp
+++ b/layout/generic/nsBlockFrame.cpp
@@ -305,7 +305,7 @@ NS_NewBlockFormattingContext(nsIPresShell* aPresShell,
nsStyleContext* aStyleContext)
{
nsBlockFrame* blockFrame = NS_NewBlockFrame(aPresShell, aStyleContext);
- blockFrame->AddStateBits(NS_BLOCK_FLOAT_MGR | NS_BLOCK_MARGIN_ROOT);
+ blockFrame->AddStateBits(NS_BLOCK_FORMATTING_CONTEXT_STATE_BITS);
return blockFrame;
}
@@ -6893,10 +6893,11 @@ nsBlockFrame::Init(nsIContent* aContent,
// (http://dev.w3.org/csswg/css-writing-modes/#block-flow)
// If the box has contain: paint (or contain: strict), then it should also
// establish a formatting context.
- if ((GetParent() && StyleVisibility()->mWritingMode !=
+ if (StyleDisplay()->mDisplay == mozilla::StyleDisplay::FlowRoot ||
+ (GetParent() && StyleVisibility()->mWritingMode !=
GetParent()->StyleVisibility()->mWritingMode) ||
StyleDisplay()->IsContainPaint()) {
- AddStateBits(NS_BLOCK_FLOAT_MGR | NS_BLOCK_MARGIN_ROOT);
+ AddStateBits(NS_BLOCK_FORMATTING_CONTEXT_STATE_BITS);
}
if ((GetStateBits() &
diff --git a/layout/generic/nsFrameStateBits.h b/layout/generic/nsFrameStateBits.h
index f8b1e541c1..ba43e37d45 100644
--- a/layout/generic/nsFrameStateBits.h
+++ b/layout/generic/nsFrameStateBits.h
@@ -483,6 +483,9 @@ FRAME_STATE_BIT(Block, 22, NS_BLOCK_MARGIN_ROOT)
// used to reserve space for the floated frames.
FRAME_STATE_BIT(Block, 23, NS_BLOCK_FLOAT_MGR)
+// For setting the relevant bits on a block formatting context:
+#define NS_BLOCK_FORMATTING_CONTEXT_STATE_BITS (NS_BLOCK_FLOAT_MGR | NS_BLOCK_MARGIN_ROOT)
+
FRAME_STATE_BIT(Block, 24, NS_BLOCK_HAS_LINE_CURSOR)
FRAME_STATE_BIT(Block, 25, NS_BLOCK_HAS_OVERFLOW_LINES)
diff --git a/layout/generic/nsHTMLParts.h b/layout/generic/nsHTMLParts.h
index 243c432b2f..97edaf75c1 100644
--- a/layout/generic/nsHTMLParts.h
+++ b/layout/generic/nsHTMLParts.h
@@ -28,8 +28,7 @@ class nsTableColFrame;
// These are all the block specific frame bits, they are copied from
// the prev-in-flow to a newly created next-in-flow, except for the
// NS_BLOCK_FLAGS_NON_INHERITED_MASK bits below.
-#define NS_BLOCK_FLAGS_MASK (NS_BLOCK_MARGIN_ROOT | \
- NS_BLOCK_FLOAT_MGR | \
+#define NS_BLOCK_FLAGS_MASK (NS_BLOCK_FORMATTING_CONTEXT_STATE_BITS | \
NS_BLOCK_CLIP_PAGINATED_OVERFLOW | \
NS_BLOCK_HAS_FIRST_LETTER_STYLE | \
NS_BLOCK_FRAME_HAS_OUTSIDE_BULLET | \
diff --git a/layout/style/nsCSSKeywordList.h b/layout/style/nsCSSKeywordList.h
index 34a46ffceb..9045da9ff1 100644
--- a/layout/style/nsCSSKeywordList.h
+++ b/layout/style/nsCSSKeywordList.h
@@ -285,6 +285,7 @@ CSS_KEY(flex, flex)
CSS_KEY(flex-end, flex_end)
CSS_KEY(flex-start, flex_start)
CSS_KEY(flip, flip)
+CSS_KEY(flow-root, flow_root)
CSS_KEY(forwards, forwards)
CSS_KEY(fraktur, fraktur)
CSS_KEY(from-image, from_image)
diff --git a/layout/style/nsCSSProps.cpp b/layout/style/nsCSSProps.cpp
index ac2978c277..24c97cf33e 100644
--- a/layout/style/nsCSSProps.cpp
+++ b/layout/style/nsCSSProps.cpp
@@ -1345,6 +1345,9 @@ KTableEntry nsCSSProps::kDisplayKTable[] = {
// The next entry is controlled by the layout.css.display-contents.enabled
// pref.
{ eCSSKeyword_contents, StyleDisplay::Contents },
+ // The next entry is controlled by the layout.css.display-flow-root.enabled
+ // pref.
+ { eCSSKeyword_flow_root, StyleDisplay::FlowRoot },
{ eCSSKeyword_UNKNOWN, -1 }
};
diff --git a/layout/style/nsRuleNode.cpp b/layout/style/nsRuleNode.cpp
index 1a451a2ef4..036d97f867 100644
--- a/layout/style/nsRuleNode.cpp
+++ b/layout/style/nsRuleNode.cpp
@@ -250,6 +250,7 @@ nsRuleNode::EnsureBlockDisplay(StyleDisplay& display,
case StyleDisplay::Flex:
case StyleDisplay::WebkitBox:
case StyleDisplay::Grid:
+ case StyleDisplay::FlowRoot:
// do not muck with these at all - already blocks
// This is equivalent to nsStyleDisplay::IsBlockOutside. (XXX Maybe we
// should just call that?)
@@ -293,6 +294,7 @@ nsRuleNode::EnsureInlineDisplay(StyleDisplay& display)
// see if the display value is already inline
switch (display) {
case StyleDisplay::Block:
+ case StyleDisplay::FlowRoot:
display = StyleDisplay::InlineBlock;
break;
case StyleDisplay::Table:
diff --git a/layout/style/nsStyleConsts.h b/layout/style/nsStyleConsts.h
index 6d207aec9b..f54387aa8a 100644
--- a/layout/style/nsStyleConsts.h
+++ b/layout/style/nsStyleConsts.h
@@ -524,6 +524,7 @@ enum class FillMode : uint32_t;
enum class StyleDisplay : uint8_t {
None = 0,
Block,
+ FlowRoot,
Inline,
InlineBlock,
ListItem,
diff --git a/layout/style/nsStyleStruct.h b/layout/style/nsStyleStruct.h
index 4bda817ddb..f49cdc43ef 100644
--- a/layout/style/nsStyleStruct.h
+++ b/layout/style/nsStyleStruct.h
@@ -2890,7 +2890,8 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleDisplay
return mozilla::StyleDisplay::Block == mDisplay ||
mozilla::StyleDisplay::ListItem == mDisplay ||
mozilla::StyleDisplay::InlineBlock == mDisplay ||
- mozilla::StyleDisplay::TableCaption == mDisplay;
+ mozilla::StyleDisplay::TableCaption == mDisplay ||
+ mozilla::StyleDisplay::FlowRoot == mDisplay;
// Should TABLE_CELL be included here? They have
// block frames nested inside of them.
// (But please audit all callers before changing.)
@@ -2902,7 +2903,8 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleDisplay
mozilla::StyleDisplay::WebkitBox == mDisplay ||
mozilla::StyleDisplay::Grid == mDisplay ||
mozilla::StyleDisplay::ListItem == mDisplay ||
- mozilla::StyleDisplay::Table == mDisplay;
+ mozilla::StyleDisplay::Table == mDisplay ||
+ mozilla::StyleDisplay::FlowRoot == mDisplay;
}
static bool IsDisplayTypeInlineOutside(mozilla::StyleDisplay aDisplay) {
diff --git a/layout/style/test/property_database.js b/layout/style/test/property_database.js
index c75f7b498f..2d6352148a 100644
--- a/layout/style/test/property_database.js
+++ b/layout/style/test/property_database.js
@@ -7892,6 +7892,10 @@ if (IsCSSPropertyPrefEnabled("layout.css.background-clip-text.enabled")) {
);
}
+if (IsCSSPropertyPrefEnabled("layout.css.display-flow-root.enabled")) {
+ gCSSProperties["display"].other_values.push("flow-root");
+}
+
// Copy aliased properties' fields from their alias targets.
for (var prop in gCSSProperties) {
var entry = gCSSProperties[prop];
diff --git a/layout/xul/nsXULLabelFrame.cpp b/layout/xul/nsXULLabelFrame.cpp
index 22b8754617..41e7e4d765 100644
--- a/layout/xul/nsXULLabelFrame.cpp
+++ b/layout/xul/nsXULLabelFrame.cpp
@@ -16,9 +16,7 @@ nsIFrame*
NS_NewXULLabelFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
{
nsXULLabelFrame* it = new (aPresShell) nsXULLabelFrame(aContext);
-
- it->AddStateBits(NS_BLOCK_FLOAT_MGR | NS_BLOCK_MARGIN_ROOT);
-
+ it->AddStateBits(NS_BLOCK_FORMATTING_CONTEXT_STATE_BITS);
return it;
}
diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js
index 5eed08f865..f3c660c124 100644
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -2606,6 +2606,9 @@ pref("layout.css.grid-template-subgrid-value.enabled", false);
// Is support for CSS contain enabled?
pref("layout.css.contain.enabled", false);
+// Is support for CSS display:flow-root enabled?
+pref("layout.css.display-flow-root.enabled", true);
+
// Is support for CSS display:contents enabled?
pref("layout.css.display-contents.enabled", true);