• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdelibs-4.14.38 API Reference
  • KDE Home
  • Contact Us
 

KHTML

  • khtml
  • xpath
step.cpp
Go to the documentation of this file.
1/*
2 * step.cc - Copyright 2005 Frerich Raabe <raabe@kde.org>
3 * Copyright 2010 Maksim Orlovich <maksim@kde.org>
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26#include "step.h"
27
28#include "dom/dom3_xpath.h"
29#include "xml/dom_docimpl.h"
30#include "xml/dom_nodeimpl.h"
31#include "xml/dom_textimpl.h"
32#include "xml/dom3_xpathimpl.h"
33
34#include "step.h"
35
36#include <QtDebug>
37
38using namespace DOM;
39using namespace DOM::XPath;
40using namespace khtml;
41using namespace khtml::XPath;
42
43
44static bool areAdjacentTextNodes( NodeImpl *n, NodeImpl *m )
45{
46 if ( !n || !m ) {
47 return false;
48 }
49
50 if ( n->nodeType() != Node::TEXT_NODE && n->nodeType() != Node::CDATA_SECTION_NODE ) {
51 return false;
52 }
53 if ( m->nodeType() != Node::TEXT_NODE && m->nodeType() != Node::CDATA_SECTION_NODE ) {
54 return false;
55 }
56
57 // ###
58#ifdef __GNUC__
59#warning "Might need more generic adjacency -- check"
60#endif
61
62 return ( n->nextSibling() && ( n->nextSibling() == m ) ) ||
63 ( m->nextSibling() && ( m->nextSibling() == n ) );
64}
65
66static DomNodeList compressTextNodes( const DomNodeList &nodes )
67{
68 DomNodeList outNodes = new StaticNodeListImpl;
69
70 for ( unsigned long n = 0; n < nodes->length(); ++n) {
71 NodeImpl* node = nodes->item( n );
72 NodeImpl* next = n+1 < nodes->length() ? nodes->item( n+1 ) : 0;
73
74 if ( !next || !areAdjacentTextNodes( node, next ) ) {
75 outNodes->append( node );
76 } else if ( areAdjacentTextNodes( node, next ) ) {
77 QString s = node->nodeValue().string();
78
79 // n2 is a potential successor, and is always in-range
80 unsigned long n2 = n+1;
81 while (n2 < nodes->length() && areAdjacentTextNodes( nodes->item( n2 ), nodes->item( n2-1) ) ) {
82 s += nodes->item( n2 )->nodeValue().string();
83 ++n2;
84 }
85 outNodes->append( node->document()->createTextNode( new DOMStringImpl( s.data(), s.length() ) ) );
86 }
87 }
88 return outNodes;
89}
90
91QString Step::axisAsString( AxisType axis )
92{
93 switch ( axis ) {
94 case AncestorAxis: return "ancestor";
95 case AncestorOrSelfAxis: return "ancestor-or-self";
96 case AttributeAxis: return "attribute";
97 case ChildAxis: return "child";
98 case DescendantAxis: return "descendant";
99 case DescendantOrSelfAxis: return "descendant-or-self";
100 case FollowingAxis: return "following";
101 case FollowingSiblingAxis: return "following-sibling";
102 case NamespaceAxis: return "namespace";
103 case ParentAxis: return "parent";
104 case PrecedingAxis: return "preceding";
105 case PrecedingSiblingAxis: return "preceding-sibling";
106 case SelfAxis: return "self";
107 }
108 return QString();
109}
110
111Step::Step(): m_compileState( NotCompiled )
112{
113}
114
115Step::Step( AxisType axis, const DOMString &nodeTest,
116 const QList<Predicate *> &predicates )
117 : m_axis( axis ),
118 m_nodeTest( nodeTest ),
119 m_compileState( NotCompiled ),
120 m_predicates( predicates )
121{
122}
123
124Step::~Step()
125{
126 qDeleteAll( m_predicates );
127}
128
129DomNodeList Step::evaluate( NodeImpl *context ) const
130{
131 assert( context );
132#ifdef XPATH_VERBOSE
133 kDebug(6011) << "Evaluating step, axis='" << axisAsString( m_axis ) <<"'"
134 << ", nodetest='" << m_nodeTest << "'"
135 << ", " << m_predicates.count() << " predicates";
136 kDebug(6011) << DOM::getPrintableName( context->id() );
137#endif
138
139 DomNodeList inNodes = nodesInAxis( context ), outNodes;
140
141 // ### optimization opportunity: can say DocumentOrder for most
142 StaticNodeListImpl::NormalizationKind known = StaticNodeListImpl::AxisOrder;
143 inNodes->setKnownNormalization(known);
144
145#ifdef XPATH_VERBOSE
146 kDebug(6011) << "Axis " << axisAsString( m_axis ) << " matches " << inNodes->length() << " nodes.";
147#endif
148
149 inNodes = nodeTestMatches( context, inNodes );
150 inNodes->setKnownNormalization(known); // nodeTest doesn't change order
151
152#ifdef XPATH_VERBOSE
153 kDebug(6011) << "\tNodetest " << m_nodeTest << " trims this number to " << inNodes->length();
154#endif
155
156 if ( m_predicates.isEmpty() )
157 return inNodes;
158
159 foreach( Predicate *predicate, m_predicates ) {
160 outNodes = new StaticNodeListImpl;
161 Expression::evaluationContext().size = int(inNodes->length());
162 Expression::evaluationContext().position = 1;
163
164 for ( unsigned long n = 0; n < inNodes->length(); ++n ) {
165 NodeImpl* node = inNodes->item( n );
166 Expression::evaluationContext().node = node;
167 EvaluationContext backupCtx = Expression::evaluationContext();
168#ifdef XPATH_VERBOSE
169 kDebug() << Expression::evaluationContext().position << "/" << node;
170#endif
171 if ( predicate->evaluate() ) {
172 outNodes->append( node );
173 }
174 Expression::evaluationContext() = backupCtx;
175 ++Expression::evaluationContext().position;
176 }
177#ifdef XPATH_VERBOSE
178 kDebug(6011) << "\tPredicate trims this number to " << outNodes->length();
179#endif
180 inNodes = outNodes;
181 inNodes->setKnownNormalization(known); // predicates don't change order
182 }
183
184 return outNodes;
185}
186
187DomNodeList Step::nodesInAxis( NodeImpl *context ) const
188{
189 //assert(context);
190 DomNodeList nodes = new StaticNodeListImpl;
191 switch ( m_axis ) {
192 case ChildAxis: {
193 NodeImpl *n = xpathFirstChild( context );
194 while ( n ) {
195 nodes->append( n );
196 n = n->nextSibling();
197 }
198 return nodes;
199 }
200 case DescendantAxis: {
201 collectChildrenRecursively( nodes, context );
202 return nodes;
203 }
204 case ParentAxis: {
205 NodeImpl* p = xpathParentNode( context );
206
207 if ( p )
208 nodes->append( p );
209 return nodes;
210 }
211 case AncestorAxis: {
212 NodeImpl *n = xpathParentNode( context );
213 while ( n ) {
214 nodes->append( n );
215 n = xpathParentNode( n );
216 }
217 return nodes;
218 }
219 case FollowingSiblingAxis: {
220 if ( context->nodeType() == Node::ATTRIBUTE_NODE ||
221 context->nodeType() == Node::XPATH_NAMESPACE_NODE ) {
222 return nodes; // empty
223 }
224
225 NodeImpl *n = context->nextSibling();
226 while ( n ) {
227 nodes->append( n );
228 n = n->nextSibling();
229 }
230 return nodes;
231 }
232 case PrecedingSiblingAxis: {
233 if ( context->nodeType() == Node::ATTRIBUTE_NODE ||
234 context->nodeType() == Node::XPATH_NAMESPACE_NODE ) {
235 return nodes; // empty
236 }
237
238 NodeImpl *n = context->previousSibling();
239 while ( n ) {
240 nodes->append( n );
241 n = n->previousSibling();
242 }
243 return nodes;
244 }
245 case FollowingAxis: {
246 NodeImpl *p = context;
247 while ( !isRootDomNode( p ) ) {
248 NodeImpl *n = nextSiblingForFollowing( p );
249 while ( n ) {
250 nodes->append( n );
251 collectChildrenRecursively( nodes, n );
252 n = n->nextSibling();
253 }
254 p = xpathParentNode( p );
255 }
256 return nodes;
257 }
258 case PrecedingAxis: {
259 NodeImpl *p = context;
260 while ( !isRootDomNode( p ) ) {
261 NodeImpl *n = p->previousSibling();
262 while ( n ) {
263 collectChildrenReverse( nodes, n );
264 nodes->append( n );
265 n = n->previousSibling();
266 }
267 p = xpathParentNode( p );
268 }
269 return nodes;
270 }
271 case AttributeAxis: {
272 if ( context->nodeType() != Node::ELEMENT_NODE ) {
273 return nodes; // empty
274 }
275
276 NamedAttrMapImpl *attrs = static_cast<ElementImpl*>(context)->attributes( true /*read-only*/ );
277 if ( !attrs ) {
278 return nodes;
279 }
280
281 for ( unsigned long i = 0; i < attrs->length(); ++i ) {
282 nodes->append( attrs->item( i ) );
283 }
284 return nodes;
285 }
286 case NamespaceAxis: {
287 // ### TODO: Need to implement this, but not a priority, since
288 // other impls don't.
289#if 0
290 if ( context->nodeType() != Node::ELEMENT_NODE ) {
291 return nodes;
292 }
293
294 bool foundXmlNsNode = false;
295 NodeImpl *node = context;
296 while ( node ) {
297 NamedAttrMapImpl *attrs =
298 node->isElementNode() ? static_cast<ElementImpl*>(node)->attributes() : 0;
299 if ( !attrs ) {
300 node = xpathParentNode( node );
301 continue;
302 }
303
304 for ( unsigned long i = 0; i < attrs->length(); ++i ) {
305 NodeImpl *n = attrs->item( i );
306 if ( n->nodeName().string().startsWith( "xmlns:" ) ) {
307 nodes->append( n );
308 } else if ( n->nodeName() == "xmlns" &&
309 !foundXmlNsNode
310 ) {
311 foundXmlNsNode = true;
312 if ( !n->nodeValue().string().isEmpty() ) {
313 nodes->append( n );
314 }
315 }
316 }
317 node = xpathParentNode( node );
318 }
319#endif
320 return nodes;
321 }
322 case SelfAxis:
323 nodes->append( context );
324 return nodes;
325 case DescendantOrSelfAxis:
326 nodes->append( context );
327 collectChildrenRecursively( nodes, context );
328 return nodes;
329 case AncestorOrSelfAxis: {
330 nodes->append( context );
331 NodeImpl *n = xpathParentNode( context );
332 while ( n ) {
333 nodes->append( n );
334 n = xpathParentNode( n );
335 }
336 return nodes;
337 }
338 default:
339 kWarning(6011) << "Unknown axis " << axisAsString( m_axis ) << " passed to Step::nodesInAxis";
340 }
341
342 return nodes; // empty
343}
344
345void Step::compileNodeTest(bool htmlCompat) const
346{
347 m_compileState = htmlCompat ? CompiledForHTML : CompiledForXML;
348
349 if ( m_nodeTest == "*" ) {
350 m_nodeTestType = NT_Star;
351 } else if ( m_nodeTest == "text()" ) {
352 m_nodeTestType = NT_Text;
353 } else if ( m_nodeTest == "comment()" ) {
354 m_nodeTestType = NT_Comment;
355 } else if ( m_nodeTest.startsWith( "processing-instruction" ) ) {
356 DOMString param;
357
358 // ### is this right? (parens?)
359 const int space = m_nodeTest.find( ' ' );
360 if ( space > -1 ) {
361 param = m_nodeTest.substring( space + 1 );
362 }
363
364 if ( param.isEmpty() ) {
365 m_nodeTestType = NT_PI;
366 } else {
367 m_nodeTestType = NT_PI_Lit;
368 m_piInfo = param;
369 }
370 } else if ( m_nodeTest == "node()" ) {
371 m_nodeTestType = NT_AnyNode;
372 } else {
373 // Some sort of name combo.
374 PrefixName prefix;
375 LocalName localName;
376
377 splitPrefixLocalName( m_nodeTest, prefix, localName, htmlCompat );
378
379 if ( prefix.id() == DOM::emptyPrefix ) {
380 // localname only
381 m_nodeTestType = NT_LocalName;
382 m_localName = localName;
383 } else if ( localName.toString() == "*" ) {
384 // namespace only
385 m_nodeTestType = NT_Namespace;
386 m_namespace = NamespaceName::fromString(namespaceFromNodetest( m_nodeTest ) );
387 } else {
388 // Both parts.
389 m_nodeTestType = NT_QName;
390 m_localName = localName;
391 m_namespace = NamespaceName::fromString(namespaceFromNodetest( m_nodeTest ) );
392 }
393 }
394}
395
396DomNodeList Step::nodeTestMatches( NodeImpl* ctx, const DomNodeList &nodes ) const
397{
398 CompileState desired = ctx->htmlCompat() ? CompiledForHTML : CompiledForXML;
399 if ( m_compileState != desired )
400 compileNodeTest( ctx->htmlCompat() );
401
402 if ( m_nodeTestType == NT_AnyNode) // no need for a new set
403 return nodes;
404
405 DomNodeList matches = new StaticNodeListImpl;
406
407 // A lot of things can be handled by just checking the type,
408 // and maybe a hair more special handling
409 int matchType;
410 switch ( m_nodeTestType ) {
411 case NT_Star:
412 matchType = primaryNodeType( m_axis );
413 break;
414 case NT_Comment:
415 matchType = Node::COMMENT_NODE;
416 break;
417 case NT_Text:
418 matchType = Node::TEXT_NODE;
419 break;
420 case NT_PI:
421 case NT_PI_Lit:
422 matchType = Node::PROCESSING_INSTRUCTION_NODE;
423 break;
424 default:
425 matchType = -1;
426 }
427
428 if ( matchType != -1 ) {
429 for ( unsigned long n = 0; n < nodes->length(); ++n ) {
430 NodeImpl *node = nodes->item( n );
431 int nodeType = node->nodeType();
432 if ( nodeType == matchType ) {
433 if ( m_nodeTestType == NT_PI_Lit && node->nodeName() != m_piInfo )
434 continue;
435
436 matches->append( node );
437 }
438
439 if ( matchType == NT_Text && nodeType == Node::CDATA_SECTION_NODE )
440 matches->append( node );
441 }
442 return matches;
443 }
444
445 // Now we are checking by name. We always want to filter out
446 // the primary axis here
447 // ### CHECK: this used to have special handling for some axes.
448 matchType = primaryNodeType( m_axis );
449 for ( unsigned long n = 0; n < nodes->length(); ++n ) {
450 NodeImpl *node = nodes->item( n );
451 if ( node->nodeType() != matchType )
452 continue;
453
454 if ( m_nodeTestType == NT_LocalName ) {
455 if ( localNamePart( node->id() ) == m_localName.id() )
456 matches->append( node );
457 } else if ( m_nodeTestType == NT_Namespace ) {
458 if ( namespacePart( node->id() ) == m_namespace.id() )
459 matches->append( node );
460 } else {
461 // NT_QName
462 if ( node->id() == makeId( m_namespace.id(), m_localName.id() ) )
463 matches->append( node );
464 }
465 }
466 return matches;
467}
468
469void Step::optimize()
470{
471 foreach( Predicate *predicate, m_predicates ) {
472 predicate->optimize();
473 }
474}
475
476QString Step::dump() const
477{
478 QString s = QString( "<step axis=\"%1\" nodetest=\"%2\">" ).arg( axisAsString( m_axis ) ).arg( m_nodeTest.string() );
479 foreach( Predicate *predicate, m_predicates ) {
480 s += predicate->dump();
481 }
482 s += "</step>";
483 return s;
484}
485
486DOMString Step::namespaceFromNodetest( const DOMString &nodeTest ) const
487{
488 int i = nodeTest.find( ':' );
489 if ( i == -1 ) {
490 return DOMString();
491 }
492
493 DOMString prefix( nodeTest.substring( 0, i ) );
494 XPathNSResolverImpl *resolver = Expression::evaluationContext().resolver;
495
496 DOM::DOMString ns;
497 if (resolver)
498 ns = resolver->lookupNamespaceURI( prefix );
499
500 if ( ns.isNull() )
501 Expression::reportNamespaceErr();
502
503 return ns;
504}
505
506unsigned int Step::primaryNodeType( AxisType axis ) const
507{
508 switch ( axis ) {
509 case AttributeAxis:
510 return Node::ATTRIBUTE_NODE;
511 case NamespaceAxis:
512 return Node::XPATH_NAMESPACE_NODE;
513 default:
514 return Node::ELEMENT_NODE;
515 }
516}
517
518// kate: indent-width 4; replace-tabs off; tab-width 4; space-indent off;
DOM::DOMString
This class implements the basic string we use in the DOM.
Definition: dom_string.h:44
DOM::DOMString::length
uint length() const
Definition: dom_string.cpp:185
DOM::DOMString::startsWith
bool startsWith(const DOMString &str) const
Definition: dom_string.cpp:287
DOM::DOMString::find
int find(const QChar c, int start=0) const
Definition: dom_string.cpp:154
DOM::DOMString::substring
DOMString substring(unsigned pos, unsigned len=UINT_MAX) const
Definition: dom_string.cpp:180
DOM::DOMString::isNull
bool isNull() const
Definition: dom_string.h:121
DOM::DOMString::string
QString string() const
Definition: dom_string.cpp:236
DOM::Node::XPATH_NAMESPACE_NODE
@ XPATH_NAMESPACE_NODE
Definition: dom_node.h:394
DOM::Node::ELEMENT_NODE
@ ELEMENT_NODE
Definition: dom_node.h:382
DOM::Node::COMMENT_NODE
@ COMMENT_NODE
Definition: dom_node.h:389
DOM::Node::PROCESSING_INSTRUCTION_NODE
@ PROCESSING_INSTRUCTION_NODE
Definition: dom_node.h:388
DOM::Node::CDATA_SECTION_NODE
@ CDATA_SECTION_NODE
Definition: dom_node.h:385
DOM::Node::TEXT_NODE
@ TEXT_NODE
Definition: dom_node.h:384
DOM::Node::ATTRIBUTE_NODE
@ ATTRIBUTE_NODE
Definition: dom_node.h:383
QList
khtml::XPath::Expression::evaluationContext
static EvaluationContext & evaluationContext()
Definition: expression.cpp:212
khtml::XPath::Expression::reportNamespaceErr
static void reportNamespaceErr()
Definition: expression.cpp:293
khtml::XPath::Predicate
Definition: predicate.h:149
khtml::XPath::Predicate::dump
QString dump() const
Definition: predicate.cpp:435
khtml::XPath::Predicate::optimize
void optimize()
Definition: predicate.cpp:430
khtml::XPath::Predicate::evaluate
bool evaluate() const
Definition: predicate.cpp:416
khtml::XPath::Step::optimize
void optimize()
Definition: step.cpp:469
khtml::XPath::Step::axisAsString
static QString axisAsString(AxisType axis)
Definition: step.cpp:91
khtml::XPath::Step::Step
Step()
Definition: step.cpp:111
khtml::XPath::Step::evaluate
DomNodeList evaluate(DOM::NodeImpl *context) const
Definition: step.cpp:129
khtml::XPath::Step::dump
QString dump() const
Definition: step.cpp:476
khtml::XPath::Step::~Step
~Step()
Definition: step.cpp:124
khtml::XPath::Step::AxisType
AxisType
Definition: step.h:45
khtml::XPath::Step::NamespaceAxis
@ NamespaceAxis
Definition: step.h:48
khtml::XPath::Step::PrecedingAxis
@ PrecedingAxis
Definition: step.h:49
khtml::XPath::Step::ParentAxis
@ ParentAxis
Definition: step.h:49
khtml::XPath::Step::ChildAxis
@ ChildAxis
Definition: step.h:47
khtml::XPath::Step::AttributeAxis
@ AttributeAxis
Definition: step.h:46
khtml::XPath::Step::PrecedingSiblingAxis
@ PrecedingSiblingAxis
Definition: step.h:49
khtml::XPath::Step::FollowingSiblingAxis
@ FollowingSiblingAxis
Definition: step.h:48
khtml::XPath::Step::DescendantAxis
@ DescendantAxis
Definition: step.h:47
khtml::XPath::Step::AncestorOrSelfAxis
@ AncestorOrSelfAxis
Definition: step.h:46
khtml::XPath::Step::DescendantOrSelfAxis
@ DescendantOrSelfAxis
Definition: step.h:47
khtml::XPath::Step::FollowingAxis
@ FollowingAxis
Definition: step.h:48
khtml::XPath::Step::SelfAxis
@ SelfAxis
Definition: step.h:50
khtml::XPath::Step::AncestorAxis
@ AncestorAxis
Definition: step.h:46
dom3_xpath.h
assert
#define assert(x)
Definition: editor.cpp:43
kDebug
#define kDebug
kWarning
#define kWarning
param
QString param(const QString &t)
prefix
QString prefix()
DOM::XPath
Definition: dom3_xpath.h:56
DOM
This library provides a full-featured HTML parser and widget.
Definition: design.h:55
next
KAction * next(const QObject *recvr, const char *slot, QObject *parent)
khtml::XPath
Definition: expression.h:45
khtml::XPath::collectChildrenReverse
void collectChildrenReverse(SharedPtr< DOM::StaticNodeListImpl > out, DOM::NodeImpl *root)
Definition: util.cpp:86
khtml::XPath::xpathFirstChild
DOM::NodeImpl * xpathFirstChild(DOM::NodeImpl *node)
Definition: util.cpp:124
khtml::XPath::isRootDomNode
bool isRootDomNode(NodeImpl *node)
Definition: util.cpp:35
khtml::XPath::xpathParentNode
DOM::NodeImpl * xpathParentNode(DOM::NodeImpl *node)
Definition: util.cpp:112
khtml::XPath::nextSiblingForFollowing
DOM::NodeImpl * nextSiblingForFollowing(DOM::NodeImpl *node)
Definition: util.cpp:140
khtml::XPath::collectChildrenRecursively
void collectChildrenRecursively(SharedPtr< DOM::StaticNodeListImpl > out, DOM::NodeImpl *root)
Definition: util.cpp:73
khtml::XPath::DomNodeList
SharedPtr< DOM::StaticNodeListImpl > DomNodeList
Definition: util.h:41
khtml
areAdjacentTextNodes
static bool areAdjacentTextNodes(NodeImpl *n, NodeImpl *m)
Definition: step.cpp:44
compressTextNodes
static DomNodeList compressTextNodes(const DomNodeList &nodes)
Definition: step.cpp:66
step.h
khtml::XPath::EvaluationContext
Definition: expression.h:48
khtml::XPath::EvaluationContext::position
unsigned long position
Definition: expression.h:61
khtml::XPath::EvaluationContext::resolver
XPathNSResolverImpl * resolver
Definition: expression.h:72
khtml::XPath::EvaluationContext::size
unsigned long size
Definition: expression.h:60
khtml::XPath::EvaluationContext::node
DOM::NodeImpl * node
Definition: expression.h:59
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Mon Feb 20 2023 00:00:00 by doxygen 1.9.6 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KHTML

Skip menu "KHTML"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdelibs-4.14.38 API Reference

Skip menu "kdelibs-4.14.38 API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal