/src/mozilla-central/dom/xbl/XBLChildrenElement.cpp
Line | Count | Source (jump to first uncovered line) |
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 | | #include "mozilla/dom/XBLChildrenElement.h" |
8 | | #include "nsCharSeparatedTokenizer.h" |
9 | | #include "mozilla/dom/NodeListBinding.h" |
10 | | #include "nsAttrValueOrString.h" |
11 | | |
12 | | namespace mozilla { |
13 | | namespace dom { |
14 | | |
15 | | XBLChildrenElement::~XBLChildrenElement() |
16 | 0 | { |
17 | 0 | } |
18 | | |
19 | | NS_IMPL_ELEMENT_CLONE(XBLChildrenElement) |
20 | | |
21 | | nsresult |
22 | | XBLChildrenElement::BeforeSetAttr(int32_t aNamespaceID, nsAtom* aName, |
23 | | const nsAttrValueOrString* aValue, |
24 | | bool aNotify) |
25 | 0 | { |
26 | 0 | if (aNamespaceID == kNameSpaceID_None) { |
27 | 0 | if (aName == nsGkAtoms::includes) { |
28 | 0 | mIncludes.Clear(); |
29 | 0 | if (aValue) { |
30 | 0 | nsCharSeparatedTokenizer tok(aValue->String(), '|', |
31 | 0 | nsCharSeparatedTokenizer::SEPARATOR_OPTIONAL); |
32 | 0 | while (tok.hasMoreTokens()) { |
33 | 0 | mIncludes.AppendElement(NS_Atomize(tok.nextToken())); |
34 | 0 | } |
35 | 0 | } |
36 | 0 | } |
37 | 0 | } |
38 | 0 |
|
39 | 0 | return nsXMLElement::BeforeSetAttr(aNamespaceID, aName, aValue, aNotify); |
40 | 0 | } |
41 | | |
42 | | void |
43 | | XBLChildrenElement::DoRemoveDefaultContent(bool aNotify) |
44 | 0 | { |
45 | 0 | // Default content is going away, need to tell layout about it first. |
46 | 0 | MOZ_ASSERT(HasChildren(), "Why bothering?"); |
47 | 0 | MOZ_ASSERT(GetParentElement()); |
48 | 0 |
|
49 | 0 | // We don't want to do this from frame construction while setting up the |
50 | 0 | // binding initially. |
51 | 0 | if (aNotify) { |
52 | 0 | Element* parent = GetParentElement(); |
53 | 0 | if (nsIDocument* doc = parent->GetComposedDoc()) { |
54 | 0 | if (nsIPresShell* shell = doc->GetShell()) { |
55 | 0 | shell->DestroyFramesForAndRestyle(parent); |
56 | 0 | } |
57 | 0 | } |
58 | 0 | } |
59 | 0 |
|
60 | 0 | for (nsIContent* child = static_cast<nsINode*>(this)->GetFirstChild(); |
61 | 0 | child; |
62 | 0 | child = child->GetNextSibling()) { |
63 | 0 | MOZ_ASSERT(!child->GetPrimaryFrame()); |
64 | 0 | MOZ_ASSERT(!child->IsElement() || !child->AsElement()->HasServoData()); |
65 | 0 | child->SetXBLInsertionPoint(nullptr); |
66 | 0 | } |
67 | 0 | } |
68 | | |
69 | | } // namespace dom |
70 | | } // namespace mozilla |
71 | | |
72 | | using namespace mozilla::dom; |
73 | | |
74 | | NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(nsAnonymousContentList, mParent) |
75 | | |
76 | | NS_IMPL_CYCLE_COLLECTING_ADDREF(nsAnonymousContentList) |
77 | | NS_IMPL_CYCLE_COLLECTING_RELEASE(nsAnonymousContentList) |
78 | | |
79 | 0 | NS_INTERFACE_TABLE_HEAD(nsAnonymousContentList) |
80 | 0 | NS_WRAPPERCACHE_INTERFACE_TABLE_ENTRY |
81 | 0 | NS_INTERFACE_TABLE(nsAnonymousContentList, nsINodeList) |
82 | 0 | NS_INTERFACE_TABLE_TO_MAP_SEGUE_CYCLE_COLLECTION(nsAnonymousContentList) |
83 | 0 | NS_INTERFACE_MAP_END |
84 | | |
85 | | uint32_t |
86 | | nsAnonymousContentList::Length() |
87 | 0 | { |
88 | 0 | if (!mParent) { |
89 | 0 | return 0; |
90 | 0 | } |
91 | 0 | |
92 | 0 | uint32_t count = 0; |
93 | 0 | for (nsIContent* child = mParent->GetFirstChild(); |
94 | 0 | child; |
95 | 0 | child = child->GetNextSibling()) { |
96 | 0 | if (child->NodeInfo()->Equals(nsGkAtoms::children, kNameSpaceID_XBL)) { |
97 | 0 | XBLChildrenElement* point = static_cast<XBLChildrenElement*>(child); |
98 | 0 | if (point->HasInsertedChildren()) { |
99 | 0 | count += point->InsertedChildrenLength(); |
100 | 0 | } |
101 | 0 | else { |
102 | 0 | count += point->GetChildCount(); |
103 | 0 | } |
104 | 0 | } |
105 | 0 | else { |
106 | 0 | ++count; |
107 | 0 | } |
108 | 0 | } |
109 | 0 |
|
110 | 0 | return count; |
111 | 0 | } |
112 | | |
113 | | nsIContent* |
114 | | nsAnonymousContentList::Item(uint32_t aIndex) |
115 | 0 | { |
116 | 0 | if (!mParent) { |
117 | 0 | return nullptr; |
118 | 0 | } |
119 | 0 | |
120 | 0 | uint32_t remIndex = aIndex; |
121 | 0 | for (nsIContent* child = mParent->GetFirstChild(); |
122 | 0 | child; |
123 | 0 | child = child->GetNextSibling()) { |
124 | 0 | if (child->NodeInfo()->Equals(nsGkAtoms::children, kNameSpaceID_XBL)) { |
125 | 0 | XBLChildrenElement* point = static_cast<XBLChildrenElement*>(child); |
126 | 0 | if (point->HasInsertedChildren()) { |
127 | 0 | if (remIndex < point->InsertedChildrenLength()) { |
128 | 0 | return point->InsertedChild(remIndex); |
129 | 0 | } |
130 | 0 | remIndex -= point->InsertedChildrenLength(); |
131 | 0 | } |
132 | 0 | else { |
133 | 0 | if (remIndex < point->GetChildCount()) { |
134 | 0 | return point->GetChildAt_Deprecated(remIndex); |
135 | 0 | } |
136 | 0 | remIndex -= point->GetChildCount(); |
137 | 0 | } |
138 | 0 | } |
139 | 0 | else { |
140 | 0 | if (remIndex == 0) { |
141 | 0 | return child; |
142 | 0 | } |
143 | 0 | --remIndex; |
144 | 0 | } |
145 | 0 | } |
146 | 0 |
|
147 | 0 | return nullptr; |
148 | 0 | } |
149 | | |
150 | | int32_t |
151 | | nsAnonymousContentList::IndexOf(nsIContent* aContent) |
152 | 0 | { |
153 | 0 | NS_ASSERTION(!aContent->NodeInfo()->Equals(nsGkAtoms::children, |
154 | 0 | kNameSpaceID_XBL), |
155 | 0 | "Looking for insertion point"); |
156 | 0 |
|
157 | 0 | if (!mParent) { |
158 | 0 | return -1; |
159 | 0 | } |
160 | 0 | |
161 | 0 | int32_t index = 0; |
162 | 0 | for (nsIContent* child = mParent->GetFirstChild(); |
163 | 0 | child; |
164 | 0 | child = child->GetNextSibling()) { |
165 | 0 | if (child->NodeInfo()->Equals(nsGkAtoms::children, kNameSpaceID_XBL)) { |
166 | 0 | XBLChildrenElement* point = static_cast<XBLChildrenElement*>(child); |
167 | 0 | if (point->HasInsertedChildren()) { |
168 | 0 | int32_t insIndex = point->IndexOfInsertedChild(aContent); |
169 | 0 | if (insIndex != -1) { |
170 | 0 | return index + insIndex; |
171 | 0 | } |
172 | 0 | index += point->InsertedChildrenLength(); |
173 | 0 | } |
174 | 0 | else { |
175 | 0 | int32_t insIndex = point->ComputeIndexOf(aContent); |
176 | 0 | if (insIndex != -1) { |
177 | 0 | return index + insIndex; |
178 | 0 | } |
179 | 0 | index += point->GetChildCount(); |
180 | 0 | } |
181 | 0 | } |
182 | 0 | else { |
183 | 0 | if (child == aContent) { |
184 | 0 | return index; |
185 | 0 | } |
186 | 0 | ++index; |
187 | 0 | } |
188 | 0 | } |
189 | 0 |
|
190 | 0 | return -1; |
191 | 0 | } |
192 | | |
193 | | JSObject* |
194 | | nsAnonymousContentList::WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto) |
195 | 0 | { |
196 | 0 | return mozilla::dom::NodeList_Binding::Wrap(cx, this, aGivenProto); |
197 | 0 | } |