Line data Source code
1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* This Source Code Form is subject to the terms of the Mozilla Public
3 : * License, v. 2.0. If a copy of the MPL was not distributed with this
4 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 :
6 : #include "DetailsFrame.h"
7 :
8 : #include "mozilla/Attributes.h"
9 : #include "mozilla/dom/HTMLDetailsElement.h"
10 : #include "mozilla/dom/HTMLSummaryElement.h"
11 : #include "nsContentUtils.h"
12 : #include "nsPlaceholderFrame.h"
13 : #include "nsTextNode.h"
14 :
15 : using namespace mozilla;
16 : using namespace mozilla::dom;
17 :
18 0 : NS_IMPL_FRAMEARENA_HELPERS(DetailsFrame)
19 :
20 0 : NS_QUERYFRAME_HEAD(DetailsFrame)
21 0 : NS_QUERYFRAME_ENTRY(DetailsFrame)
22 0 : NS_QUERYFRAME_ENTRY(nsIAnonymousContentCreator)
23 0 : NS_QUERYFRAME_TAIL_INHERITING(nsBlockFrame)
24 :
25 : nsBlockFrame*
26 0 : NS_NewDetailsFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
27 : {
28 0 : return new (aPresShell) DetailsFrame(aContext);
29 : }
30 :
31 : namespace mozilla {
32 :
33 0 : DetailsFrame::DetailsFrame(nsStyleContext* aContext)
34 0 : : nsBlockFrame(aContext, kClassID)
35 : {
36 0 : }
37 :
38 0 : DetailsFrame::~DetailsFrame()
39 : {
40 0 : }
41 :
42 : void
43 0 : DetailsFrame::SetInitialChildList(ChildListID aListID, nsFrameList& aChildList)
44 : {
45 : #ifdef DEBUG
46 0 : if (aListID == kPrincipalList) {
47 0 : CheckValidMainSummary(aChildList);
48 : }
49 : #endif
50 :
51 0 : nsBlockFrame::SetInitialChildList(aListID, aChildList);
52 0 : }
53 :
54 : #ifdef DEBUG
55 : bool
56 0 : DetailsFrame::CheckValidMainSummary(const nsFrameList& aFrameList) const
57 : {
58 0 : for (nsIFrame* child : aFrameList) {
59 : HTMLSummaryElement* summary =
60 0 : HTMLSummaryElement::FromContent(child->GetContent());
61 :
62 0 : if (child == aFrameList.FirstChild()) {
63 0 : if (summary && summary->IsMainSummary()) {
64 0 : return true;
65 0 : } else if (child->GetContent() == GetContent()) {
66 : // The child frame's content is the same as our content, which means
67 : // it's a kind of wrapper frame. Descend into its child list to find
68 : // main summary.
69 0 : if (CheckValidMainSummary(child->PrincipalChildList())) {
70 0 : return true;
71 : }
72 : }
73 : } else {
74 0 : NS_ASSERTION(!summary || !summary->IsMainSummary(),
75 : "Rest of the children are either not summary element "
76 : "or are not the main summary!");
77 : }
78 : }
79 0 : return false;
80 : }
81 : #endif
82 :
83 : void
84 0 : DetailsFrame::DestroyFrom(nsIFrame* aDestructRoot)
85 : {
86 0 : nsContentUtils::DestroyAnonymousContent(&mDefaultSummary);
87 0 : nsBlockFrame::DestroyFrom(aDestructRoot);
88 0 : }
89 :
90 : nsresult
91 0 : DetailsFrame::CreateAnonymousContent(nsTArray<ContentInfo>& aElements)
92 : {
93 0 : auto* details = HTMLDetailsElement::FromContent(GetContent());
94 0 : if (details->GetFirstSummary()) {
95 0 : return NS_OK;
96 : }
97 :
98 : // The <details> element lacks any direct <summary> child. Create a default
99 : // <summary> element as an anonymous content.
100 : nsNodeInfoManager* nodeInfoManager =
101 0 : GetContent()->NodeInfo()->NodeInfoManager();
102 :
103 : already_AddRefed<NodeInfo> nodeInfo =
104 : nodeInfoManager->GetNodeInfo(nsGkAtoms::summary, nullptr, kNameSpaceID_XHTML,
105 0 : nsIDOMNode::ELEMENT_NODE);
106 0 : mDefaultSummary = new HTMLSummaryElement(nodeInfo);
107 :
108 0 : nsXPIDLString defaultSummaryText;
109 : nsContentUtils::GetLocalizedString(nsContentUtils::eFORMS_PROPERTIES,
110 0 : "DefaultSummary", defaultSummaryText);
111 0 : RefPtr<nsTextNode> description = new nsTextNode(nodeInfoManager);
112 0 : description->SetText(defaultSummaryText, false);
113 0 : mDefaultSummary->AppendChildTo(description, false);
114 :
115 0 : aElements.AppendElement(mDefaultSummary);
116 :
117 0 : return NS_OK;
118 : }
119 :
120 : void
121 0 : DetailsFrame::AppendAnonymousContentTo(nsTArray<nsIContent*>& aElements,
122 : uint32_t aFilter)
123 : {
124 0 : if (mDefaultSummary) {
125 0 : aElements.AppendElement(mDefaultSummary);
126 : }
127 0 : }
128 :
129 : bool
130 0 : DetailsFrame::HasMainSummaryFrame(nsIFrame* aSummaryFrame)
131 : {
132 : nsIFrame* firstChild =
133 0 : nsPlaceholderFrame::GetRealFrameFor(mFrames.FirstChild());
134 :
135 0 : return aSummaryFrame == firstChild;
136 : }
137 :
138 : } // namespace mozilla
|