Line data Source code
1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 : /* This Source Code Form is subject to the terms of the Mozilla Public
4 : * License, v. 2.0. If a copy of the MPL was not distributed with this
5 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 :
7 : #ifndef nsIContentInlines_h
8 : #define nsIContentInlines_h
9 :
10 : #include "nsIContent.h"
11 : #include "nsIDocument.h"
12 : #include "nsBindingManager.h"
13 : #include "nsContentUtils.h"
14 : #include "nsAtom.h"
15 : #include "nsIFrame.h"
16 : #include "mozilla/dom/Element.h"
17 : #include "mozilla/dom/HTMLSlotElement.h"
18 : #include "mozilla/dom/ShadowRoot.h"
19 :
20 : inline bool
21 2 : nsIContent::IsInHTMLDocument() const
22 : {
23 2 : return OwnerDoc()->IsHTMLDocument();
24 : }
25 :
26 : inline bool
27 59428 : nsIContent::IsInChromeDocument() const
28 : {
29 59428 : return nsContentUtils::IsChromeDoc(OwnerDoc());
30 : }
31 :
32 : inline void
33 664 : nsIContent::SetPrimaryFrame(nsIFrame* aFrame)
34 : {
35 1328 : MOZ_ASSERT(IsInUncomposedDoc() || IsInShadowTree(), "This will end badly!");
36 :
37 : // FIXME bug 749326
38 664 : NS_ASSERTION(!aFrame || !mPrimaryFrame || aFrame == mPrimaryFrame,
39 : "Losing track of existing primary frame");
40 :
41 664 : if (aFrame) {
42 580 : if (MOZ_LIKELY(!IsHTMLElement(nsGkAtoms::area)) ||
43 0 : aFrame->GetContent() == this) {
44 : aFrame->SetIsPrimaryFrame(true);
45 : }
46 84 : } else if (nsIFrame* currentPrimaryFrame = GetPrimaryFrame()) {
47 84 : if (MOZ_LIKELY(!IsHTMLElement(nsGkAtoms::area)) ||
48 0 : currentPrimaryFrame->GetContent() == this) {
49 : currentPrimaryFrame->SetIsPrimaryFrame(false);
50 : }
51 : }
52 :
53 664 : mPrimaryFrame = aFrame;
54 664 : }
55 :
56 0 : inline mozilla::dom::ShadowRoot* nsIContent::GetShadowRoot() const
57 : {
58 0 : if (!IsElement()) {
59 : return nullptr;
60 : }
61 :
62 0 : return AsElement()->GetShadowRoot();
63 : }
64 :
65 : template<nsINode::FlattenedParentType aType>
66 : static inline nsINode*
67 215540 : GetFlattenedTreeParentNode(const nsINode* aNode)
68 : {
69 215540 : if (!aNode->IsContent()) {
70 : return nullptr;
71 : }
72 :
73 215540 : nsINode* parent = aNode->GetParentNode();
74 430920 : if (!parent || !parent->IsContent()) {
75 : return parent;
76 : }
77 :
78 209740 : const nsIContent* content = aNode->AsContent();
79 209740 : nsIContent* parentAsContent = parent->AsContent();
80 :
81 209190 : if (aType == nsINode::eForStyle &&
82 212840 : content->IsRootOfNativeAnonymousSubtree() &&
83 3650 : parentAsContent == content->OwnerDoc()->GetRootElement()) {
84 : const bool docLevel =
85 1794 : content->GetProperty(nsGkAtoms::docLevelNativeAnonymousContent);
86 3232 : return docLevel ? content->OwnerDocAsNode() : parent;
87 : }
88 :
89 207946 : if (content->IsRootOfAnonymousSubtree()) {
90 : return parent;
91 : }
92 :
93 184568 : if (parentAsContent->GetShadowRoot()) {
94 : // If it's not assigned to any slot it's not part of the flat tree, and thus
95 : // we return null.
96 0 : return content->GetAssignedSlot();
97 : }
98 :
99 184568 : if (parentAsContent->IsInShadowTree()) {
100 0 : if (auto* slot = mozilla::dom::HTMLSlotElement::FromNode(parentAsContent)) {
101 : // If the assigned nodes list is empty, we're fallback content which is
102 : // active, otherwise we are not part of the flat tree.
103 0 : return slot->AssignedNodes().IsEmpty()
104 : ? parent
105 0 : : nullptr;
106 : }
107 :
108 0 : if (auto* shadowRoot = mozilla::dom::ShadowRoot::FromNode(parentAsContent)) {
109 0 : return shadowRoot->GetHost();
110 : }
111 : }
112 :
113 318348 : if (content->HasFlag(NODE_MAY_BE_IN_BINDING_MNGR) ||
114 133780 : parent->HasFlag(NODE_MAY_BE_IN_BINDING_MNGR)) {
115 66572 : if (nsIContent* xblInsertionPoint = content->GetXBLInsertionPoint()) {
116 34400 : return xblInsertionPoint->GetParent();
117 : }
118 :
119 64344 : if (parent->OwnerDoc()->BindingManager()->GetBindingWithContent(parentAsContent)) {
120 : // This is an unassigned node child of the bound element, so it isn't part
121 : // of the flat tree.
122 : return nullptr;
123 : }
124 : }
125 :
126 150168 : MOZ_ASSERT(!parentAsContent->IsActiveChildrenElement(),
127 : "<xbl:children> isn't in the flattened tree");
128 :
129 : // Common case.
130 : return parent;
131 : }
132 :
133 : inline nsINode*
134 : nsINode::GetFlattenedTreeParentNode() const
135 : {
136 1352 : return ::GetFlattenedTreeParentNode<nsINode::eNotForStyle>(this);
137 : }
138 :
139 : inline nsIContent*
140 1162 : nsIContent::GetFlattenedTreeParent() const
141 : {
142 2324 : nsINode* parent = GetFlattenedTreeParentNode();
143 2164 : return (parent && parent->IsContent()) ? parent->AsContent() : nullptr;
144 : }
145 :
146 : inline bool
147 450 : nsIContent::IsEventAttributeName(nsAtom* aName)
148 : {
149 450 : const char16_t* name = aName->GetUTF16String();
150 450 : if (name[0] != 'o' || name[1] != 'n') {
151 : return false;
152 : }
153 :
154 2 : return IsEventAttributeNameInternal(aName);
155 : }
156 :
157 : inline nsINode*
158 : nsINode::GetFlattenedTreeParentNodeForStyle() const
159 : {
160 214186 : return ::GetFlattenedTreeParentNode<nsINode::eForStyle>(this);
161 : }
162 :
163 : inline bool
164 352 : nsINode::NodeOrAncestorHasDirAuto() const
165 : {
166 704 : return AncestorHasDirAuto() || (IsElement() && AsElement()->HasDirAuto());
167 : }
168 :
169 : inline bool
170 0 : nsINode::IsEditable() const
171 : {
172 0 : if (HasFlag(NODE_IS_EDITABLE)) {
173 : // The node is in an editable contentEditable subtree.
174 : return true;
175 : }
176 :
177 0 : nsIDocument* doc = GetUncomposedDoc();
178 :
179 : // Check if the node is in a document and the document is in designMode.
180 0 : return doc && doc->HasFlag(NODE_IS_EDITABLE);
181 : }
182 :
183 : inline bool
184 613380 : nsIContent::IsActiveChildrenElement() const
185 : {
186 1226760 : if (!mNodeInfo->Equals(nsGkAtoms::children, kNameSpaceID_XBL)) {
187 : return false;
188 : }
189 :
190 89676 : nsIContent* bindingParent = GetBindingParent();
191 89676 : if (!bindingParent) {
192 : return false;
193 : }
194 :
195 : // We reuse the binding parent machinery for Shadow DOM too, so prevent that
196 : // from getting us confused in this case.
197 89676 : return !bindingParent->GetShadowRoot();
198 : }
199 :
200 : inline bool
201 0 : nsIContent::IsInAnonymousSubtree() const
202 : {
203 0 : NS_ASSERTION(!IsInNativeAnonymousSubtree() || GetBindingParent() ||
204 : (!IsInUncomposedDoc() &&
205 : static_cast<nsIContent*>(SubtreeRoot())->IsInNativeAnonymousSubtree()),
206 : "Must have binding parent when in native anonymous subtree which is in document.\n"
207 : "Native anonymous subtree which is not in document must have native anonymous root.");
208 :
209 : if (IsInNativeAnonymousSubtree()) {
210 : return true;
211 : }
212 :
213 : nsIContent* bindingParent = GetBindingParent();
214 : if (!bindingParent) {
215 : return false;
216 : }
217 :
218 : // We reuse the binding parent machinery for Shadow DOM too, so prevent that
219 : // from getting us confused in this case.
220 : return !bindingParent->GetShadowRoot();
221 : }
222 :
223 : #endif // nsIContentInlines_h
|