--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -3618,23 +3618,30 @@ nsCSSFrameConstructor::FindDataByInt(int
}
/* static */
const nsCSSFrameConstructor::FrameConstructionData*
nsCSSFrameConstructor::FindDataByTag(nsAtom* aTag,
Element* aElement,
nsStyleContext* aStyleContext,
const FrameConstructionDataByTag* aDataPtr,
- uint32_t aDataLength)
-{
+ uint32_t aDataLength,
+ bool* aTagFound)
+{
+ if (aTagFound) {
+ *aTagFound = false;
+ }
for (const FrameConstructionDataByTag *curData = aDataPtr,
*endData = aDataPtr + aDataLength;
curData != endData;
++curData) {
if (*curData->mTag == aTag) {
+ if (aTagFound) {
+ *aTagFound = true;
+ }
const FrameConstructionData* data = &curData->mData;
if (data->mBits & FCDATA_FUNC_IS_DATA_GETTER) {
return data->mFunc.mDataGetter(aElement, aStyleContext);
}
return data;
}
}
@@ -3728,18 +3735,39 @@ nsCSSFrameConstructor::FindHTMLData(Elem
SIMPLE_TAG_CHAIN(canvas, nsCSSFrameConstructor::FindCanvasData),
SIMPLE_TAG_CREATE(video, NS_NewHTMLVideoFrame),
SIMPLE_TAG_CREATE(audio, NS_NewHTMLVideoFrame),
SIMPLE_TAG_CREATE(progress, NS_NewProgressFrame),
SIMPLE_TAG_CREATE(meter, NS_NewMeterFrame),
COMPLEX_TAG_CREATE(details, &nsCSSFrameConstructor::ConstructDetailsFrame)
};
- return FindDataByTag(aTag, aElement, aStyleContext, sHTMLData,
- ArrayLength(sHTMLData));
+ bool tagFound;
+ const FrameConstructionData* data =
+ FindDataByTag(aTag, aElement, aStyleContext, sHTMLData,
+ ArrayLength(sHTMLData), &tagFound);
+
+ // https://drafts.csswg.org/css-display/#unbox-html
+ if (tagFound &&
+ MOZ_UNLIKELY(aStyleContext->StyleDisplay()->mDisplay ==
+ StyleDisplay::Contents)) {
+ // <button>, <legend>, <details> and <fieldset> don’t have any special
+ // behavior; display: contents simply removes their principal box, and their
+ // contents render as normal.
+ if (aTag != nsGkAtoms::button &&
+ aTag != nsGkAtoms::legend &&
+ aTag != nsGkAtoms::details &&
+ aTag != nsGkAtoms::fieldset) {
+ // On the rest of unusual HTML elements, display: contents creates no box.
+ static const FrameConstructionData sSuppressData = SUPPRESS_FCDATA();
+ return &sSuppressData;
+ }
+ }
+
+ return data;
}
/* static */
const nsCSSFrameConstructor::FrameConstructionData*
nsCSSFrameConstructor::FindImgData(Element* aElement,
nsStyleContext* aStyleContext)
{
if (!nsImageFrame::ShouldCreateImageFrameFor(aElement, aStyleContext)) {
@@ -4492,18 +4520,32 @@ nsCSSFrameConstructor::FindXULTagData(El
nsCSSFrameConstructor::FindXULListBoxBodyData),
SIMPLE_TAG_CHAIN(listitem, nsCSSFrameConstructor::FindXULListItemData),
#endif /* MOZ_XUL */
SIMPLE_XUL_CREATE(slider, NS_NewSliderFrame),
SIMPLE_XUL_CREATE(scrollbar, NS_NewScrollbarFrame),
SIMPLE_XUL_CREATE(scrollbarbutton, NS_NewScrollbarButtonFrame)
};
- return FindDataByTag(aTag, aElement, aStyleContext, sXULTagData,
- ArrayLength(sXULTagData));
+ bool tagFound;
+ const FrameConstructionData* data =
+ FindDataByTag(aTag, aElement, aStyleContext, sXULTagData,
+ ArrayLength(sXULTagData), &tagFound);
+
+ // There's no spec that says what display: contents means for special XUL
+ // elements, but we do the same as for HTML "Unusual Elements", i.e. treat it
+ // as display:none.
+ if (tagFound &&
+ MOZ_UNLIKELY(aStyleContext->StyleDisplay()->mDisplay ==
+ StyleDisplay::Contents)) {
+ static const FrameConstructionData sSuppressData = SUPPRESS_FCDATA();
+ return &sSuppressData;
+ }
+
+ return data;
}
#ifdef MOZ_XUL
/* static */
const nsCSSFrameConstructor::FrameConstructionData*
nsCSSFrameConstructor::FindPopupGroupData(Element* aElement,
nsStyleContext* /* unused */)
{
@@ -4966,18 +5008,17 @@ nsCSSFrameConstructor::FindDisplayData(c
NS_NewRubyBaseContainerFrame)),
FCDATA_FOR_DISPLAY(StyleDisplay::RubyText,
FCDATA_DECL(FCDATA_IS_LINE_PARTICIPANT |
FCDATA_DESIRED_PARENT_TYPE_TO_BITS(eTypeRubyTextContainer),
NS_NewRubyTextFrame)),
FCDATA_FOR_DISPLAY(StyleDisplay::RubyTextContainer,
FCDATA_DECL(FCDATA_DESIRED_PARENT_TYPE_TO_BITS(eTypeRuby),
NS_NewRubyTextContainerFrame)),
- FCDATA_FOR_DISPLAY(StyleDisplay::Contents,
- FULL_CTOR_FCDATA(FCDATA_IS_CONTENTS, nullptr/*never called*/)),
+ FCDATA_FOR_DISPLAY(StyleDisplay::Contents, UNREACHABLE_FCDATA()),
FCDATA_FOR_DISPLAY(StyleDisplay::WebkitBox,
FCDATA_DECL(FCDATA_MAY_NEED_SCROLLFRAME, NS_NewFlexContainerFrame)),
FCDATA_FOR_DISPLAY(StyleDisplay::WebkitInlineBox,
FCDATA_DECL(FCDATA_MAY_NEED_SCROLLFRAME, NS_NewFlexContainerFrame)),
FCDATA_FOR_DISPLAY(StyleDisplay::MozBox,
FCDATA_DECL(FCDATA_MAY_NEED_SCROLLFRAME, NS_NewFlexContainerFrame)),
FCDATA_FOR_DISPLAY(StyleDisplay::MozInlineBox,
FCDATA_DECL(FCDATA_MAY_NEED_SCROLLFRAME, NS_NewFlexContainerFrame)),
@@ -5552,16 +5593,33 @@ nsCSSFrameConstructor::FindSVGData(Eleme
return &sSuppressData;
}
// We don't need frames for animation elements
if (aElement->IsNodeOfType(nsINode::eANIMATION)) {
return &sSuppressData;
}
+ // https://drafts.csswg.org/css-display/#unbox-svg
+ if (aStyleContext->StyleDisplay()->mDisplay == StyleDisplay::Contents) {
+ // For root <svg> elements, display: contents behaves as display: none.
+ if (aTag == nsGkAtoms::svg && !parentIsSVG) {
+ return &sSuppressData;
+ }
+
+ // For nested <svg>, <g>, <use> and <tspan> behave normally, but any other
+ // element behaves as display: none as well.
+ if (aTag != nsGkAtoms::g &&
+ aTag != nsGkAtoms::use &&
+ aTag != nsGkAtoms::svg &&
+ aTag != nsGkAtoms::tspan) {
+ return &sSuppressData;
+ }
+ }
+
if (aTag == nsGkAtoms::svg && !parentIsSVG) {
// We need outer <svg> elements to have an nsSVGOuterSVGFrame regardless
// of whether they fail conditional processing attributes, since various
// SVG frames assume that one exists. We handle the non-rendering
// of failing outer <svg> element contents like <switch> statements,
// and do the PassesConditionalProcessingTests call in
// nsSVGOuterSVGFrame::Init.
static const FrameConstructionData sOuterSVGData =
@@ -6070,17 +6128,21 @@ nsCSSFrameConstructor::AddFrameConstruct
!display->IsAbsolutelyPositionedStyle() &&
!(aParentFrame && aParentFrame->IsGridContainerFrame()) &&
!(bits & FCDATA_IS_TABLE_PART) && !(bits & FCDATA_IS_SVG_TEXT);
if (canHavePageBreak && display->mBreakBefore) {
AddPageBreakItem(aContent, aItems);
}
- if (MOZ_UNLIKELY(bits & FCDATA_IS_CONTENTS)) {
+ // FIXME(emilio, https://github.com/w3c/csswg-drafts/issues/2167):
+ //
+ // Figure out what should happen for display: contents in MathML.
+ if (display->mDisplay == StyleDisplay::Contents &&
+ !aContent->IsMathMLElement()) {
if (!GetDisplayContentsStyleFor(aContent)) {
MOZ_ASSERT(styleContext->GetPseudo() || !isGeneratedContent,
"Should have had pseudo type");
aState.mFrameManager->RegisterDisplayContentsStyleFor(aContent,
styleContext);
} else {
aState.mFrameManager->ChangeRegisteredDisplayContentsStyleFor(aContent,
styleContext);
--- a/layout/base/nsCSSFrameConstructor.h
+++ b/layout/base/nsCSSFrameConstructor.h
@@ -730,20 +730,16 @@ private:
block formatting context wrapper around the kids of this frame
using the FrameConstructionData's mPseudoAtom for its anonymous
box type. */
#define FCDATA_CREATE_BLOCK_WRAPPER_FOR_ALL_KIDS 0x40000
/* If FCDATA_IS_SVG_TEXT is set, then this text frame is a descendant of
an SVG text frame. */
#define FCDATA_IS_SVG_TEXT 0x80000
/**
- * display:contents
- */
-#define FCDATA_IS_CONTENTS 0x100000
- /**
* When FCDATA_CREATE_BLOCK_WRAPPER_FOR_ALL_KIDS is set, this bit says
* if we should create a grid/flex/columnset container instead of
* a block wrapper when the styles says so.
*/
#define FCDATA_ALLOW_GRID_FLEX_COLUMNSET 0x200000
/**
* Whether the kids of this FrameConstructionData should be flagged as having
* a wrapper anon box parent. This should only be set if
@@ -823,26 +819,31 @@ private:
match or if the matching integer has a FrameConstructionDataGetter that
returns null. */
static const FrameConstructionData*
FindDataByInt(int32_t aInt, Element* aElement,
nsStyleContext* aStyleContext,
const FrameConstructionDataByInt* aDataPtr,
uint32_t aDataLength);
- /* A function that takes a tag, content, style context, and array of
- FrameConstructionDataByTags and finds the appropriate frame construction
- data to use and returns it. This can return null if none of the tags
- match or if the matching tag has a FrameConstructionDataGetter that
- returns null. */
+ /**
+ * A function that takes a tag, content, style context, and array of
+ * FrameConstructionDataByTags and finds the appropriate frame construction
+ * data to use and returns it.
+ *
+ * This can return null if none of the tags match or if the matching tag has a
+ * FrameConstructionDataGetter that returns null. In the case that the tags
+ * actually match, aTagFound will be true, even if the return value is null.
+ */
static const FrameConstructionData*
FindDataByTag(nsAtom* aTag, Element* aElement,
nsStyleContext* aStyleContext,
const FrameConstructionDataByTag* aDataPtr,
- uint32_t aDataLength);
+ uint32_t aDataLength,
+ bool* aTagFound = nullptr);
/* A class representing a list of FrameConstructionItems. Instances of this
class are only created as AutoFrameConstructionItemList, or as a member
of FrameConstructionItem. */
class FrameConstructionItemList
{
public:
void Reset(nsCSSFrameConstructor* aFCtor)
--- a/layout/reftests/css-display/display-contents-acid-ref.html
+++ b/layout/reftests/css-display/display-contents-acid-ref.html
@@ -169,16 +169,12 @@ 0
<div class="contents c3"><div>3</div></div>
</div>
<span class="c2 b"><legend class="inline c1">Legend</legend><legend class="inline c1">Legend</legend></span>
<br clear="all">
<span class="c3">x<div class="inline c1">float:left</div></span>
<span class="c3">y<div class="inline c1">position:absolute</div></span>
-<!-- -->
-
-<fieldset class="c1" style="display:inline"><legend>Legend</legend>fieldset</fieldset>
-<button class="c1">but<span>ton</span></button>
-<select class="c1"><option>select</select>
+<span class="c1">Legendfieldset but<span>ton</span></span>
</body>
</html>
--- a/layout/reftests/css-display/display-contents-acid.html
+++ b/layout/reftests/css-display/display-contents-acid.html
@@ -176,16 +176,17 @@ 0
<div class="contents c3"><!-- comment node --></div>
<div class="contents c3"><?PI ?></div>
<span class="c2"><legend class="contents c1">Legend</legend><legend class="contents c1">Legend</legend></span>
<br clear="all">
<span class="c3">x<div class="contents c1" style="float:left">float:left</div></span>
<span class="c3">y<div class="contents c1" style="position:absolute">position:absolute</div></span>
-<!-- Stuff below should simply ignore having display:contents -->
+<fieldset class="contents c1"><legend class="contents">Legend</legend>fieldset</fieldset>
+<button class="contents c1" style="font: inherit;">but<span>ton</span></button>
-<fieldset class="contents c1"><legend class="contents">Legend</legend>fieldset</fieldset>
-<button class="contents c1">but<span>ton</span></button>
+<!-- Stuff below should simply behave as having display: none -->
+
<select class="contents c1"><option>select</select>
</body>
</html>
--- a/layout/reftests/css-display/display-contents-fieldset-ref.html
+++ b/layout/reftests/css-display/display-contents-fieldset-ref.html
@@ -18,35 +18,43 @@ legend { border: 1px solid; }
</style>
</head>
<body>
<fieldset><div class="test contents"></div></fieldset>
<fieldset><div class="test contents">x</div></fieldset>
<fieldset><div class="test contents after"></div></fieldset>
<fieldset><div class="test contents before"></div></fieldset>
<fieldset><div class="test contents before after"></div></fieldset>
-<fieldset><legend class="test contents"></legend></fieldset>
-<fieldset><legend class="test contents" style="padding:0"></legend></fieldset>
-<fieldset><legend class="contents"><div class="test contents"></div></legend></fieldset>
+<fieldset><span></span></fieldset>
+<fieldset><span></span></fieldset>
+<fieldset><span></span></fieldset>
<fieldset class="test2"></fieldset>
<fieldset class="test2 after"></fieldset>
<fieldset class="test2"><legend class="static"></legend></fieldset>
<fieldset class="test2"><legend class="static contents"></legend></fieldset>
<fieldset class="test2"><legend class="static" style="padding:0"></legend></fieldset>
<fieldset class="test2 p0"></fieldset>
-<fieldset class="test2 p0"></fieldset>
+<fieldset class="test3 p0"></fieldset>
<fieldset class="test2 p0"><legend class="static"></legend></fieldset>
-<fieldset class="test2 p0"><legend class="static"></legend></fieldset>
+<fieldset class="test3 p0"><legend class="static"></legend></fieldset>
<script>
document.body.offsetHeight;
var tests = document.querySelectorAll('.test');
for (i=0; i < tests.length; ++i) {
test = tests[i];
test.appendChild(document.createElement('span'));
}
-var tests = document.querySelectorAll('.test2,.test3');
+var tests = document.querySelectorAll('.test2');
+for (i=0; i < tests.length; ++i) {
+ test = tests[i];
+ let span = document.createElement('dummy-inline');
+ span.innerHTML = "legend";
+ test.appendChild(span);
+}
+
+var tests = document.querySelectorAll('.test3');
for (i=0; i < tests.length; ++i) {
test = tests[i];
test.appendChild(document.createElement('legend'));
}
</script>
</body>
</html>
--- a/layout/svg/nsSVGUseFrame.cpp
+++ b/layout/svg/nsSVGUseFrame.cpp
@@ -161,18 +161,20 @@ nsSVGUseFrame::NotifySVGChanged(uint32_t
}
//----------------------------------------------------------------------
// nsIAnonymousContentCreator methods:
nsresult
nsSVGUseFrame::CreateAnonymousContent(nsTArray<ContentInfo>& aElements)
{
- SVGUseElement *use = static_cast<SVGUseElement*>(GetContent());
-
+ // FIXME(emilio): This should not be done at frame construction time, but
+ // using Shadow DOM or something like that instead, to support properly
+ // display: contents in <svg:use>.
+ auto use = static_cast<SVGUseElement*>(GetContent());
mContentClone = use->CreateAnonymousContent();
nsLayoutUtils::PostRestyleEvent(
use, nsRestyleHint(0), nsChangeHint_InvalidateRenderingObservers);
if (!mContentClone)
return NS_ERROR_FAILURE;
aElements.AppendElement(mContentClone);
return NS_OK;
}
--- a/testing/web-platform/meta/MANIFEST.json
+++ b/testing/web-platform/meta/MANIFEST.json
@@ -102532,16 +102532,28 @@
[
"/css/css-display/display-contents-table-002-ref.html",
"=="
]
],
{}
]
],
+ "css/css-display/display-contents-fieldset-nested-legend.html": [
+ [
+ "/css/css-display/display-contents-fieldset-nested-legend.html",
+ [
+ [
+ "/css/css-display/display-contents-fieldset-nested-legend-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
"css/css-display/display-contents-first-letter-001.html": [
[
"/css/css-display/display-contents-first-letter-001.html",
[
[
"/css/css-display/display-contents-pass-green-no-red-ref.html",
"=="
]
@@ -229853,16 +229865,21 @@
{}
]
],
"css/css-display/display-contents-dynamic-pseudo-insertion-001-ref.html": [
[
{}
]
],
+ "css/css-display/display-contents-fieldset-nested-legend-ref.html": [
+ [
+ {}
+ ]
+ ],
"css/css-display/display-contents-flex-001-ref.html": [
[
{}
]
],
"css/css-display/display-contents-flex-002-ref.html": [
[
{}
@@ -469148,16 +469165,24 @@
"css/css-display/display-contents-dynamic-table-002-inline.html": [
"1c7f34107b3778f5d6f7d538ed05eb886dba08ed",
"reftest"
],
"css/css-display/display-contents-dynamic-table-002-none.html": [
"c874f59947d37659e640d4e0abb8a0dc0f03927d",
"reftest"
],
+ "css/css-display/display-contents-fieldset-nested-legend-ref.html": [
+ "89fbd146ffbd862ba3d0f058d8d8c9d8024da0fa",
+ "support"
+ ],
+ "css/css-display/display-contents-fieldset-nested-legend.html": [
+ "45be585ab1523c180b3ba159d25d0dadd80456ac",
+ "reftest"
+ ],
"css/css-display/display-contents-first-letter-001.html": [
"acfaf8f68595c7eb36585309b9d6b0bc5c0ffe41",
"reftest"
],
"css/css-display/display-contents-first-line-001.html": [
"19f4bc895d895a6dd62b638960b4b7f2f26f5752",
"reftest"
],
@@ -504565,21 +504590,21 @@
"13056acc82d5e59310d10af30da8e46f73929e5f",
"support"
],
"css/css-ui/text-overflow-025.html": [
"b4a2e0d1b86fd8893421de4335c9b6f36df1fc4d",
"reftest"
],
"css/css-ui/text-overflow-026-ref.html": [
- "1a7d6d524a217d8fc2252e6434ac1b8fb3d5af2f",
+ "03c0337af58ba7bada64ab36721d9f1fe2f9a2f3",
"support"
],
"css/css-ui/text-overflow-026.html": [
- "34cb2b690321f6f93763de2841ebdf5a9275f515",
+ "5087fe90cb3ef8e340be316f1534cb6dba3e0d17",
"reftest"
],
"css/css-ui/text-overflow-ref.html": [
"db55b0b95a7406e9c4f00081b3e2cbe6b07363f7",
"support"
],
"css/css-ui/text-overflow.html": [
"d3a6c835c23b82a85398e7981461a0cd3a75b861",
@@ -524409,17 +524434,17 @@
"a53b3bd5909771c800c5d3e874fd83ae77f0efeb",
"support"
],
"dom/events/EventListener-incumbent-global-subsubframe.sub.html": [
"35ffc948502021b3367ae759b5f5ac362fd7acaa",
"support"
],
"dom/events/EventListener-invoke-legacy.html": [
- "e56b332acb454ab76964b78588536777946ddff8",
+ "13cb3802cb2722417b876ded17fddd222c69564a",
"testharness"
],
"dom/events/EventListenerOptions-capture.html": [
"cebd60a18add5403d4f0bd68e88e05daacfd241a",
"testharness"
],
"dom/events/EventTarget-addEventListener.html": [
"85dea0178b16b5c3e8ddbfa9a8b4bd8424bc0a3d",
@@ -545945,17 +545970,17 @@
"f2a20180b6bf5f9c89f5b9541885d55dc8a8ade6",
"support"
],
"html/semantics/scripting-1/the-script-element/module/instantiation-error-2.html": [
"e2c860b1b348148fc6b9d77f918894b1bac42c94",
"testharness"
],
"html/semantics/scripting-1/the-script-element/module/instantiation-error-3.html": [
- "996d1aa45c5975e13ac0f1e9c9249b3d452ed2e2",
+ "3365d69d34e442962370a1f0ed22017876efe4fe",
"testharness"
],
"html/semantics/scripting-1/the-script-element/module/instantiation-error-4.html": [
"224fe5510f09c3dd6d58f9dcf61b4d6fca04c96c",
"testharness"
],
"html/semantics/scripting-1/the-script-element/module/instantiation-error-4a.js": [
"051586d3af5158af29ee8f46157964252a47ef65",
@@ -546073,33 +546098,33 @@
"a04ecfd484ada80c436c880c6fb39abba47eac1c",
"testharness"
],
"html/semantics/scripting-1/the-script-element/module/late-star-export-request.html": [
"2fd8c4ee6fcc66a8ddc2100a0840ebcc324a7d58",
"testharness"
],
"html/semantics/scripting-1/the-script-element/module/load-error-events-inline.html": [
- "9b35d8d7ba6bb4826274c9570056cc962660d715",
+ "bbdfd11cfc7e52748f07d09ebe7cf6782ad5e782",
"testharness"
],
"html/semantics/scripting-1/the-script-element/module/load-error-events.html": [
"304dc3a7e9cd48699742b0a1431adda1d0f253c0",
"testharness"
],
"html/semantics/scripting-1/the-script-element/module/missing-export-nested.js": [
"5c6c1dae178b88b42ce87964e372f7d7db99ba70",
"support"
],
"html/semantics/scripting-1/the-script-element/module/missing-export.js": [
"27cd038ca24450b1aeb9fe52cb9dea85998d108c",
"support"
],
"html/semantics/scripting-1/the-script-element/module/module-in-xhtml.xhtml": [
- "32a4a4db2a5325b909078c73f76ab51085e66c5a",
+ "4b41e3e07ff72b0f181b0dd3a6c1aab40a01da0c",
"testharness"
],
"html/semantics/scripting-1/the-script-element/module/module-vs-script-1.html": [
"a7fd504c7bfeefb445de9f2a1212986f27e80465",
"testharness"
],
"html/semantics/scripting-1/the-script-element/module/module-vs-script-2.html": [
"ca5ee235cc345d01e3d98cf3512dc26b9ad1896e",
@@ -569437,17 +569462,17 @@
"881f51c7f9c64f6d69746e1e195c11cf6e29fb3e",
"testharness"
],
"service-workers/service-worker/unregister-controller.https.html": [
"24cf65bf38dcdd90e24c20bd6be3823db1e9a601",
"testharness"
],
"service-workers/service-worker/unregister-then-register-new-script.https.html": [
- "43964791edbb2b5cd3b3ed27b600e78412902240",
+ "ee8d7cd4e47cdb9bcf2b39c911593bc671df914d",
"testharness"
],
"service-workers/service-worker/unregister-then-register.https.html": [
"b4a5e1933296cf96fa001822b5e269a5db60b188",
"testharness"
],
"service-workers/service-worker/unregister.https.html": [
"672dbc9f930b829099b5788f995958f208cba3b7",
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/css/css-display/display-contents-fieldset-nested-legend-ref.html
@@ -0,0 +1,6 @@
+<!doctype html>
+<meta charset="utf-8">
+<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
+<link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.com">
+<title>CSS Test Reference</title>
+<fieldset style="color: green">P<legend style="padding: 0">legend</legend>ASS</fieldset>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/css/css-display/display-contents-fieldset-nested-legend.html
@@ -0,0 +1,24 @@
+<!doctype html>
+<!--
+ Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<meta charset="utf-8">
+<link rel="match" href="display-contents-fieldset-nested-legend-ref.html">
+<link rel="help" href="https://drafts.csswg.org/css-display/#unbox">
+<link rel="help" href="https://drafts.csswg.org/css-display/#valdef-display-contents">
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1427292">
+<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
+<link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.com">
+<title>CSS Test: display: contents on legend</title>
+<style>
+fieldset {
+ color: red;
+}
+.contents {
+ display: contents;
+ color: green;
+ border: 10px solid red;
+}
+</style>
+<fieldset><legend class="contents">P<legend>legend</legend>ASS</legend></fieldset>