michael@0: /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- michael@0: * michael@0: * This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "nsTraversal.h" michael@0: michael@0: #include "nsIDOMNode.h" michael@0: #include "nsError.h" michael@0: #include "nsINode.h" michael@0: #include "mozilla/AutoRestore.h" michael@0: michael@0: #include "nsGkAtoms.h" michael@0: michael@0: using namespace mozilla; michael@0: using namespace mozilla::dom; michael@0: michael@0: nsTraversal::nsTraversal(nsINode *aRoot, michael@0: uint32_t aWhatToShow, michael@0: const NodeFilterHolder &aFilter) : michael@0: mRoot(aRoot), michael@0: mWhatToShow(aWhatToShow), michael@0: mFilter(aFilter), michael@0: mInAcceptNode(false) michael@0: { michael@0: NS_ASSERTION(aRoot, "invalid root in call to nsTraversal constructor"); michael@0: } michael@0: michael@0: nsTraversal::~nsTraversal() michael@0: { michael@0: /* destructor code */ michael@0: } michael@0: michael@0: /* michael@0: * Tests if and how a node should be filtered. Uses mWhatToShow and michael@0: * mFilter to test the node. michael@0: * @param aNode Node to test michael@0: * @param aResult Whether we succeeded michael@0: * @returns Filtervalue. See nsIDOMNodeFilter.idl michael@0: */ michael@0: int16_t michael@0: nsTraversal::TestNode(nsINode* aNode, mozilla::ErrorResult& aResult) michael@0: { michael@0: if (mInAcceptNode) { michael@0: aResult.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); michael@0: return 0; michael@0: } michael@0: michael@0: uint16_t nodeType = aNode->NodeType(); michael@0: michael@0: if (nodeType <= 12 && !((1 << (nodeType-1)) & mWhatToShow)) { michael@0: return nsIDOMNodeFilter::FILTER_SKIP; michael@0: } michael@0: michael@0: if (!mFilter.GetISupports()) { michael@0: // No filter, just accept michael@0: return nsIDOMNodeFilter::FILTER_ACCEPT; michael@0: } michael@0: michael@0: if (mFilter.HasWebIDLCallback()) { michael@0: AutoRestore inAcceptNode(mInAcceptNode); michael@0: mInAcceptNode = true; michael@0: return mFilter.GetWebIDLCallback()-> michael@0: AcceptNode(*aNode, aResult, CallbackObject::eRethrowExceptions); michael@0: } michael@0: michael@0: nsCOMPtr domNode = do_QueryInterface(aNode); michael@0: AutoRestore inAcceptNode(mInAcceptNode); michael@0: mInAcceptNode = true; michael@0: int16_t filtered; michael@0: nsresult rv = mFilter.GetXPCOMCallback()->AcceptNode(domNode, &filtered); michael@0: if (NS_FAILED(rv)) { michael@0: aResult.Throw(rv); michael@0: } michael@0: return filtered; michael@0: }