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

KHTML

  • khtml
  • xpath
functions.cpp
Go to the documentation of this file.
1/*
2 * functions.cc - Copyright 2005 Frerich Raabe <raabe@kde.org>
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25#include "functions.h"
26
27#include "xml/dom_docimpl.h"
28#include "xml/dom_nodeimpl.h"
29#include "xml/dom_nodelistimpl.h"
30#include "xml/dom_elementimpl.h"
31#include "kjs/operations.h"
32
33#include <QtDebug>
34
35#include <math.h>
36
37using namespace DOM;
38
39namespace khtml {
40namespace XPath {
41
42#define DEFINE_FUNCTION_CREATOR(Class) \
43static Function *create##Class() { return new Class; }
44
45class Interval
46{
47 public:
48 static const int Inf =-1;
49
50 Interval();
51 Interval( int value );
52 Interval( int min, int max );
53
54 bool contains( int value ) const;
55
56 QString asString() const;
57
58 private:
59 int m_min;
60 int m_max;
61};
62
63class FunLast : public Function
64{
65 public:
66 virtual bool isConstant() const;
67
68 private:
69 virtual Value doEvaluate() const;
70};
71
72class FunPosition : public Function
73{
74 public:
75 virtual bool isConstant() const;
76
77 private:
78 virtual Value doEvaluate() const;
79};
80
81class FunCount : public Function
82{
83 public:
84 virtual bool isConstant() const;
85
86 private:
87 virtual Value doEvaluate() const;
88};
89
90// Base for various node-property functions, that have
91// the same node picking logic. It passes the proper node,
92// if any, or otherwise returns an empty string by itself
93class NodeFunction : public Function
94{
95 private:
96 virtual Value doEvaluate() const;
97 virtual Value evaluateOnNode( DOM::NodeImpl* node ) const = 0;
98};
99
100class FunLocalName : public NodeFunction
101{
102 public:
103 virtual bool isConstant() const;
104
105 private:
106 virtual Value evaluateOnNode( DOM::NodeImpl* node ) const;
107};
108
109class FunNamespaceURI : public NodeFunction
110{
111 public:
112 virtual bool isConstant() const;
113
114 private:
115 virtual Value evaluateOnNode( DOM::NodeImpl* node ) const;
116};
117
118class FunName : public NodeFunction
119{
120 public:
121 virtual bool isConstant() const;
122
123 private:
124 virtual Value evaluateOnNode( DOM::NodeImpl* node ) const;
125};
126
127class FunId : public Function
128{
129 private:
130 virtual Value doEvaluate() const;
131};
132
133class FunString : public Function
134{
135 private:
136 virtual Value doEvaluate() const;
137};
138
139class FunConcat : public Function
140{
141 private:
142 virtual Value doEvaluate() const;
143};
144
145class FunStartsWith : public Function
146{
147 private:
148 virtual Value doEvaluate() const;
149};
150
151class FunContains : public Function
152{
153 private:
154 virtual Value doEvaluate() const;
155};
156
157class FunSubstringBefore : public Function
158{
159 private:
160 virtual Value doEvaluate() const;
161};
162
163class FunSubstringAfter : public Function
164{
165 private:
166 virtual Value doEvaluate() const;
167};
168
169class FunSubstring : public Function
170{
171 private:
172 virtual Value doEvaluate() const;
173};
174
175class FunStringLength : public Function
176{
177 private:
178 virtual Value doEvaluate() const;
179};
180
181class FunNormalizeSpace : public Function
182{
183 private:
184 virtual Value doEvaluate() const;
185};
186
187class FunTranslate : public Function
188{
189 private:
190 virtual Value doEvaluate() const;
191};
192
193class FunBoolean : public Function
194{
195 private:
196 virtual Value doEvaluate() const;
197};
198
199class FunNot : public Function
200{
201 private:
202 virtual Value doEvaluate() const;
203};
204
205class FunTrue : public Function
206{
207 public:
208 virtual bool isConstant() const;
209
210 private:
211 virtual Value doEvaluate() const;
212};
213
214class FunFalse : public Function
215{
216 public:
217 virtual bool isConstant() const;
218
219 private:
220 virtual Value doEvaluate() const;
221};
222
223class FunLang : public Function
224{
225 public:
226 virtual bool isConstant() const;
227
228 private:
229 virtual Value doEvaluate() const;
230};
231
232class FunNumber : public Function
233{
234 private:
235 virtual Value doEvaluate() const;
236};
237
238class FunSum : public Function
239{
240 private:
241 virtual Value doEvaluate() const;
242};
243
244class FunFloor : public Function
245{
246 private:
247 virtual Value doEvaluate() const;
248};
249
250class FunCeiling : public Function
251{
252 private:
253 virtual Value doEvaluate() const;
254};
255
256class FunRound : public Function
257{
258 private:
259 virtual Value doEvaluate() const;
260};
261
262DEFINE_FUNCTION_CREATOR( FunLast )
263DEFINE_FUNCTION_CREATOR( FunPosition )
264DEFINE_FUNCTION_CREATOR( FunCount )
265DEFINE_FUNCTION_CREATOR( FunLocalName )
266DEFINE_FUNCTION_CREATOR( FunNamespaceURI )
267DEFINE_FUNCTION_CREATOR( FunName )
268DEFINE_FUNCTION_CREATOR( FunId )
269
270DEFINE_FUNCTION_CREATOR( FunString )
271DEFINE_FUNCTION_CREATOR( FunConcat )
272DEFINE_FUNCTION_CREATOR( FunStartsWith )
273DEFINE_FUNCTION_CREATOR( FunContains )
274DEFINE_FUNCTION_CREATOR( FunSubstringBefore )
275DEFINE_FUNCTION_CREATOR( FunSubstringAfter )
276DEFINE_FUNCTION_CREATOR( FunSubstring )
277DEFINE_FUNCTION_CREATOR( FunStringLength )
278DEFINE_FUNCTION_CREATOR( FunNormalizeSpace )
279DEFINE_FUNCTION_CREATOR( FunTranslate )
280
281DEFINE_FUNCTION_CREATOR( FunBoolean )
282DEFINE_FUNCTION_CREATOR( FunNot )
283DEFINE_FUNCTION_CREATOR( FunTrue )
284DEFINE_FUNCTION_CREATOR( FunFalse )
285DEFINE_FUNCTION_CREATOR( FunLang )
286
287DEFINE_FUNCTION_CREATOR( FunNumber )
288DEFINE_FUNCTION_CREATOR( FunSum )
289DEFINE_FUNCTION_CREATOR( FunFloor )
290DEFINE_FUNCTION_CREATOR( FunCeiling )
291DEFINE_FUNCTION_CREATOR( FunRound )
292
293#undef DEFINE_FUNCTION_CREATOR
294
295Interval::Interval()
296 : m_min( Inf ),
297 m_max( Inf )
298{
299}
300
301Interval::Interval( int value )
302 : m_min( value ),
303 m_max( value )
304{
305}
306
307Interval::Interval( int min, int max )
308 : m_min( min ),
309 m_max( max )
310{
311}
312
313bool Interval::contains( int value ) const
314{
315 if ( m_min == Inf && m_max == Inf ) {
316 return true;
317 }
318
319 if ( m_min == Inf ) {
320 return value <= m_max;
321 }
322
323 if ( m_max == Inf ) {
324 return value >= m_min;
325 }
326
327 return value >= m_min && value <= m_max;
328}
329
330QString Interval::asString() const
331{
332 QString s = "[";
333
334 if ( m_min == Inf ) {
335 s += "-Infinity";
336 } else {
337 s += QString::number( m_min );
338 }
339
340 s += "..";
341
342 if ( m_max == Inf ) {
343 s += "Infinity";
344 } else {
345 s += QString::number( m_max );
346 }
347
348 s += "]";
349
350 return s;
351}
352
353void Function::setArguments( const QList<Expression *> &args )
354{
355 foreach( Expression *arg, args ) {
356 addSubExpression( arg );
357 }
358}
359
360void Function::setName( const DOM::DOMString &name )
361{
362 m_name = name;
363}
364
365QString Function::dump() const
366{
367 if ( argCount() == 0 ) {
368 return QString( "<function name=\"%1\"/>" ).arg( name().string() );
369 }
370
371 QString s = QString( "<function name=\"%1\">" ).arg( name().string() );
372 for ( unsigned int i = 0; i < argCount(); ++i ) {
373 s += "<operand>" + arg( i )->dump() + "</operand>";
374 }
375 s += "</function>";
376 return s;
377}
378
379
380Expression *Function::arg( int i )
381{
382 return subExpr( i );
383}
384
385const Expression *Function::arg( int i ) const
386{
387 return subExpr( i );
388}
389
390unsigned int Function::argCount() const
391{
392 return subExprCount();
393}
394
395DOM::DOMString Function::name() const
396{
397 return m_name;
398}
399
400Value FunLast::doEvaluate() const
401{
402 return Value( double( Expression::evaluationContext().size ) );
403}
404
405bool FunLast::isConstant() const
406{
407 return false;
408}
409
410Value FunPosition::doEvaluate() const
411{
412 return Value( double( Expression::evaluationContext().position ) );
413}
414
415bool FunPosition::isConstant() const
416{
417 return false;
418}
419
420Value NodeFunction::doEvaluate() const
421{
422 NodeImpl *node = 0;
423 if ( argCount() > 0 ) {
424 Value a = arg( 0 )->evaluate();
425 if ( a.isNodeset() && a.toNodeset()->length() ) {
426 node = a.toNodeset()->first();
427 }
428 } else {
429 // no argument -> default to context node
430 node = evaluationContext().node;
431 }
432
433 if ( !node )
434 return Value( DOMString() );
435
436 return evaluateOnNode( node );
437}
438
439bool FunLocalName::isConstant() const
440{
441 return false;
442}
443
444Value FunLocalName::evaluateOnNode( DOM::NodeImpl* node ) const
445{
446 DOM::DOMString n;
447 switch ( node->nodeType() ) {
448 case Node::PROCESSING_INSTRUCTION_NODE:
449 n = node->nodeName(); // target name
450 break;
451 default:
452 n = node->localName();
453 }
454 return Value( n );
455}
456
457bool FunNamespaceURI::isConstant() const
458{
459 return false;
460}
461
462Value FunNamespaceURI::evaluateOnNode( DOM::NodeImpl* node ) const
463{
464 return Value( node->namespaceURI() );
465}
466
467Value FunId::doEvaluate() const
468{
469 Value a = arg( 0 )->evaluate();
470
471 WTF::Vector<DOM::DOMString> ids;
472
473 QString queryString; // whitespace-separated IDs
474 if ( a.isNodeset() ) {
475 DomNodeList set = a.toNodeset();
476 for ( unsigned long i = 0; i < set->length(); ++i)
477 queryString += stringValue( set->item(i) ).string() + QLatin1Char(' ');
478 } else {
479 queryString = a.toString().string();
480 }
481
482 QStringList qids = queryString.simplified().split(' ');
483 for ( int i = 0; i < qids.size(); ++i)
484 ids.append( DOM::DOMString( qids[i] ) );
485
486 DomNodeList out = new StaticNodeListImpl();
487 DOM::DocumentImpl* doc = Expression::evaluationContext().node->document();
488
489 for ( unsigned i = 0; i < ids.size(); ++i ) {
490 DOM::ElementImpl* e = doc->getElementById( ids[i] );
491
492 if ( e )
493 out->append( e );
494 }
495
496 return Value( out );
497}
498
499bool FunName::isConstant() const
500{
501 return false;
502}
503
504Value FunName::evaluateOnNode( DOM::NodeImpl* node ) const
505{
506 DOM::DOMString n;
507 switch ( node->nodeType() ) {
508 case Node::TEXT_NODE:
509 case Node::CDATA_SECTION_NODE:
510 case Node::COMMENT_NODE:
511 case Node::DOCUMENT_NODE:
512 // All of these have an empty XPath name
513 break;
514 case Node::ELEMENT_NODE: {
515 n = static_cast<DOM::ElementImpl*>( node )->nonCaseFoldedTagName();
516 break;
517 }
518 default:
519 n = node->nodeName();
520 }
521 return Value( n );
522}
523
524Value FunCount::doEvaluate() const
525{
526 Value a = arg( 0 )->evaluate();
527 if ( !a.isNodeset() ) {
528 Expression::reportInvalidExpressionErr();
529 kWarning() << "count() expects <nodeset>";
530 return Value( );
531 }
532 a.toNodeset()->normalizeUpto(StaticNodeListImpl::AxisOrder);
533
534 return Value( double( a.toNodeset()->length() ) );
535}
536
537bool FunCount::isConstant() const
538{
539 return false;
540}
541
542Value FunString::doEvaluate() const
543{
544 if ( argCount() == 0 ) {
545 DOMString s = Value( Expression::evaluationContext().node ).toString();
546 return Value( s );
547 }
548 return Value( arg( 0 )->evaluate().toString() );
549}
550
551Value FunConcat::doEvaluate() const
552{
553 QString str;
554 for ( unsigned int i = 0; i < argCount(); ++i ) {
555 str.append( arg( i )->evaluate().toString().string() );
556 }
557 return Value( DOMString( str ) );
558}
559
560Value FunStartsWith::doEvaluate() const
561{
562 DOMString s1 = arg( 0 )->evaluate().toString();
563 DOMString s2 = arg( 1 )->evaluate().toString();
564
565 if ( s2.isEmpty() ) {
566 return Value( true );
567 }
568
569 return Value( s1.startsWith( s2 ) );
570}
571
572Value FunContains::doEvaluate() const
573{
574 QString s1 = arg( 0 )->evaluate().toString().string();
575 QString s2 = arg( 1 )->evaluate().toString().string();
576
577 if ( s2.isEmpty() ) {
578 return Value( true );
579 }
580
581 return Value( s1.contains( s2 ) );
582}
583
584Value FunSubstringBefore::doEvaluate() const
585{
586 QString s1 = arg( 0 )->evaluate().toString().string();
587 QString s2 = arg( 1 )->evaluate().toString().string();
588
589 if ( s2.isEmpty() ) {
590 return Value( DOMString() );
591 }
592
593 int i = s1.indexOf( s2 );
594 if ( i == -1 ) {
595 return Value( DOMString() );
596 }
597
598 return Value( DOMString( s1.left( i ) ) );
599}
600
601Value FunSubstringAfter::doEvaluate() const
602{
603 QString s1 = arg( 0 )->evaluate().toString().string();
604 QString s2 = arg( 1 )->evaluate().toString().string();
605
606 if ( s2.isEmpty() ) {
607 return Value( s1 );
608 }
609
610 int i = s1.indexOf( s2 );
611 if ( i == -1 ) {
612 return Value( DOMString() );
613 }
614
615 return Value( DOMString( s1.mid( i + s2.length() ) ) );
616}
617
618Value FunSubstring::doEvaluate() const
619{
620 QString s = arg( 0 )->evaluate().toString().string();
621 long pos = long( qRound( arg( 1 )->evaluate().toNumber() ) );
622 bool haveLength = argCount() == 3;
623 long len = -1;
624 if ( haveLength ) {
625 len = long( qRound( arg( 2 )->evaluate().toNumber() ) );
626 }
627
628 if ( pos > long( s.length() ) ) {
629 return Value( DOMString() );
630 }
631
632 if ( haveLength && pos < 1 ) {
633 len -= 1 - pos;
634 pos = 1;
635 if ( len < 1 ) {
636 return Value( DOMString() );
637 }
638 }
639
640 return Value( DOMString( s.mid( pos - 1, len ) ) );
641}
642
643Value FunStringLength::doEvaluate() const
644{
645 if ( argCount() == 0 ) {
646 DOMString s = Value( Expression::evaluationContext().node ).toString();
647 return Value( double( s.length() ) );
648 }
649
650 return Value( double( arg( 0 )->evaluate().toString().length() ) );
651}
652
653Value FunNormalizeSpace::doEvaluate() const
654{
655 if ( argCount() == 0 ) {
656 DOMString s = Value( Expression::evaluationContext().node ).toString();
657 return Value( DOMString( s.string().simplified() ) );
658 }
659
660 QString s = arg( 0 )->evaluate().toString().string();
661 s = s.simplified();
662 return Value( DOMString( s ) );
663}
664
665Value FunTranslate::doEvaluate() const
666{
667 QString s1 = arg( 0 )->evaluate().toString().string();
668 QString s2 = arg( 1 )->evaluate().toString().string();
669 QString s3 = arg( 2 )->evaluate().toString().string();
670 QString newString;
671
672 for ( int i1 = 0; i1 < s1.length(); ++i1 ) {
673 QChar ch = s1[ i1 ];
674 int i2 = s2.indexOf( ch );
675 if ( i2 == -1 ) {
676 newString += ch;
677 } else if ( i2 < s3.length() ) {
678 newString += s3[ i2 ];
679 }
680 }
681
682 return Value( DOMString( newString ) );
683}
684
685Value FunBoolean::doEvaluate() const
686{
687 return Value( arg( 0 )->evaluate().toBoolean() );
688}
689
690Value FunNot::doEvaluate() const
691{
692 return Value( !arg( 0 )->evaluate().toBoolean() );
693}
694
695Value FunTrue::doEvaluate() const
696{
697 return Value( true );
698}
699
700bool FunTrue::isConstant() const
701{
702 return true;
703}
704
705#ifdef __GNUC__
706#warning "This looks bogus"
707#endif
708
709Value FunLang::doEvaluate() const
710{
711 QString lang = arg( 0 )->evaluate().toString().string();
712
713 NodeImpl* node = evaluationContext().node;
714
715 DOMString langNodeValue;
716
717 while ( node ) {
718 if (node->isElementNode()) {
719 langNodeValue = static_cast<ElementImpl*>(node)->getAttribute("xml:lang");
720 if ( !langNodeValue.isNull() )
721 break;
722 }
723 node = xpathParentNode( node );
724 }
725
726 if ( langNodeValue.isNull() ) {
727 return Value( false );
728 }
729
730 // extract 'en' out of 'en-us'
731 QString langNodeValueString = langNodeValue.string();
732 QString langNodeBaseString = langNodeValueString.left( langNodeValueString.indexOf( '-' ) );
733
734 return Value( langNodeValueString.toLower() == lang.toLower() ||
735 langNodeBaseString.toLower() == lang.toLower() );
736}
737
738bool FunLang::isConstant() const
739{
740 return false;
741}
742
743Value FunFalse::doEvaluate() const
744{
745 return Value( false );
746}
747
748bool FunFalse::isConstant() const
749{
750 return true;
751}
752
753Value FunNumber::doEvaluate() const
754{
755 Value vi;
756 if ( argCount() == 0 ) {
757 // Spec'd: convert context node to singleton nodeset, call
758 // string on that --> that's just stringValue on that node.
759 // then we call number on that string
760 vi = Value(stringValue(evaluationContext().node));
761 } else {
762 vi = arg( 0 )->evaluate();
763 }
764
765 return Value( vi.toNumber() );
766}
767
768Value FunSum::doEvaluate() const
769{
770 Value a = arg( 0 )->evaluate();
771 if ( !a.isNodeset() ) {
772 Expression::reportInvalidExpressionErr();
773 kWarning() << "sum() expects <nodeset>";
774 return Value( 0.0 );
775 }
776
777 double sum = 0.0;
778 const DomNodeList nodes = a.toNodeset();
779 for (unsigned long n = 0; n < nodes->length(); ++n) {
780 NodeImpl* node = nodes->item(n);
781 sum += Value( stringValue( node ) ).toNumber();
782 }
783 return Value( sum );
784}
785
786Value FunFloor::doEvaluate() const
787{
788 const double num = arg( 0 )->evaluate().toNumber();
789
790 if ( KJS::isNaN( num ) || KJS::isInf( num ) ) {
791 return Value( num );
792 }
793
794 return Value( floor( num ) );
795}
796
797Value FunCeiling::doEvaluate() const
798{
799 const double num = arg( 0 )->evaluate().toNumber();
800
801 if ( KJS::isNaN( num ) || KJS::isInf( num ) ) {
802 return Value( num );
803 }
804
805 return Value( ceil( num ) );
806}
807
808Value FunRound::doEvaluate() const
809{
810 return Value( double( qRound( arg( 0 )->evaluate().toNumber() ) ) );
811}
812
813struct FunctionLibrary::FunctionRec
814{
815 typedef Function *(*FactoryFn )();
816
817 FactoryFn factoryFn;
818 Interval args;
819};
820
821struct FunctionMapping
822{
823 const char *name;
824 FunctionLibrary::FunctionRec function;
825};
826
827static FunctionMapping functions[] = {
828 { "last", { &createFunLast, 0 } },
829 { "last", { &createFunLast, 0 } },
830 { "position", { &createFunPosition, 0 } },
831 { "count", { &createFunCount, 1 } },
832 { "sum", { &createFunSum, 1 } },
833 { "local-name", { &createFunLocalName, Interval( 0, 1 ) } },
834 { "namespace-uri", { &createFunNamespaceURI, Interval( 0, 1 ) } },
835 { "id", { &createFunId, 1 } },
836 { "name", { &createFunName, Interval( 0, 1 ) } },
837
838
839 { "string", { &createFunString, Interval( 0, 1 ) } },
840 { "concat", { &createFunConcat, Interval( 2, Interval::Inf ) } },
841 { "starts-with", { &createFunStartsWith, 2 } },
842 { "contains", { &createFunContains, 2 } },
843 { "substring-before", { &createFunSubstringBefore, 2 } },
844 { "substring-after", { &createFunSubstringAfter, 2 } },
845 { "substring", { &createFunSubstring, Interval( 2, 3 ) } },
846 { "string-length", { &createFunStringLength, Interval( 0, 1 ) } },
847 { "normalize-space", { &createFunNormalizeSpace, Interval( 0, 1 ) } },
848 { "translate", { &createFunTranslate, 3 } },
849
850 { "boolean", { &createFunBoolean, 1 } },
851 { "not", { &createFunNot, 1 } },
852 { "true", { &createFunTrue, 0 } },
853 { "false", { &createFunFalse, 0 } },
854 { "lang", { &createFunLang, 1 } },
855
856 { "number", { &createFunNumber, Interval( 0, 1 ) } },
857 { "floor", { &createFunFloor, 1 } },
858 { "ceiling", { &createFunCeiling, 1 } },
859 { "round", { &createFunRound, 1 } }
860};
861static const unsigned int numFunctions = sizeof( functions ) / sizeof( functions[ 0 ] );
862
863FunctionLibrary &FunctionLibrary::self()
864{
865 static FunctionLibrary instance;
866 return instance;
867}
868
869FunctionLibrary::FunctionLibrary()
870{
871 for ( unsigned int i = 0; i < numFunctions; ++i ) {
872 m_functionDict.insert( functions[ i ].name, functions[ i ].function );
873 }
874}
875
876Function *FunctionLibrary::getFunction( const DOM::DOMString& name,
877 const QList<Expression *> &args ) const
878{
879 if ( !m_functionDict.contains( name ) ) {
880 kWarning() << "Function '" << name << "' not supported by this implementation.";
881
882 return 0;
883 }
884
885 FunctionRec functionRec = m_functionDict[ name ];
886 if ( !functionRec.args.contains( args.count() ) ) {
887 kWarning() << "Function '" << name << "' requires " << functionRec.args.asString() << " arguments, but " << args.count() << " given.";
888 return 0;
889 }
890
891 Function *function = functionRec.factoryFn();
892 function->setArguments( args );
893 function->setName( name );
894 return function;
895}
896
897} //namespace XPath
898} //namespace khtml
899
900// 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::isNull
bool isNull() const
Definition: dom_string.h:121
DOM::DOMString::string
QString string() const
Definition: dom_string.cpp:236
DOM::DOMString::isEmpty
bool isEmpty() const
Definition: dom_string.cpp:368
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::DOCUMENT_NODE
@ DOCUMENT_NODE
Definition: dom_node.h:390
QList
khtml::XPath::Expression
Definition: expression.h:115
khtml::XPath::FunctionLibrary
Definition: functions.h:58
khtml::XPath::Function
Definition: functions.h:40
khtml::XPath::Function::setArguments
void setArguments(const QList< Expression * > &args)
Definition: functions.cpp:353
khtml::XPath::Function::setName
void setName(const DOM::DOMString &name)
Definition: functions.cpp:360
khtml::XPath::Value
Definition: expression.h:76
DEFINE_FUNCTION_CREATOR
#define DEFINE_FUNCTION_CREATOR(Class)
Definition: functions.cpp:42
functions.h
kWarning
#define kWarning
DOM
This library provides a full-featured HTML parser and widget.
Definition: design.h:55
name
const char * name(StandardAction id)
khtml::XPath::numFunctions
static const unsigned int numFunctions
Definition: functions.cpp:861
khtml::XPath::functions
static FunctionMapping functions[]
Definition: functions.cpp:827
khtml::XPath::xpathParentNode
DOM::NodeImpl * xpathParentNode(DOM::NodeImpl *node)
Definition: util.cpp:112
khtml::XPath::stringValue
DOMString stringValue(NodeImpl *node)
Definition: util.cpp:68
khtml::XPath::DomNodeList
SharedPtr< DOM::StaticNodeListImpl > DomNodeList
Definition: util.h:41
khtml
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