void RenderPartObject::updateWidget()
{
  QString url;
  QString serviceType;
  QStringList params;
  KHTMLPart *part = m_view->part();

  setNeedsLayoutAndMinMaxRecalc();

  if (element()->id() == ID_OBJECT) {

      HTMLObjectElementImpl *o = static_cast<HTMLObjectElementImpl *>(element());

      // Check for a child EMBED tag.
      HTMLEmbedElementImpl *embed = 0;
      for (NodeImpl *child = o->firstChild(); child; child = child->nextSibling()) {
          if (child->id() == ID_EMBED) {
              embed = static_cast<HTMLEmbedElementImpl *>( child );
              break;
          }
      }
      
      // Use the attributes from the EMBED tag instead of the OBJECT tag including WIDTH and HEIGHT.
      HTMLElementImpl *embedOrObject;
      if (embed) {
          embedOrObject = (HTMLElementImpl *)embed;
          DOMString attribute = embedOrObject->getAttribute(ATTR_WIDTH);
          if (!attribute.isEmpty()) {
              o->setAttribute(ATTR_WIDTH, attribute);
          }
          attribute = embedOrObject->getAttribute(ATTR_HEIGHT);
          if (!attribute.isEmpty()) {
              o->setAttribute(ATTR_HEIGHT, attribute);
          }
          url = embed->url;
          serviceType = embed->serviceType;
      } else {
          embedOrObject = (HTMLElementImpl *)o;
      }
      
      // If there was no URL or type defined in EMBED, try the OBJECT tag.
      if (url.isEmpty()) {
          url = o->url;
      }
      if (serviceType.isEmpty()) {
          serviceType = o->serviceType;
      }
      
      // Then try the PARAM tags for the URL and type attributes.
      NodeImpl *child = o->firstChild();
      while (child && (url.isEmpty() || serviceType.isEmpty())) {
          if (child->id() == ID_PARAM) {
              HTMLParamElementImpl *p = static_cast<HTMLParamElementImpl *>( child );
              QString name = p->name().lower();
              if (url.isEmpty() && (QString::equals(name,"src") || QString::equals(name,"movie") || QString::equals(name,"code"))) {
                  url = p->value();
              }
              if (serviceType.isEmpty() && QString::equals(name,"type")) {
                  serviceType = p->value();
              }
              
          }
          child = child->nextSibling();
      }
      
      // Lastly try to map a specific CLASSID to a type.
      if (serviceType.isEmpty() && !o->classId.isEmpty()) {
          if (o->classId.contains("D27CDB6E-AE6D-11cf-96B8-444553540000")) {
              // It is ActiveX, but the nsplugin system handling
              // should also work, that's why we don't override the
              // serviceType with application/x-activex-handler
              // but let the KTrader in khtmlpart::createPart() detect
              // the user's preference: launch with activex viewer or
              // with nspluginviewer (Niko)
              serviceType = "application/x-shockwave-flash";
          } else if(o->classId.contains("CFCDAA03-8BE4-11cf-B84B-0020AFBBCCFA")) {
              serviceType = "audio/x-pn-realaudio-plugin";
          } else if(o->classId.contains("02BF25D5-8C17-4B23-BC80-D3488ABDDC6B")) {
              serviceType = "video/quicktime";
          } else if(o->classId.contains("166B1BCA-3F9C-11CF-8075-444553540000")) {
              serviceType = "application/x-director";
          } else {
              // We have a clsid, means this is activex (Niko)
              serviceType = "application/x-activex-handler";
          }
          // TODO: add more plugins here
      }
      
      // If no URL and type, abort.
      if (url.isEmpty() && serviceType.isEmpty()) {
#ifdef DEBUG_LAYOUT
          kdDebug() << "RenderPartObject::close - empty url and serverType" << endl;
#endif
          return;
      }
      
      // Turn the attributes of either the EMBED tag or OBJECT tag into an array.
      NamedAttrMapImpl* attributes = embedOrObject->attributes();
      if (attributes) {
          for (unsigned long i = 0; i < attributes->length(); ++i) {
              AttributeImpl* it = attributes->attributeItem(i);
              params.append(o->getDocument()->attrName(it->id()).string() + "=\"" + it->value().string() + "\"");
          }
      }
      
      params.append( QString::fromLatin1("__KHTML__CLASSID=\"%1\"").arg( o->classId ) );
      params.append( QString::fromLatin1("__KHTML__CODEBASE=\"%1\"").arg( o->getAttribute(ATTR_CODEBASE).string() ) );
      
      part->requestObject( this, url, serviceType, params );
  } else if ( element()->id() == ID_EMBED ) {

      HTMLEmbedElementImpl *o = static_cast<HTMLEmbedElementImpl *>(element());
      url = o->url;
      serviceType = o->serviceType;

      if ( url.isEmpty() && serviceType.isEmpty() ) {
#ifdef DEBUG_LAYOUT
          kdDebug() << "RenderPartObject::close - empty url and serverType" << endl;
#endif
          return;
      }
      // add all attributes set on the embed object
      NamedAttrMapImpl* a = o->attributes();
      if (a) {
          for (unsigned long i = 0; i < a->length(); ++i) {
              AttributeImpl* it = a->attributeItem(i);
              params.append(o->getDocument()->attrName(it->id()).string() + "=\"" + it->value().string() + "\"");
          }
      }
      part->requestObject( this, url, serviceType, params );
  } else {
      assert(element()->id() == ID_IFRAME);
      HTMLIFrameElementImpl *o = static_cast<HTMLIFrameElementImpl *>(element());
      url = o->url.string();
      if (url.isEmpty())
	  url = "about:blank";
      KHTMLView *v = static_cast<KHTMLView *>(m_view);
      bool requestSucceeded = v->part()->requestFrame( this, url, o->name.string(), QStringList(), true );
      if (requestSucceeded && QString::equals(url,"about:blank")) {
	  KHTMLPart *newPart = v->part()->findFrame( o->name.string() );
	  if (newPart && newPart->xmlDocImpl()) {
	      newPart->xmlDocImpl()->setBaseURL( v->part()->baseURL().url() );
	  }
      }
  }
}
NodeImpl *HTMLCollectionImpl::getNamedItem( NodeImpl *current, int attr_id,
					    const DOMString &name ) 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:   // all OBJECT and APPLET elements
		if(e->id() == ID_OBJECT || e->id() == ID_APPLET)
		    check = true;
		break;
	    case DOC_LINKS:     // all A _and_ AREA elements with a value for href
		if(e->id() == ID_A || e->id() == ID_AREA)
		    if(e->getAttribute(ATTR_HREF) != 0)
			check = true;
		break;
	    case DOC_ANCHORS:      // all A elements with a value for name
		if( e->hasID() )
		    check = true;
		else if(e->id() == ID_A)
		    if(e->getAttribute(ATTR_NAME) != 0)
			check = true;
		break;
	    case DOC_ALL:
		check = true;
		break;
	    default:
		kdDebug( 6030 ) << "Error in HTMLCollection, wrong tagId!" << endl;
		break;
	    }
	    if(check && e->getAttribute(attr_id) == name)
	    {
		//kdDebug( 6030 ) << "found node: " << e << " " << current << " " << e->id() << endl;
		return current;
	    }
	    NodeImpl *retval = 0;
	    if(deep && current->firstChild())
		retval = getNamedItem(current->firstChild(), attr_id, name);
	    if(retval)
	    {
		//kdDebug( 6030 ) << "got a return value " << retval << endl;
		return retval;
	    }
	}
	current = current->nextSibling();
    }
    return 0;
}
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:   // all OBJECT and APPLET elements
		if(e->id() == ID_OBJECT || e->id() == ID_APPLET)
		    len++;
		break;
	    case DOC_LINKS:     // all A _and_ AREA elements with a value for href
		if(e->id() == ID_A || e->id() == ID_AREA)
		    if(e->getAttribute(ATTR_HREF) != 0)
			len++;
		break;
	    case DOC_ANCHORS:      // all A elements with a value for name and all elements with an id attribute
		if ( e->hasID() )
		    len++;
		else if(e->id() == ID_A) {
		    if(e->getAttribute(ATTR_NAME) != 0)
			len++;
		}  
		break;
	    case DOC_ALL:      // "all" elements
		len++;
		break;
	    default:
		kdDebug( 6030 ) << "Error in HTMLCollection, wrong tagId!" << endl;
	    }
	    if(deep && current->firstChild())
		len += calcLength(current->firstChild());
	}
	current = current->nextSibling();
    }
    return len;
}
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:   // all OBJECT and APPLET elements
		if(e->id() == ID_OBJECT || e->id() == ID_APPLET)
		    len++;
		break;
	    case DOC_LINKS:     // all A _and_ AREA elements with a value for href
		if(e->id() == ID_A || e->id() == ID_AREA)
		    if(e->getAttribute(ATTR_HREF) != 0)
			len++;
		break;
	    case DOC_ANCHORS:      // all A elements with a value for name or an id attribute
		if( e->hasID() )
		    len++;
		else if(e->id() == ID_A)
		    if(e->getAttribute(ATTR_NAME) != 0)
			len++;
		break;
	    case DOC_ALL:
		len++;
		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;
}