dom/xbl/XBLChildrenElement.cpp

changeset 0
6474c204b198
equal deleted inserted replaced
-1:000000000000 0:d28410b940c7
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=2 sw=2 et tw=79: */
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
11 namespace mozilla {
12 namespace dom {
13
14 XBLChildrenElement::~XBLChildrenElement()
15 {
16 }
17
18 NS_IMPL_ADDREF_INHERITED(XBLChildrenElement, Element)
19 NS_IMPL_RELEASE_INHERITED(XBLChildrenElement, Element)
20
21 NS_INTERFACE_TABLE_HEAD(XBLChildrenElement)
22 NS_INTERFACE_TABLE_INHERITED(XBLChildrenElement, nsIDOMNode,
23 nsIDOMElement)
24 NS_ELEMENT_INTERFACE_TABLE_TO_MAP_SEGUE
25 NS_INTERFACE_MAP_END_INHERITING(Element)
26
27 NS_IMPL_ELEMENT_CLONE(XBLChildrenElement)
28
29 nsIAtom*
30 XBLChildrenElement::GetIDAttributeName() const
31 {
32 return nullptr;
33 }
34
35 nsIAtom*
36 XBLChildrenElement::DoGetID() const
37 {
38 return nullptr;
39 }
40
41 nsresult
42 XBLChildrenElement::UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttribute,
43 bool aNotify)
44 {
45 if (aAttribute == nsGkAtoms::includes &&
46 aNameSpaceID == kNameSpaceID_None) {
47 mIncludes.Clear();
48 }
49
50 return Element::UnsetAttr(aNameSpaceID, aAttribute, aNotify);
51 }
52
53 bool
54 XBLChildrenElement::ParseAttribute(int32_t aNamespaceID,
55 nsIAtom* aAttribute,
56 const nsAString& aValue,
57 nsAttrValue& aResult)
58 {
59 if (aAttribute == nsGkAtoms::includes &&
60 aNamespaceID == kNameSpaceID_None) {
61 mIncludes.Clear();
62 nsCharSeparatedTokenizer tok(aValue, '|',
63 nsCharSeparatedTokenizer::SEPARATOR_OPTIONAL);
64 while (tok.hasMoreTokens()) {
65 nsCOMPtr<nsIAtom> atom = do_GetAtom(tok.nextToken());
66 mIncludes.AppendElement(atom);
67 }
68 }
69
70 return false;
71 }
72
73 } // namespace mozilla
74 } // namespace dom
75
76 using namespace mozilla::dom;
77
78 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_1(nsAnonymousContentList, mParent)
79
80 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsAnonymousContentList)
81 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsAnonymousContentList)
82
83 NS_INTERFACE_TABLE_HEAD(nsAnonymousContentList)
84 NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
85 NS_INTERFACE_TABLE_INHERITED(nsAnonymousContentList, nsINodeList,
86 nsIDOMNodeList)
87 NS_INTERFACE_TABLE_TO_MAP_SEGUE
88 NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(nsAnonymousContentList)
89 NS_INTERFACE_MAP_ENTRY(nsISupports)
90 NS_INTERFACE_MAP_END
91
92 NS_IMETHODIMP
93 nsAnonymousContentList::GetLength(uint32_t* aLength)
94 {
95 if (!mParent) {
96 *aLength = 0;
97 return NS_OK;
98 }
99
100 uint32_t count = 0;
101 for (nsIContent* child = mParent->GetFirstChild();
102 child;
103 child = child->GetNextSibling()) {
104 if (child->NodeInfo()->Equals(nsGkAtoms::children, kNameSpaceID_XBL)) {
105 XBLChildrenElement* point = static_cast<XBLChildrenElement*>(child);
106 if (!point->mInsertedChildren.IsEmpty()) {
107 count += point->mInsertedChildren.Length();
108 }
109 else {
110 count += point->GetChildCount();
111 }
112 }
113 else {
114 ++count;
115 }
116 }
117
118 *aLength = count;
119
120 return NS_OK;
121 }
122
123 NS_IMETHODIMP
124 nsAnonymousContentList::Item(uint32_t aIndex, nsIDOMNode** aReturn)
125 {
126 nsIContent* item = Item(aIndex);
127 if (!item) {
128 return NS_ERROR_FAILURE;
129 }
130
131 return CallQueryInterface(item, aReturn);
132 }
133
134 nsIContent*
135 nsAnonymousContentList::Item(uint32_t aIndex)
136 {
137 if (!mParent) {
138 return nullptr;
139 }
140
141 uint32_t remIndex = aIndex;
142 for (nsIContent* child = mParent->GetFirstChild();
143 child;
144 child = child->GetNextSibling()) {
145 if (child->NodeInfo()->Equals(nsGkAtoms::children, kNameSpaceID_XBL)) {
146 XBLChildrenElement* point = static_cast<XBLChildrenElement*>(child);
147 if (!point->mInsertedChildren.IsEmpty()) {
148 if (remIndex < point->mInsertedChildren.Length()) {
149 return point->mInsertedChildren[remIndex];
150 }
151 remIndex -= point->mInsertedChildren.Length();
152 }
153 else {
154 if (remIndex < point->GetChildCount()) {
155 return point->GetChildAt(remIndex);
156 }
157 remIndex -= point->GetChildCount();
158 }
159 }
160 else {
161 if (remIndex == 0) {
162 return child;
163 }
164 --remIndex;
165 }
166 }
167
168 return nullptr;
169 }
170
171 int32_t
172 nsAnonymousContentList::IndexOf(nsIContent* aContent)
173 {
174 NS_ASSERTION(!aContent->NodeInfo()->Equals(nsGkAtoms::children,
175 kNameSpaceID_XBL),
176 "Looking for insertion point");
177
178 if (!mParent) {
179 return -1;
180 }
181
182 uint32_t index = 0;
183 for (nsIContent* child = mParent->GetFirstChild();
184 child;
185 child = child->GetNextSibling()) {
186 if (child->NodeInfo()->Equals(nsGkAtoms::children, kNameSpaceID_XBL)) {
187 XBLChildrenElement* point = static_cast<XBLChildrenElement*>(child);
188 if (!point->mInsertedChildren.IsEmpty()) {
189 uint32_t insIndex = point->mInsertedChildren.IndexOf(aContent);
190 if (insIndex != point->mInsertedChildren.NoIndex) {
191 return index + insIndex;
192 }
193 index += point->mInsertedChildren.Length();
194 }
195 else {
196 int32_t insIndex = point->IndexOf(aContent);
197 if (insIndex != -1) {
198 return index + (uint32_t)insIndex;
199 }
200 index += point->GetChildCount();
201 }
202 }
203 else {
204 if (child == aContent) {
205 return index;
206 }
207 ++index;
208 }
209 }
210
211 return -1;
212 }
213
214 JSObject*
215 nsAnonymousContentList::WrapObject(JSContext *cx)
216 {
217 return mozilla::dom::NodeListBinding::Wrap(cx, this);
218 }

mercurial