~ubuntu-branches/ubuntu/precise/kompozer/precise

« back to all changes in this revision

Viewing changes to mozilla/extensions/inspector/base/src/inDeepTreeWalker.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Anthony Yarusso
  • Date: 2007-08-27 01:11:03 UTC
  • Revision ID: james.westby@ubuntu.com-20070827011103-2jgf4s6532gqu2ka
Tags: upstream-0.7.10
ImportĀ upstreamĀ versionĀ 0.7.10

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* ***** BEGIN LICENSE BLOCK *****
 
2
 * Version: NPL 1.1/GPL 2.0/LGPL 2.1
 
3
 *
 
4
 * The contents of this file are subject to the Netscape Public License
 
5
 * Version 1.1 (the "License"); you may not use this file except in
 
6
 * compliance with the License. You may obtain a copy of the License at
 
7
 * http://www.mozilla.org/NPL/
 
8
 *
 
9
 * Software distributed under the License is distributed on an "AS IS" basis,
 
10
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 
11
 * for the specific language governing rights and limitations under the
 
12
 * License.
 
13
 *
 
14
 * The Original Code is mozilla.org code.
 
15
 *
 
16
 * The Initial Developer of the Original Code is 
 
17
 * Netscape Communications Corporation.
 
18
 * Portions created by the Initial Developer are Copyright (C) 2001
 
19
 * the Initial Developer. All Rights Reserved.
 
20
 *
 
21
 * Contributor(s):
 
22
 *   Joe Hewitt <hewitt@netscape.com> (original author)
 
23
 *
 
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 NPL, 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 NPL, the GPL or the LGPL.
 
36
 *
 
37
 * ***** END LICENSE BLOCK ***** */
 
38
 
 
39
#include "inDeepTreeWalker.h"
 
40
#include "inLayoutUtils.h"
 
41
 
 
42
#include "nsString.h"
 
43
#include "nsIDOMDocument.h"
 
44
#include "nsIDOMNodeFilter.h"
 
45
#include "nsIDOMNodeList.h"
 
46
#include "nsIServiceManagerUtils.h"
 
47
#include "inIDOMUtils.h"
 
48
 
 
49
/*****************************************************************************
 
50
 * This implementation does not currently operaate according to the W3C spec.
 
51
 * So far, only parentNode() and nextNode() are implemented, and are not
 
52
 * interoperable.  
 
53
 *****************************************************************************/
 
54
 
 
55
////////////////////////////////////////////////////
 
56
 
 
57
MOZ_DECL_CTOR_COUNTER(DeepTreeStackItem)
 
58
 
 
59
struct DeepTreeStackItem 
 
60
{
 
61
  DeepTreeStackItem()  { MOZ_COUNT_CTOR(DeepTreeStackItem); }
 
62
  ~DeepTreeStackItem() { MOZ_COUNT_DTOR(DeepTreeStackItem); }
 
63
 
 
64
  nsCOMPtr<nsIDOMNode> node;
 
65
  nsCOMPtr<nsIDOMNodeList> kids;
 
66
  PRUint32 lastIndex;
 
67
};
 
68
 
 
69
////////////////////////////////////////////////////
 
70
 
 
71
inDeepTreeWalker::inDeepTreeWalker() 
 
72
  : mShowAnonymousContent(PR_FALSE),
 
73
    mShowSubDocuments(PR_FALSE),
 
74
    mWhatToShow(nsIDOMNodeFilter::SHOW_ALL)
 
75
{
 
76
}
 
77
 
 
78
inDeepTreeWalker::~inDeepTreeWalker() 
 
79
 
80
  for (PRInt32 i = mStack.Count() - 1; i >= 0; --i) {
 
81
    delete NS_STATIC_CAST(DeepTreeStackItem*, mStack[i]);
 
82
  }
 
83
}
 
84
 
 
85
NS_IMPL_ISUPPORTS1(inDeepTreeWalker, inIDeepTreeWalker)
 
86
 
 
87
////////////////////////////////////////////////////
 
88
// inIDeepTreeWalker
 
89
 
 
90
NS_IMETHODIMP
 
91
inDeepTreeWalker::GetShowAnonymousContent(PRBool *aShowAnonymousContent)
 
92
{
 
93
  *aShowAnonymousContent = mShowAnonymousContent;
 
94
  return NS_OK;
 
95
}
 
96
 
 
97
NS_IMETHODIMP
 
98
inDeepTreeWalker::SetShowAnonymousContent(PRBool aShowAnonymousContent)
 
99
{
 
100
  mShowAnonymousContent = aShowAnonymousContent;
 
101
  return NS_OK;
 
102
}
 
103
 
 
104
NS_IMETHODIMP
 
105
inDeepTreeWalker::GetShowSubDocuments(PRBool *aShowSubDocuments)
 
106
{
 
107
  *aShowSubDocuments = mShowSubDocuments;
 
108
  return NS_OK;
 
109
}
 
110
 
 
111
NS_IMETHODIMP
 
112
inDeepTreeWalker::SetShowSubDocuments(PRBool aShowSubDocuments)
 
113
{
 
114
  mShowSubDocuments = aShowSubDocuments;
 
115
  return NS_OK;
 
116
}
 
117
 
 
118
NS_IMETHODIMP
 
119
inDeepTreeWalker::Init(nsIDOMNode* aRoot, PRUint32 aWhatToShow)
 
120
{
 
121
  mRoot = aRoot;
 
122
  mWhatToShow = aWhatToShow;
 
123
  
 
124
  PushNode(aRoot);
 
125
 
 
126
  return NS_OK;
 
127
}
 
128
 
 
129
////////////////////////////////////////////////////
 
130
// nsIDOMTreeWalker
 
131
 
 
132
NS_IMETHODIMP
 
133
inDeepTreeWalker::GetRoot(nsIDOMNode** aRoot)
 
134
{
 
135
  *aRoot = mRoot;
 
136
  NS_IF_ADDREF(*aRoot);
 
137
  
 
138
  return NS_OK;
 
139
}
 
140
 
 
141
NS_IMETHODIMP 
 
142
inDeepTreeWalker::GetWhatToShow(PRUint32* aWhatToShow)
 
143
{
 
144
  *aWhatToShow = mWhatToShow;
 
145
  return NS_OK;
 
146
}
 
147
 
 
148
NS_IMETHODIMP
 
149
inDeepTreeWalker::GetFilter(nsIDOMNodeFilter** aFilter)
 
150
{
 
151
  return NS_ERROR_NOT_IMPLEMENTED;
 
152
}
 
153
 
 
154
NS_IMETHODIMP
 
155
inDeepTreeWalker::GetExpandEntityReferences(PRBool* aExpandEntityReferences)
 
156
{
 
157
  return NS_ERROR_NOT_IMPLEMENTED;
 
158
}
 
159
 
 
160
NS_IMETHODIMP
 
161
inDeepTreeWalker::GetCurrentNode(nsIDOMNode** aCurrentNode)
 
162
{
 
163
  *aCurrentNode = mCurrentNode;
 
164
  NS_IF_ADDREF(*aCurrentNode);
 
165
  
 
166
  return NS_OK;
 
167
}
 
168
 
 
169
NS_IMETHODIMP
 
170
inDeepTreeWalker::SetCurrentNode(nsIDOMNode* aCurrentNode)
 
171
{
 
172
  return NS_ERROR_NOT_IMPLEMENTED;
 
173
}
 
174
 
 
175
NS_IMETHODIMP
 
176
inDeepTreeWalker::ParentNode(nsIDOMNode** _retval)
 
177
{
 
178
  *_retval = nsnull;
 
179
  if (!mCurrentNode) return NS_OK;
 
180
 
 
181
  if (!mDOMUtils) {
 
182
    mDOMUtils = do_GetService("@mozilla.org/inspector/dom-utils;1");
 
183
    if (!mDOMUtils) {
 
184
      return NS_ERROR_OUT_OF_MEMORY;
 
185
    }
 
186
  }
 
187
 
 
188
  nsresult rv = mDOMUtils->GetParentForNode(mCurrentNode, mShowAnonymousContent,
 
189
                                            _retval);
 
190
  mCurrentNode = *_retval;
 
191
  return rv;
 
192
}
 
193
 
 
194
NS_IMETHODIMP
 
195
inDeepTreeWalker::FirstChild(nsIDOMNode **_retval)
 
196
{
 
197
  return NS_ERROR_NOT_IMPLEMENTED;
 
198
}
 
199
 
 
200
NS_IMETHODIMP
 
201
inDeepTreeWalker::LastChild(nsIDOMNode **_retval)
 
202
{
 
203
  return NS_ERROR_NOT_IMPLEMENTED;
 
204
}
 
205
 
 
206
NS_IMETHODIMP
 
207
inDeepTreeWalker::PreviousSibling(nsIDOMNode **_retval)
 
208
{
 
209
  return NS_ERROR_NOT_IMPLEMENTED;
 
210
}
 
211
 
 
212
NS_IMETHODIMP
 
213
inDeepTreeWalker::NextSibling(nsIDOMNode **_retval)
 
214
{
 
215
  return NS_ERROR_NOT_IMPLEMENTED;
 
216
}
 
217
 
 
218
NS_IMETHODIMP
 
219
inDeepTreeWalker::PreviousNode(nsIDOMNode **_retval)
 
220
{
 
221
  return NS_ERROR_NOT_IMPLEMENTED;
 
222
}
 
223
 
 
224
NS_IMETHODIMP
 
225
inDeepTreeWalker::NextNode(nsIDOMNode **_retval)
 
226
{
 
227
  if (!mCurrentNode) return NS_OK;
 
228
  
 
229
  nsCOMPtr<nsIDOMNode> next;
 
230
  
 
231
  while (1) {
 
232
    DeepTreeStackItem* top = (DeepTreeStackItem*)mStack.ElementAt(mStack.Count()-1);
 
233
    nsCOMPtr<nsIDOMNodeList> kids = top->kids;
 
234
    PRUint32 childCount;
 
235
    kids->GetLength(&childCount);
 
236
 
 
237
    if (top->lastIndex == childCount) {
 
238
      mStack.RemoveElementAt(mStack.Count()-1);
 
239
      delete top;
 
240
      if (mStack.Count() == 0) {
 
241
        mCurrentNode = nsnull;
 
242
        break;
 
243
      }
 
244
    } else {
 
245
      kids->Item(top->lastIndex++, getter_AddRefs(next));
 
246
      PushNode(next);
 
247
      break;      
 
248
    }
 
249
  } 
 
250
  
 
251
  *_retval = next;
 
252
  NS_IF_ADDREF(*_retval);
 
253
  
 
254
  return NS_OK;
 
255
}
 
256
 
 
257
void
 
258
inDeepTreeWalker::PushNode(nsIDOMNode* aNode)
 
259
{
 
260
  mCurrentNode = aNode;
 
261
  if (!aNode) return;
 
262
 
 
263
  DeepTreeStackItem* item = new DeepTreeStackItem();
 
264
  item->node = aNode;
 
265
 
 
266
  nsCOMPtr<nsIDOMNodeList> kids;
 
267
  if (mShowSubDocuments) {
 
268
    nsCOMPtr<nsIDOMDocument> domdoc = inLayoutUtils::GetSubDocumentFor(aNode);
 
269
    if (domdoc) {
 
270
      domdoc->GetChildNodes(getter_AddRefs(kids));
 
271
    }
 
272
  }
 
273
  
 
274
  if (!kids) {
 
275
    if (mShowAnonymousContent) {
 
276
      nsCOMPtr<nsIBindingManager> bindingManager = inLayoutUtils::GetBindingManagerFor(aNode);
 
277
      nsCOMPtr<nsIContent> content = do_QueryInterface(aNode);
 
278
      if (bindingManager) {
 
279
        bindingManager->GetAnonymousNodesFor(content, getter_AddRefs(kids));
 
280
        if (!kids)
 
281
          bindingManager->GetContentListFor(content, getter_AddRefs(kids));
 
282
      } else {
 
283
        aNode->GetChildNodes(getter_AddRefs(kids));
 
284
      }
 
285
    } else
 
286
      aNode->GetChildNodes(getter_AddRefs(kids));
 
287
  }
 
288
  
 
289
  item->kids = kids;
 
290
  item->lastIndex = 0;
 
291
  mStack.AppendElement((void*)item);
 
292
}
 
293
 
 
294
/*
 
295
// This NextNode implementation does not require the use of stacks, 
 
296
// as does the one above. However, it does not handle anonymous 
 
297
// content and sub-documents.
 
298
NS_IMETHODIMP
 
299
inDeepTreeWalker::NextNode(nsIDOMNode **_retval)
 
300
{
 
301
  if (!mCurrentNode) return NS_OK;
 
302
  
 
303
  // walk down the tree first
 
304
  nsCOMPtr<nsIDOMNode> next;
 
305
  mCurrentNode->GetFirstChild(getter_AddRefs(next));
 
306
  if (!next) {
 
307
    mCurrentNode->GetNextSibling(getter_AddRefs(next));
 
308
    if (!next) { 
 
309
      // we've hit the end, so walk back up the tree until another
 
310
      // downward opening is found, or the top of the tree
 
311
      nsCOMPtr<nsIDOMNode> subject = mCurrentNode;
 
312
      nsCOMPtr<nsIDOMNode> parent;
 
313
      while (1) {
 
314
        subject->GetParentNode(getter_AddRefs(parent));
 
315
        if (!parent) // hit the top of the tree
 
316
          break;
 
317
        parent->GetNextSibling(getter_AddRefs(subject));
 
318
        if (subject) { // found a downward opening
 
319
          next = subject;
 
320
          break;
 
321
        } else // walk up another level
 
322
          subject = parent;
 
323
      } 
 
324
    }
 
325
  }
 
326
  
 
327
  mCurrentNode = next;
 
328
  
 
329
  *_retval = next;
 
330
  NS_IF_ADDREF(*_retval);
 
331
  
 
332
  return NS_OK;
 
333
}
 
334
 
 
335
 
 
336
char* getURL(nsIDOMDocument* aDoc)
 
337
{
 
338
  nsCOMPtr<nsIDocument> doc = do_QueryInterface(aDoc);
 
339
  nsIURI *uri = doc->GetDocumentURI();
 
340
  char* s;
 
341
  uri->GetSpec(&s);
 
342
  return s;
 
343
}
 
344
*/