|
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 } |