00001
00024
00025 #include "html/html_miscimpl.h"
00026 #include "html/html_formimpl.h"
00027
00028 #include "misc/htmlhashes.h"
00029 #include "dom/dom_node.h"
00030
00031 using namespace DOM;
00032
00033 #include <kdebug.h>
00034
00035 HTMLBaseFontElementImpl::HTMLBaseFontElementImpl(DocumentPtr *doc)
00036 : HTMLElementImpl(doc)
00037 {
00038 }
00039
00040 HTMLBaseFontElementImpl::~HTMLBaseFontElementImpl()
00041 {
00042 }
00043
00044 NodeImpl::Id HTMLBaseFontElementImpl::id() const
00045 {
00046 return ID_BASEFONT;
00047 }
00048
00049
00050
00051 HTMLCollectionImpl::HTMLCollectionImpl(NodeImpl *_base, int _type)
00052 {
00053 base = _base;
00054 base->ref();
00055 type = _type;
00056 currentItem = 0L;
00057 idsDone = false;
00058 }
00059
00060 HTMLCollectionImpl::~HTMLCollectionImpl()
00061 {
00062 base->deref();
00063 }
00064
00065 unsigned long HTMLCollectionImpl::calcLength(NodeImpl *current) const
00066 {
00067 unsigned long len = 0;
00068 while(current)
00069 {
00070 if(current->nodeType() == Node::ELEMENT_NODE)
00071 {
00072 bool deep = true;
00073 HTMLElementImpl *e = static_cast<HTMLElementImpl *>(current);
00074 switch(type)
00075 {
00076 case DOC_IMAGES:
00077 if(e->id() == ID_IMG)
00078 len++;
00079 break;
00080 case DOC_FORMS:
00081 if(e->id() == ID_FORM)
00082 len++;
00083 break;
00084 case TABLE_TBODIES:
00085 if(e->id() == ID_TBODY)
00086 len++;
00087 else if(e->id() == ID_TABLE)
00088 deep = false;
00089 break;
00090 case TR_CELLS:
00091 if(e->id() == ID_TD || e->id() == ID_TH)
00092 len++;
00093 else if(e->id() == ID_TABLE)
00094 deep = false;
00095 break;
00096 case TABLE_ROWS:
00097 case TSECTION_ROWS:
00098 if(e->id() == ID_TR)
00099 len++;
00100 else if(e->id() == ID_TABLE)
00101 deep = false;
00102 break;
00103 case SELECT_OPTIONS:
00104 if(e->id() == ID_OPTION)
00105 len++;
00106 break;
00107 case MAP_AREAS:
00108 if(e->id() == ID_AREA)
00109 len++;
00110 break;
00111 case DOC_APPLETS:
00112 if(e->id() == ID_OBJECT || e->id() == ID_APPLET)
00113 len++;
00114 break;
00115 case DOC_LINKS:
00116 if(e->id() == ID_A || e->id() == ID_AREA)
00117 if(!e->getAttribute(ATTR_HREF).isNull())
00118 len++;
00119 break;
00120 case DOC_ANCHORS:
00121 if(e->id() == ID_A) {
00122 if(e->hasID() || !e->getAttribute(ATTR_NAME).isNull())
00123 len++;
00124 }
00125 break;
00126 case DOC_ALL:
00127 len++;
00128 break;
00129 case NODE_CHILDREN:
00130 len++;
00131 deep = false;
00132 break;
00133 default:
00134 kdDebug( 6030 ) << "Error in HTMLCollection, wrong tagId!" << endl;
00135 }
00136 if(deep && current->firstChild())
00137 len += calcLength(current->firstChild());
00138 }
00139 current = current->nextSibling();
00140 }
00141 return len;
00142 }
00143
00144
00145
00146 unsigned long HTMLCollectionImpl::length() const
00147 {
00148 return calcLength(base->firstChild());
00149 }
00150
00151 NodeImpl *HTMLCollectionImpl::getItem(NodeImpl *current, int index, int &len) const
00152 {
00153 while(current)
00154 {
00155 if(current->nodeType() == Node::ELEMENT_NODE)
00156 {
00157 bool deep = true;
00158 HTMLElementImpl *e = static_cast<HTMLElementImpl *>(current);
00159 switch(type)
00160 {
00161 case DOC_IMAGES:
00162 if(e->id() == ID_IMG)
00163 len++;
00164 break;
00165 case DOC_FORMS:
00166 if(e->id() == ID_FORM)
00167 len++;
00168 break;
00169 case TABLE_TBODIES:
00170 if(e->id() == ID_TBODY)
00171 len++;
00172 else if(e->id() == ID_TABLE)
00173 deep = false;
00174 break;
00175 case TR_CELLS:
00176 if(e->id() == ID_TD || e->id() == ID_TH)
00177 len++;
00178 else if(e->id() == ID_TABLE)
00179 deep = false;
00180 break;
00181 case TABLE_ROWS:
00182 case TSECTION_ROWS:
00183 if(e->id() == ID_TR)
00184 len++;
00185 else if(e->id() == ID_TABLE)
00186 deep = false;
00187 break;
00188 case SELECT_OPTIONS:
00189 if(e->id() == ID_OPTION)
00190 len++;
00191 break;
00192 case MAP_AREAS:
00193 if(e->id() == ID_AREA)
00194 len++;
00195 break;
00196 case DOC_APPLETS:
00197 if(e->id() == ID_OBJECT || e->id() == ID_APPLET)
00198 len++;
00199 break;
00200 case DOC_LINKS:
00201 if(e->id() == ID_A || e->id() == ID_AREA)
00202 if(!e->getAttribute(ATTR_HREF).isNull())
00203 len++;
00204 break;
00205 case DOC_ANCHORS:
00206 if(e->id() == ID_A) {
00207 if(e->hasID() || !e->getAttribute(ATTR_NAME).isNull())
00208 len++;
00209 }
00210 break;
00211 case DOC_ALL:
00212 len++;
00213 break;
00214 case NODE_CHILDREN:
00215 len++;
00216 deep = false;
00217 break;
00218 default:
00219 kdDebug( 6030 ) << "Error in HTMLCollection, wrong tagId!" << endl;
00220 }
00221 if(len == (index + 1)) return current;
00222 NodeImpl *retval=0;
00223 if(deep && current->firstChild())
00224 retval = getItem(current->firstChild(), index, len);
00225 if(retval) return retval;
00226 }
00227 current = current->nextSibling();
00228 }
00229 return 0;
00230 }
00231
00232 NodeImpl *HTMLCollectionImpl::item( unsigned long index ) const
00233 {
00234 int pos = 0;
00235 return getItem(base->firstChild(), index, pos);
00236 }
00237
00238 NodeImpl *HTMLCollectionImpl::firstItem() const
00239 {
00240 int pos = 0;
00241 currentItem = getItem(base->firstChild(), 0, pos);
00242 return currentItem;
00243 }
00244
00245 NodeImpl *HTMLCollectionImpl::nextItem() const
00246 {
00247 int pos = 0;
00248
00249 NodeImpl *retval = getItem(currentItem, 1, pos);
00250 if (retval)
00251 {
00252 currentItem = retval;
00253 return retval;
00254 }
00255
00256 while( !retval && currentItem->parentNode()
00257 && currentItem->parentNode() != base )
00258 {
00259 currentItem = currentItem->parentNode();
00260 if (currentItem->nextSibling())
00261 {
00262
00263 pos = 0;
00264 retval = getItem(currentItem->nextSibling(), 0, pos);
00265 }
00266 }
00267 currentItem = retval;
00268 return currentItem;
00269 }
00270
00271 NodeImpl *HTMLCollectionImpl::getNamedItem( NodeImpl *current, int attr_id,
00272 const DOMString &name ) const
00273 {
00274 if(name.isEmpty())
00275 return 0;
00276
00277 while(current)
00278 {
00279 if(current->nodeType() == Node::ELEMENT_NODE)
00280 {
00281 bool deep = true;
00282 bool check = false;
00283 HTMLElementImpl *e = static_cast<HTMLElementImpl *>(current);
00284 switch(type)
00285 {
00286 case DOC_IMAGES:
00287 if(e->id() == ID_IMG)
00288 check = true;
00289 break;
00290 case DOC_FORMS:
00291 if(e->id() == ID_FORM)
00292 check = true;
00293 break;
00294 case TABLE_TBODIES:
00295 if(e->id() == ID_TBODY)
00296 check = true;
00297 else if(e->id() == ID_TABLE)
00298 deep = false;
00299 break;
00300 case TR_CELLS:
00301 if(e->id() == ID_TD || e->id() == ID_TH)
00302 check = true;
00303 else if(e->id() == ID_TABLE)
00304 deep = false;
00305 break;
00306 case TABLE_ROWS:
00307 case TSECTION_ROWS:
00308 if(e->id() == ID_TR)
00309 check = true;
00310 else if(e->id() == ID_TABLE)
00311 deep = false;
00312 break;
00313 case SELECT_OPTIONS:
00314 if(e->id() == ID_OPTION)
00315 check = true;
00316 break;
00317 case MAP_AREAS:
00318 if(e->id() == ID_AREA)
00319 check = true;
00320 break;
00321 case DOC_APPLETS:
00322 if(e->id() == ID_OBJECT || e->id() == ID_APPLET)
00323 check = true;
00324 break;
00325 case DOC_LINKS:
00326 if(e->id() == ID_A || e->id() == ID_AREA)
00327 if(!e->getAttribute(ATTR_HREF).isNull())
00328 check = true;
00329 break;
00330 case DOC_ANCHORS:
00331 if(e->id() == ID_A) {
00332 if(e->hasID() || !e->getAttribute(ATTR_NAME).isNull())
00333 check = true;
00334 }
00335 break;
00336 case DOC_ALL:
00337 check = true;
00338 break;
00339 case NODE_CHILDREN:
00340 check = true;
00341 deep = false;
00342 break;
00343 default:
00344 kdDebug( 6030 ) << "Error in HTMLCollection, wrong tagId!" << endl;
00345 break;
00346 }
00347 if(check && e->getAttribute(attr_id) == name)
00348 {
00349
00350 return current;
00351 }
00352 NodeImpl *retval = 0;
00353 if(deep && current->firstChild())
00354 retval = getNamedItem(current->firstChild(), attr_id, name);
00355 if(retval)
00356 {
00357
00358 return retval;
00359 }
00360 }
00361 current = current->nextSibling();
00362 }
00363 return 0;
00364 }
00365
00366 NodeImpl *HTMLCollectionImpl::namedItem( const DOMString &name ) const
00367 {
00368
00369
00370
00371
00372
00373 idsDone = false;
00374 currentItem = getNamedItem(base->firstChild(), ATTR_ID, name);
00375 if(currentItem)
00376 return currentItem;
00377 idsDone = true;
00378 currentItem = getNamedItem(base->firstChild(), ATTR_NAME, name);
00379 return currentItem;
00380 }
00381
00382 NodeImpl *HTMLCollectionImpl::nextNamedItem( const DOMString &name ) const
00383 {
00384
00385
00386 NodeImpl *impl = nextNamedItemInternal( name );
00387 if (!idsDone)
00388 return impl;
00389
00390 bool ok = false;
00391 while (impl && !ok)
00392 {
00393 if(impl->nodeType() == Node::ELEMENT_NODE)
00394 {
00395 HTMLElementImpl *e = static_cast<HTMLElementImpl *>(impl);
00396 ok = (e->getAttribute(ATTR_ID) != name);
00397 if (!ok)
00398 impl = nextNamedItemInternal( name );
00399 } else
00400 ok = true;
00401 }
00402 return impl;
00403 }
00404
00405 NodeImpl *HTMLCollectionImpl::nextNamedItemInternal( const DOMString &name ) const
00406 {
00407
00408
00409 currentItem = nextItem();
00410
00411
00412 if ( currentItem )
00413 {
00414
00415 NodeImpl *retval = getNamedItem(currentItem, idsDone ? ATTR_NAME : ATTR_ID, name);
00416 if ( retval )
00417 {
00418
00419 currentItem = retval;
00420 return retval;
00421 }
00422
00423
00424 while( !retval && currentItem->parentNode()
00425 && currentItem->parentNode() != base )
00426 {
00427 currentItem = currentItem->parentNode();
00428 if (currentItem->nextSibling())
00429 {
00430
00431 retval = getNamedItem(currentItem->nextSibling(), idsDone ? ATTR_NAME : ATTR_ID, name);
00432 }
00433 }
00434 if ( retval )
00435 {
00436
00437 currentItem = retval;
00438 return currentItem;
00439 }
00440 }
00441
00442 if ( idsDone )
00443 return 0;
00444
00445
00446 idsDone = true;
00447 currentItem = getNamedItem(base->firstChild(), ATTR_NAME, name);
00448 return currentItem;
00449
00450 }
00451
00452
00453
00454 unsigned long HTMLFormCollectionImpl::calcLength(NodeImpl*) const
00455 {
00456 QPtrList<HTMLGenericFormElementImpl> l = static_cast<HTMLFormElementImpl*>( base )->formElements;
00457
00458 int len = 0;
00459 for ( unsigned i = 0; i < l.count(); i++ )
00460 if ( l.at( i )->isEnumeratable() )
00461 ++len;
00462
00463 return len;
00464 }
00465
00466 NodeImpl* HTMLFormCollectionImpl::getItem(NodeImpl *, int index, int&) const
00467 {
00468 QPtrList<HTMLGenericFormElementImpl> l = static_cast<HTMLFormElementImpl*>( base )->formElements;
00469
00470 for ( unsigned i = 0; i < l.count(); i++ ) {
00471
00472 if( l.at( i )->isEnumeratable() ) {
00473 if ( !index )
00474 return l.at( i );
00475
00476 --index;
00477 }
00478 }
00479
00480 return 0;
00481 }
00482
00483 NodeImpl* HTMLFormCollectionImpl::getNamedItem(NodeImpl*, int attr_id, const DOMString& name) const
00484 {
00485 currentPos = 0;
00486 return getNamedFormItem( attr_id, name, 0 );
00487 }
00488
00489 NodeImpl* HTMLFormCollectionImpl::getNamedFormItem(int attr_id, const DOMString& name, int duplicateNumber) const
00490 {
00491 if(base->nodeType() == Node::ELEMENT_NODE)
00492 {
00493 HTMLElementImpl* e = static_cast<HTMLElementImpl*>(base);
00494 bool foundInputElements = false;
00495 if(e->id() == ID_FORM)
00496 {
00497 HTMLGenericFormElementImpl* element;
00498 HTMLFormElementImpl* f = static_cast<HTMLFormElementImpl*>(e);
00499
00500 for(element = f->formElements.first(); element; element = f->formElements.next())
00501 if(element->isEnumeratable() && element->getAttribute(attr_id) == name)
00502 {
00503 if (!duplicateNumber)
00504 return element;
00505 --duplicateNumber;
00506 foundInputElements = true;
00507 }
00508 }
00509
00510 if ( !foundInputElements )
00511 {
00512 HTMLImageElementImpl* element;
00513 HTMLFormElementImpl* f = static_cast<HTMLFormElementImpl*>(e);
00514
00515 for(element = f->imgElements.first(); element; element = f->imgElements.next())
00516 if(element->getAttribute(attr_id) == name)
00517 {
00518 if (!duplicateNumber)
00519 return element;
00520 --duplicateNumber;
00521 foundInputElements = true;
00522 }
00523 }
00524 }
00525 return 0;
00526 }
00527
00528 NodeImpl * HTMLFormCollectionImpl::firstItem() const
00529 {
00530 currentPos = 0;
00531 int dummy = 0;
00532 return getItem(0 , currentPos, dummy);
00533 }
00534
00535 NodeImpl * HTMLFormCollectionImpl::nextItem() const
00536 {
00537
00538 int dummy = 0;
00539 return getItem(0 , ++currentPos, dummy);
00540 }
00541
00542 NodeImpl * HTMLFormCollectionImpl::nextNamedItemInternal( const DOMString &name ) const
00543 {
00544 NodeImpl *retval = getNamedFormItem( idsDone ? ATTR_NAME : ATTR_ID, name, ++currentPos );
00545 if ( retval )
00546 return retval;
00547 if ( idsDone )
00548 return 0;
00549
00550 idsDone = true;
00551 return getNamedItem(base->firstChild(), ATTR_NAME, name);
00552 }