File indexing completed on 2024-04-21 14:58:47
0001 /* 0002 * util.cc - Copyright 2005 Frerich Raabe <raabe@kde.org> 0003 * 0004 * Redistribution and use in source and binary forms, with or without 0005 * modification, are permitted provided that the following conditions 0006 * are met: 0007 * 0008 * 1. Redistributions of source code must retain the above copyright 0009 * notice, this list of conditions and the following disclaimer. 0010 * 2. Redistributions in binary form must reproduce the above copyright 0011 * notice, this list of conditions and the following disclaimer in the 0012 * documentation and/or other materials provided with the distribution. 0013 * 0014 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 0015 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 0016 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 0017 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 0018 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 0019 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 0020 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 0021 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 0022 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 0023 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 0024 */ 0025 #include "util.h" 0026 #include "xml/dom_nodeimpl.h" 0027 #include "xml/dom_elementimpl.h" 0028 #include "xml/dom_nodelistimpl.h" 0029 0030 using namespace DOM; 0031 0032 namespace khtml 0033 { 0034 namespace XPath 0035 { 0036 0037 bool isRootDomNode(NodeImpl *node) 0038 { 0039 return node && !xpathParentNode(node); 0040 } 0041 0042 static QString stringValueImpl(NodeImpl *node) 0043 { 0044 // ### how different is this from textContent? 0045 // ### "The string-value of a namespace node is the namespace URI that is being bound to the namespace prefix; if it is relative, it must be resolved just like a namespace URI in an expanded-name." 0046 switch (node->nodeType()) { 0047 case Node::ATTRIBUTE_NODE: 0048 case Node::PROCESSING_INSTRUCTION_NODE: 0049 case Node::COMMENT_NODE: 0050 case Node::TEXT_NODE: 0051 case Node::CDATA_SECTION_NODE: 0052 return node->nodeValue().string(); 0053 default: 0054 if (isRootDomNode(node) 0055 || node->nodeType() == Node::ELEMENT_NODE) { 0056 QString str; 0057 0058 for (NodeImpl *cur = node->firstChild(); cur; cur = cur->traverseNextNode(node)) { 0059 // We only include the value of text kids here. 0060 int type = cur->nodeType(); 0061 if (type == Node::TEXT_NODE || type == Node::CDATA_SECTION_NODE) { 0062 str.append(stringValueImpl(cur)); 0063 } 0064 } 0065 return str; 0066 } 0067 } 0068 return QString(); 0069 } 0070 0071 DOMString stringValue(NodeImpl *node) 0072 { 0073 return stringValueImpl(node); 0074 } 0075 0076 void collectChildrenRecursively(SharedPtr<DOM::StaticNodeListImpl> out, 0077 DOM::NodeImpl *root) 0078 { 0079 // ### probably beter to use traverseNext and the like 0080 0081 NodeImpl *n = xpathFirstChild(root); 0082 while (n) { 0083 out->append(n); 0084 collectChildrenRecursively(out, n); 0085 n = n->nextSibling(); 0086 } 0087 } 0088 0089 void collectChildrenReverse(SharedPtr<DOM::StaticNodeListImpl> out, 0090 DOM::NodeImpl *root) 0091 { 0092 // ### probably beter to use traverseNext and the like 0093 0094 NodeImpl *n = xpathLastChild(root); 0095 while (n) { 0096 collectChildrenReverse(out, n); 0097 out->append(n); 0098 n = n->previousSibling(); 0099 } 0100 } 0101 0102 bool isValidContextNode(NodeImpl *node) 0103 { 0104 return node && ( 0105 node->nodeType() == Node::ELEMENT_NODE || 0106 node->nodeType() == Node::ATTRIBUTE_NODE || 0107 node->nodeType() == Node::TEXT_NODE || 0108 node->nodeType() == Node::CDATA_SECTION_NODE || 0109 node->nodeType() == Node::PROCESSING_INSTRUCTION_NODE || 0110 node->nodeType() == Node::COMMENT_NODE || 0111 node->nodeType() == Node::DOCUMENT_NODE || 0112 node->nodeType() == Node::XPATH_NAMESPACE_NODE); 0113 } 0114 0115 DOM::NodeImpl *xpathParentNode(DOM::NodeImpl *node) 0116 { 0117 DOM::NodeImpl *res = nullptr; 0118 if (node) { 0119 if (node->nodeType() == Node::ATTRIBUTE_NODE) { 0120 res = static_cast<DOM::AttrImpl *>(node)->ownerElement(); 0121 } else { 0122 res = node->parentNode(); 0123 } 0124 } 0125 return res; 0126 } 0127 0128 DOM::NodeImpl *xpathFirstChild(DOM::NodeImpl *node) 0129 { 0130 DOM::NodeImpl *res = nullptr; 0131 if (node && node->nodeType() != Node::ATTRIBUTE_NODE) { 0132 res = node->firstChild(); 0133 } 0134 return res; 0135 } 0136 0137 DOM::NodeImpl *xpathLastChild(DOM::NodeImpl *node) 0138 { 0139 DOM::NodeImpl *res = nullptr; 0140 if (node && node->nodeType() != Node::ATTRIBUTE_NODE) { 0141 res = node->lastChild(); 0142 } 0143 return res; 0144 } 0145 0146 DOM::NodeImpl *nextSiblingForFollowing(DOM::NodeImpl *node) 0147 { 0148 DOM::NodeImpl *res = nullptr; 0149 if (node) { 0150 if (node->nodeType() == Node::ATTRIBUTE_NODE) { 0151 res = static_cast<DOM::AttrImpl *>(node)->ownerElement()->firstChild(); 0152 } else { 0153 res = node->nextSibling(); 0154 } 0155 } 0156 return res; 0157 } 0158 0159 } // namespace khtml 0160 } // namespace XPath 0161