1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* ***** BEGIN LICENSE BLOCK *****
3 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 : *
5 : * The contents of this file are subject to the Mozilla Public License Version
6 : * 1.1 (the "License"); you may not use this file except in compliance with
7 : * the License. You may obtain a copy of the License at
8 : * http://www.mozilla.org/MPL/
9 : *
10 : * Software distributed under the License is distributed on an "AS IS" basis,
11 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : * for the specific language governing rights and limitations under the
13 : * License.
14 : *
15 : * The Original Code is mozilla.org code.
16 : *
17 : * The Initial Developer of the Original Code is
18 : * Netscape Communications Corporation.
19 : * Portions created by the Initial Developer are Copyright (C) 2001
20 : * the Initial Developer. All Rights Reserved.
21 : *
22 : * Contributor(s):
23 : * Joe Hewitt <hewitt@netscape.com> (original author)
24 : *
25 : * Alternatively, the contents of this file may be used under the terms of
26 : * either the GNU General Public License Version 2 or later (the "GPL"), or
27 : * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 : * in which case the provisions of the GPL or the LGPL are applicable instead
29 : * of those above. If you wish to allow use of your version of this file only
30 : * under the terms of either the GPL or the LGPL, and not to allow others to
31 : * use your version of this file under the terms of the MPL, indicate your
32 : * decision by deleting the provisions above and replace them with the notice
33 : * and other provisions required by the GPL or the LGPL. If you do not delete
34 : * the provisions above, a recipient may use your version of this file under
35 : * the terms of any one of the MPL, the GPL or the LGPL.
36 : *
37 : * ***** END LICENSE BLOCK ***** */
38 :
39 : #include "mozilla/Util.h"
40 :
41 : #include "inDOMView.h"
42 : #include "inIDOMUtils.h"
43 :
44 : #include "inLayoutUtils.h"
45 :
46 : #include "nsString.h"
47 : #include "nsReadableUtils.h"
48 : #include "nsISupportsArray.h"
49 : #include "nsIDOMNode.h"
50 : #include "nsIDOMNodeFilter.h"
51 : #include "nsIDOMNodeList.h"
52 : #include "nsIDOMCharacterData.h"
53 : #include "nsIDOMAttr.h"
54 : #include "nsIDOMDocument.h"
55 : #include "nsIDOMNamedNodeMap.h"
56 : #include "nsIDOMMutationEvent.h"
57 : #include "nsBindingManager.h"
58 : #include "nsINameSpaceManager.h"
59 : #include "nsIDocument.h"
60 : #include "nsIServiceManager.h"
61 : #include "nsITreeColumns.h"
62 : #include "mozilla/dom/Element.h"
63 :
64 : #ifdef ACCESSIBILITY
65 : #include "nsIAccessible.h"
66 : #include "nsIAccessibilityService.h"
67 : #endif
68 :
69 : using namespace mozilla;
70 :
71 : ////////////////////////////////////////////////////////////////////////
72 : // inDOMViewNode
73 :
74 : class inDOMViewNode
75 : {
76 : public:
77 : inDOMViewNode() {}
78 : inDOMViewNode(nsIDOMNode* aNode);
79 : ~inDOMViewNode();
80 :
81 : nsCOMPtr<nsIDOMNode> node;
82 :
83 : inDOMViewNode* parent;
84 : inDOMViewNode* next;
85 : inDOMViewNode* previous;
86 :
87 : PRInt32 level;
88 : bool isOpen;
89 : bool isContainer;
90 : bool hasAnonymous;
91 : bool hasSubDocument;
92 : };
93 :
94 0 : inDOMViewNode::inDOMViewNode(nsIDOMNode* aNode) :
95 : node(aNode),
96 : parent(nsnull),
97 : next(nsnull),
98 : previous(nsnull),
99 : level(0),
100 : isOpen(false),
101 : isContainer(false),
102 : hasAnonymous(false),
103 0 : hasSubDocument(false)
104 : {
105 :
106 0 : }
107 :
108 0 : inDOMViewNode::~inDOMViewNode()
109 : {
110 0 : }
111 :
112 : ////////////////////////////////////////////////////////////////////////
113 :
114 0 : inDOMView::inDOMView() :
115 : mShowAnonymous(false),
116 : mShowSubDocuments(false),
117 : mShowWhitespaceNodes(true),
118 : mShowAccessibleNodes(false),
119 0 : mWhatToShow(nsIDOMNodeFilter::SHOW_ALL)
120 : {
121 0 : }
122 :
123 0 : inDOMView::~inDOMView()
124 : {
125 0 : SetRootNode(nsnull);
126 0 : }
127 :
128 : #define DOMVIEW_ATOM(name_, value_) nsIAtom* inDOMView::name_ = nsnull;
129 : #include "inDOMViewAtomList.h"
130 : #undef DOMVIEW_ATOM
131 :
132 : #define DOMVIEW_ATOM(name_, value_) NS_STATIC_ATOM_BUFFER(name_##_buffer, value_)
133 : #include "inDOMViewAtomList.h"
134 : #undef DOMVIEW_ATOM
135 :
136 : /* static */ const nsStaticAtom inDOMView::Atoms_info[] = {
137 : #define DOMVIEW_ATOM(name_, value_) NS_STATIC_ATOM(name_##_buffer, &inDOMView::name_),
138 : #include "inDOMViewAtomList.h"
139 : #undef DOMVIEW_ATOM
140 : };
141 :
142 : /* static */ void
143 1404 : inDOMView::InitAtoms()
144 : {
145 1404 : NS_RegisterStaticAtoms(Atoms_info);
146 1404 : }
147 :
148 : ////////////////////////////////////////////////////////////////////////
149 : // nsISupports
150 :
151 0 : NS_IMPL_ISUPPORTS3(inDOMView,
152 : inIDOMView,
153 : nsITreeView,
154 : nsIMutationObserver)
155 :
156 : ////////////////////////////////////////////////////////////////////////
157 : // inIDOMView
158 :
159 : NS_IMETHODIMP
160 0 : inDOMView::GetRootNode(nsIDOMNode** aNode)
161 : {
162 0 : *aNode = mRootNode;
163 0 : NS_IF_ADDREF(*aNode);
164 0 : return NS_OK;
165 : }
166 :
167 : NS_IMETHODIMP
168 0 : inDOMView::SetRootNode(nsIDOMNode* aNode)
169 : {
170 0 : if (mTree)
171 0 : mTree->BeginUpdateBatch();
172 :
173 0 : if (mRootDocument) {
174 : // remove previous document observer
175 0 : nsCOMPtr<nsINode> doc(do_QueryInterface(mRootDocument));
176 0 : if (doc)
177 0 : doc->RemoveMutationObserver(this);
178 : }
179 :
180 0 : RemoveAllNodes();
181 :
182 0 : mRootNode = aNode;
183 :
184 0 : if (aNode) {
185 : // If we are able to show element nodes, then start with the root node
186 : // as the first node in the buffer
187 0 : if (mWhatToShow & nsIDOMNodeFilter::SHOW_ELEMENT) {
188 : // allocate new node array
189 0 : AppendNode(CreateNode(aNode, nsnull));
190 : } else {
191 : // place only the children of the root node in the buffer
192 0 : ExpandNode(-1);
193 : }
194 :
195 : // store an owning reference to document so that it isn't
196 : // destroyed before we are
197 0 : mRootDocument = do_QueryInterface(aNode);
198 0 : if (!mRootDocument) {
199 0 : aNode->GetOwnerDocument(getter_AddRefs(mRootDocument));
200 : }
201 :
202 : // add document observer
203 0 : nsCOMPtr<nsINode> doc(do_QueryInterface(mRootDocument));
204 0 : if (doc)
205 0 : doc->AddMutationObserver(this);
206 : } else {
207 0 : mRootDocument = nsnull;
208 : }
209 :
210 0 : if (mTree)
211 0 : mTree->EndUpdateBatch();
212 :
213 0 : return NS_OK;
214 : }
215 :
216 : NS_IMETHODIMP
217 0 : inDOMView::GetNodeFromRowIndex(PRInt32 rowIndex, nsIDOMNode **_retval)
218 : {
219 0 : inDOMViewNode* viewNode = nsnull;
220 0 : RowToNode(rowIndex, &viewNode);
221 0 : if (!viewNode) return NS_ERROR_FAILURE;
222 0 : *_retval = viewNode->node;
223 0 : NS_IF_ADDREF(*_retval);
224 :
225 0 : return NS_OK;
226 : }
227 :
228 : NS_IMETHODIMP
229 0 : inDOMView::GetRowIndexFromNode(nsIDOMNode *node, PRInt32 *_retval)
230 : {
231 0 : NodeToRow(node, _retval);
232 0 : return NS_OK;
233 : }
234 :
235 :
236 : NS_IMETHODIMP
237 0 : inDOMView::GetShowAnonymousContent(bool *aShowAnonymousContent)
238 : {
239 0 : *aShowAnonymousContent = mShowAnonymous;
240 0 : return NS_OK;
241 : }
242 :
243 : NS_IMETHODIMP
244 0 : inDOMView::SetShowAnonymousContent(bool aShowAnonymousContent)
245 : {
246 0 : mShowAnonymous = aShowAnonymousContent;
247 0 : return NS_OK;
248 : }
249 :
250 : NS_IMETHODIMP
251 0 : inDOMView::GetShowSubDocuments(bool *aShowSubDocuments)
252 : {
253 0 : *aShowSubDocuments = mShowSubDocuments;
254 0 : return NS_OK;
255 : }
256 :
257 : NS_IMETHODIMP
258 0 : inDOMView::SetShowSubDocuments(bool aShowSubDocuments)
259 : {
260 0 : mShowSubDocuments = aShowSubDocuments;
261 0 : return NS_OK;
262 : }
263 :
264 : NS_IMETHODIMP
265 0 : inDOMView::GetShowWhitespaceNodes(bool *aShowWhitespaceNodes)
266 : {
267 0 : *aShowWhitespaceNodes = mShowWhitespaceNodes;
268 0 : return NS_OK;
269 : }
270 :
271 : NS_IMETHODIMP
272 0 : inDOMView::SetShowWhitespaceNodes(bool aShowWhitespaceNodes)
273 : {
274 0 : mShowWhitespaceNodes = aShowWhitespaceNodes;
275 0 : return NS_OK;
276 : }
277 :
278 : NS_IMETHODIMP
279 0 : inDOMView::GetShowAccessibleNodes(bool *aShowAccessibleNodes)
280 : {
281 0 : *aShowAccessibleNodes = mShowAccessibleNodes;
282 0 : return NS_OK;
283 : }
284 :
285 : NS_IMETHODIMP
286 0 : inDOMView::SetShowAccessibleNodes(bool aShowAccessibleNodes)
287 : {
288 0 : mShowAccessibleNodes = aShowAccessibleNodes;
289 0 : return NS_OK;
290 : }
291 :
292 : NS_IMETHODIMP
293 0 : inDOMView::GetWhatToShow(PRUint32 *aWhatToShow)
294 : {
295 0 : *aWhatToShow = mWhatToShow;
296 0 : return NS_OK;
297 : }
298 :
299 : NS_IMETHODIMP
300 0 : inDOMView::SetWhatToShow(PRUint32 aWhatToShow)
301 : {
302 0 : mWhatToShow = aWhatToShow;
303 0 : return NS_OK;
304 : }
305 :
306 : NS_IMETHODIMP
307 0 : inDOMView::Rebuild()
308 : {
309 0 : nsCOMPtr<nsIDOMNode> root;
310 0 : GetRootNode(getter_AddRefs(root));
311 0 : SetRootNode(root);
312 0 : return NS_OK;
313 : }
314 :
315 : ////////////////////////////////////////////////////////////////////////
316 : // nsITreeView
317 :
318 : NS_IMETHODIMP
319 0 : inDOMView::GetRowCount(PRInt32 *aRowCount)
320 : {
321 0 : *aRowCount = GetRowCount();
322 0 : return NS_OK;
323 : }
324 :
325 : NS_IMETHODIMP
326 0 : inDOMView::GetRowProperties(PRInt32 index, nsISupportsArray *properties)
327 : {
328 0 : return NS_OK;
329 : }
330 :
331 : NS_IMETHODIMP
332 0 : inDOMView::GetCellProperties(PRInt32 row, nsITreeColumn* col, nsISupportsArray *properties)
333 : {
334 0 : inDOMViewNode* node = nsnull;
335 0 : RowToNode(row, &node);
336 0 : if (!node) return NS_ERROR_FAILURE;
337 :
338 0 : nsCOMPtr<nsIContent> content = do_QueryInterface(node->node);
339 0 : if (content && content->IsInAnonymousSubtree()) {
340 0 : properties->AppendElement(kAnonymousAtom);
341 : }
342 :
343 : PRUint16 nodeType;
344 0 : node->node->GetNodeType(&nodeType);
345 0 : switch (nodeType) {
346 : case nsIDOMNode::ELEMENT_NODE:
347 0 : properties->AppendElement(kElementNodeAtom);
348 0 : break;
349 : case nsIDOMNode::ATTRIBUTE_NODE:
350 0 : properties->AppendElement(kAttributeNodeAtom);
351 0 : break;
352 : case nsIDOMNode::TEXT_NODE:
353 0 : properties->AppendElement(kTextNodeAtom);
354 0 : break;
355 : case nsIDOMNode::CDATA_SECTION_NODE:
356 0 : properties->AppendElement(kCDataSectionNodeAtom);
357 0 : break;
358 : case nsIDOMNode::ENTITY_REFERENCE_NODE:
359 0 : properties->AppendElement(kEntityReferenceNodeAtom);
360 0 : break;
361 : case nsIDOMNode::ENTITY_NODE:
362 0 : properties->AppendElement(kEntityNodeAtom);
363 0 : break;
364 : case nsIDOMNode::PROCESSING_INSTRUCTION_NODE:
365 0 : properties->AppendElement(kProcessingInstructionNodeAtom);
366 0 : break;
367 : case nsIDOMNode::COMMENT_NODE:
368 0 : properties->AppendElement(kCommentNodeAtom);
369 0 : break;
370 : case nsIDOMNode::DOCUMENT_NODE:
371 0 : properties->AppendElement(kDocumentNodeAtom);
372 0 : break;
373 : case nsIDOMNode::DOCUMENT_TYPE_NODE:
374 0 : properties->AppendElement(kDocumentTypeNodeAtom);
375 0 : break;
376 : case nsIDOMNode::DOCUMENT_FRAGMENT_NODE:
377 0 : properties->AppendElement(kDocumentFragmentNodeAtom);
378 0 : break;
379 : case nsIDOMNode::NOTATION_NODE:
380 0 : properties->AppendElement(kNotationNodeAtom);
381 0 : break;
382 : }
383 :
384 : #ifdef ACCESSIBILITY
385 0 : if (mShowAccessibleNodes) {
386 : nsCOMPtr<nsIAccessibilityService> accService(
387 0 : do_GetService("@mozilla.org/accessibilityService;1"));
388 0 : NS_ENSURE_TRUE(accService, NS_ERROR_FAILURE);
389 :
390 0 : nsCOMPtr<nsIAccessible> accessible;
391 : nsresult rv =
392 0 : accService->GetAccessibleFor(node->node, getter_AddRefs(accessible));
393 0 : if (NS_SUCCEEDED(rv) && accessible)
394 0 : properties->AppendElement(kAccessibleNodeAtom);
395 : }
396 : #endif
397 :
398 0 : return NS_OK;
399 : }
400 :
401 : NS_IMETHODIMP
402 0 : inDOMView::GetColumnProperties(nsITreeColumn* col, nsISupportsArray *properties)
403 : {
404 0 : return NS_OK;
405 : }
406 :
407 : NS_IMETHODIMP
408 0 : inDOMView::GetImageSrc(PRInt32 row, nsITreeColumn* col, nsAString& _retval)
409 : {
410 0 : return NS_OK;
411 : }
412 :
413 : NS_IMETHODIMP
414 0 : inDOMView::GetProgressMode(PRInt32 row, nsITreeColumn* col, PRInt32* _retval)
415 : {
416 0 : return NS_OK;
417 : }
418 :
419 : NS_IMETHODIMP
420 0 : inDOMView::GetCellValue(PRInt32 row, nsITreeColumn* col, nsAString& _retval)
421 : {
422 0 : return NS_OK;
423 : }
424 :
425 : NS_IMETHODIMP
426 0 : inDOMView::GetCellText(PRInt32 row, nsITreeColumn* col, nsAString& _retval)
427 : {
428 0 : inDOMViewNode* node = nsnull;
429 0 : RowToNode(row, &node);
430 0 : if (!node) return NS_ERROR_FAILURE;
431 :
432 0 : nsIDOMNode* domNode = node->node;
433 :
434 0 : nsAutoString colID;
435 0 : col->GetId(colID);
436 0 : if (colID.EqualsLiteral("colNodeName"))
437 0 : domNode->GetNodeName(_retval);
438 0 : else if (colID.EqualsLiteral("colLocalName"))
439 0 : domNode->GetLocalName(_retval);
440 0 : else if (colID.EqualsLiteral("colPrefix"))
441 0 : domNode->GetPrefix(_retval);
442 0 : else if (colID.EqualsLiteral("colNamespaceURI"))
443 0 : domNode->GetNamespaceURI(_retval);
444 0 : else if (colID.EqualsLiteral("colNodeType")) {
445 : PRUint16 nodeType;
446 0 : domNode->GetNodeType(&nodeType);
447 0 : nsAutoString temp;
448 0 : temp.AppendInt(PRInt32(nodeType));
449 0 : _retval = temp;
450 0 : } else if (colID.EqualsLiteral("colNodeValue"))
451 0 : domNode->GetNodeValue(_retval);
452 : else {
453 0 : if (StringBeginsWith(colID, NS_LITERAL_STRING("col@"))) {
454 0 : nsCOMPtr<nsIDOMElement> el = do_QueryInterface(node->node);
455 0 : if (el) {
456 0 : nsAutoString attr;
457 0 : colID.Right(attr, colID.Length()-4); // have to use this because Substring is crashing on me!
458 0 : el->GetAttribute(attr, _retval);
459 : }
460 : }
461 : }
462 :
463 0 : return NS_OK;
464 : }
465 :
466 : NS_IMETHODIMP
467 0 : inDOMView::IsContainer(PRInt32 index, bool *_retval)
468 : {
469 0 : inDOMViewNode* node = nsnull;
470 0 : RowToNode(index, &node);
471 0 : if (!node) return NS_ERROR_FAILURE;
472 :
473 0 : *_retval = node->isContainer;
474 0 : return NS_OK;
475 : }
476 :
477 : NS_IMETHODIMP
478 0 : inDOMView::IsContainerOpen(PRInt32 index, bool *_retval)
479 : {
480 0 : inDOMViewNode* node = nsnull;
481 0 : RowToNode(index, &node);
482 0 : if (!node) return NS_ERROR_FAILURE;
483 :
484 0 : *_retval = node->isOpen;
485 0 : return NS_OK;
486 : }
487 :
488 : NS_IMETHODIMP
489 0 : inDOMView::IsContainerEmpty(PRInt32 index, bool *_retval)
490 : {
491 0 : inDOMViewNode* node = nsnull;
492 0 : RowToNode(index, &node);
493 0 : if (!node) return NS_ERROR_FAILURE;
494 :
495 0 : *_retval = node->isContainer ? false : true;
496 0 : return NS_OK;
497 : }
498 :
499 : NS_IMETHODIMP
500 0 : inDOMView::GetLevel(PRInt32 index, PRInt32 *_retval)
501 : {
502 0 : inDOMViewNode* node = nsnull;
503 0 : RowToNode(index, &node);
504 0 : if (!node) return NS_ERROR_FAILURE;
505 :
506 0 : *_retval = node->level;
507 0 : return NS_OK;
508 : }
509 :
510 : NS_IMETHODIMP
511 0 : inDOMView::GetParentIndex(PRInt32 rowIndex, PRInt32 *_retval)
512 : {
513 0 : inDOMViewNode* node = nsnull;
514 0 : RowToNode(rowIndex, &node);
515 0 : if (!node) return NS_ERROR_FAILURE;
516 :
517 : // GetParentIndex returns -1 if there is no parent
518 0 : *_retval = -1;
519 :
520 0 : inDOMViewNode* checkNode = nsnull;
521 0 : PRInt32 i = rowIndex - 1;
522 0 : do {
523 0 : nsresult rv = RowToNode(i, &checkNode);
524 0 : if (NS_FAILED(rv)) {
525 : // No parent. Just break out.
526 0 : break;
527 : }
528 :
529 0 : if (checkNode == node->parent) {
530 0 : *_retval = i;
531 0 : return NS_OK;
532 : }
533 0 : --i;
534 : } while (checkNode);
535 :
536 0 : return NS_OK;
537 : }
538 :
539 : NS_IMETHODIMP
540 0 : inDOMView::HasNextSibling(PRInt32 rowIndex, PRInt32 afterIndex, bool *_retval)
541 : {
542 0 : inDOMViewNode* node = nsnull;
543 0 : RowToNode(rowIndex, &node);
544 0 : if (!node) return NS_ERROR_FAILURE;
545 :
546 0 : *_retval = node->next != nsnull;
547 :
548 0 : return NS_OK;
549 : }
550 :
551 : NS_IMETHODIMP
552 0 : inDOMView::ToggleOpenState(PRInt32 index)
553 : {
554 0 : inDOMViewNode* node = nsnull;
555 0 : RowToNode(index, &node);
556 0 : if (!node) return NS_ERROR_FAILURE;
557 :
558 0 : PRInt32 oldCount = GetRowCount();
559 0 : if (node->isOpen)
560 0 : CollapseNode(index);
561 : else
562 0 : ExpandNode(index);
563 :
564 : // Update the twisty.
565 0 : mTree->InvalidateRow(index);
566 :
567 0 : mTree->RowCountChanged(index+1, GetRowCount() - oldCount);
568 :
569 0 : return NS_OK;
570 : }
571 :
572 : NS_IMETHODIMP
573 0 : inDOMView::SetTree(nsITreeBoxObject *tree)
574 : {
575 0 : mTree = tree;
576 0 : return NS_OK;
577 : }
578 :
579 : NS_IMETHODIMP
580 0 : inDOMView::GetSelection(nsITreeSelection * *aSelection)
581 : {
582 0 : *aSelection = mSelection;
583 0 : NS_IF_ADDREF(*aSelection);
584 0 : return NS_OK;
585 : }
586 :
587 0 : NS_IMETHODIMP inDOMView::SetSelection(nsITreeSelection * aSelection)
588 : {
589 0 : mSelection = aSelection;
590 0 : return NS_OK;
591 : }
592 :
593 : NS_IMETHODIMP
594 0 : inDOMView::SelectionChanged()
595 : {
596 0 : return NS_OK;
597 : }
598 :
599 : NS_IMETHODIMP
600 0 : inDOMView::SetCellValue(PRInt32 row, nsITreeColumn* col, const nsAString& value)
601 : {
602 0 : return NS_OK;
603 : }
604 :
605 : NS_IMETHODIMP
606 0 : inDOMView::SetCellText(PRInt32 row, nsITreeColumn* col, const nsAString& value)
607 : {
608 0 : return NS_OK;
609 : }
610 :
611 : NS_IMETHODIMP
612 0 : inDOMView::CycleHeader(nsITreeColumn* col)
613 : {
614 0 : return NS_OK;
615 : }
616 :
617 : NS_IMETHODIMP
618 0 : inDOMView::CycleCell(PRInt32 row, nsITreeColumn* col)
619 : {
620 0 : return NS_OK;
621 : }
622 :
623 : NS_IMETHODIMP
624 0 : inDOMView::IsEditable(PRInt32 row, nsITreeColumn* col, bool *_retval)
625 : {
626 0 : return NS_OK;
627 : }
628 :
629 :
630 : NS_IMETHODIMP
631 0 : inDOMView::IsSelectable(PRInt32 row, nsITreeColumn* col, bool *_retval)
632 : {
633 0 : return NS_OK;
634 : }
635 :
636 : NS_IMETHODIMP
637 0 : inDOMView::IsSeparator(PRInt32 index, bool *_retval)
638 : {
639 0 : return NS_OK;
640 : }
641 :
642 : NS_IMETHODIMP
643 0 : inDOMView::IsSorted(bool *_retval)
644 : {
645 0 : return NS_OK;
646 : }
647 :
648 : NS_IMETHODIMP
649 0 : inDOMView::CanDrop(PRInt32 index, PRInt32 orientation,
650 : nsIDOMDataTransfer* aDataTransfer, bool *_retval)
651 : {
652 0 : *_retval = false;
653 0 : return NS_OK;
654 : }
655 :
656 : NS_IMETHODIMP
657 0 : inDOMView::Drop(PRInt32 row, PRInt32 orientation, nsIDOMDataTransfer* aDataTransfer)
658 : {
659 0 : return NS_OK;
660 : }
661 :
662 : NS_IMETHODIMP
663 0 : inDOMView::PerformAction(const PRUnichar *action)
664 : {
665 0 : return NS_OK;
666 : }
667 :
668 : NS_IMETHODIMP
669 0 : inDOMView::PerformActionOnRow(const PRUnichar *action, PRInt32 row)
670 : {
671 0 : return NS_OK;
672 : }
673 :
674 : NS_IMETHODIMP
675 0 : inDOMView::PerformActionOnCell(const PRUnichar* action, PRInt32 row, nsITreeColumn* col)
676 : {
677 0 : return NS_OK;
678 : }
679 :
680 : ///////////////////////////////////////////////////////////////////////
681 : // nsIMutationObserver
682 :
683 : void
684 0 : inDOMView::NodeWillBeDestroyed(const nsINode* aNode)
685 : {
686 0 : NS_NOTREACHED("Document destroyed while we're holding a strong ref to it");
687 0 : }
688 :
689 : void
690 0 : inDOMView::AttributeChanged(nsIDocument* aDocument, dom::Element* aElement,
691 : PRInt32 aNameSpaceID, nsIAtom* aAttribute,
692 : PRInt32 aModType)
693 : {
694 0 : if (!mTree) {
695 0 : return;
696 : }
697 :
698 0 : if (!(mWhatToShow & nsIDOMNodeFilter::SHOW_ATTRIBUTE)) {
699 0 : return;
700 : }
701 :
702 0 : nsCOMPtr<nsIMutationObserver> kungFuDeathGrip(this);
703 :
704 : // get the dom attribute node, if there is any
705 0 : nsCOMPtr<nsIDOMNode> content(do_QueryInterface(aElement));
706 0 : nsCOMPtr<nsIDOMElement> el(do_QueryInterface(aElement));
707 0 : nsCOMPtr<nsIDOMAttr> domAttr;
708 0 : nsDependentAtomString attrStr(aAttribute);
709 0 : if (aNameSpaceID) {
710 : nsCOMPtr<nsINameSpaceManager> nsm =
711 0 : do_GetService(NS_NAMESPACEMANAGER_CONTRACTID);
712 0 : if (!nsm) {
713 : // we can't find out which attribute we want :(
714 : return;
715 : }
716 0 : nsString attrNS;
717 0 : nsresult rv = nsm->GetNameSpaceURI(aNameSpaceID, attrNS);
718 0 : if (NS_FAILED(rv)) {
719 : return;
720 : }
721 0 : (void)el->GetAttributeNodeNS(attrNS, attrStr, getter_AddRefs(domAttr));
722 : } else {
723 0 : (void)el->GetAttributeNode(attrStr, getter_AddRefs(domAttr));
724 : }
725 :
726 0 : if (aModType == nsIDOMMutationEvent::MODIFICATION) {
727 : // No fancy stuff here, just invalidate the changed row
728 0 : if (!domAttr) {
729 : return;
730 : }
731 0 : PRInt32 row = 0;
732 0 : NodeToRow(domAttr, &row);
733 0 : mTree->InvalidateRange(row, row);
734 0 : } else if (aModType == nsIDOMMutationEvent::ADDITION) {
735 0 : if (!domAttr) {
736 : return;
737 : }
738 : // get the number of attributes on this content node
739 0 : nsCOMPtr<nsIDOMNamedNodeMap> attrs;
740 0 : content->GetAttributes(getter_AddRefs(attrs));
741 : PRUint32 attrCount;
742 0 : attrs->GetLength(&attrCount);
743 :
744 0 : inDOMViewNode* contentNode = nsnull;
745 : PRInt32 contentRow;
746 : PRInt32 attrRow;
747 0 : if (mRootNode == content &&
748 0 : !(mWhatToShow & nsIDOMNodeFilter::SHOW_ELEMENT)) {
749 : // if this view has a root node but is not displaying it,
750 : // it is ok to act as if the changed attribute is on the root.
751 0 : attrRow = attrCount - 1;
752 : } else {
753 0 : if (NS_FAILED(NodeToRow(content, &contentRow))) {
754 : return;
755 : }
756 0 : RowToNode(contentRow, &contentNode);
757 0 : if (!contentNode->isOpen) {
758 : return;
759 : }
760 0 : attrRow = contentRow + attrCount;
761 : }
762 :
763 0 : inDOMViewNode* newNode = CreateNode(domAttr, contentNode);
764 0 : inDOMViewNode* insertNode = nsnull;
765 0 : RowToNode(attrRow, &insertNode);
766 0 : if (insertNode) {
767 0 : if (contentNode &&
768 : insertNode->level <= contentNode->level) {
769 0 : RowToNode(attrRow-1, &insertNode);
770 0 : InsertLinkAfter(newNode, insertNode);
771 : } else
772 0 : InsertLinkBefore(newNode, insertNode);
773 : }
774 0 : InsertNode(newNode, attrRow);
775 0 : mTree->RowCountChanged(attrRow, 1);
776 0 : } else if (aModType == nsIDOMMutationEvent::REMOVAL) {
777 : // At this point, the attribute is already gone from the DOM, but is still represented
778 : // in our mRows array. Search through the content node's children for the corresponding
779 : // node and remove it.
780 :
781 : // get the row of the content node
782 0 : inDOMViewNode* contentNode = nsnull;
783 : PRInt32 contentRow;
784 : PRInt32 baseLevel;
785 0 : if (NS_SUCCEEDED(NodeToRow(content, &contentRow))) {
786 0 : RowToNode(contentRow, &contentNode);
787 0 : baseLevel = contentNode->level;
788 : } else {
789 0 : if (mRootNode == content) {
790 0 : contentRow = -1;
791 0 : baseLevel = -1;
792 : } else
793 : return;
794 : }
795 :
796 : // search for the attribute node that was removed
797 0 : inDOMViewNode* checkNode = nsnull;
798 0 : PRInt32 row = 0;
799 0 : for (row = contentRow+1; row < GetRowCount(); ++row) {
800 0 : checkNode = GetNodeAt(row);
801 0 : if (checkNode->level == baseLevel+1) {
802 0 : domAttr = do_QueryInterface(checkNode->node);
803 0 : if (domAttr) {
804 0 : nsAutoString attrName;
805 0 : domAttr->GetNodeName(attrName);
806 0 : if (attrName.Equals(attrStr)) {
807 : // we have found the row for the attribute that was removed
808 0 : RemoveLink(checkNode);
809 0 : RemoveNode(row);
810 0 : mTree->RowCountChanged(row, -1);
811 : break;
812 : }
813 : }
814 : }
815 0 : if (checkNode->level <= baseLevel)
816 0 : break;
817 : }
818 :
819 : }
820 : }
821 :
822 : void
823 0 : inDOMView::ContentAppended(nsIDocument *aDocument,
824 : nsIContent* aContainer,
825 : nsIContent* aFirstNewContent,
826 : PRInt32 /* unused */)
827 : {
828 0 : if (!mTree) {
829 0 : return;
830 : }
831 :
832 0 : for (nsIContent* cur = aFirstNewContent; cur; cur = cur->GetNextSibling()) {
833 : // Our ContentInserted impl doesn't use the index
834 0 : ContentInserted(aDocument, aContainer, cur, 0);
835 : }
836 : }
837 :
838 : void
839 0 : inDOMView::ContentInserted(nsIDocument *aDocument, nsIContent* aContainer,
840 : nsIContent* aChild, PRInt32 /* unused */)
841 : {
842 0 : if (!mTree)
843 0 : return;
844 :
845 : nsresult rv;
846 0 : nsCOMPtr<nsIDOMNode> childDOMNode(do_QueryInterface(aChild));
847 0 : nsCOMPtr<nsIDOMNode> parent;
848 0 : if (!mDOMUtils) {
849 0 : mDOMUtils = do_GetService("@mozilla.org/inspector/dom-utils;1");
850 0 : if (!mDOMUtils) {
851 : return;
852 : }
853 : }
854 0 : mDOMUtils->GetParentForNode(childDOMNode, mShowAnonymous,
855 0 : getter_AddRefs(parent));
856 :
857 : // find the inDOMViewNode for the parent of the inserted content
858 0 : PRInt32 parentRow = 0;
859 0 : if (NS_FAILED(rv = NodeToRow(parent, &parentRow)))
860 : return;
861 0 : inDOMViewNode* parentNode = nsnull;
862 0 : if (NS_FAILED(rv = RowToNode(parentRow, &parentNode)))
863 : return;
864 :
865 0 : nsCOMPtr<nsIMutationObserver> kungFuDeathGrip(this);
866 :
867 0 : if (!parentNode->isOpen) {
868 : // Parent is not open, so don't bother creating tree rows for the
869 : // kids. But do indicate that it's now a container, if needed.
870 0 : if (!parentNode->isContainer) {
871 0 : parentNode->isContainer = true;
872 0 : mTree->InvalidateRow(parentRow);
873 : }
874 : return;
875 : }
876 :
877 : // get the previous sibling of the inserted content
878 0 : nsCOMPtr<nsIDOMNode> previous;
879 0 : GetRealPreviousSibling(childDOMNode, parent, getter_AddRefs(previous));
880 0 : inDOMViewNode* previousNode = nsnull;
881 :
882 0 : PRInt32 row = 0;
883 0 : if (previous) {
884 : // find the inDOMViewNode for the previous sibling of the inserted content
885 0 : PRInt32 previousRow = 0;
886 0 : if (NS_FAILED(rv = NodeToRow(previous, &previousRow)))
887 : return;
888 0 : if (NS_FAILED(rv = RowToNode(previousRow, &previousNode)))
889 : return;
890 :
891 : // get the last descendant of the previous row, which is the row
892 : // after which to insert this new row
893 0 : GetLastDescendantOf(previousNode, previousRow, &row);
894 0 : ++row;
895 : } else {
896 : // there is no previous sibling, so the new row will be inserted after the parent
897 0 : row = parentRow+1;
898 : }
899 :
900 0 : inDOMViewNode* newNode = CreateNode(childDOMNode, parentNode);
901 :
902 0 : if (previous) {
903 0 : InsertLinkAfter(newNode, previousNode);
904 : } else {
905 : PRInt32 firstChildRow;
906 0 : if (NS_SUCCEEDED(GetFirstDescendantOf(parentNode, parentRow, &firstChildRow))) {
907 : inDOMViewNode* firstChild;
908 0 : RowToNode(firstChildRow, &firstChild);
909 0 : InsertLinkBefore(newNode, firstChild);
910 : }
911 : }
912 :
913 : // insert new node
914 0 : InsertNode(newNode, row);
915 :
916 0 : mTree->RowCountChanged(row, 1);
917 : }
918 :
919 : void
920 0 : inDOMView::ContentRemoved(nsIDocument *aDocument, nsIContent* aContainer,
921 : nsIContent* aChild, PRInt32 aIndexInContainer,
922 : nsIContent* aPreviousSibling)
923 : {
924 0 : if (!mTree)
925 0 : return;
926 :
927 : nsresult rv;
928 :
929 : // find the inDOMViewNode for the old child
930 0 : nsCOMPtr<nsIDOMNode> oldDOMNode(do_QueryInterface(aChild));
931 0 : PRInt32 row = 0;
932 0 : if (NS_FAILED(rv = NodeToRow(oldDOMNode, &row)))
933 : return;
934 : inDOMViewNode* oldNode;
935 0 : if (NS_FAILED(rv = RowToNode(row, &oldNode)))
936 : return;
937 :
938 0 : nsCOMPtr<nsIMutationObserver> kungFuDeathGrip(this);
939 :
940 : // The parent may no longer be a container. Note that we don't want
941 : // to access oldNode after calling RemoveNode, so do this now.
942 0 : inDOMViewNode* parentNode = oldNode->parent;
943 0 : bool isOnlyChild = oldNode->previous == nsnull && oldNode->next == nsnull;
944 :
945 : // Keep track of how many rows we are removing. It's at least one,
946 : // but if we're open it's more.
947 0 : PRInt32 oldCount = GetRowCount();
948 :
949 0 : if (oldNode->isOpen)
950 0 : CollapseNode(row);
951 :
952 0 : RemoveLink(oldNode);
953 0 : RemoveNode(row);
954 :
955 0 : if (isOnlyChild) {
956 : // Fix up the parent
957 0 : parentNode->isContainer = false;
958 0 : parentNode->isOpen = false;
959 0 : mTree->InvalidateRow(NodeToRow(parentNode));
960 : }
961 :
962 0 : mTree->RowCountChanged(row, GetRowCount() - oldCount);
963 : }
964 :
965 : ///////////////////////////////////////////////////////////////////////
966 : // inDOMView
967 :
968 : //////// NODE MANAGEMENT
969 :
970 : inDOMViewNode*
971 0 : inDOMView::GetNodeAt(PRInt32 aRow)
972 : {
973 0 : return mNodes.ElementAt(aRow);
974 : }
975 :
976 : PRInt32
977 0 : inDOMView::GetRowCount()
978 : {
979 0 : return mNodes.Length();
980 : }
981 :
982 : PRInt32
983 0 : inDOMView::NodeToRow(inDOMViewNode* aNode)
984 : {
985 0 : return mNodes.IndexOf(aNode);
986 : }
987 :
988 : inDOMViewNode*
989 0 : inDOMView::CreateNode(nsIDOMNode* aNode, inDOMViewNode* aParent)
990 : {
991 0 : inDOMViewNode* viewNode = new inDOMViewNode(aNode);
992 0 : viewNode->level = aParent ? aParent->level+1 : 0;
993 0 : viewNode->parent = aParent;
994 :
995 0 : nsCOMArray<nsIDOMNode> grandKids;
996 0 : GetChildNodesFor(aNode, grandKids);
997 0 : viewNode->isContainer = (grandKids.Count() > 0);
998 0 : return viewNode;
999 : }
1000 :
1001 : bool
1002 0 : inDOMView::RowOutOfBounds(PRInt32 aRow, PRInt32 aCount)
1003 : {
1004 0 : return aRow < 0 || aRow >= GetRowCount() || aCount+aRow > GetRowCount();
1005 : }
1006 :
1007 : void
1008 0 : inDOMView::AppendNode(inDOMViewNode* aNode)
1009 : {
1010 0 : mNodes.AppendElement(aNode);
1011 0 : }
1012 :
1013 : void
1014 0 : inDOMView::InsertNode(inDOMViewNode* aNode, PRInt32 aRow)
1015 : {
1016 0 : if (RowOutOfBounds(aRow, 1))
1017 0 : AppendNode(aNode);
1018 : else
1019 0 : mNodes.InsertElementAt(aRow, aNode);
1020 0 : }
1021 :
1022 : void
1023 0 : inDOMView::RemoveNode(PRInt32 aRow)
1024 : {
1025 0 : if (RowOutOfBounds(aRow, 1))
1026 0 : return;
1027 :
1028 0 : delete GetNodeAt(aRow);
1029 0 : mNodes.RemoveElementAt(aRow);
1030 : }
1031 :
1032 : void
1033 0 : inDOMView::ReplaceNode(inDOMViewNode* aNode, PRInt32 aRow)
1034 : {
1035 0 : if (RowOutOfBounds(aRow, 1))
1036 0 : return;
1037 :
1038 0 : delete GetNodeAt(aRow);
1039 0 : mNodes.ElementAt(aRow) = aNode;
1040 : }
1041 :
1042 : void
1043 0 : inDOMView::InsertNodes(nsTArray<inDOMViewNode*>& aNodes, PRInt32 aRow)
1044 : {
1045 0 : if (aRow < 0 || aRow > GetRowCount())
1046 0 : return;
1047 :
1048 0 : mNodes.InsertElementsAt(aRow, aNodes);
1049 : }
1050 :
1051 : void
1052 0 : inDOMView::RemoveNodes(PRInt32 aRow, PRInt32 aCount)
1053 : {
1054 0 : if (aRow < 0)
1055 0 : return;
1056 :
1057 0 : PRInt32 rowCount = GetRowCount();
1058 0 : for (PRInt32 i = aRow; i < aRow+aCount && i < rowCount; ++i) {
1059 0 : delete GetNodeAt(i);
1060 : }
1061 :
1062 0 : mNodes.RemoveElementsAt(aRow, aCount);
1063 : }
1064 :
1065 : void
1066 0 : inDOMView::RemoveAllNodes()
1067 : {
1068 0 : PRInt32 rowCount = GetRowCount();
1069 0 : for (PRInt32 i = 0; i < rowCount; ++i) {
1070 0 : delete GetNodeAt(i);
1071 : }
1072 :
1073 0 : mNodes.Clear();
1074 0 : }
1075 :
1076 : void
1077 0 : inDOMView::ExpandNode(PRInt32 aRow)
1078 : {
1079 0 : inDOMViewNode* node = nsnull;
1080 0 : RowToNode(aRow, &node);
1081 :
1082 0 : nsCOMArray<nsIDOMNode> kids;
1083 : GetChildNodesFor(node ? node->node : mRootNode,
1084 0 : kids);
1085 0 : PRInt32 kidCount = kids.Count();
1086 :
1087 0 : nsTArray<inDOMViewNode*> list(kidCount);
1088 :
1089 0 : inDOMViewNode* newNode = nsnull;
1090 0 : inDOMViewNode* prevNode = nsnull;
1091 :
1092 0 : for (PRInt32 i = 0; i < kidCount; ++i) {
1093 0 : newNode = CreateNode(kids[i], node);
1094 0 : list.AppendElement(newNode);
1095 :
1096 0 : if (prevNode)
1097 0 : prevNode->next = newNode;
1098 0 : newNode->previous = prevNode;
1099 0 : prevNode = newNode;
1100 : }
1101 :
1102 0 : InsertNodes(list, aRow+1);
1103 :
1104 0 : if (node)
1105 0 : node->isOpen = true;
1106 0 : }
1107 :
1108 : void
1109 0 : inDOMView::CollapseNode(PRInt32 aRow)
1110 : {
1111 0 : inDOMViewNode* node = nsnull;
1112 0 : nsresult rv = RowToNode(aRow, &node);
1113 0 : if (NS_FAILED(rv)) {
1114 0 : return;
1115 : }
1116 :
1117 0 : PRInt32 row = 0;
1118 0 : GetLastDescendantOf(node, aRow, &row);
1119 :
1120 0 : RemoveNodes(aRow+1, row-aRow);
1121 :
1122 0 : node->isOpen = false;
1123 : }
1124 :
1125 : //////// NODE AND ROW CONVERSION
1126 :
1127 : nsresult
1128 0 : inDOMView::RowToNode(PRInt32 aRow, inDOMViewNode** aNode)
1129 : {
1130 0 : if (aRow < 0 || aRow >= GetRowCount())
1131 0 : return NS_ERROR_FAILURE;
1132 :
1133 0 : *aNode = GetNodeAt(aRow);
1134 0 : return NS_OK;
1135 : }
1136 :
1137 : nsresult
1138 0 : inDOMView::NodeToRow(nsIDOMNode* aNode, PRInt32* aRow)
1139 : {
1140 0 : PRInt32 rowCount = GetRowCount();
1141 0 : for (PRInt32 i = 0; i < rowCount; ++i) {
1142 0 : if (GetNodeAt(i)->node == aNode) {
1143 0 : *aRow = i;
1144 0 : return NS_OK;
1145 : }
1146 : }
1147 :
1148 0 : *aRow = -1;
1149 0 : return NS_ERROR_FAILURE;
1150 : }
1151 :
1152 : //////// NODE HIERARCHY MUTATION
1153 :
1154 : void
1155 0 : inDOMView::InsertLinkAfter(inDOMViewNode* aNode, inDOMViewNode* aInsertAfter)
1156 : {
1157 0 : if (aInsertAfter->next)
1158 0 : aInsertAfter->next->previous = aNode;
1159 0 : aNode->next = aInsertAfter->next;
1160 0 : aInsertAfter->next = aNode;
1161 0 : aNode->previous = aInsertAfter;
1162 0 : }
1163 :
1164 : void
1165 0 : inDOMView::InsertLinkBefore(inDOMViewNode* aNode, inDOMViewNode* aInsertBefore)
1166 : {
1167 0 : if (aInsertBefore->previous)
1168 0 : aInsertBefore->previous->next = aNode;
1169 0 : aNode->previous = aInsertBefore->previous;
1170 0 : aInsertBefore->previous = aNode;
1171 0 : aNode->next = aInsertBefore;
1172 0 : }
1173 :
1174 : void
1175 0 : inDOMView::RemoveLink(inDOMViewNode* aNode)
1176 : {
1177 0 : if (aNode->previous)
1178 0 : aNode->previous->next = aNode->next;
1179 0 : if (aNode->next)
1180 0 : aNode->next->previous = aNode->previous;
1181 0 : }
1182 :
1183 : void
1184 0 : inDOMView::ReplaceLink(inDOMViewNode* aNewNode, inDOMViewNode* aOldNode)
1185 : {
1186 0 : if (aOldNode->previous)
1187 0 : aOldNode->previous->next = aNewNode;
1188 0 : if (aOldNode->next)
1189 0 : aOldNode->next->previous = aNewNode;
1190 0 : aNewNode->next = aOldNode->next;
1191 0 : aNewNode->previous = aOldNode->previous;
1192 0 : }
1193 :
1194 : //////// NODE HIERARCHY UTILITIES
1195 :
1196 : nsresult
1197 0 : inDOMView::GetFirstDescendantOf(inDOMViewNode* aNode, PRInt32 aRow, PRInt32* aResult)
1198 : {
1199 : // get the first node that is a descendant of the previous sibling
1200 0 : PRInt32 row = 0;
1201 : inDOMViewNode* node;
1202 0 : for (row = aRow+1; row < GetRowCount(); ++row) {
1203 0 : node = GetNodeAt(row);
1204 0 : if (node->parent == aNode) {
1205 0 : *aResult = row;
1206 0 : return NS_OK;
1207 : }
1208 0 : if (node->level <= aNode->level)
1209 0 : break;
1210 : }
1211 0 : return NS_ERROR_FAILURE;
1212 : }
1213 :
1214 : nsresult
1215 0 : inDOMView::GetLastDescendantOf(inDOMViewNode* aNode, PRInt32 aRow, PRInt32* aResult)
1216 : {
1217 : // get the last node that is a descendant of the previous sibling
1218 0 : PRInt32 row = 0;
1219 0 : for (row = aRow+1; row < GetRowCount(); ++row) {
1220 0 : if (GetNodeAt(row)->level <= aNode->level)
1221 0 : break;
1222 : }
1223 0 : *aResult = row-1;
1224 0 : return NS_OK;
1225 : }
1226 :
1227 : //////// DOM UTILITIES
1228 :
1229 : nsresult
1230 0 : inDOMView::GetChildNodesFor(nsIDOMNode* aNode, nsCOMArray<nsIDOMNode>& aResult)
1231 : {
1232 0 : NS_ENSURE_ARG(aNode);
1233 : // Need to do this test to prevent unfortunate NYI assertion
1234 : // on nsXULAttribute::GetChildNodes
1235 0 : nsCOMPtr<nsIDOMAttr> attr = do_QueryInterface(aNode);
1236 0 : if (!attr) {
1237 : // attribute nodes
1238 0 : if (mWhatToShow & nsIDOMNodeFilter::SHOW_ATTRIBUTE) {
1239 0 : nsCOMPtr<nsIDOMNamedNodeMap> attrs;
1240 0 : aNode->GetAttributes(getter_AddRefs(attrs));
1241 0 : if (attrs) {
1242 0 : AppendAttrsToArray(attrs, aResult);
1243 : }
1244 : }
1245 :
1246 0 : if (mWhatToShow & nsIDOMNodeFilter::SHOW_ELEMENT) {
1247 0 : nsCOMPtr<nsIDOMNodeList> kids;
1248 0 : if (!mDOMUtils) {
1249 0 : mDOMUtils = do_GetService("@mozilla.org/inspector/dom-utils;1");
1250 0 : if (!mDOMUtils) {
1251 0 : return NS_ERROR_FAILURE;
1252 : }
1253 : }
1254 :
1255 0 : mDOMUtils->GetChildrenForNode(aNode, mShowAnonymous,
1256 0 : getter_AddRefs(kids));
1257 :
1258 0 : if (kids) {
1259 0 : AppendKidsToArray(kids, aResult);
1260 : }
1261 : }
1262 :
1263 0 : if (mShowSubDocuments) {
1264 : nsCOMPtr<nsIDOMNode> domdoc =
1265 0 : do_QueryInterface(inLayoutUtils::GetSubDocumentFor(aNode));
1266 0 : if (domdoc) {
1267 0 : aResult.AppendObject(domdoc);
1268 : }
1269 : }
1270 : }
1271 :
1272 0 : return NS_OK;
1273 : }
1274 :
1275 : nsresult
1276 0 : inDOMView::GetRealPreviousSibling(nsIDOMNode* aNode, nsIDOMNode* aRealParent, nsIDOMNode** aSibling)
1277 : {
1278 : // XXXjrh: This won't work for some cases during some situations where XBL insertion points
1279 : // are involved. Fix me!
1280 0 : aNode->GetPreviousSibling(aSibling);
1281 0 : return NS_OK;
1282 : }
1283 :
1284 : nsresult
1285 0 : inDOMView::AppendKidsToArray(nsIDOMNodeList* aKids,
1286 : nsCOMArray<nsIDOMNode>& aArray)
1287 : {
1288 0 : PRUint32 l = 0;
1289 0 : aKids->GetLength(&l);
1290 0 : nsCOMPtr<nsIDOMNode> kid;
1291 0 : PRUint16 nodeType = 0;
1292 :
1293 : // Try and get DOM Utils in case we don't have one yet.
1294 0 : if (!mShowWhitespaceNodes && !mDOMUtils) {
1295 0 : mDOMUtils = do_CreateInstance("@mozilla.org/inspector/dom-utils;1");
1296 : }
1297 :
1298 0 : for (PRUint32 i = 0; i < l; ++i) {
1299 0 : aKids->Item(i, getter_AddRefs(kid));
1300 0 : kid->GetNodeType(&nodeType);
1301 :
1302 0 : NS_ASSERTION(nodeType && nodeType <= nsIDOMNode::NOTATION_NODE,
1303 : "Unknown node type. "
1304 : "Were new types added to the spec?");
1305 : // As of DOM Level 2 Core and Traversal, each NodeFilter constant
1306 : // is defined as the lower nth bit in the NodeFilter bitmask,
1307 : // where n is the numeric constant of the nodeType it represents.
1308 : // If this invariant ever changes, we will need to update the
1309 : // following line.
1310 0 : PRUint32 filterForNodeType = 1 << (nodeType - 1);
1311 :
1312 0 : if (mWhatToShow & filterForNodeType) {
1313 0 : if ((nodeType == nsIDOMNode::TEXT_NODE ||
1314 : nodeType == nsIDOMNode::COMMENT_NODE) &&
1315 0 : !mShowWhitespaceNodes && mDOMUtils) {
1316 0 : nsCOMPtr<nsIDOMCharacterData> data = do_QueryInterface(kid);
1317 0 : NS_ASSERTION(data, "Does not implement nsIDOMCharacterData!");
1318 : bool ignore;
1319 0 : mDOMUtils->IsIgnorableWhitespace(data, &ignore);
1320 0 : if (ignore) {
1321 0 : continue;
1322 : }
1323 : }
1324 :
1325 0 : aArray.AppendObject(kid);
1326 : }
1327 : }
1328 :
1329 0 : return NS_OK;
1330 : }
1331 :
1332 : nsresult
1333 0 : inDOMView::AppendAttrsToArray(nsIDOMNamedNodeMap* aKids,
1334 : nsCOMArray<nsIDOMNode>& aArray)
1335 : {
1336 0 : PRUint32 l = 0;
1337 0 : aKids->GetLength(&l);
1338 0 : nsCOMPtr<nsIDOMNode> kid;
1339 0 : for (PRUint32 i = 0; i < l; ++i) {
1340 0 : aKids->Item(i, getter_AddRefs(kid));
1341 0 : aArray.AppendObject(kid);
1342 : }
1343 0 : return NS_OK;
1344 : }
|