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
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
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:
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
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
00448 if (m_render) dispatchHTMLEvent(EventImpl::LOAD_EVENT,false,false);
00449 }
00450
00451 void HTMLObjectElementImpl::detach()
00452 {
00453 if (attached())
00454
00455 dispatchHTMLEvent(EventImpl::UNLOAD_EVENT,false,false);
00456
00457 HTMLElementImpl::detach();
00458 }
00459
00460 void HTMLObjectElementImpl::renderAlternative()
00461 {
00462
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
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"