nsresult nsXPathResult::SetExprResult(txAExprResult* aExprResult, PRUint16 aResultType) { mResultType = aResultType; if ((isSnapshot() || isIterator() || isNode()) && aExprResult->getResultType() != txAExprResult::NODESET) { return NS_ERROR_DOM_TYPE_ERR; } if (mDocument) { mDocument->RemoveObserver(this); mDocument = nsnull; } mResult.set(aExprResult); if (!isIterator()) { return NS_OK; } mInvalidIteratorState = PR_FALSE; txNodeSet* nodeSet = NS_STATIC_CAST(txNodeSet*, aExprResult); nsCOMPtr<nsIDOMNode> node; if (nodeSet->size() > 0) { nsresult rv = txXPathNativeNode::getNode(nodeSet->get(0), getter_AddRefs(node)); NS_ENSURE_SUCCESS(rv, rv); // If we support the document() function in DOM-XPath we need to // observe all documents that we have resultnodes in. nsCOMPtr<nsIDOMDocument> document; node->GetOwnerDocument(getter_AddRefs(document)); if (document) { mDocument = do_QueryInterface(document); } else { mDocument = do_QueryInterface(node); } NS_ASSERTION(mDocument, "We need a document!"); if (mDocument) { mDocument->AddObserver(this); } } return NS_OK; }
NS_IMETHODIMP nsXPathResult::IterateNext(nsIDOMNode **aResult) { if (!isIterator()) { return NS_ERROR_DOM_TYPE_ERR; } if (mDocument) { mDocument->FlushPendingNotifications(Flush_Content); } if (mInvalidIteratorState) { return NS_ERROR_DOM_INVALID_STATE_ERR; } txNodeSet *nodeSet = NS_STATIC_CAST(txNodeSet*, mResult.get()); if (mCurrentPos < (PRUint32)nodeSet->size()) { return txXPathNativeNode::getNode(nodeSet->get(mCurrentPos++), aResult); } *aResult = nsnull; return NS_OK; }
NS_IMETHODIMP nsXPathResult::GetInvalidIteratorState(PRBool *aInvalidIteratorState) { *aInvalidIteratorState = isIterator() && mInvalidIteratorState; return NS_OK; }
nsresult XPathResult::Clone(nsIXPathResult **aResult) { *aResult = nullptr; if (isIterator() && mInvalidIteratorState) { return NS_ERROR_DOM_INVALID_STATE_ERR; } NS_ADDREF(*aResult = new XPathResult(*this)); return NS_OK; }
nsresult nsXPathResult::GetExprResult(txAExprResult** aExprResult) { if (isIterator() && mInvalidIteratorState) { return NS_ERROR_DOM_INVALID_STATE_ERR; } *aExprResult = mResult.get(); if (!*aExprResult) { return NS_ERROR_DOM_INVALID_STATE_ERR; } NS_ADDREF(*aExprResult); return NS_OK; }
nsresult nsXPathResult::Clone(nsIXPathResult **aResult) { *aResult = nsnull; if (isIterator() && mInvalidIteratorState) { return NS_ERROR_DOM_INVALID_STATE_ERR; } nsCOMPtr<nsIXPathResult> result = new nsXPathResult(); if (!result) { return NS_ERROR_OUT_OF_MEMORY; } nsresult rv = result->SetExprResult(mResult.get(), mResultType); NS_ENSURE_SUCCESS(rv, rv); result.swap(*aResult); return NS_OK; }
nsresult XPathResult::GetExprResult(txAExprResult** aExprResult) { if (isIterator() && mInvalidIteratorState) { return NS_ERROR_DOM_INVALID_STATE_ERR; } if (mResult) { NS_ADDREF(*aExprResult = mResult); return NS_OK; } if (mResultNodes.Count() == 0) { return NS_ERROR_DOM_INVALID_STATE_ERR; } RefPtr<txNodeSet> nodeSet = new txNodeSet(nullptr); if (!nodeSet) { return NS_ERROR_OUT_OF_MEMORY; } uint32_t i, count = mResultNodes.Count(); for (i = 0; i < count; ++i) { nsAutoPtr<txXPathNode> node(txXPathNativeNode::createXPathNode(mResultNodes[i])); if (!node) { return NS_ERROR_OUT_OF_MEMORY; } nodeSet->append(*node); } NS_ADDREF(*aExprResult = nodeSet); return NS_OK; }
nsresult XPathResult::SetExprResult(txAExprResult* aExprResult, uint16_t aResultType, nsINode* aContextNode) { MOZ_ASSERT(aExprResult); if ((isSnapshot(aResultType) || isIterator(aResultType) || isNode(aResultType)) && aExprResult->getResultType() != txAExprResult::NODESET) { // The DOM spec doesn't really say what should happen when reusing an // XPathResult and an error is thrown. Let's not touch the XPathResult // in that case. return NS_ERROR_DOM_TYPE_ERR; } mResultType = aResultType; mContextNode = do_GetWeakReference(aContextNode); if (mDocument) { mDocument->RemoveMutationObserver(this); mDocument = nullptr; } mResultNodes.Clear(); // XXX This will keep the recycler alive, should we clear it? mResult = aExprResult; switch (mResultType) { case BOOLEAN_TYPE: { mBooleanResult = mResult->booleanValue(); break; } case NUMBER_TYPE: { mNumberResult = mResult->numberValue(); break; } case STRING_TYPE: { mResult->stringValue(mStringResult); break; } default: { MOZ_ASSERT(isNode() || isIterator() || isSnapshot()); } } if (aExprResult->getResultType() == txAExprResult::NODESET) { txNodeSet *nodeSet = static_cast<txNodeSet*>(aExprResult); int32_t i, count = nodeSet->size(); for (i = 0; i < count; ++i) { nsINode* node = txXPathNativeNode::getNode(nodeSet->get(i)); mResultNodes.AppendObject(node); } if (count > 0) { mResult = nullptr; } } if (!isIterator()) { return NS_OK; } mInvalidIteratorState = false; if (mResultNodes.Count() > 0) { // If we support the document() function in DOM-XPath we need to // observe all documents that we have resultnodes in. mDocument = mResultNodes[0]->OwnerDoc(); NS_ASSERTION(mDocument, "We need a document!"); if (mDocument) { mDocument->AddMutationObserver(this); } } return NS_OK; }