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 : #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 0 : XBLChildrenElement::~XBLChildrenElement()
16 : {
17 0 : }
18 :
19 1424 : NS_IMPL_ADDREF_INHERITED(XBLChildrenElement, Element)
20 1018 : NS_IMPL_RELEASE_INHERITED(XBLChildrenElement, Element)
21 :
22 936 : NS_INTERFACE_TABLE_HEAD(XBLChildrenElement)
23 936 : NS_INTERFACE_TABLE_INHERITED(XBLChildrenElement, nsIDOMNode,
24 : nsIDOMElement)
25 936 : NS_ELEMENT_INTERFACE_TABLE_TO_MAP_SEGUE
26 0 : NS_INTERFACE_MAP_END_INHERITING(Element)
27 :
28 326 : NS_IMPL_ELEMENT_CLONE(XBLChildrenElement)
29 :
30 : nsresult
31 116 : XBLChildrenElement::BeforeSetAttr(int32_t aNamespaceID, nsIAtom* aName,
32 : const nsAttrValueOrString* aValue,
33 : bool aNotify)
34 : {
35 116 : if (aNamespaceID == kNameSpaceID_None) {
36 116 : if (aName == nsGkAtoms::includes) {
37 116 : mIncludes.Clear();
38 116 : if (aValue) {
39 : nsCharSeparatedTokenizer tok(aValue->String(), '|',
40 116 : nsCharSeparatedTokenizer::SEPARATOR_OPTIONAL);
41 688 : while (tok.hasMoreTokens()) {
42 286 : mIncludes.AppendElement(NS_Atomize(tok.nextToken()));
43 : }
44 : }
45 : }
46 : }
47 :
48 116 : return nsXMLElement::BeforeSetAttr(aNamespaceID, aName, aValue, aNotify);
49 : }
50 :
51 : } // namespace dom
52 : } // namespace mozilla
53 :
54 : using namespace mozilla::dom;
55 :
56 0 : NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(nsAnonymousContentList, mParent)
57 :
58 9 : NS_IMPL_CYCLE_COLLECTING_ADDREF(nsAnonymousContentList)
59 0 : NS_IMPL_CYCLE_COLLECTING_RELEASE(nsAnonymousContentList)
60 :
61 9 : NS_INTERFACE_TABLE_HEAD(nsAnonymousContentList)
62 9 : NS_WRAPPERCACHE_INTERFACE_TABLE_ENTRY
63 9 : NS_INTERFACE_TABLE_INHERITED(nsAnonymousContentList, nsINodeList,
64 : nsIDOMNodeList)
65 9 : NS_INTERFACE_TABLE_TO_MAP_SEGUE
66 9 : NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(nsAnonymousContentList)
67 0 : NS_INTERFACE_MAP_ENTRY(nsISupports)
68 0 : NS_INTERFACE_MAP_END
69 :
70 : NS_IMETHODIMP
71 19 : nsAnonymousContentList::GetLength(uint32_t* aLength)
72 : {
73 19 : if (!mParent) {
74 0 : *aLength = 0;
75 0 : return NS_OK;
76 : }
77 :
78 19 : uint32_t count = 0;
79 81 : for (nsIContent* child = mParent->GetFirstChild();
80 81 : child;
81 62 : child = child->GetNextSibling()) {
82 62 : if (child->NodeInfo()->Equals(nsGkAtoms::children, kNameSpaceID_XBL)) {
83 14 : XBLChildrenElement* point = static_cast<XBLChildrenElement*>(child);
84 14 : if (point->HasInsertedChildren()) {
85 10 : count += point->InsertedChildrenLength();
86 : }
87 : else {
88 4 : count += point->GetChildCount();
89 : }
90 : }
91 : else {
92 48 : ++count;
93 : }
94 : }
95 :
96 19 : *aLength = count;
97 :
98 19 : return NS_OK;
99 : }
100 :
101 : NS_IMETHODIMP
102 0 : nsAnonymousContentList::Item(uint32_t aIndex, nsIDOMNode** aReturn)
103 : {
104 0 : nsIContent* item = Item(aIndex);
105 0 : if (!item) {
106 0 : return NS_ERROR_FAILURE;
107 : }
108 :
109 0 : return CallQueryInterface(item, aReturn);
110 : }
111 :
112 : nsIContent*
113 52 : nsAnonymousContentList::Item(uint32_t aIndex)
114 : {
115 52 : if (!mParent) {
116 0 : return nullptr;
117 : }
118 :
119 52 : uint32_t remIndex = aIndex;
120 97 : for (nsIContent* child = mParent->GetFirstChild();
121 97 : child;
122 45 : child = child->GetNextSibling()) {
123 97 : if (child->NodeInfo()->Equals(nsGkAtoms::children, kNameSpaceID_XBL)) {
124 27 : XBLChildrenElement* point = static_cast<XBLChildrenElement*>(child);
125 27 : if (point->HasInsertedChildren()) {
126 27 : if (remIndex < point->InsertedChildrenLength()) {
127 13 : return point->InsertedChild(remIndex);
128 : }
129 14 : remIndex -= point->InsertedChildrenLength();
130 : }
131 : else {
132 0 : if (remIndex < point->GetChildCount()) {
133 0 : return point->GetChildAt(remIndex);
134 : }
135 0 : remIndex -= point->GetChildCount();
136 : }
137 : }
138 : else {
139 70 : if (remIndex == 0) {
140 39 : return child;
141 : }
142 31 : --remIndex;
143 : }
144 : }
145 :
146 0 : return nullptr;
147 : }
148 :
149 : int32_t
150 0 : nsAnonymousContentList::IndexOf(nsIContent* aContent)
151 : {
152 0 : NS_ASSERTION(!aContent->NodeInfo()->Equals(nsGkAtoms::children,
153 : kNameSpaceID_XBL),
154 : "Looking for insertion point");
155 :
156 0 : if (!mParent) {
157 0 : return -1;
158 : }
159 :
160 0 : int32_t index = 0;
161 0 : for (nsIContent* child = mParent->GetFirstChild();
162 0 : child;
163 0 : child = child->GetNextSibling()) {
164 0 : if (child->NodeInfo()->Equals(nsGkAtoms::children, kNameSpaceID_XBL)) {
165 0 : XBLChildrenElement* point = static_cast<XBLChildrenElement*>(child);
166 0 : if (point->HasInsertedChildren()) {
167 0 : int32_t insIndex = point->IndexOfInsertedChild(aContent);
168 0 : if (insIndex != -1) {
169 0 : return index + insIndex;
170 : }
171 0 : index += point->InsertedChildrenLength();
172 : }
173 : else {
174 0 : int32_t insIndex = point->IndexOf(aContent);
175 0 : if (insIndex != -1) {
176 0 : return index + insIndex;
177 : }
178 0 : index += point->GetChildCount();
179 : }
180 : }
181 : else {
182 0 : if (child == aContent) {
183 0 : return index;
184 : }
185 0 : ++index;
186 : }
187 : }
188 :
189 0 : return -1;
190 : }
191 :
192 : JSObject*
193 0 : nsAnonymousContentList::WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto)
194 : {
195 0 : return mozilla::dom::NodeListBinding::Wrap(cx, this, aGivenProto);
196 : }
|