HTML - details/summary - debug mode - assertion failure: !summary || !summary->IsMainSummary()

This commit is contained in:
janekptacijarabaci
2017-12-01 08:17:29 +01:00
committed by Roy Tam
parent e115651888
commit 89a578521b
16 changed files with 271 additions and 48 deletions
+17 -11
View File
@@ -3510,13 +3510,6 @@ nsCSSFrameConstructor::FindHTMLData(Element* aElement,
return nullptr;
}
if (aTag == nsGkAtoms::summary &&
(!aParentFrame || aParentFrame->GetType() != nsGkAtoms::detailsFrame)) {
// <summary> is special only if it is a direct child of <details>. If it
// isn't, construct it as a normal block frame instead of a summary frame.
return nullptr;
}
static const FrameConstructionDataByTag sHTMLData[] = {
SIMPLE_TAG_CHAIN(img, nsCSSFrameConstructor::FindImgData),
SIMPLE_TAG_CHAIN(mozgeneratedcontentimage,
@@ -5765,10 +5758,23 @@ nsCSSFrameConstructor::AddFrameConstructionItemsInternal(nsFrameConstructorState
return;
}
FrameConstructionItem* item =
aItems.AppendItem(data, aContent, aTag, aNameSpaceID,
pendingBinding, styleContext.forget(),
aSuppressWhiteSpaceOptimizations, aAnonChildren);
FrameConstructionItem* item = nullptr;
if (details && details->Open()) {
auto* summary = HTMLSummaryElement::FromContentOrNull(aContent);
if (summary && summary->IsMainSummary()) {
// If details is open, the main summary needs to be rendered as if it is
// the first child, so add the item to the front of the item list.
item = aItems.PrependItem(data, aContent, aTag, aNameSpaceID,
pendingBinding, styleContext.forget(),
aSuppressWhiteSpaceOptimizations, aAnonChildren);
}
}
if (!item) {
item = aItems.AppendItem(data, aContent, aTag, aNameSpaceID,
pendingBinding, styleContext.forget(),
aSuppressWhiteSpaceOptimizations, aAnonChildren);
}
item->mIsText = isText;
item->mIsGeneratedContent = isGeneratedContent;
item->mIsAnonymousContentCreatorContent =
+21
View File
@@ -853,6 +853,27 @@ private:
return item;
}
// Arguments are the same as AppendItem().
FrameConstructionItem* PrependItem(const FrameConstructionData* aFCData,
nsIContent* aContent,
nsIAtom* aTag,
int32_t aNameSpaceID,
PendingBinding* aPendingBinding,
already_AddRefed<nsStyleContext>&& aStyleContext,
bool aSuppressWhiteSpaceOptimizations,
nsTArray<nsIAnonymousContentCreator::ContentInfo>* aAnonChildren)
{
FrameConstructionItem* item =
new FrameConstructionItem(aFCData, aContent, aTag, aNameSpaceID,
aPendingBinding, aStyleContext,
aSuppressWhiteSpaceOptimizations,
aAnonChildren);
PR_INSERT_LINK(item, &mItems);
++mItemCount;
++mDesiredParentCounts[item->DesiredParentType()];
return item;
}
void AppendUndisplayedItem(nsIContent* aContent,
nsStyleContext* aStyleContext) {
mUndisplayedItems.AppendElement(UndisplayedItem(aContent, aStyleContext));
+32 -37
View File
@@ -46,49 +46,44 @@ DetailsFrame::GetType() const
void
DetailsFrame::SetInitialChildList(ChildListID aListID, nsFrameList& aChildList)
{
if (aListID == kPrincipalList) {
HTMLDetailsElement* details = HTMLDetailsElement::FromContent(GetContent());
bool isOpen = details->Open();
if (isOpen) {
// If details is open, the first summary needs to be rendered as if it is
// the first child.
for (nsFrameList::Enumerator e(aChildList); !e.AtEnd(); e.Next()) {
HTMLSummaryElement* summary =
HTMLSummaryElement::FromContent(e.get()->GetContent());
if (summary && summary->IsMainSummary()) {
// Take out the first summary frame and insert it to the beginning of
// the list.
aChildList.RemoveFrame(e.get());
aChildList.InsertFrame(nullptr, nullptr, e.get());
break;
}
}
}
#ifdef DEBUG
for (nsFrameList::Enumerator e(aChildList); !e.AtEnd(); e.Next()) {
HTMLSummaryElement* summary =
HTMLSummaryElement::FromContent(e.get()->GetContent());
if (e.get() == aChildList.FirstChild()) {
if (summary && summary->IsMainSummary()) {
break;
}
} else {
MOZ_ASSERT(!summary || !summary->IsMainSummary(),
"Rest of the children are neither summary elements nor"
"the main summary!");
}
}
#endif
if (aListID == kPrincipalList) {
CheckValidMainSummary(aChildList);
}
#endif
nsBlockFrame::SetInitialChildList(aListID, aChildList);
}
#ifdef DEBUG
bool
DetailsFrame::CheckValidMainSummary(const nsFrameList& aFrameList) const
{
for (nsFrameList::Enumerator e(aFrameList); !e.AtEnd(); e.Next()) {
HTMLSummaryElement* summary =
HTMLSummaryElement::FromContent(e.get()->GetContent());
if (e.get() == aFrameList.FirstChild()) {
if (summary && summary->IsMainSummary()) {
return true;
} else if (e.get()->GetContent() == GetContent()) {
// The child frame's content is the same as our content, which means
// it's a kind of wrapper frame. Descend into its child list to find
// main summary.
if (CheckValidMainSummary(e.get()->PrincipalChildList())) {
return true;
}
}
} else {
NS_ASSERTION(!summary || !summary->IsMainSummary(),
"Rest of the children are either not summary element "
"or are not the main summary!");
}
}
return false;
}
#endif
void
DetailsFrame::DestroyFrom(nsIFrame* aDestructRoot)
{
+6
View File
@@ -38,6 +38,12 @@ public:
}
#endif
#ifdef DEBUG
// Check the frame of the main summary element is the first child in the frame
// list. Returns true if we found the main summary frame; false otherwise.
bool CheckValidMainSummary(const nsFrameList& aFrameList) const;
#endif
void SetInitialChildList(ChildListID aListID,
nsFrameList& aChildList) override;
+9
View File
@@ -0,0 +1,9 @@
<details>
<summary>
<li>
<style>
summary{
all:initial
}
:first-child::first-line
{}
@@ -580,3 +580,4 @@ load 1222783.xhtml
load details-display-none-summary-1.html
load details-display-none-summary-2.html
load details-display-none-summary-3.html
load 1304441.html
@@ -0,0 +1,18 @@
<!DOCTYPE html>
<!-- Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ -->
<html>
<style>
div#details::first-line {
color: blue;
}
</style>
<body>
<div id="details">
<span>Summary
<div>Block in summary</div>
</span>
</div>
</body>
</html>
@@ -0,0 +1,24 @@
<!DOCTYPE html>
<!-- Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ -->
<html>
<style>
summary {
display: inline; /* ::first-line appiles only to inline element. */
}
details::first-line {
color: blue;
}
</style>
<body>
<details>
<summary>Summary
<!-- Need ib-split so that the summary has multiple frames. -->
<div>Block in summary</div>
</summary>
<p>This is the details.</p>
</details>
</body>
</html>
@@ -0,0 +1,24 @@
<!DOCTYPE html>
<!-- Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ -->
<html>
<style>
summary {
display: inline; /* ::first-line appiles only to inline element. */
}
details::first-line {
color: blue;
}
</style>
<body>
<details open>
<summary>Summary
<!-- Need ib-split so that the summary has multiple frames. -->
<div>Block in summary</div>
</summary>
<span>This is the details.</span>
</details>
</body>
</html>
@@ -0,0 +1,24 @@
<!DOCTYPE html>
<!-- Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ -->
<html>
<style>
summary {
display: inline; /* ::first-line appiles only to inline element. */
}
details::first-line {
color: blue;
}
</style>
<body>
<details open>
<span>This is the details.</span>
<summary>Summary
<!-- Need ib-split so that the summary has multiple frames. -->
<div>Block in summary</div>
</summary>
</details>
</body>
</html>
@@ -0,0 +1,19 @@
<!DOCTYPE html>
<!-- Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ -->
<html>
<style>
div#details::first-line {
color: blue;
}
</style>
<body>
<div id="details">
<span>Summary
<div>Block in summary</div>
</span>
<span>This is the details.</span>
</div>
</body>
</html>
@@ -0,0 +1,14 @@
<!DOCTYPE html>
<!-- Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ -->
<html>
<body>
<div>
<span>Summary
<div>Block in summary</div>
</span>
<p>This is the details.</p>
</div>
</body>
</html>
@@ -0,0 +1,22 @@
<!DOCTYPE html>
<!-- Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ -->
<html>
<style>
summary {
display: inline;
}
</style>
<body>
<details open>
<p>This is the details.</p>
<!-- Make summary the second element child so that layout will try to
render it as the first child. -->
<summary>Summary
<!-- Need ib-split so that the summary has multiple frames. -->
<div>Block in summary</div>
</summary>
</details>
</body>
</html>
@@ -0,0 +1,14 @@
<!DOCTYPE html>
<!-- Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ -->
<html>
<body>
<div>
<span style="display: table-cell;">Summary
<div>Block in summary</div>
</span>
<p>This is the details.</p>
</div>
</body>
</html>
@@ -0,0 +1,21 @@
<!DOCTYPE html>
<!-- Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ -->
<html>
<style>
summary {
display: table-cell;
}
</style>
<body>
<details open>
<p>This is the details.</p>
<!-- Make summary the second element child so that layout will try to
render it as the first child. -->
<summary>Summary
<div>Block in summary</div>
</summary>
</details>
</body>
</html>
@@ -4,6 +4,8 @@
== summary-not-first-child.html single-summary.html
== open-summary-not-first-child.html open-single-summary.html
== open-summary-block-style.html open-summary-block-style-ref.html
== open-summary-inline-style.html open-summary-inline-style-ref.html
== open-summary-table-cell-style.html open-summary-table-cell-style-ref.html
== no-summary.html no-summary-ref.html
== open-no-summary.html open-no-summary-ref.html
== summary-not-in-details.html summary-not-in-details-ref.html
@@ -61,6 +63,9 @@
== details-three-columns.html details-three-columns-ref.html
== details-writing-mode.html details-writing-mode-ref.html
== details-in-ol.html details-in-ol-ref.html
== details-first-line.html details-first-line-ref.html
== open-details-first-line-1.html open-details-first-line-ref.html
== open-details-first-line-2.html open-details-first-line-ref.html
# Dispatch mouse click to summary
== mouse-click-single-summary.html open-single-summary.html