LCOV - code coverage report
Current view: directory - layout/inspector/src - inDOMView.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 596 3 0.5 %
Date: 2012-06-02 Functions: 87 1 1.1 %

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

Generated by: LCOV version 1.7