khtml Library API Documentation

html_objectimpl.cpp

00001 
00023 #include "html/html_objectimpl.h"
00024 
00025 #include "khtml_part.h"
00026 #include "dom/dom_string.h"
00027 #include "misc/htmlhashes.h"
00028 #include "khtmlview.h"
00029 #include <qstring.h>
00030 #include <qvariant.h>
00031 #include <qmap.h>
00032 #include <qtimer.h>
00033 #include <kdebug.h>
00034 
00035 #include "xml/dom_docimpl.h"
00036 #include "css/cssstyleselector.h"
00037 #include "css/csshelper.h"
00038 #include "css/cssproperties.h"
00039 #include "css/cssvalues.h"
00040 #include "rendering/render_applet.h"
00041 #include "rendering/render_frames.h"
00042 #include "rendering/render_image.h"
00043 #include "xml/dom2_eventsimpl.h"
00044 
00045 #ifndef Q_WS_QWS // We don't have Java in Qt Embedded
00046 #include "java/kjavaappletwidget.h"
00047 #include "java/kjavaappletcontext.h"
00048 #endif
00049 
00050 using namespace DOM;
00051 using namespace khtml;
00052 
00053 // -------------------------------------------------------------------------
00054 LiveConnectElementImpl::LiveConnectElementImpl(DocumentPtr *doc)
00055   : HTMLElementImpl(doc), liveconnect(0L), timer (new QTimer(this)) {
00056     connect(timer, SIGNAL(timeout()), this, SLOT(timerDone()));
00057 }
00058 
00059 bool LiveConnectElementImpl::get(const unsigned long objid, const QString & field, KParts::LiveConnectExtension::Type & type, unsigned long & retobjid, QString & value) {
00060     if (!liveconnect)
00061         return false;
00062     return liveconnect->get(objid, field, type, retobjid, value);
00063 }
00064 
00065 bool LiveConnectElementImpl::put(const unsigned long objid, const QString & field, const QString & value) {
00066     if (!liveconnect)
00067         return false;
00068     return liveconnect->put(objid, field, value);
00069 }
00070 
00071 bool LiveConnectElementImpl::call(const unsigned long objid, const QString & func, const QStringList & args, KParts::LiveConnectExtension::Type & type, unsigned long & retobjid, QString & value) {
00072     if (!liveconnect)
00073         return false;
00074     return liveconnect->call(objid, func, args, type, retobjid, value);
00075 }
00076 
00077 void LiveConnectElementImpl::unregister(const unsigned long objid) {
00078     if (!liveconnect)
00079         return;
00080     liveconnect->unregister(objid);
00081 }
00082 
00083 void LiveConnectElementImpl::setLiveConnect(KParts::LiveConnectExtension * lc) {
00084     liveconnect = lc;
00085     if (lc)
00086         connect(lc, SIGNAL(partEvent(const unsigned long, const QString &, const KParts::LiveConnectExtension::ArgList &)), static_cast<LiveConnectElementImpl*>(this), SLOT(liveConnectEvent( const unsigned long, const QString&, const KParts::LiveConnectExtension::ArgList &)));
00087 }
00088 
00089 void LiveConnectElementImpl::liveConnectEvent(const unsigned long, const QString & event, const KParts::LiveConnectExtension::ArgList & args)
00090 {
00091     if (!liveconnect)
00092         // not attached
00093         return;
00094 
00095     if (timer->isActive()) {
00096         timerDone();
00097         timer->stop();
00098     }
00099     script.sprintf("%s(", event.latin1());
00100     KParts::LiveConnectExtension::ArgList::const_iterator i = args.begin();
00101     for ( ; i != args.end(); i++) {
00102         if (i != args.begin())
00103             script += ",";
00104         if ((*i).first == KParts::LiveConnectExtension::TypeString) {
00105             script += "\"";
00106             script += (*i).second;
00107             script += "\"";
00108         } else
00109             script += (*i).second;
00110     }
00111     script += ")";
00112 
00113     kdDebug(6036) << "LiveConnectElementImpl::liveConnectEvent " << script << endl;
00114     KHTMLView* w = getDocument()->view();
00115     w->part()->executeScript(this, script);
00116     //timer->start(0, true);
00117 }
00118 
00119 void LiveConnectElementImpl::timerDone() {
00120     KHTMLView* w = getDocument()->view();
00121     w->part()->executeScript(this, script);
00122 }
00123 
00124 void LiveConnectElementImpl::detach() {
00125     if (timer->isActive())
00126         timer->stop();
00127     setLiveConnect(0L);
00128 
00129     HTMLElementImpl::detach();
00130 }
00131 
00132 // -------------------------------------------------------------------------
00133 
00134 HTMLAppletElementImpl::HTMLAppletElementImpl(DocumentPtr *doc)
00135   : LiveConnectElementImpl(doc)
00136 {
00137 }
00138 
00139 HTMLAppletElementImpl::~HTMLAppletElementImpl()
00140 {
00141 }
00142 
00143 NodeImpl::Id HTMLAppletElementImpl::id() const
00144 {
00145     return ID_APPLET;
00146 }
00147 
00148 KJavaApplet* HTMLAppletElementImpl::applet() const
00149 {
00150 #ifndef Q_WS_QWS // We don't have Java in Qt Embedded
00151     if (!m_render || !m_render->isApplet())
00152         return 0L;
00153 
00154     return static_cast<KJavaAppletWidget*>(static_cast<RenderApplet*>(m_render)->widget())->applet();
00155 #else
00156     return 0;
00157 #endif
00158 }
00159 
00160 void HTMLAppletElementImpl::parseAttribute(AttributeImpl *attr)
00161 {
00162     switch( attr->id() )
00163     {
00164     case ATTR_CODEBASE:
00165     case ATTR_ARCHIVE:
00166     case ATTR_CODE:
00167     case ATTR_OBJECT:
00168     case ATTR_ALT:
00169     case ATTR_ID:
00170     case ATTR_NAME:
00171         break;
00172     case ATTR_WIDTH:
00173         addCSSLength(CSS_PROP_WIDTH, attr->value());
00174         break;
00175     case ATTR_HEIGHT:
00176         addCSSLength(CSS_PROP_HEIGHT, attr->value());
00177         break;
00178     case ATTR_ALIGN:
00179         addHTMLAlignment( attr->value() );
00180         break;
00181     default:
00182         HTMLElementImpl::parseAttribute(attr);
00183     }
00184 }
00185 
00186 void HTMLAppletElementImpl::attach()
00187 {
00188     if (!parentNode()->renderer() || getAttribute(ATTR_CODE).isNull()) {
00189         NodeBaseImpl::attach();
00190         return;
00191     }
00192 
00193     KHTMLView *view = getDocument()->view();
00194 
00195 #ifndef Q_WS_QWS // FIXME?
00196     KURL url = getDocument()->baseURL();
00197     DOMString codeBase = getAttribute( ATTR_CODEBASE );
00198     DOMString code = getAttribute( ATTR_CODE );
00199     if ( !codeBase.isEmpty() )
00200         url = KURL( url, codeBase.string() );
00201     if ( !code.isEmpty() )
00202         url = KURL( url, code.string() );
00203 
00204     if( view->part()->javaEnabled() && isURLAllowed( url.url() ) )
00205     {
00206         QMap<QString, QString> args;
00207 
00208         args.insert( "code", code.string());
00209         if(!codeBase.isNull())
00210             args.insert( "codeBase", codeBase.string() );
00211         DOMString name = getDocument()->htmlMode() != DocumentImpl::XHtml ?
00212                          getAttribute(ATTR_NAME) : getAttribute(ATTR_ID);
00213         if (name.isNull())
00214             setAttribute(ATTR_ID, code.string());
00215         else
00216             args.insert( "name", name.string() );
00217         DOMString archive = getAttribute(ATTR_ARCHIVE);
00218         if(!archive.isNull())
00219             args.insert( "archive", archive.string() );
00220 
00221         args.insert( "baseURL", getDocument()->baseURL() );
00222         m_render = new RenderApplet(this, args);
00223         setLiveConnect(applet()->getLiveConnectExtension());
00224 
00225         m_render->setStyle(getDocument()->styleSelector()->styleForElement(this));
00226         parentNode()->renderer()->addChild(m_render, nextRenderer());
00227         NodeBaseImpl::attach();
00228     }
00229     else
00230 #endif
00231         ElementImpl::attach();
00232 }
00233 
00234 // -------------------------------------------------------------------------
00235 
00236 HTMLEmbedElementImpl::HTMLEmbedElementImpl(DocumentPtr *doc)
00237     : LiveConnectElementImpl(doc)
00238 {
00239 }
00240 
00241 HTMLEmbedElementImpl::~HTMLEmbedElementImpl()
00242 {
00243 }
00244 
00245 NodeImpl::Id HTMLEmbedElementImpl::id() const
00246 {
00247     return ID_EMBED;
00248 }
00249 
00250 void HTMLEmbedElementImpl::parseAttribute(AttributeImpl *attr)
00251 {
00252   DOM::DOMStringImpl *stringImpl = attr->val();
00253   QConstString cv( stringImpl->s, stringImpl->l );
00254   QString val = cv.string();
00255 
00256   int pos;
00257   switch ( attr->id() )
00258   {
00259      case ATTR_TYPE:
00260         serviceType = val.lower();
00261         pos = serviceType.find( ";" );
00262         if ( pos!=-1 )
00263             serviceType = serviceType.left( pos );
00264         serviceType.truncate( serviceType.find( "-plugin" ) );
00265         break;
00266      case ATTR_CODE:
00267      case ATTR_SRC:
00268          url = khtml::parseURL(attr->val()).string();
00269          break;
00270      case ATTR_WIDTH:
00271         addCSSLength( CSS_PROP_WIDTH, attr->value() );
00272         break;
00273      case ATTR_HEIGHT:
00274         addCSSLength( CSS_PROP_HEIGHT, attr->value());
00275         break;
00276      case ATTR_BORDER:
00277         addCSSLength(CSS_PROP_BORDER_WIDTH, attr->value());
00278         addCSSProperty( CSS_PROP_BORDER_TOP_STYLE, CSS_VAL_SOLID );
00279         addCSSProperty( CSS_PROP_BORDER_RIGHT_STYLE, CSS_VAL_SOLID );
00280         addCSSProperty( CSS_PROP_BORDER_BOTTOM_STYLE, CSS_VAL_SOLID );
00281         addCSSProperty( CSS_PROP_BORDER_LEFT_STYLE, CSS_VAL_SOLID );
00282         break;
00283      case ATTR_VSPACE:
00284         addCSSLength(CSS_PROP_MARGIN_TOP, attr->value());
00285         addCSSLength(CSS_PROP_MARGIN_BOTTOM, attr->value());
00286         break;
00287      case ATTR_HSPACE:
00288         addCSSLength(CSS_PROP_MARGIN_LEFT, attr->value());
00289         addCSSLength(CSS_PROP_MARGIN_RIGHT, attr->value());
00290         break;
00291      case ATTR_ALIGN:
00292         addHTMLAlignment( attr->value() );
00293         break;
00294      case ATTR_VALIGN:
00295         addCSSProperty(CSS_PROP_VERTICAL_ALIGN, attr->value());
00296         break;
00297      case ATTR_PLUGINPAGE:
00298      case ATTR_PLUGINSPAGE:
00299         pluginPage = val;
00300         break;
00301      case ATTR_HIDDEN:
00302         if (val.lower()=="yes" || val.lower()=="true")
00303            hidden = true;
00304         else
00305            hidden = false;
00306         break;
00307      default:
00308         HTMLElementImpl::parseAttribute( attr );
00309   }
00310 }
00311 
00312 void HTMLEmbedElementImpl::attach()
00313 {
00314     assert(!attached());
00315     assert(!m_render);
00316 
00317     if (parentNode()->renderer()) {
00318         KHTMLView* w = getDocument()->view();
00319         RenderStyle* _style = getDocument()->styleSelector()->styleForElement( this );
00320         _style->ref();
00321 
00322         if (w->part()->pluginsEnabled() && isURLAllowed( url ) &&
00323             parentNode()->id() != ID_OBJECT && _style->display() != NONE ) {
00324             m_render = new RenderPartObject(this);
00325             m_render->setStyle(_style );
00326             parentNode()->renderer()->addChild(m_render, nextRenderer());
00327             static_cast<RenderPartObject*>(m_render)->updateWidget();
00328             setLiveConnect(w->part()->liveConnectExtension(static_cast<RenderPartObject*>(m_render)));
00329         }
00330         _style->deref();
00331     }
00332 
00333     NodeBaseImpl::attach();
00334 }
00335 
00336 // -------------------------------------------------------------------------
00337 
00338 HTMLObjectElementImpl::HTMLObjectElementImpl(DocumentPtr *doc)
00339     : LiveConnectElementImpl(doc)
00340 {
00341     needWidgetUpdate = false;
00342     m_renderAlternative = false;
00343 }
00344 
00345 HTMLObjectElementImpl::~HTMLObjectElementImpl()
00346 {
00347 }
00348 
00349 NodeImpl::Id HTMLObjectElementImpl::id() const
00350 {
00351     return ID_OBJECT;
00352 }
00353 
00354 HTMLFormElementImpl *HTMLObjectElementImpl::form() const
00355 {
00356   return 0;
00357 }
00358 
00359 void HTMLObjectElementImpl::parseAttribute(AttributeImpl *attr)
00360 {
00361   DOM::DOMStringImpl *stringImpl = attr->val();
00362   QString val = QConstString( stringImpl->s, stringImpl->l ).string();
00363   int pos;
00364   switch ( attr->id() )
00365   {
00366     case ATTR_TYPE:
00367     case ATTR_CODETYPE:
00368       serviceType = val.lower();
00369       pos = serviceType.find( ";" );
00370       if ( pos!=-1 )
00371           serviceType = serviceType.left( pos );
00372       serviceType.truncate( serviceType.find( "-plugin" ) );
00373       needWidgetUpdate = true;
00374       break;
00375     case ATTR_DATA:
00376       url = khtml::parseURL( val ).string();
00377       needWidgetUpdate = true;
00378       break;
00379     case ATTR_WIDTH:
00380       addCSSLength( CSS_PROP_WIDTH, attr->value());
00381       break;
00382     case ATTR_HEIGHT:
00383       addCSSLength( CSS_PROP_HEIGHT, attr->value());
00384       break;
00385     case ATTR_CLASSID:
00386       classId = val;
00387       needWidgetUpdate = true;
00388       break;
00389     case ATTR_ONLOAD: // ### support load/unload on object elements
00390         setHTMLEventListener(EventImpl::LOAD_EVENT,
00391             getDocument()->createHTMLEventListener(attr->value().string()));
00392         break;
00393     case ATTR_ONUNLOAD:
00394         setHTMLEventListener(EventImpl::UNLOAD_EVENT,
00395             getDocument()->createHTMLEventListener(attr->value().string()));
00396         break;
00397     default:
00398       HTMLElementImpl::parseAttribute( attr );
00399   }
00400 }
00401 
00402 DocumentImpl* HTMLObjectElementImpl::contentDocument() const
00403 {
00404     if ( !m_render ) return 0;
00405     if ( !m_render->isWidget() ) return 0;
00406     QWidget* widget = static_cast<RenderWidget*>( m_render )->widget();
00407     if( widget && widget->inherits("KHTMLView") )
00408         return static_cast<KHTMLView*>( widget )->part()->xmlDocImpl();
00409     return 0;
00410 }
00411 
00412 void HTMLObjectElementImpl::attach()
00413 {
00414     assert(!attached());
00415     assert(!m_render);
00416 
00417     KHTMLView* w = getDocument()->view();
00418     if ( !w->part()->pluginsEnabled() ||
00419          ( url.isEmpty() && classId.isEmpty() ) ||
00420          m_renderAlternative || !isURLAllowed( url ) ) {
00421         // render alternative content
00422         ElementImpl::attach();
00423         return;
00424     }
00425 
00426     RenderStyle* _style = getDocument()->styleSelector()->styleForElement(this);
00427     _style->ref();
00428 
00429     if (parentNode()->renderer() && _style->display() != NONE) {
00430         needWidgetUpdate=false;
00431         bool imagelike = serviceType.startsWith("image/");
00432         if (imagelike)
00433             m_render = new RenderImage(this);
00434         else
00435             m_render = new RenderPartObject(this);
00436 
00437         m_render->setStyle(_style);
00438         parentNode()->renderer()->addChild(m_render, nextRenderer());
00439         if (imagelike)
00440             m_render->updateFromElement();
00441     }
00442 
00443     _style->deref();
00444 
00445     NodeBaseImpl::attach();
00446 
00447     // ### do this when we are actually finished loading instead
00448     if (m_render)  dispatchHTMLEvent(EventImpl::LOAD_EVENT,false,false);
00449 }
00450 
00451 void HTMLObjectElementImpl::detach()
00452 {
00453     if (attached())
00454         // ### do this when we are actualy removed from document instead
00455         dispatchHTMLEvent(EventImpl::UNLOAD_EVENT,false,false);
00456 
00457   HTMLElementImpl::detach();
00458 }
00459 
00460 void HTMLObjectElementImpl::renderAlternative()
00461 {
00462     // an unbelievable hack. FIXME!!
00463 
00464     if ( m_renderAlternative ) return;
00465 
00466     if ( attached() )
00467         detach();
00468 
00469     m_renderAlternative = true;
00470 
00471     attach();
00472 }
00473 
00474 void HTMLObjectElementImpl::recalcStyle( StyleChange ch )
00475 {
00476     if (needWidgetUpdate) {
00477         if(m_render && strcmp( m_render->renderName(),  "RenderPartObject" ) == 0 )
00478             static_cast<RenderPartObject*>(m_render)->updateWidget();
00479         needWidgetUpdate = false;
00480     }
00481     HTMLElementImpl::recalcStyle( ch );
00482 }
00483 
00484 // -------------------------------------------------------------------------
00485 
00486 NodeImpl::Id HTMLParamElementImpl::id() const
00487 {
00488     return ID_PARAM;
00489 }
00490 
00491 void HTMLParamElementImpl::parseAttribute(AttributeImpl *attr)
00492 {
00493     switch( attr->id() )
00494     {
00495     case ATTR_ID:
00496         if (getDocument()->htmlMode() != DocumentImpl::XHtml) break;
00497         // fall through
00498     case ATTR_NAME:
00499         m_name = attr->value().string();
00500         break;
00501     case ATTR_VALUE:
00502         m_value = attr->value().string();
00503         break;
00504     }
00505 }
00506 
00507 #include "html_objectimpl.moc"
KDE Logo
This file is part of the documentation for kdelibs Version 3.1.5.
Documentation copyright © 1996-2002 the KDE developers.
Generated on Wed Jan 28 13:33:57 2004 by doxygen 1.3.4 written by Dimitri van Heesch, © 1997-2001