1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/layout/inspector/inDOMView.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,1287 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#include "inDOMView.h" 1.10 +#include "inIDOMUtils.h" 1.11 + 1.12 +#include "inLayoutUtils.h" 1.13 + 1.14 +#include "nsString.h" 1.15 +#include "nsReadableUtils.h" 1.16 +#include "nsIDOMNode.h" 1.17 +#include "nsIDOMNodeFilter.h" 1.18 +#include "nsIDOMNodeList.h" 1.19 +#include "nsIDOMCharacterData.h" 1.20 +#include "nsIDOMAttr.h" 1.21 +#include "nsIDOMMozNamedAttrMap.h" 1.22 +#include "nsIDOMMutationEvent.h" 1.23 +#include "nsBindingManager.h" 1.24 +#include "nsNameSpaceManager.h" 1.25 +#include "nsIDocument.h" 1.26 +#include "nsIServiceManager.h" 1.27 +#include "nsITreeColumns.h" 1.28 +#include "nsITreeBoxObject.h" 1.29 +#include "mozilla/dom/Element.h" 1.30 +#include "mozilla/Services.h" 1.31 + 1.32 +#ifdef ACCESSIBILITY 1.33 +#include "nsIAccessible.h" 1.34 +#include "nsIAccessibilityService.h" 1.35 +#endif 1.36 + 1.37 +using namespace mozilla; 1.38 + 1.39 +//////////////////////////////////////////////////////////////////////// 1.40 +// inDOMViewNode 1.41 + 1.42 +class inDOMViewNode 1.43 +{ 1.44 +public: 1.45 + inDOMViewNode() {} 1.46 + inDOMViewNode(nsIDOMNode* aNode); 1.47 + ~inDOMViewNode(); 1.48 + 1.49 + nsCOMPtr<nsIDOMNode> node; 1.50 + 1.51 + inDOMViewNode* parent; 1.52 + inDOMViewNode* next; 1.53 + inDOMViewNode* previous; 1.54 + 1.55 + int32_t level; 1.56 + bool isOpen; 1.57 + bool isContainer; 1.58 + bool hasAnonymous; 1.59 + bool hasSubDocument; 1.60 +}; 1.61 + 1.62 +inDOMViewNode::inDOMViewNode(nsIDOMNode* aNode) : 1.63 + node(aNode), 1.64 + parent(nullptr), 1.65 + next(nullptr), 1.66 + previous(nullptr), 1.67 + level(0), 1.68 + isOpen(false), 1.69 + isContainer(false), 1.70 + hasAnonymous(false), 1.71 + hasSubDocument(false) 1.72 +{ 1.73 + 1.74 +} 1.75 + 1.76 +inDOMViewNode::~inDOMViewNode() 1.77 +{ 1.78 +} 1.79 + 1.80 +//////////////////////////////////////////////////////////////////////// 1.81 + 1.82 +inDOMView::inDOMView() : 1.83 + mShowAnonymous(false), 1.84 + mShowSubDocuments(false), 1.85 + mShowWhitespaceNodes(true), 1.86 + mShowAccessibleNodes(false), 1.87 + mWhatToShow(nsIDOMNodeFilter::SHOW_ALL) 1.88 +{ 1.89 +} 1.90 + 1.91 +inDOMView::~inDOMView() 1.92 +{ 1.93 + SetRootNode(nullptr); 1.94 +} 1.95 + 1.96 + 1.97 +//////////////////////////////////////////////////////////////////////// 1.98 +// nsISupports 1.99 + 1.100 +NS_IMPL_ISUPPORTS(inDOMView, 1.101 + inIDOMView, 1.102 + nsITreeView, 1.103 + nsIMutationObserver) 1.104 + 1.105 +//////////////////////////////////////////////////////////////////////// 1.106 +// inIDOMView 1.107 + 1.108 +NS_IMETHODIMP 1.109 +inDOMView::GetRootNode(nsIDOMNode** aNode) 1.110 +{ 1.111 + *aNode = mRootNode; 1.112 + NS_IF_ADDREF(*aNode); 1.113 + return NS_OK; 1.114 +} 1.115 + 1.116 +NS_IMETHODIMP 1.117 +inDOMView::SetRootNode(nsIDOMNode* aNode) 1.118 +{ 1.119 + if (mTree) 1.120 + mTree->BeginUpdateBatch(); 1.121 + 1.122 + if (mRootDocument) { 1.123 + // remove previous document observer 1.124 + nsCOMPtr<nsINode> doc(do_QueryInterface(mRootDocument)); 1.125 + if (doc) 1.126 + doc->RemoveMutationObserver(this); 1.127 + } 1.128 + 1.129 + RemoveAllNodes(); 1.130 + 1.131 + mRootNode = aNode; 1.132 + 1.133 + if (aNode) { 1.134 + // If we are able to show element nodes, then start with the root node 1.135 + // as the first node in the buffer 1.136 + if (mWhatToShow & nsIDOMNodeFilter::SHOW_ELEMENT) { 1.137 + // allocate new node array 1.138 + AppendNode(CreateNode(aNode, nullptr)); 1.139 + } else { 1.140 + // place only the children of the root node in the buffer 1.141 + ExpandNode(-1); 1.142 + } 1.143 + 1.144 + // store an owning reference to document so that it isn't 1.145 + // destroyed before we are 1.146 + mRootDocument = do_QueryInterface(aNode); 1.147 + if (!mRootDocument) { 1.148 + aNode->GetOwnerDocument(getter_AddRefs(mRootDocument)); 1.149 + } 1.150 + 1.151 + // add document observer 1.152 + nsCOMPtr<nsINode> doc(do_QueryInterface(mRootDocument)); 1.153 + if (doc) 1.154 + doc->AddMutationObserver(this); 1.155 + } else { 1.156 + mRootDocument = nullptr; 1.157 + } 1.158 + 1.159 + if (mTree) 1.160 + mTree->EndUpdateBatch(); 1.161 + 1.162 + return NS_OK; 1.163 +} 1.164 + 1.165 +NS_IMETHODIMP 1.166 +inDOMView::GetNodeFromRowIndex(int32_t rowIndex, nsIDOMNode **_retval) 1.167 +{ 1.168 + inDOMViewNode* viewNode = nullptr; 1.169 + RowToNode(rowIndex, &viewNode); 1.170 + if (!viewNode) return NS_ERROR_FAILURE; 1.171 + *_retval = viewNode->node; 1.172 + NS_IF_ADDREF(*_retval); 1.173 + 1.174 + return NS_OK; 1.175 +} 1.176 + 1.177 +NS_IMETHODIMP 1.178 +inDOMView::GetRowIndexFromNode(nsIDOMNode *node, int32_t *_retval) 1.179 +{ 1.180 + NodeToRow(node, _retval); 1.181 + return NS_OK; 1.182 +} 1.183 + 1.184 + 1.185 +NS_IMETHODIMP 1.186 +inDOMView::GetShowAnonymousContent(bool *aShowAnonymousContent) 1.187 +{ 1.188 + *aShowAnonymousContent = mShowAnonymous; 1.189 + return NS_OK; 1.190 +} 1.191 + 1.192 +NS_IMETHODIMP 1.193 +inDOMView::SetShowAnonymousContent(bool aShowAnonymousContent) 1.194 +{ 1.195 + mShowAnonymous = aShowAnonymousContent; 1.196 + return NS_OK; 1.197 +} 1.198 + 1.199 +NS_IMETHODIMP 1.200 +inDOMView::GetShowSubDocuments(bool *aShowSubDocuments) 1.201 +{ 1.202 + *aShowSubDocuments = mShowSubDocuments; 1.203 + return NS_OK; 1.204 +} 1.205 + 1.206 +NS_IMETHODIMP 1.207 +inDOMView::SetShowSubDocuments(bool aShowSubDocuments) 1.208 +{ 1.209 + mShowSubDocuments = aShowSubDocuments; 1.210 + return NS_OK; 1.211 +} 1.212 + 1.213 +NS_IMETHODIMP 1.214 +inDOMView::GetShowWhitespaceNodes(bool *aShowWhitespaceNodes) 1.215 +{ 1.216 + *aShowWhitespaceNodes = mShowWhitespaceNodes; 1.217 + return NS_OK; 1.218 +} 1.219 + 1.220 +NS_IMETHODIMP 1.221 +inDOMView::SetShowWhitespaceNodes(bool aShowWhitespaceNodes) 1.222 +{ 1.223 + mShowWhitespaceNodes = aShowWhitespaceNodes; 1.224 + return NS_OK; 1.225 +} 1.226 + 1.227 +NS_IMETHODIMP 1.228 +inDOMView::GetShowAccessibleNodes(bool *aShowAccessibleNodes) 1.229 +{ 1.230 + *aShowAccessibleNodes = mShowAccessibleNodes; 1.231 + return NS_OK; 1.232 +} 1.233 + 1.234 +NS_IMETHODIMP 1.235 +inDOMView::SetShowAccessibleNodes(bool aShowAccessibleNodes) 1.236 +{ 1.237 + mShowAccessibleNodes = aShowAccessibleNodes; 1.238 + return NS_OK; 1.239 +} 1.240 + 1.241 +NS_IMETHODIMP 1.242 +inDOMView::GetWhatToShow(uint32_t *aWhatToShow) 1.243 +{ 1.244 + *aWhatToShow = mWhatToShow; 1.245 + return NS_OK; 1.246 +} 1.247 + 1.248 +NS_IMETHODIMP 1.249 +inDOMView::SetWhatToShow(uint32_t aWhatToShow) 1.250 +{ 1.251 + mWhatToShow = aWhatToShow; 1.252 + return NS_OK; 1.253 +} 1.254 + 1.255 +NS_IMETHODIMP 1.256 +inDOMView::Rebuild() 1.257 +{ 1.258 + nsCOMPtr<nsIDOMNode> root; 1.259 + GetRootNode(getter_AddRefs(root)); 1.260 + SetRootNode(root); 1.261 + return NS_OK; 1.262 +} 1.263 + 1.264 +//////////////////////////////////////////////////////////////////////// 1.265 +// nsITreeView 1.266 + 1.267 +NS_IMETHODIMP 1.268 +inDOMView::GetRowCount(int32_t *aRowCount) 1.269 +{ 1.270 + *aRowCount = GetRowCount(); 1.271 + return NS_OK; 1.272 +} 1.273 + 1.274 +NS_IMETHODIMP 1.275 +inDOMView::GetRowProperties(int32_t index, nsAString& aProps) 1.276 +{ 1.277 + return NS_OK; 1.278 +} 1.279 + 1.280 +NS_IMETHODIMP 1.281 +inDOMView::GetCellProperties(int32_t row, nsITreeColumn* col, 1.282 + nsAString& aProps) 1.283 +{ 1.284 + inDOMViewNode* node = nullptr; 1.285 + RowToNode(row, &node); 1.286 + if (!node) return NS_ERROR_FAILURE; 1.287 + 1.288 + nsCOMPtr<nsIContent> content = do_QueryInterface(node->node); 1.289 + if (content && content->IsInAnonymousSubtree()) { 1.290 + aProps.AppendLiteral("anonymous "); 1.291 + } 1.292 + 1.293 + uint16_t nodeType; 1.294 + node->node->GetNodeType(&nodeType); 1.295 + switch (nodeType) { 1.296 + case nsIDOMNode::ELEMENT_NODE: 1.297 + aProps.AppendLiteral("ELEMENT_NODE"); 1.298 + break; 1.299 + case nsIDOMNode::ATTRIBUTE_NODE: 1.300 + aProps.AppendLiteral("ATTRIBUTE_NODE"); 1.301 + break; 1.302 + case nsIDOMNode::TEXT_NODE: 1.303 + aProps.AppendLiteral("TEXT_NODE"); 1.304 + break; 1.305 + case nsIDOMNode::CDATA_SECTION_NODE: 1.306 + aProps.AppendLiteral("CDATA_SECTION_NODE"); 1.307 + break; 1.308 + case nsIDOMNode::ENTITY_REFERENCE_NODE: 1.309 + aProps.AppendLiteral("ENTITY_REFERENCE_NODE"); 1.310 + break; 1.311 + case nsIDOMNode::ENTITY_NODE: 1.312 + aProps.AppendLiteral("ENTITY_NODE"); 1.313 + break; 1.314 + case nsIDOMNode::PROCESSING_INSTRUCTION_NODE: 1.315 + aProps.AppendLiteral("PROCESSING_INSTRUCTION_NODE"); 1.316 + break; 1.317 + case nsIDOMNode::COMMENT_NODE: 1.318 + aProps.AppendLiteral("COMMENT_NODE"); 1.319 + break; 1.320 + case nsIDOMNode::DOCUMENT_NODE: 1.321 + aProps.AppendLiteral("DOCUMENT_NODE"); 1.322 + break; 1.323 + case nsIDOMNode::DOCUMENT_TYPE_NODE: 1.324 + aProps.AppendLiteral("DOCUMENT_TYPE_NODE"); 1.325 + break; 1.326 + case nsIDOMNode::DOCUMENT_FRAGMENT_NODE: 1.327 + aProps.AppendLiteral("DOCUMENT_FRAGMENT_NODE"); 1.328 + break; 1.329 + case nsIDOMNode::NOTATION_NODE: 1.330 + aProps.AppendLiteral("NOTATION_NODE"); 1.331 + break; 1.332 + } 1.333 + 1.334 +#ifdef ACCESSIBILITY 1.335 + if (mShowAccessibleNodes) { 1.336 + nsCOMPtr<nsIAccessibilityService> accService( 1.337 + do_GetService("@mozilla.org/accessibilityService;1")); 1.338 + NS_ENSURE_TRUE(accService, NS_ERROR_FAILURE); 1.339 + 1.340 + nsCOMPtr<nsIAccessible> accessible; 1.341 + nsresult rv = 1.342 + accService->GetAccessibleFor(node->node, getter_AddRefs(accessible)); 1.343 + if (NS_SUCCEEDED(rv) && accessible) 1.344 + aProps.AppendLiteral(" ACCESSIBLE_NODE"); 1.345 + } 1.346 +#endif 1.347 + 1.348 + return NS_OK; 1.349 +} 1.350 + 1.351 +NS_IMETHODIMP 1.352 +inDOMView::GetColumnProperties(nsITreeColumn* col, nsAString& aProps) 1.353 +{ 1.354 + return NS_OK; 1.355 +} 1.356 + 1.357 +NS_IMETHODIMP 1.358 +inDOMView::GetImageSrc(int32_t row, nsITreeColumn* col, nsAString& _retval) 1.359 +{ 1.360 + return NS_OK; 1.361 +} 1.362 + 1.363 +NS_IMETHODIMP 1.364 +inDOMView::GetProgressMode(int32_t row, nsITreeColumn* col, int32_t* _retval) 1.365 +{ 1.366 + return NS_OK; 1.367 +} 1.368 + 1.369 +NS_IMETHODIMP 1.370 +inDOMView::GetCellValue(int32_t row, nsITreeColumn* col, nsAString& _retval) 1.371 +{ 1.372 + return NS_OK; 1.373 +} 1.374 + 1.375 +NS_IMETHODIMP 1.376 +inDOMView::GetCellText(int32_t row, nsITreeColumn* col, nsAString& _retval) 1.377 +{ 1.378 + inDOMViewNode* node = nullptr; 1.379 + RowToNode(row, &node); 1.380 + if (!node) return NS_ERROR_FAILURE; 1.381 + 1.382 + nsIDOMNode* domNode = node->node; 1.383 + 1.384 + nsAutoString colID; 1.385 + col->GetId(colID); 1.386 + if (colID.EqualsLiteral("colNodeName")) 1.387 + domNode->GetNodeName(_retval); 1.388 + else if (colID.EqualsLiteral("colLocalName")) 1.389 + domNode->GetLocalName(_retval); 1.390 + else if (colID.EqualsLiteral("colPrefix")) 1.391 + domNode->GetPrefix(_retval); 1.392 + else if (colID.EqualsLiteral("colNamespaceURI")) 1.393 + domNode->GetNamespaceURI(_retval); 1.394 + else if (colID.EqualsLiteral("colNodeType")) { 1.395 + uint16_t nodeType; 1.396 + domNode->GetNodeType(&nodeType); 1.397 + nsAutoString temp; 1.398 + temp.AppendInt(int32_t(nodeType)); 1.399 + _retval = temp; 1.400 + } else if (colID.EqualsLiteral("colNodeValue")) 1.401 + domNode->GetNodeValue(_retval); 1.402 + else { 1.403 + if (StringBeginsWith(colID, NS_LITERAL_STRING("col@"))) { 1.404 + nsCOMPtr<nsIDOMElement> el = do_QueryInterface(node->node); 1.405 + if (el) { 1.406 + nsAutoString attr; 1.407 + colID.Right(attr, colID.Length()-4); // have to use this because Substring is crashing on me! 1.408 + el->GetAttribute(attr, _retval); 1.409 + } 1.410 + } 1.411 + } 1.412 + 1.413 + return NS_OK; 1.414 +} 1.415 + 1.416 +NS_IMETHODIMP 1.417 +inDOMView::IsContainer(int32_t index, bool *_retval) 1.418 +{ 1.419 + inDOMViewNode* node = nullptr; 1.420 + RowToNode(index, &node); 1.421 + if (!node) return NS_ERROR_FAILURE; 1.422 + 1.423 + *_retval = node->isContainer; 1.424 + return NS_OK; 1.425 +} 1.426 + 1.427 +NS_IMETHODIMP 1.428 +inDOMView::IsContainerOpen(int32_t index, bool *_retval) 1.429 +{ 1.430 + inDOMViewNode* node = nullptr; 1.431 + RowToNode(index, &node); 1.432 + if (!node) return NS_ERROR_FAILURE; 1.433 + 1.434 + *_retval = node->isOpen; 1.435 + return NS_OK; 1.436 +} 1.437 + 1.438 +NS_IMETHODIMP 1.439 +inDOMView::IsContainerEmpty(int32_t index, bool *_retval) 1.440 +{ 1.441 + inDOMViewNode* node = nullptr; 1.442 + RowToNode(index, &node); 1.443 + if (!node) return NS_ERROR_FAILURE; 1.444 + 1.445 + *_retval = node->isContainer ? false : true; 1.446 + return NS_OK; 1.447 +} 1.448 + 1.449 +NS_IMETHODIMP 1.450 +inDOMView::GetLevel(int32_t index, int32_t *_retval) 1.451 +{ 1.452 + inDOMViewNode* node = nullptr; 1.453 + RowToNode(index, &node); 1.454 + if (!node) return NS_ERROR_FAILURE; 1.455 + 1.456 + *_retval = node->level; 1.457 + return NS_OK; 1.458 +} 1.459 + 1.460 +NS_IMETHODIMP 1.461 +inDOMView::GetParentIndex(int32_t rowIndex, int32_t *_retval) 1.462 +{ 1.463 + inDOMViewNode* node = nullptr; 1.464 + RowToNode(rowIndex, &node); 1.465 + if (!node) return NS_ERROR_FAILURE; 1.466 + 1.467 + // GetParentIndex returns -1 if there is no parent 1.468 + *_retval = -1; 1.469 + 1.470 + inDOMViewNode* checkNode = nullptr; 1.471 + int32_t i = rowIndex - 1; 1.472 + do { 1.473 + nsresult rv = RowToNode(i, &checkNode); 1.474 + if (NS_FAILED(rv)) { 1.475 + // No parent. Just break out. 1.476 + break; 1.477 + } 1.478 + 1.479 + if (checkNode == node->parent) { 1.480 + *_retval = i; 1.481 + return NS_OK; 1.482 + } 1.483 + --i; 1.484 + } while (checkNode); 1.485 + 1.486 + return NS_OK; 1.487 +} 1.488 + 1.489 +NS_IMETHODIMP 1.490 +inDOMView::HasNextSibling(int32_t rowIndex, int32_t afterIndex, bool *_retval) 1.491 +{ 1.492 + inDOMViewNode* node = nullptr; 1.493 + RowToNode(rowIndex, &node); 1.494 + if (!node) return NS_ERROR_FAILURE; 1.495 + 1.496 + *_retval = node->next != nullptr; 1.497 + 1.498 + return NS_OK; 1.499 +} 1.500 + 1.501 +NS_IMETHODIMP 1.502 +inDOMView::ToggleOpenState(int32_t index) 1.503 +{ 1.504 + inDOMViewNode* node = nullptr; 1.505 + RowToNode(index, &node); 1.506 + if (!node) return NS_ERROR_FAILURE; 1.507 + 1.508 + int32_t oldCount = GetRowCount(); 1.509 + if (node->isOpen) 1.510 + CollapseNode(index); 1.511 + else 1.512 + ExpandNode(index); 1.513 + 1.514 + // Update the twisty. 1.515 + mTree->InvalidateRow(index); 1.516 + 1.517 + mTree->RowCountChanged(index+1, GetRowCount() - oldCount); 1.518 + 1.519 + return NS_OK; 1.520 +} 1.521 + 1.522 +NS_IMETHODIMP 1.523 +inDOMView::SetTree(nsITreeBoxObject *tree) 1.524 +{ 1.525 + mTree = tree; 1.526 + return NS_OK; 1.527 +} 1.528 + 1.529 +NS_IMETHODIMP 1.530 +inDOMView::GetSelection(nsITreeSelection * *aSelection) 1.531 +{ 1.532 + *aSelection = mSelection; 1.533 + NS_IF_ADDREF(*aSelection); 1.534 + return NS_OK; 1.535 +} 1.536 + 1.537 +NS_IMETHODIMP inDOMView::SetSelection(nsITreeSelection * aSelection) 1.538 +{ 1.539 + mSelection = aSelection; 1.540 + return NS_OK; 1.541 +} 1.542 + 1.543 +NS_IMETHODIMP 1.544 +inDOMView::SelectionChanged() 1.545 +{ 1.546 + return NS_OK; 1.547 +} 1.548 + 1.549 +NS_IMETHODIMP 1.550 +inDOMView::SetCellValue(int32_t row, nsITreeColumn* col, const nsAString& value) 1.551 +{ 1.552 + return NS_OK; 1.553 +} 1.554 + 1.555 +NS_IMETHODIMP 1.556 +inDOMView::SetCellText(int32_t row, nsITreeColumn* col, const nsAString& value) 1.557 +{ 1.558 + return NS_OK; 1.559 +} 1.560 + 1.561 +NS_IMETHODIMP 1.562 +inDOMView::CycleHeader(nsITreeColumn* col) 1.563 +{ 1.564 + return NS_OK; 1.565 +} 1.566 + 1.567 +NS_IMETHODIMP 1.568 +inDOMView::CycleCell(int32_t row, nsITreeColumn* col) 1.569 +{ 1.570 + return NS_OK; 1.571 +} 1.572 + 1.573 +NS_IMETHODIMP 1.574 +inDOMView::IsEditable(int32_t row, nsITreeColumn* col, bool *_retval) 1.575 +{ 1.576 + return NS_OK; 1.577 +} 1.578 + 1.579 + 1.580 +NS_IMETHODIMP 1.581 +inDOMView::IsSelectable(int32_t row, nsITreeColumn* col, bool *_retval) 1.582 +{ 1.583 + return NS_OK; 1.584 +} 1.585 + 1.586 +NS_IMETHODIMP 1.587 +inDOMView::IsSeparator(int32_t index, bool *_retval) 1.588 +{ 1.589 + return NS_OK; 1.590 +} 1.591 + 1.592 +NS_IMETHODIMP 1.593 +inDOMView::IsSorted(bool *_retval) 1.594 +{ 1.595 + return NS_OK; 1.596 +} 1.597 + 1.598 +NS_IMETHODIMP 1.599 +inDOMView::CanDrop(int32_t index, int32_t orientation, 1.600 + nsIDOMDataTransfer* aDataTransfer, bool *_retval) 1.601 +{ 1.602 + *_retval = false; 1.603 + return NS_OK; 1.604 +} 1.605 + 1.606 +NS_IMETHODIMP 1.607 +inDOMView::Drop(int32_t row, int32_t orientation, nsIDOMDataTransfer* aDataTransfer) 1.608 +{ 1.609 + return NS_OK; 1.610 +} 1.611 + 1.612 +NS_IMETHODIMP 1.613 +inDOMView::PerformAction(const char16_t *action) 1.614 +{ 1.615 + return NS_OK; 1.616 +} 1.617 + 1.618 +NS_IMETHODIMP 1.619 +inDOMView::PerformActionOnRow(const char16_t *action, int32_t row) 1.620 +{ 1.621 + return NS_OK; 1.622 +} 1.623 + 1.624 +NS_IMETHODIMP 1.625 +inDOMView::PerformActionOnCell(const char16_t* action, int32_t row, nsITreeColumn* col) 1.626 +{ 1.627 + return NS_OK; 1.628 +} 1.629 + 1.630 +/////////////////////////////////////////////////////////////////////// 1.631 +// nsIMutationObserver 1.632 + 1.633 +void 1.634 +inDOMView::NodeWillBeDestroyed(const nsINode* aNode) 1.635 +{ 1.636 + NS_NOTREACHED("Document destroyed while we're holding a strong ref to it"); 1.637 +} 1.638 + 1.639 +void 1.640 +inDOMView::AttributeChanged(nsIDocument* aDocument, dom::Element* aElement, 1.641 + int32_t aNameSpaceID, nsIAtom* aAttribute, 1.642 + int32_t aModType) 1.643 +{ 1.644 + if (!mTree) { 1.645 + return; 1.646 + } 1.647 + 1.648 + if (!(mWhatToShow & nsIDOMNodeFilter::SHOW_ATTRIBUTE)) { 1.649 + return; 1.650 + } 1.651 + 1.652 + nsCOMPtr<nsIMutationObserver> kungFuDeathGrip(this); 1.653 + 1.654 + // get the dom attribute node, if there is any 1.655 + nsCOMPtr<nsIDOMElement> el(do_QueryInterface(aElement)); 1.656 + nsCOMPtr<nsIDOMAttr> domAttr; 1.657 + nsDependentAtomString attrStr(aAttribute); 1.658 + if (aNameSpaceID) { 1.659 + nsNameSpaceManager* nsm = nsNameSpaceManager::GetInstance(); 1.660 + if (!nsm) { 1.661 + // we can't find out which attribute we want :( 1.662 + return; 1.663 + } 1.664 + nsString attrNS; 1.665 + nsresult rv = nsm->GetNameSpaceURI(aNameSpaceID, attrNS); 1.666 + if (NS_FAILED(rv)) { 1.667 + return; 1.668 + } 1.669 + (void)el->GetAttributeNodeNS(attrNS, attrStr, getter_AddRefs(domAttr)); 1.670 + } else { 1.671 + (void)el->GetAttributeNode(attrStr, getter_AddRefs(domAttr)); 1.672 + } 1.673 + 1.674 + if (aModType == nsIDOMMutationEvent::MODIFICATION) { 1.675 + // No fancy stuff here, just invalidate the changed row 1.676 + if (!domAttr) { 1.677 + return; 1.678 + } 1.679 + int32_t row = 0; 1.680 + NodeToRow(domAttr, &row); 1.681 + mTree->InvalidateRange(row, row); 1.682 + } else if (aModType == nsIDOMMutationEvent::ADDITION) { 1.683 + if (!domAttr) { 1.684 + return; 1.685 + } 1.686 + // get the number of attributes on this content node 1.687 + nsCOMPtr<nsIDOMMozNamedAttrMap> attrs; 1.688 + el->GetAttributes(getter_AddRefs(attrs)); 1.689 + uint32_t attrCount; 1.690 + attrs->GetLength(&attrCount); 1.691 + 1.692 + inDOMViewNode* contentNode = nullptr; 1.693 + int32_t contentRow; 1.694 + int32_t attrRow; 1.695 + if (mRootNode == el && 1.696 + !(mWhatToShow & nsIDOMNodeFilter::SHOW_ELEMENT)) { 1.697 + // if this view has a root node but is not displaying it, 1.698 + // it is ok to act as if the changed attribute is on the root. 1.699 + attrRow = attrCount - 1; 1.700 + } else { 1.701 + if (NS_FAILED(NodeToRow(el, &contentRow))) { 1.702 + return; 1.703 + } 1.704 + RowToNode(contentRow, &contentNode); 1.705 + if (!contentNode->isOpen) { 1.706 + return; 1.707 + } 1.708 + attrRow = contentRow + attrCount; 1.709 + } 1.710 + 1.711 + inDOMViewNode* newNode = CreateNode(domAttr, contentNode); 1.712 + inDOMViewNode* insertNode = nullptr; 1.713 + RowToNode(attrRow, &insertNode); 1.714 + if (insertNode) { 1.715 + if (contentNode && 1.716 + insertNode->level <= contentNode->level) { 1.717 + RowToNode(attrRow-1, &insertNode); 1.718 + InsertLinkAfter(newNode, insertNode); 1.719 + } else 1.720 + InsertLinkBefore(newNode, insertNode); 1.721 + } 1.722 + InsertNode(newNode, attrRow); 1.723 + mTree->RowCountChanged(attrRow, 1); 1.724 + } else if (aModType == nsIDOMMutationEvent::REMOVAL) { 1.725 + // At this point, the attribute is already gone from the DOM, but is still represented 1.726 + // in our mRows array. Search through the content node's children for the corresponding 1.727 + // node and remove it. 1.728 + 1.729 + // get the row of the content node 1.730 + inDOMViewNode* contentNode = nullptr; 1.731 + int32_t contentRow; 1.732 + int32_t baseLevel; 1.733 + if (NS_SUCCEEDED(NodeToRow(el, &contentRow))) { 1.734 + RowToNode(contentRow, &contentNode); 1.735 + baseLevel = contentNode->level; 1.736 + } else { 1.737 + if (mRootNode == el) { 1.738 + contentRow = -1; 1.739 + baseLevel = -1; 1.740 + } else 1.741 + return; 1.742 + } 1.743 + 1.744 + // search for the attribute node that was removed 1.745 + inDOMViewNode* checkNode = nullptr; 1.746 + int32_t row = 0; 1.747 + for (row = contentRow+1; row < GetRowCount(); ++row) { 1.748 + checkNode = GetNodeAt(row); 1.749 + if (checkNode->level == baseLevel+1) { 1.750 + domAttr = do_QueryInterface(checkNode->node); 1.751 + if (domAttr) { 1.752 + nsAutoString attrName; 1.753 + domAttr->GetNodeName(attrName); 1.754 + if (attrName.Equals(attrStr)) { 1.755 + // we have found the row for the attribute that was removed 1.756 + RemoveLink(checkNode); 1.757 + RemoveNode(row); 1.758 + mTree->RowCountChanged(row, -1); 1.759 + break; 1.760 + } 1.761 + } 1.762 + } 1.763 + if (checkNode->level <= baseLevel) 1.764 + break; 1.765 + } 1.766 + 1.767 + } 1.768 +} 1.769 + 1.770 +void 1.771 +inDOMView::ContentAppended(nsIDocument *aDocument, 1.772 + nsIContent* aContainer, 1.773 + nsIContent* aFirstNewContent, 1.774 + int32_t /* unused */) 1.775 +{ 1.776 + if (!mTree) { 1.777 + return; 1.778 + } 1.779 + 1.780 + for (nsIContent* cur = aFirstNewContent; cur; cur = cur->GetNextSibling()) { 1.781 + // Our ContentInserted impl doesn't use the index 1.782 + ContentInserted(aDocument, aContainer, cur, 0); 1.783 + } 1.784 +} 1.785 + 1.786 +void 1.787 +inDOMView::ContentInserted(nsIDocument *aDocument, nsIContent* aContainer, 1.788 + nsIContent* aChild, int32_t /* unused */) 1.789 +{ 1.790 + if (!mTree) 1.791 + return; 1.792 + 1.793 + nsresult rv; 1.794 + nsCOMPtr<nsIDOMNode> childDOMNode(do_QueryInterface(aChild)); 1.795 + nsCOMPtr<nsIDOMNode> parent; 1.796 + if (!mDOMUtils) { 1.797 + mDOMUtils = services::GetInDOMUtils(); 1.798 + if (!mDOMUtils) { 1.799 + return; 1.800 + } 1.801 + } 1.802 + mDOMUtils->GetParentForNode(childDOMNode, mShowAnonymous, 1.803 + getter_AddRefs(parent)); 1.804 + 1.805 + // find the inDOMViewNode for the parent of the inserted content 1.806 + int32_t parentRow = 0; 1.807 + if (NS_FAILED(rv = NodeToRow(parent, &parentRow))) 1.808 + return; 1.809 + inDOMViewNode* parentNode = nullptr; 1.810 + if (NS_FAILED(rv = RowToNode(parentRow, &parentNode))) 1.811 + return; 1.812 + 1.813 + nsCOMPtr<nsIMutationObserver> kungFuDeathGrip(this); 1.814 + 1.815 + if (!parentNode->isOpen) { 1.816 + // Parent is not open, so don't bother creating tree rows for the 1.817 + // kids. But do indicate that it's now a container, if needed. 1.818 + if (!parentNode->isContainer) { 1.819 + parentNode->isContainer = true; 1.820 + mTree->InvalidateRow(parentRow); 1.821 + } 1.822 + return; 1.823 + } 1.824 + 1.825 + // get the previous sibling of the inserted content 1.826 + nsCOMPtr<nsIDOMNode> previous; 1.827 + GetRealPreviousSibling(childDOMNode, parent, getter_AddRefs(previous)); 1.828 + inDOMViewNode* previousNode = nullptr; 1.829 + 1.830 + int32_t row = 0; 1.831 + if (previous) { 1.832 + // find the inDOMViewNode for the previous sibling of the inserted content 1.833 + int32_t previousRow = 0; 1.834 + if (NS_FAILED(rv = NodeToRow(previous, &previousRow))) 1.835 + return; 1.836 + if (NS_FAILED(rv = RowToNode(previousRow, &previousNode))) 1.837 + return; 1.838 + 1.839 + // get the last descendant of the previous row, which is the row 1.840 + // after which to insert this new row 1.841 + GetLastDescendantOf(previousNode, previousRow, &row); 1.842 + ++row; 1.843 + } else { 1.844 + // there is no previous sibling, so the new row will be inserted after the parent 1.845 + row = parentRow+1; 1.846 + } 1.847 + 1.848 + inDOMViewNode* newNode = CreateNode(childDOMNode, parentNode); 1.849 + 1.850 + if (previous) { 1.851 + InsertLinkAfter(newNode, previousNode); 1.852 + } else { 1.853 + int32_t firstChildRow; 1.854 + if (NS_SUCCEEDED(GetFirstDescendantOf(parentNode, parentRow, &firstChildRow))) { 1.855 + inDOMViewNode* firstChild; 1.856 + RowToNode(firstChildRow, &firstChild); 1.857 + InsertLinkBefore(newNode, firstChild); 1.858 + } 1.859 + } 1.860 + 1.861 + // insert new node 1.862 + InsertNode(newNode, row); 1.863 + 1.864 + mTree->RowCountChanged(row, 1); 1.865 +} 1.866 + 1.867 +void 1.868 +inDOMView::ContentRemoved(nsIDocument *aDocument, nsIContent* aContainer, 1.869 + nsIContent* aChild, int32_t aIndexInContainer, 1.870 + nsIContent* aPreviousSibling) 1.871 +{ 1.872 + if (!mTree) 1.873 + return; 1.874 + 1.875 + nsresult rv; 1.876 + 1.877 + // find the inDOMViewNode for the old child 1.878 + nsCOMPtr<nsIDOMNode> oldDOMNode(do_QueryInterface(aChild)); 1.879 + int32_t row = 0; 1.880 + if (NS_FAILED(rv = NodeToRow(oldDOMNode, &row))) 1.881 + return; 1.882 + inDOMViewNode* oldNode; 1.883 + if (NS_FAILED(rv = RowToNode(row, &oldNode))) 1.884 + return; 1.885 + 1.886 + nsCOMPtr<nsIMutationObserver> kungFuDeathGrip(this); 1.887 + 1.888 + // The parent may no longer be a container. Note that we don't want 1.889 + // to access oldNode after calling RemoveNode, so do this now. 1.890 + inDOMViewNode* parentNode = oldNode->parent; 1.891 + bool isOnlyChild = oldNode->previous == nullptr && oldNode->next == nullptr; 1.892 + 1.893 + // Keep track of how many rows we are removing. It's at least one, 1.894 + // but if we're open it's more. 1.895 + int32_t oldCount = GetRowCount(); 1.896 + 1.897 + if (oldNode->isOpen) 1.898 + CollapseNode(row); 1.899 + 1.900 + RemoveLink(oldNode); 1.901 + RemoveNode(row); 1.902 + 1.903 + if (isOnlyChild) { 1.904 + // Fix up the parent 1.905 + parentNode->isContainer = false; 1.906 + parentNode->isOpen = false; 1.907 + mTree->InvalidateRow(NodeToRow(parentNode)); 1.908 + } 1.909 + 1.910 + mTree->RowCountChanged(row, GetRowCount() - oldCount); 1.911 +} 1.912 + 1.913 +/////////////////////////////////////////////////////////////////////// 1.914 +// inDOMView 1.915 + 1.916 +//////// NODE MANAGEMENT 1.917 + 1.918 +inDOMViewNode* 1.919 +inDOMView::GetNodeAt(int32_t aRow) 1.920 +{ 1.921 + return mNodes.ElementAt(aRow); 1.922 +} 1.923 + 1.924 +int32_t 1.925 +inDOMView::GetRowCount() 1.926 +{ 1.927 + return mNodes.Length(); 1.928 +} 1.929 + 1.930 +int32_t 1.931 +inDOMView::NodeToRow(inDOMViewNode* aNode) 1.932 +{ 1.933 + return mNodes.IndexOf(aNode); 1.934 +} 1.935 + 1.936 +inDOMViewNode* 1.937 +inDOMView::CreateNode(nsIDOMNode* aNode, inDOMViewNode* aParent) 1.938 +{ 1.939 + inDOMViewNode* viewNode = new inDOMViewNode(aNode); 1.940 + viewNode->level = aParent ? aParent->level+1 : 0; 1.941 + viewNode->parent = aParent; 1.942 + 1.943 + nsCOMArray<nsIDOMNode> grandKids; 1.944 + GetChildNodesFor(aNode, grandKids); 1.945 + viewNode->isContainer = (grandKids.Count() > 0); 1.946 + return viewNode; 1.947 +} 1.948 + 1.949 +bool 1.950 +inDOMView::RowOutOfBounds(int32_t aRow, int32_t aCount) 1.951 +{ 1.952 + return aRow < 0 || aRow >= GetRowCount() || aCount+aRow > GetRowCount(); 1.953 +} 1.954 + 1.955 +void 1.956 +inDOMView::AppendNode(inDOMViewNode* aNode) 1.957 +{ 1.958 + mNodes.AppendElement(aNode); 1.959 +} 1.960 + 1.961 +void 1.962 +inDOMView::InsertNode(inDOMViewNode* aNode, int32_t aRow) 1.963 +{ 1.964 + if (RowOutOfBounds(aRow, 1)) 1.965 + AppendNode(aNode); 1.966 + else 1.967 + mNodes.InsertElementAt(aRow, aNode); 1.968 +} 1.969 + 1.970 +void 1.971 +inDOMView::RemoveNode(int32_t aRow) 1.972 +{ 1.973 + if (RowOutOfBounds(aRow, 1)) 1.974 + return; 1.975 + 1.976 + delete GetNodeAt(aRow); 1.977 + mNodes.RemoveElementAt(aRow); 1.978 +} 1.979 + 1.980 +void 1.981 +inDOMView::ReplaceNode(inDOMViewNode* aNode, int32_t aRow) 1.982 +{ 1.983 + if (RowOutOfBounds(aRow, 1)) 1.984 + return; 1.985 + 1.986 + delete GetNodeAt(aRow); 1.987 + mNodes.ElementAt(aRow) = aNode; 1.988 +} 1.989 + 1.990 +void 1.991 +inDOMView::InsertNodes(nsTArray<inDOMViewNode*>& aNodes, int32_t aRow) 1.992 +{ 1.993 + if (aRow < 0 || aRow > GetRowCount()) 1.994 + return; 1.995 + 1.996 + mNodes.InsertElementsAt(aRow, aNodes); 1.997 +} 1.998 + 1.999 +void 1.1000 +inDOMView::RemoveNodes(int32_t aRow, int32_t aCount) 1.1001 +{ 1.1002 + if (aRow < 0) 1.1003 + return; 1.1004 + 1.1005 + int32_t rowCount = GetRowCount(); 1.1006 + for (int32_t i = aRow; i < aRow+aCount && i < rowCount; ++i) { 1.1007 + delete GetNodeAt(i); 1.1008 + } 1.1009 + 1.1010 + mNodes.RemoveElementsAt(aRow, aCount); 1.1011 +} 1.1012 + 1.1013 +void 1.1014 +inDOMView::RemoveAllNodes() 1.1015 +{ 1.1016 + int32_t rowCount = GetRowCount(); 1.1017 + for (int32_t i = 0; i < rowCount; ++i) { 1.1018 + delete GetNodeAt(i); 1.1019 + } 1.1020 + 1.1021 + mNodes.Clear(); 1.1022 +} 1.1023 + 1.1024 +void 1.1025 +inDOMView::ExpandNode(int32_t aRow) 1.1026 +{ 1.1027 + inDOMViewNode* node = nullptr; 1.1028 + RowToNode(aRow, &node); 1.1029 + 1.1030 + nsCOMArray<nsIDOMNode> kids; 1.1031 + GetChildNodesFor(node ? node->node : mRootNode, 1.1032 + kids); 1.1033 + int32_t kidCount = kids.Count(); 1.1034 + 1.1035 + nsTArray<inDOMViewNode*> list(kidCount); 1.1036 + 1.1037 + inDOMViewNode* newNode = nullptr; 1.1038 + inDOMViewNode* prevNode = nullptr; 1.1039 + 1.1040 + for (int32_t i = 0; i < kidCount; ++i) { 1.1041 + newNode = CreateNode(kids[i], node); 1.1042 + list.AppendElement(newNode); 1.1043 + 1.1044 + if (prevNode) 1.1045 + prevNode->next = newNode; 1.1046 + newNode->previous = prevNode; 1.1047 + prevNode = newNode; 1.1048 + } 1.1049 + 1.1050 + InsertNodes(list, aRow+1); 1.1051 + 1.1052 + if (node) 1.1053 + node->isOpen = true; 1.1054 +} 1.1055 + 1.1056 +void 1.1057 +inDOMView::CollapseNode(int32_t aRow) 1.1058 +{ 1.1059 + inDOMViewNode* node = nullptr; 1.1060 + nsresult rv = RowToNode(aRow, &node); 1.1061 + if (NS_FAILED(rv)) { 1.1062 + return; 1.1063 + } 1.1064 + 1.1065 + int32_t row = 0; 1.1066 + GetLastDescendantOf(node, aRow, &row); 1.1067 + 1.1068 + RemoveNodes(aRow+1, row-aRow); 1.1069 + 1.1070 + node->isOpen = false; 1.1071 +} 1.1072 + 1.1073 +//////// NODE AND ROW CONVERSION 1.1074 + 1.1075 +nsresult 1.1076 +inDOMView::RowToNode(int32_t aRow, inDOMViewNode** aNode) 1.1077 +{ 1.1078 + if (aRow < 0 || aRow >= GetRowCount()) 1.1079 + return NS_ERROR_FAILURE; 1.1080 + 1.1081 + *aNode = GetNodeAt(aRow); 1.1082 + return NS_OK; 1.1083 +} 1.1084 + 1.1085 +nsresult 1.1086 +inDOMView::NodeToRow(nsIDOMNode* aNode, int32_t* aRow) 1.1087 +{ 1.1088 + int32_t rowCount = GetRowCount(); 1.1089 + for (int32_t i = 0; i < rowCount; ++i) { 1.1090 + if (GetNodeAt(i)->node == aNode) { 1.1091 + *aRow = i; 1.1092 + return NS_OK; 1.1093 + } 1.1094 + } 1.1095 + 1.1096 + *aRow = -1; 1.1097 + return NS_ERROR_FAILURE; 1.1098 +} 1.1099 + 1.1100 +//////// NODE HIERARCHY MUTATION 1.1101 + 1.1102 +void 1.1103 +inDOMView::InsertLinkAfter(inDOMViewNode* aNode, inDOMViewNode* aInsertAfter) 1.1104 +{ 1.1105 + if (aInsertAfter->next) 1.1106 + aInsertAfter->next->previous = aNode; 1.1107 + aNode->next = aInsertAfter->next; 1.1108 + aInsertAfter->next = aNode; 1.1109 + aNode->previous = aInsertAfter; 1.1110 +} 1.1111 + 1.1112 +void 1.1113 +inDOMView::InsertLinkBefore(inDOMViewNode* aNode, inDOMViewNode* aInsertBefore) 1.1114 +{ 1.1115 + if (aInsertBefore->previous) 1.1116 + aInsertBefore->previous->next = aNode; 1.1117 + aNode->previous = aInsertBefore->previous; 1.1118 + aInsertBefore->previous = aNode; 1.1119 + aNode->next = aInsertBefore; 1.1120 +} 1.1121 + 1.1122 +void 1.1123 +inDOMView::RemoveLink(inDOMViewNode* aNode) 1.1124 +{ 1.1125 + if (aNode->previous) 1.1126 + aNode->previous->next = aNode->next; 1.1127 + if (aNode->next) 1.1128 + aNode->next->previous = aNode->previous; 1.1129 +} 1.1130 + 1.1131 +void 1.1132 +inDOMView::ReplaceLink(inDOMViewNode* aNewNode, inDOMViewNode* aOldNode) 1.1133 +{ 1.1134 + if (aOldNode->previous) 1.1135 + aOldNode->previous->next = aNewNode; 1.1136 + if (aOldNode->next) 1.1137 + aOldNode->next->previous = aNewNode; 1.1138 + aNewNode->next = aOldNode->next; 1.1139 + aNewNode->previous = aOldNode->previous; 1.1140 +} 1.1141 + 1.1142 +//////// NODE HIERARCHY UTILITIES 1.1143 + 1.1144 +nsresult 1.1145 +inDOMView::GetFirstDescendantOf(inDOMViewNode* aNode, int32_t aRow, int32_t* aResult) 1.1146 +{ 1.1147 + // get the first node that is a descendant of the previous sibling 1.1148 + int32_t row = 0; 1.1149 + inDOMViewNode* node; 1.1150 + for (row = aRow+1; row < GetRowCount(); ++row) { 1.1151 + node = GetNodeAt(row); 1.1152 + if (node->parent == aNode) { 1.1153 + *aResult = row; 1.1154 + return NS_OK; 1.1155 + } 1.1156 + if (node->level <= aNode->level) 1.1157 + break; 1.1158 + } 1.1159 + return NS_ERROR_FAILURE; 1.1160 +} 1.1161 + 1.1162 +nsresult 1.1163 +inDOMView::GetLastDescendantOf(inDOMViewNode* aNode, int32_t aRow, int32_t* aResult) 1.1164 +{ 1.1165 + // get the last node that is a descendant of the previous sibling 1.1166 + int32_t row = 0; 1.1167 + for (row = aRow+1; row < GetRowCount(); ++row) { 1.1168 + if (GetNodeAt(row)->level <= aNode->level) 1.1169 + break; 1.1170 + } 1.1171 + *aResult = row-1; 1.1172 + return NS_OK; 1.1173 +} 1.1174 + 1.1175 +//////// DOM UTILITIES 1.1176 + 1.1177 +nsresult 1.1178 +inDOMView::GetChildNodesFor(nsIDOMNode* aNode, nsCOMArray<nsIDOMNode>& aResult) 1.1179 +{ 1.1180 + NS_ENSURE_ARG(aNode); 1.1181 + // attribute nodes 1.1182 + if (mWhatToShow & nsIDOMNodeFilter::SHOW_ATTRIBUTE) { 1.1183 + nsCOMPtr<nsIDOMElement> element = do_QueryInterface(aNode); 1.1184 + if (element) { 1.1185 + nsCOMPtr<nsIDOMMozNamedAttrMap> attrs; 1.1186 + element->GetAttributes(getter_AddRefs(attrs)); 1.1187 + if (attrs) { 1.1188 + AppendAttrsToArray(attrs, aResult); 1.1189 + } 1.1190 + } 1.1191 + } 1.1192 + 1.1193 + if (mWhatToShow & nsIDOMNodeFilter::SHOW_ELEMENT) { 1.1194 + nsCOMPtr<nsIDOMNodeList> kids; 1.1195 + if (!mDOMUtils) { 1.1196 + mDOMUtils = services::GetInDOMUtils(); 1.1197 + if (!mDOMUtils) { 1.1198 + return NS_ERROR_FAILURE; 1.1199 + } 1.1200 + } 1.1201 + 1.1202 + mDOMUtils->GetChildrenForNode(aNode, mShowAnonymous, 1.1203 + getter_AddRefs(kids)); 1.1204 + 1.1205 + if (kids) { 1.1206 + AppendKidsToArray(kids, aResult); 1.1207 + } 1.1208 + } 1.1209 + 1.1210 + if (mShowSubDocuments) { 1.1211 + nsCOMPtr<nsIDOMNode> domdoc = 1.1212 + do_QueryInterface(inLayoutUtils::GetSubDocumentFor(aNode)); 1.1213 + if (domdoc) { 1.1214 + aResult.AppendObject(domdoc); 1.1215 + } 1.1216 + } 1.1217 + 1.1218 + return NS_OK; 1.1219 +} 1.1220 + 1.1221 +nsresult 1.1222 +inDOMView::GetRealPreviousSibling(nsIDOMNode* aNode, nsIDOMNode* aRealParent, nsIDOMNode** aSibling) 1.1223 +{ 1.1224 + // XXXjrh: This won't work for some cases during some situations where XBL insertion points 1.1225 + // are involved. Fix me! 1.1226 + aNode->GetPreviousSibling(aSibling); 1.1227 + return NS_OK; 1.1228 +} 1.1229 + 1.1230 +nsresult 1.1231 +inDOMView::AppendKidsToArray(nsIDOMNodeList* aKids, 1.1232 + nsCOMArray<nsIDOMNode>& aArray) 1.1233 +{ 1.1234 + uint32_t l = 0; 1.1235 + aKids->GetLength(&l); 1.1236 + nsCOMPtr<nsIDOMNode> kid; 1.1237 + uint16_t nodeType = 0; 1.1238 + 1.1239 + // Try and get DOM Utils in case we don't have one yet. 1.1240 + if (!mShowWhitespaceNodes && !mDOMUtils) { 1.1241 + mDOMUtils = services::GetInDOMUtils(); 1.1242 + } 1.1243 + 1.1244 + for (uint32_t i = 0; i < l; ++i) { 1.1245 + aKids->Item(i, getter_AddRefs(kid)); 1.1246 + kid->GetNodeType(&nodeType); 1.1247 + 1.1248 + NS_ASSERTION(nodeType && nodeType <= nsIDOMNode::NOTATION_NODE, 1.1249 + "Unknown node type. " 1.1250 + "Were new types added to the spec?"); 1.1251 + // As of DOM Level 2 Core and Traversal, each NodeFilter constant 1.1252 + // is defined as the lower nth bit in the NodeFilter bitmask, 1.1253 + // where n is the numeric constant of the nodeType it represents. 1.1254 + // If this invariant ever changes, we will need to update the 1.1255 + // following line. 1.1256 + uint32_t filterForNodeType = 1 << (nodeType - 1); 1.1257 + 1.1258 + if (mWhatToShow & filterForNodeType) { 1.1259 + if ((nodeType == nsIDOMNode::TEXT_NODE || 1.1260 + nodeType == nsIDOMNode::COMMENT_NODE) && 1.1261 + !mShowWhitespaceNodes && mDOMUtils) { 1.1262 + nsCOMPtr<nsIDOMCharacterData> data = do_QueryInterface(kid); 1.1263 + NS_ASSERTION(data, "Does not implement nsIDOMCharacterData!"); 1.1264 + bool ignore; 1.1265 + mDOMUtils->IsIgnorableWhitespace(data, &ignore); 1.1266 + if (ignore) { 1.1267 + continue; 1.1268 + } 1.1269 + } 1.1270 + 1.1271 + aArray.AppendObject(kid); 1.1272 + } 1.1273 + } 1.1274 + 1.1275 + return NS_OK; 1.1276 +} 1.1277 + 1.1278 +nsresult 1.1279 +inDOMView::AppendAttrsToArray(nsIDOMMozNamedAttrMap* aAttributes, 1.1280 + nsCOMArray<nsIDOMNode>& aArray) 1.1281 +{ 1.1282 + uint32_t l = 0; 1.1283 + aAttributes->GetLength(&l); 1.1284 + nsCOMPtr<nsIDOMAttr> attribute; 1.1285 + for (uint32_t i = 0; i < l; ++i) { 1.1286 + aAttributes->Item(i, getter_AddRefs(attribute)); 1.1287 + aArray.AppendObject(attribute); 1.1288 + } 1.1289 + return NS_OK; 1.1290 +}