/* static */ void txXPathNodeUtils::getNodeName(const txXPathNode& aNode, nsAString& aName) { if (aNode.isDocument()) { aName.Truncate(); return; } if (aNode.isContent()) { // Elements and PIs have a name if (aNode.mNode->IsElement() || aNode.mNode->NodeType() == nsIDOMNode::PROCESSING_INSTRUCTION_NODE) { aName = aNode.Content()->NodeName(); return; } aName.Truncate(); return; } aNode.Content()->GetAttrNameAt(aNode.mIndex)->GetQualifiedName(aName); }
/* static */ void txXPathNodeUtils::appendNodeValue(const txXPathNode& aNode, nsAString& aResult) { if (aNode.isAttribute()) { const nsAttrName* name = aNode.Content()->GetAttrNameAt(aNode.mIndex); if (aResult.IsEmpty()) { aNode.Content()->GetAttr(name->NamespaceID(), name->LocalName(), aResult); } else { nsAutoString result; aNode.Content()->GetAttr(name->NamespaceID(), name->LocalName(), result); aResult.Append(result); } return; } if (aNode.isDocument() || aNode.mNode->IsElement() || aNode.mNode->IsNodeOfType(nsINode::eDOCUMENT_FRAGMENT)) { nsContentUtils::AppendNodeTextContent(aNode.mNode, true, aResult); return; } aNode.Content()->AppendTextTo(aResult); }
/* static */ already_AddRefed<nsAtom> txXPathNodeUtils::getLocalName(const txXPathNode& aNode) { if (aNode.isDocument()) { return nullptr; } if (aNode.isContent()) { if (aNode.mNode->IsElement()) { RefPtr<nsAtom> localName = aNode.Content()->NodeInfo()->NameAtom(); return localName.forget(); } if (aNode.mNode->IsNodeOfType(nsINode::ePROCESSING_INSTRUCTION)) { return NS_Atomize(aNode.mNode->NodeName()); } return nullptr; } // This is an attribute node, so we necessarily come from an element. RefPtr<nsAtom> localName = aNode.Content()->AsElement()->GetAttrNameAt(aNode.mIndex)->LocalName(); return localName.forget(); }
/* static */ already_AddRefed<nsIAtom> txXPathNodeUtils::getLocalName(const txXPathNode& aNode) { if (aNode.isDocument()) { return nsnull; } if (aNode.isContent()) { if (aNode.mNode->IsElement()) { nsIAtom* localName = aNode.Content()->Tag(); NS_ADDREF(localName); return localName; } if (aNode.mNode->IsNodeOfType(nsINode::ePROCESSING_INSTRUCTION)) { nsCOMPtr<nsIDOMNode> node = do_QueryInterface(aNode.mNode); nsAutoString target; node->GetNodeName(target); return NS_NewAtom(target); } return nsnull; } nsIAtom* localName = aNode.Content()-> GetAttrNameAt(aNode.mIndex)->LocalName(); NS_ADDREF(localName); return localName; }
/* static */ bool txXPathNodeUtils::getAttr(const txXPathNode& aNode, nsIAtom* aLocalName, PRInt32 aNSID, nsAString& aValue) { if (aNode.isDocument() || aNode.isAttribute()) { return false; } return aNode.Content()->GetAttr(aNSID, aLocalName, aValue); }
/* static */ PRUint16 txXPathNodeUtils::getNodeType(const txXPathNode& aNode) { if (aNode.isDocument()) { return txXPathNodeType::DOCUMENT_NODE; } if (aNode.isContent()) { return aNode.mNode->NodeType(); } return txXPathNodeType::ATTRIBUTE_NODE; }
/* static */ PRInt32 txXPathNodeUtils::getNamespaceID(const txXPathNode& aNode) { if (aNode.isDocument()) { return kNameSpaceID_None; } if (aNode.isContent()) { return aNode.Content()->GetNameSpaceID(); } return aNode.Content()->GetAttrNameAt(aNode.mIndex)->NamespaceID(); }
/* static */ PRUint16 txXPathNodeUtils::getNodeType(const txXPathNode& aNode) { if (aNode.isDocument()) { return txXPathNodeType::DOCUMENT_NODE; } if (aNode.isContent()) { PRUint16 type; nsCOMPtr<nsIDOMNode> node = do_QueryInterface(aNode.mNode); node->GetNodeType(&type); return type; } return txXPathNodeType::ATTRIBUTE_NODE; }
/* static */ void txXPathNodeUtils::getLocalName(const txXPathNode& aNode, nsAString& aLocalName) { if (aNode.isDocument()) { aLocalName.Truncate(); return; } if (aNode.isContent()) { if (aNode.mNode->IsNodeOfType(nsINode::eELEMENT)) { nsINodeInfo* nodeInfo = aNode.Content()->NodeInfo(); nodeInfo->GetLocalName(aLocalName); // Check for html if (nodeInfo->NamespaceEquals(kNameSpaceID_None) && aNode.mNode->IsNodeOfType(nsINode::eHTML)) { ToUpperCase(aLocalName); } return; } if (aNode.mNode->IsNodeOfType(nsINode::ePROCESSING_INSTRUCTION)) { // PIs don't have a nodeinfo but do have a name nsCOMPtr<nsIDOMNode> node = do_QueryInterface(aNode.mNode); node->GetNodeName(aLocalName); return; } aLocalName.Truncate(); return; } aNode.Content()->GetAttrNameAt(aNode.mIndex)->LocalName()-> ToString(aLocalName); // Check for html if (aNode.Content()->NodeInfo()->NamespaceEquals(kNameSpaceID_None) && aNode.Content()->IsNodeOfType(nsINode::eHTML)) { ToUpperCase(aLocalName); } }
/* static */ void txXPathNodeUtils::getNodeName(const txXPathNode& aNode, nsAString& aName) { if (aNode.isDocument()) { aName.Truncate(); return; } if (aNode.isContent()) { if (aNode.mNode->IsElement()) { nsINodeInfo* nodeInfo = aNode.Content()->NodeInfo(); nodeInfo->GetQualifiedName(aName); // Check for html if (aNode.Content()->IsHTML() && aNode.Content()->IsInHTMLDocument()) { ToUpperCase(aName); } return; } if (aNode.mNode->IsNodeOfType(nsINode::ePROCESSING_INSTRUCTION)) { // PIs don't have a nodeinfo but do have a name nsCOMPtr<nsIDOMNode> node = do_QueryInterface(aNode.mNode); node->GetNodeName(aName); return; } aName.Truncate(); return; } aNode.Content()->GetAttrNameAt(aNode.mIndex)->GetQualifiedName(aName); // Check for html if (aNode.Content()->IsHTML()) { ToUpperCase(aName); } }
/* static */ void txXPathNodeUtils::getLocalName(const txXPathNode& aNode, nsAString& aLocalName) { if (aNode.isDocument()) { aLocalName.Truncate(); return; } if (aNode.isContent()) { if (aNode.mNode->IsElement()) { mozilla::dom::NodeInfo* nodeInfo = aNode.Content()->NodeInfo(); nodeInfo->GetName(aLocalName); return; } if (aNode.mNode->IsNodeOfType(nsINode::ePROCESSING_INSTRUCTION)) { // PIs don't have a nodeinfo but do have a name // XXXbz Not actually true, but this function looks like it wants // different things from elements and PIs for "local name"... aLocalName = aNode.mNode->NodeName(); return; } aLocalName.Truncate(); return; } aNode.Content()->AsElement()->GetAttrNameAt(aNode.mIndex)->LocalName()-> ToString(aLocalName); // Check for html if (aNode.Content()->NodeInfo()->NamespaceEquals(kNameSpaceID_None) && aNode.Content()->IsHTMLElement()) { nsContentUtils::ASCIIToUpper(aLocalName); } }
/* static */ PRIntn txXPathNodeUtils::comparePosition(const txXPathNode& aNode, const txXPathNode& aOtherNode) { // First check for equal nodes or attribute-nodes on the same element. if (aNode.mNode == aOtherNode.mNode) { if (aNode.mIndex == aOtherNode.mIndex) { return 0; } NS_ASSERTION(!aNode.isDocument() && !aOtherNode.isDocument(), "documents should always have a set index"); if (aNode.isContent() || (!aOtherNode.isContent() && aNode.mIndex < aOtherNode.mIndex)) { return -1; } return 1; } // Get document for both nodes. nsIDocument* document = aNode.mNode->GetCurrentDoc(); nsIDocument* otherDocument = aOtherNode.mNode->GetCurrentDoc(); // If the nodes have different current documents, compare the document // pointers. if (document != otherDocument) { return document < otherDocument ? -1 : 1; } // Now either both nodes are in orphan trees, or they are both in the // same tree. // Get parents up the tree. nsAutoTArray<nsINode*, 8> parents, otherParents; nsINode* node = aNode.mNode; nsINode* otherNode = aOtherNode.mNode; nsINode* parent, *otherParent; while (node && otherNode) { parent = node->GetNodeParent(); otherParent = otherNode->GetNodeParent(); // Hopefully this is a common case. if (parent == otherParent) { if (!parent) { // Both node and otherNode are root nodes in respective orphan // tree. return node < otherNode ? -1 : 1; } return parent->IndexOf(node) < parent->IndexOf(otherNode) ? -1 : 1; } parents.AppendElement(node); otherParents.AppendElement(otherNode); node = parent; otherNode = otherParent; } while (node) { parents.AppendElement(node); node = node->GetNodeParent(); } while (otherNode) { otherParents.AppendElement(otherNode); otherNode = otherNode->GetNodeParent(); } // Walk back down along the parent-chains until we find where they split. PRInt32 total = parents.Length() - 1; PRInt32 otherTotal = otherParents.Length() - 1; NS_ASSERTION(total != otherTotal, "Can't have same number of parents"); PRInt32 lastIndex = NS_MIN(total, otherTotal); PRInt32 i; parent = nsnull; for (i = 0; i <= lastIndex; ++i) { node = parents.ElementAt(total - i); otherNode = otherParents.ElementAt(otherTotal - i); if (node != otherNode) { if (!parent) { // The two nodes are in different orphan subtrees. NS_ASSERTION(i == 0, "this shouldn't happen"); return node < otherNode ? -1 : 1; } PRInt32 index = parent->IndexOf(node); PRInt32 otherIndex = parent->IndexOf(otherNode); NS_ASSERTION(index != otherIndex && index >= 0 && otherIndex >= 0, "invalid index in compareTreePosition"); return index < otherIndex ? -1 : 1; } parent = node; } // One node is a descendant of the other. The one with the shortest // parent-chain is first in the document. return total < otherTotal ? -1 : 1; }