#include "html/html_miscimpl.h"
#include "html/html_formimpl.h"
#include "misc/htmlhashes.h"
#include "dom/dom_node.h"
using namespace DOM;
#include <kdebug.h>
HTMLBaseFontElementImpl::HTMLBaseFontElementImpl(DocumentPtr *doc)
: HTMLElementImpl(doc)
{
}
HTMLBaseFontElementImpl::~HTMLBaseFontElementImpl()
{
}
NodeImpl::Id HTMLBaseFontElementImpl::id() const
{
return ID_BASEFONT;
}
HTMLCollectionImpl::HTMLCollectionImpl(NodeImpl *_base, int _type)
{
base = _base;
base->ref();
type = _type;
currentItem = 0L;
idsDone = false;
}
HTMLCollectionImpl::~HTMLCollectionImpl()
{
base->deref();
}
unsigned long HTMLCollectionImpl::calcLength(NodeImpl *current) const
{
unsigned long len = 0;
while(current)
{
if(current->nodeType() == Node::ELEMENT_NODE)
{
bool deep = true;
HTMLElementImpl *e = static_cast<HTMLElementImpl *>(current);
switch(type)
{
case DOC_IMAGES:
if(e->id() == ID_IMG)
len++;
break;
case DOC_FORMS:
if(e->id() == ID_FORM)
len++;
break;
case TABLE_TBODIES:
if(e->id() == ID_TBODY)
len++;
else if(e->id() == ID_TABLE)
deep = false;
break;
case TR_CELLS:
if(e->id() == ID_TD)
len++;
else if(e->id() == ID_TABLE)
deep = false;
break;
case TABLE_ROWS:
case TSECTION_ROWS:
if(e->id() == ID_TR || e->id() == ID_TH)
len++;
else if(e->id() == ID_TABLE)
deep = false;
break;
case SELECT_OPTIONS:
if(e->id() == ID_OPTION)
len++;
break;
case MAP_AREAS:
if(e->id() == ID_AREA)
len++;
break;
case DOC_APPLETS: if(e->id() == ID_OBJECT || e->id() == ID_APPLET)
len++;
break;
case DOC_LINKS: if(e->id() == ID_A || e->id() == ID_AREA)
if(!e->getAttribute(ATTR_HREF).isNull())
len++;
break;
case DOC_ANCHORS: if(e->id() == ID_A) {
if(!e->getAttribute(ATTR_NAME).isNull())
len++;
}
break;
case DOC_ALL: len++;
break;
case NODE_CHILDREN: len++;
deep = false;
break;
default:
kdDebug( 6030 ) << "Error in HTMLCollection, wrong tagId!" << endl;
}
if(deep && current->firstChild())
len += calcLength(current->firstChild());
}
current = current->nextSibling();
}
return len;
}
unsigned long HTMLCollectionImpl::length() const
{
return calcLength(base->firstChild());
}
NodeImpl *HTMLCollectionImpl::getItem(NodeImpl *current, int index, int &len) const
{
while(current)
{
if(current->nodeType() == Node::ELEMENT_NODE)
{
bool deep = true;
HTMLElementImpl *e = static_cast<HTMLElementImpl *>(current);
switch(type)
{
case DOC_IMAGES:
if(e->id() == ID_IMG)
len++;
break;
case DOC_FORMS:
if(e->id() == ID_FORM)
len++;
break;
case TABLE_TBODIES:
if(e->id() == ID_TBODY)
len++;
else if(e->id() == ID_TABLE)
deep = false;
break;
case TR_CELLS:
if(e->id() == ID_TD)
len++;
else if(e->id() == ID_TABLE)
deep = false;
break;
case TABLE_ROWS:
case TSECTION_ROWS:
if(e->id() == ID_TR || e->id() == ID_TH)
len++;
else if(e->id() == ID_TABLE)
deep = false;
break;
case SELECT_OPTIONS:
if(e->id() == ID_OPTION)
len++;
break;
case MAP_AREAS:
if(e->id() == ID_AREA)
len++;
break;
case DOC_APPLETS: if(e->id() == ID_OBJECT || e->id() == ID_APPLET)
len++;
break;
case DOC_LINKS: if(e->id() == ID_A || e->id() == ID_AREA)
if(!e->getAttribute(ATTR_HREF).isNull())
len++;
break;
case DOC_ANCHORS: if(e->id() == ID_A)
if(!e->getAttribute(ATTR_NAME).isNull())
len++;
break;
case DOC_ALL:
len++;
break;
case NODE_CHILDREN:
len++;
deep = false;
break;
default:
kdDebug( 6030 ) << "Error in HTMLCollection, wrong tagId!" << endl;
}
if(len == (index + 1)) return current;
NodeImpl *retval=0;
if(deep && current->firstChild())
retval = getItem(current->firstChild(), index, len);
if(retval) return retval;
}
current = current->nextSibling();
}
return 0;
}
NodeImpl *HTMLCollectionImpl::item( unsigned long index ) const
{
int pos = 0;
return getItem(base->firstChild(), index, pos);
}
NodeImpl *HTMLCollectionImpl::firstItem() const
{
int pos = 0;
currentItem = getItem(base->firstChild(), 0, pos);
return currentItem;
}
NodeImpl *HTMLCollectionImpl::nextItem() const
{
int pos = 0;
NodeImpl *retval = getItem(currentItem, 1, pos);
if (retval)
{
currentItem = retval;
return retval;
}
while( !retval && currentItem && currentItem->parentNode()
&& currentItem->parentNode() != base )
{
currentItem = currentItem->parentNode();
if (currentItem->nextSibling())
{
pos = 0;
retval = getItem(currentItem->nextSibling(), 0, pos);
}
}
currentItem = retval;
return currentItem;
}
NodeImpl *HTMLCollectionImpl::getNamedItem( NodeImpl *current, int attr_id,
const DOMString &name, bool caseSensitive ) const
{
if(name.isEmpty())
return 0;
while(current)
{
if(current->nodeType() == Node::ELEMENT_NODE)
{
bool deep = true;
bool check = false;
HTMLElementImpl *e = static_cast<HTMLElementImpl *>(current);
switch(type)
{
case DOC_IMAGES:
if(e->id() == ID_IMG)
check = true;
break;
case DOC_FORMS:
if(e->id() == ID_FORM)
check = true;
break;
case TABLE_TBODIES:
if(e->id() == ID_TBODY)
check = true;
else if(e->id() == ID_TABLE)
deep = false;
break;
case TR_CELLS:
if(e->id() == ID_TD)
check = true;
else if(e->id() == ID_TABLE)
deep = false;
break;
case TABLE_ROWS:
case TSECTION_ROWS:
if(e->id() == ID_TR || e->id() == ID_TH)
check = true;
else if(e->id() == ID_TABLE)
deep = false;
break;
case SELECT_OPTIONS:
if(e->id() == ID_OPTION)
check = true;
break;
case MAP_AREAS:
if(e->id() == ID_AREA)
check = true;
break;
case DOC_APPLETS: if(e->id() == ID_OBJECT || e->id() == ID_APPLET)
check = true;
break;
case DOC_LINKS: if(e->id() == ID_A || e->id() == ID_AREA)
if(!e->getAttribute(ATTR_HREF).isNull())
check = true;
break;
case DOC_ANCHORS: if(e->id() == ID_A)
if(!e->getAttribute(ATTR_NAME).isNull())
check = true;
break;
case DOC_ALL:
check = true;
break;
case NODE_CHILDREN:
check = true;
deep = false;
break;
default:
kdDebug( 6030 ) << "Error in HTMLCollection, wrong tagId!" << endl;
break;
}
if (check) {
bool found;
if (caseSensitive)
found = e->getAttribute(attr_id) == name;
else
found = e->getAttribute(attr_id).lower() == name.lower();
if (found) {
return current;
}
}
NodeImpl *retval = 0;
if(deep && current->firstChild())
retval = getNamedItem(current->firstChild(), attr_id, name, caseSensitive);
if(retval)
{
return retval;
}
}
current = current->nextSibling();
}
return 0;
}
NodeImpl *HTMLCollectionImpl::namedItem( const DOMString &name, bool caseSensitive ) const
{
idsDone = false;
currentItem = getNamedItem(base->firstChild(), ATTR_ID, name, caseSensitive);
if(currentItem)
return currentItem;
idsDone = true;
currentItem = getNamedItem(base->firstChild(), ATTR_NAME, name, caseSensitive);
return currentItem;
}
NodeImpl *HTMLCollectionImpl::nextNamedItem( const DOMString &name ) const
{
NodeImpl *impl = nextNamedItemInternal( name );
if (!idsDone) return impl;
bool ok = false;
while (impl && !ok)
{
if(impl->nodeType() == Node::ELEMENT_NODE)
{
HTMLElementImpl *e = static_cast<HTMLElementImpl *>(impl);
ok = (e->getAttribute(ATTR_ID) != name);
if (!ok)
impl = nextNamedItemInternal( name );
} else ok = true;
}
return impl;
}
NodeImpl *HTMLCollectionImpl::nextNamedItemInternal( const DOMString &name ) const
{
currentItem = nextItem();
if ( currentItem )
{
NodeImpl *retval = getNamedItem(currentItem, idsDone ? ATTR_NAME : ATTR_ID, name);
if ( retval )
{
currentItem = retval;
return retval;
}
while( !retval && currentItem->parentNode()
&& currentItem->parentNode() != base )
{
currentItem = currentItem->parentNode();
if (currentItem->nextSibling())
{
retval = getNamedItem(currentItem->nextSibling(), idsDone ? ATTR_NAME : ATTR_ID, name);
}
}
if ( retval )
{
currentItem = retval;
return currentItem;
}
}
if ( idsDone )
return 0;
idsDone = true;
currentItem = getNamedItem(base->firstChild(), ATTR_NAME, name);
return currentItem;
}
unsigned long HTMLFormCollectionImpl::calcLength(NodeImpl*) const
{
QPtrList<HTMLGenericFormElementImpl> l = static_cast<HTMLFormElementImpl*>( base )->formElements;
int len = 0;
for ( unsigned i = 0; i < l.count(); i++ )
if ( l.at( i )->isEnumeratable() )
++len;
return len;
}
NodeImpl* HTMLFormCollectionImpl::getItem(NodeImpl *, int index, int&) const
{
QPtrList<HTMLGenericFormElementImpl> l = static_cast<HTMLFormElementImpl*>( base )->formElements;
for ( unsigned i = 0; i < l.count(); i++ ) {
if( l.at( i )->isEnumeratable() ) {
if ( !index )
return l.at( i );
--index;
}
}
return 0;
}
NodeImpl* HTMLFormCollectionImpl::getNamedItem(NodeImpl*, int attr_id, const DOMString& name, bool caseSensitive) const
{
currentPos = 0;
return getNamedFormItem( attr_id, name, 0, caseSensitive );
}
NodeImpl* HTMLFormCollectionImpl::getNamedFormItem(int attr_id, const DOMString& name, int duplicateNumber, bool caseSensitive) const
{
if(base->nodeType() == Node::ELEMENT_NODE)
{
HTMLElementImpl* e = static_cast<HTMLElementImpl*>(base);
if(e->id() == ID_FORM)
{
HTMLFormElementImpl* f = static_cast<HTMLFormElementImpl*>(e);
for(HTMLGenericFormElementImpl* e = f->formElements.first(); e; e = f->formElements.next())
if(e->isEnumeratable()) {
bool found;
if (caseSensitive)
found = e->getAttribute(attr_id) == name;
else
found = e->getAttribute(attr_id).lower() == name.lower();
if (found) {
if (!duplicateNumber)
return e;
--duplicateNumber;
}
}
}
NodeImpl* retval = getNamedImgItem( base->firstChild(), attr_id, name, duplicateNumber, caseSensitive );
if ( retval )
return retval;
}
return 0;
}
NodeImpl* HTMLFormCollectionImpl::getNamedImgItem(NodeImpl* current, int attr_id, const DOMString& name, int& duplicateNumber, bool caseSensitive) const
{
while ( current )
{
if(current->nodeType() == Node::ELEMENT_NODE)
{
HTMLElementImpl *e = static_cast<HTMLElementImpl *>(current);
if(e->id() == ID_IMG) {
bool found;
if (caseSensitive)
found = e->getAttribute(attr_id) == name;
else
found = e->getAttribute(attr_id).lower() == name.lower();
if (found)
{
if (!duplicateNumber)
return current;
--duplicateNumber;
}
}
if(current->firstChild())
{
NodeImpl *retval = getNamedImgItem(current->firstChild(), attr_id, name, duplicateNumber, caseSensitive);
if(retval)
{
return retval;
}
}
}
current = current->nextSibling();
} return 0;
}
NodeImpl * HTMLFormCollectionImpl::firstItem() const
{
currentPos = 0;
int dummy = 0;
return getItem(0 , currentPos, dummy);
}
NodeImpl * HTMLFormCollectionImpl::nextItem() const
{
int dummy = 0;
return getItem(0 , ++currentPos, dummy);
}
NodeImpl * HTMLFormCollectionImpl::nextNamedItemInternal( const DOMString &name ) const
{
NodeImpl *retval = getNamedFormItem( idsDone ? ATTR_NAME : ATTR_ID, name, ++currentPos, true );
if ( retval )
return retval;
if ( idsDone ) return 0;
idsDone = true;
return getNamedItem(base->firstChild(), ATTR_NAME, name, true);
}