1
/* ***** BEGIN LICENSE BLOCK *****
2
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
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/
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
14
* The Original Code is mozilla.org code.
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.
22
* Joe Hewitt <hewitt@netscape.com> (original author)
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.
37
* ***** END LICENSE BLOCK ***** */
39
#include "inDeepTreeWalker.h"
40
#include "inLayoutUtils.h"
43
#include "nsIDOMDocument.h"
44
#include "nsIDOMNodeFilter.h"
45
#include "nsIDOMNodeList.h"
46
#include "nsIServiceManagerUtils.h"
47
#include "inIDOMUtils.h"
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
53
*****************************************************************************/
55
////////////////////////////////////////////////////
57
MOZ_DECL_CTOR_COUNTER(DeepTreeStackItem)
59
struct DeepTreeStackItem
61
DeepTreeStackItem() { MOZ_COUNT_CTOR(DeepTreeStackItem); }
62
~DeepTreeStackItem() { MOZ_COUNT_DTOR(DeepTreeStackItem); }
64
nsCOMPtr<nsIDOMNode> node;
65
nsCOMPtr<nsIDOMNodeList> kids;
69
////////////////////////////////////////////////////
71
inDeepTreeWalker::inDeepTreeWalker()
72
: mShowAnonymousContent(PR_FALSE),
73
mShowSubDocuments(PR_FALSE),
74
mWhatToShow(nsIDOMNodeFilter::SHOW_ALL)
78
inDeepTreeWalker::~inDeepTreeWalker()
80
for (PRInt32 i = mStack.Count() - 1; i >= 0; --i) {
81
delete NS_STATIC_CAST(DeepTreeStackItem*, mStack[i]);
85
NS_IMPL_ISUPPORTS1(inDeepTreeWalker, inIDeepTreeWalker)
87
////////////////////////////////////////////////////
91
inDeepTreeWalker::GetShowAnonymousContent(PRBool *aShowAnonymousContent)
93
*aShowAnonymousContent = mShowAnonymousContent;
98
inDeepTreeWalker::SetShowAnonymousContent(PRBool aShowAnonymousContent)
100
mShowAnonymousContent = aShowAnonymousContent;
105
inDeepTreeWalker::GetShowSubDocuments(PRBool *aShowSubDocuments)
107
*aShowSubDocuments = mShowSubDocuments;
112
inDeepTreeWalker::SetShowSubDocuments(PRBool aShowSubDocuments)
114
mShowSubDocuments = aShowSubDocuments;
119
inDeepTreeWalker::Init(nsIDOMNode* aRoot, PRUint32 aWhatToShow)
122
mWhatToShow = aWhatToShow;
129
////////////////////////////////////////////////////
133
inDeepTreeWalker::GetRoot(nsIDOMNode** aRoot)
136
NS_IF_ADDREF(*aRoot);
142
inDeepTreeWalker::GetWhatToShow(PRUint32* aWhatToShow)
144
*aWhatToShow = mWhatToShow;
149
inDeepTreeWalker::GetFilter(nsIDOMNodeFilter** aFilter)
151
return NS_ERROR_NOT_IMPLEMENTED;
155
inDeepTreeWalker::GetExpandEntityReferences(PRBool* aExpandEntityReferences)
157
return NS_ERROR_NOT_IMPLEMENTED;
161
inDeepTreeWalker::GetCurrentNode(nsIDOMNode** aCurrentNode)
163
*aCurrentNode = mCurrentNode;
164
NS_IF_ADDREF(*aCurrentNode);
170
inDeepTreeWalker::SetCurrentNode(nsIDOMNode* aCurrentNode)
172
return NS_ERROR_NOT_IMPLEMENTED;
176
inDeepTreeWalker::ParentNode(nsIDOMNode** _retval)
179
if (!mCurrentNode) return NS_OK;
182
mDOMUtils = do_GetService("@mozilla.org/inspector/dom-utils;1");
184
return NS_ERROR_OUT_OF_MEMORY;
188
nsresult rv = mDOMUtils->GetParentForNode(mCurrentNode, mShowAnonymousContent,
190
mCurrentNode = *_retval;
195
inDeepTreeWalker::FirstChild(nsIDOMNode **_retval)
197
return NS_ERROR_NOT_IMPLEMENTED;
201
inDeepTreeWalker::LastChild(nsIDOMNode **_retval)
203
return NS_ERROR_NOT_IMPLEMENTED;
207
inDeepTreeWalker::PreviousSibling(nsIDOMNode **_retval)
209
return NS_ERROR_NOT_IMPLEMENTED;
213
inDeepTreeWalker::NextSibling(nsIDOMNode **_retval)
215
return NS_ERROR_NOT_IMPLEMENTED;
219
inDeepTreeWalker::PreviousNode(nsIDOMNode **_retval)
221
return NS_ERROR_NOT_IMPLEMENTED;
225
inDeepTreeWalker::NextNode(nsIDOMNode **_retval)
227
if (!mCurrentNode) return NS_OK;
229
nsCOMPtr<nsIDOMNode> next;
232
DeepTreeStackItem* top = (DeepTreeStackItem*)mStack.ElementAt(mStack.Count()-1);
233
nsCOMPtr<nsIDOMNodeList> kids = top->kids;
235
kids->GetLength(&childCount);
237
if (top->lastIndex == childCount) {
238
mStack.RemoveElementAt(mStack.Count()-1);
240
if (mStack.Count() == 0) {
241
mCurrentNode = nsnull;
245
kids->Item(top->lastIndex++, getter_AddRefs(next));
252
NS_IF_ADDREF(*_retval);
258
inDeepTreeWalker::PushNode(nsIDOMNode* aNode)
260
mCurrentNode = aNode;
263
DeepTreeStackItem* item = new DeepTreeStackItem();
266
nsCOMPtr<nsIDOMNodeList> kids;
267
if (mShowSubDocuments) {
268
nsCOMPtr<nsIDOMDocument> domdoc = inLayoutUtils::GetSubDocumentFor(aNode);
270
domdoc->GetChildNodes(getter_AddRefs(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));
281
bindingManager->GetContentListFor(content, getter_AddRefs(kids));
283
aNode->GetChildNodes(getter_AddRefs(kids));
286
aNode->GetChildNodes(getter_AddRefs(kids));
291
mStack.AppendElement((void*)item);
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.
299
inDeepTreeWalker::NextNode(nsIDOMNode **_retval)
301
if (!mCurrentNode) return NS_OK;
303
// walk down the tree first
304
nsCOMPtr<nsIDOMNode> next;
305
mCurrentNode->GetFirstChild(getter_AddRefs(next));
307
mCurrentNode->GetNextSibling(getter_AddRefs(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;
314
subject->GetParentNode(getter_AddRefs(parent));
315
if (!parent) // hit the top of the tree
317
parent->GetNextSibling(getter_AddRefs(subject));
318
if (subject) { // found a downward opening
321
} else // walk up another level
330
NS_IF_ADDREF(*_retval);
336
char* getURL(nsIDOMDocument* aDoc)
338
nsCOMPtr<nsIDocument> doc = do_QueryInterface(aDoc);
339
nsIURI *uri = doc->GetDocumentURI();