fix logic
[personal-kdelibs.git] / khtml / html / html_objectimpl.cpp
blobf4980632df21b42edd1a8fdc7730d4b1a3918567
1 /**
2 * This file is part of the DOM implementation for KDE.
4 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
5 * (C) 1999 Antti Koivisto (koivisto@kde.org)
6 * (C) 2000 Stefan Schimanski (1Stein@gmx.de)
7 * (C) 2007, 2008 Maks Orlovich (maksim@kde.org)
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Library General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Library General Public License for more details.
19 * You should have received a copy of the GNU Library General Public License
20 * along with this library; see the file COPYING.LIB. If not, write to
21 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22 * Boston, MA 02110-1301, USA.
24 #include "html/html_objectimpl.h"
26 #include "khtml_part.h"
27 #include "dom/dom_string.h"
28 #include "misc/htmlhashes.h"
29 #include "imload/imagemanager.h"
30 #include "khtmlview.h"
31 #include <QtCore/QCharRef>
32 #include <QtCore/QVariant>
33 #include <QtCore/QMap>
34 #include <QtCore/QTimer>
35 #include <QImageReader>
37 #include <kdebug.h>
38 #include <kmessagebox.h>
39 #include <kmimetype.h>
42 #include "xml/dom_docimpl.h"
43 #include "css/cssstyleselector.h"
44 #include "css/csshelper.h"
45 #include "css/cssproperties.h"
46 #include "css/cssvalues.h"
47 #include "rendering/render_frames.h"
48 #include "rendering/render_image.h"
49 #include "xml/dom2_eventsimpl.h"
51 using namespace DOM;
52 using namespace khtml;
54 HTMLPartContainerElementImpl::HTMLPartContainerElementImpl(DocumentImpl *doc)
55 : HTMLElementImpl(doc)
57 m_needToComputeContent = true;
58 m_childWidget = 0;
61 HTMLPartContainerElementImpl::~HTMLPartContainerElementImpl()
63 // Kill the renderer here, since we are asking for a widget to be deleted
64 if (m_render)
65 detach();
67 if (m_childWidget)
68 m_childWidget->deleteLater();
71 void HTMLPartContainerElementImpl::recalcStyle(StyleChange ch)
73 computeContentIfNeeded();
75 HTMLElementImpl::recalcStyle( ch );
78 void HTMLPartContainerElementImpl::close()
80 HTMLElementImpl::close(); // Do it first, to make sure closed() is set.
81 computeContentIfNeeded();
84 void HTMLPartContainerElementImpl::computeContentIfNeeded()
86 if (!m_needToComputeContent)
87 return;
89 m_needToComputeContent = false;
90 computeContent();
93 void HTMLPartContainerElementImpl::setNeedComputeContent()
95 m_needToComputeContent = true;
96 if (closed())
97 setChanged(); //React quickly when not in the middle of parsing..
100 void HTMLPartContainerElementImpl::setWidget(QWidget* widget)
102 if (widget == m_childWidget)
103 return; // The same part got navigated. Don't do anything
105 QWidget* oldWidget = m_childWidget;
106 m_childWidget = widget;
107 if (m_childWidget)
108 m_childWidget->hide();
110 setWidgetNotify(m_childWidget);
111 if (oldWidget) {
112 oldWidget->hide();
113 oldWidget->deleteLater();
117 void HTMLPartContainerElementImpl::partLoadingErrorNotify()
119 clearChildWidget();
122 void HTMLPartContainerElementImpl::clearChildWidget()
124 setWidget(0);
127 bool HTMLPartContainerElementImpl::mimetypeHandledInternally(const QString&)
129 return false;
132 void HTMLPartContainerElementImpl::slotEmitLoadEvent()
134 dispatchHTMLEvent(EventImpl::LOAD_EVENT, false, false);
137 // -------------------------------------------------------------------------
138 HTMLObjectBaseElementImpl::HTMLObjectBaseElementImpl(DocumentImpl *doc)
139 : HTMLPartContainerElementImpl(doc)
141 m_renderAlternative = false;
142 m_imageLike = false;
143 m_rerender = false;
146 void HTMLObjectBaseElementImpl::setServiceType(const QString & val) {
147 serviceType = val.toLower();
148 int pos = serviceType.indexOf( ";" );
149 if ( pos!=-1 )
150 serviceType.truncate( pos );
153 void HTMLObjectBaseElementImpl::parseAttribute(AttributeImpl *attr)
155 switch ( attr->id() )
157 case ATTR_TYPE:
158 case ATTR_CODETYPE:
159 if (attr->val()) {
160 DOM::DOMStringImpl *stringImpl = attr->val();
161 QString val = QString::fromRawData( stringImpl->s, stringImpl->l );
162 setServiceType( val );
163 setNeedComputeContent();
165 break;
166 case ATTR_WIDTH:
167 if (!attr->value().isEmpty())
168 addCSSLength(CSS_PROP_WIDTH, attr->value());
169 else
170 removeCSSProperty(CSS_PROP_WIDTH);
171 break;
172 case ATTR_HEIGHT:
173 if (!attr->value().isEmpty())
174 addCSSLength(CSS_PROP_HEIGHT, attr->value());
175 else
176 removeCSSProperty(CSS_PROP_HEIGHT);
177 break;
178 case ATTR_NAME:
179 if (inDocument() && m_name != attr->value()) {
180 document()->underDocNamedCache().remove(m_name.string(), this);
181 document()->underDocNamedCache().add (attr->value().string(), this);
183 m_name = attr->value();
184 //fallthrough
185 default:
186 HTMLElementImpl::parseAttribute( attr );
191 void HTMLObjectBaseElementImpl::defaultEventHandler(EventImpl *e)
193 // ### duplicated in HTMLIFrameElementImpl
194 if ( e->target() == this && m_render && m_render->isWidget()
195 && static_cast<RenderWidget*>(m_render)->isRedirectedWidget()
196 && qobject_cast<KHTMLView*>(static_cast<RenderWidget*>(m_render)->widget())) {
197 switch(e->id()) {
198 case EventImpl::MOUSEDOWN_EVENT:
199 case EventImpl::MOUSEUP_EVENT:
200 case EventImpl::MOUSEMOVE_EVENT:
201 case EventImpl::MOUSEOUT_EVENT:
202 case EventImpl::MOUSEOVER_EVENT:
203 case EventImpl::KHTML_MOUSEWHEEL_EVENT:
204 case EventImpl::KEYDOWN_EVENT:
205 case EventImpl::KEYUP_EVENT:
206 case EventImpl::KEYPRESS_EVENT:
207 case EventImpl::DOMFOCUSIN_EVENT:
208 case EventImpl::DOMFOCUSOUT_EVENT:
209 if (static_cast<RenderWidget*>(m_render)->handleEvent(*e))
210 e->setDefaultHandled();
211 default:
212 break;
215 HTMLElementImpl::defaultEventHandler(e);
219 void HTMLObjectBaseElementImpl::removedFromDocument()
221 document()->underDocNamedCache().remove(m_name.string(), this);
222 HTMLElementImpl::removedFromDocument();
225 void HTMLObjectBaseElementImpl::insertedIntoDocument()
227 document()->underDocNamedCache().add(m_name.string(), this);
228 HTMLElementImpl::insertedIntoDocument();
231 void HTMLObjectBaseElementImpl::removeId(const QString& id)
233 document()->underDocNamedCache().remove(id, this);
234 HTMLElementImpl::removeId(id);
237 void HTMLObjectBaseElementImpl::addId (const QString& id)
239 document()->underDocNamedCache().add(id, this);
240 HTMLElementImpl::addId(id);
243 void HTMLObjectBaseElementImpl::requestRerender()
245 if (m_rerender) return;
246 m_rerender = true;
247 QTimer::singleShot( 0, this, SLOT( slotRerender()) );
250 void HTMLObjectBaseElementImpl::slotRerender()
252 // the singleshot timer might have fired after we're removed
253 // from the document, but not yet deleted due to references
254 if ( !inDocument() || !m_rerender ) return;
256 // ### there can be a m_render if this is called from our attach indirectly
257 if ( attached() || m_render) {
258 detach();
259 attach();
262 m_rerender = false;
265 void HTMLObjectBaseElementImpl::attach() {
266 assert(!attached());
267 assert(!m_render);
269 computeContentIfNeeded();
270 m_rerender = false;
272 if (m_renderAlternative && !m_imageLike) {
273 // render alternative content
274 ElementImpl::attach();
275 return;
278 if (!parentNode()->renderer()) {
279 NodeBaseImpl::attach();
280 return;
283 RenderStyle* _style = document()->styleSelector()->styleForElement(this);
284 _style->ref();
286 if (parentNode()->renderer() && parentNode()->renderer()->childAllowed() &&
287 _style->display() != NONE)
289 if (m_imageLike) {
290 m_render = new (document()->renderArena()) RenderImage(this);
291 // make sure we don't attach the inner contents
292 addCSSProperty(CSS_PROP_DISPLAY, CSS_VAL_NONE);
294 else {
295 m_render = new (document()->renderArena()) RenderPartObject(this);
296 // If we already have a widget, set it.
297 if (childWidget())
298 static_cast<RenderFrame*>(m_render)->setWidget(childWidget());
301 m_render->setStyle(_style);
302 parentNode()->renderer()->addChild(m_render, nextRenderer());
303 if (m_imageLike)
304 m_render->updateFromElement();
307 _style->deref();
308 NodeBaseImpl::attach();
311 HTMLEmbedElementImpl* HTMLObjectBaseElementImpl::relevantEmbed()
313 for (NodeImpl *child = firstChild(); child; child = child->nextSibling()) {
314 if ( child->id() == ID_EMBED ) {
315 return static_cast<HTMLEmbedElementImpl *>( child );
319 return 0;
322 bool HTMLObjectBaseElementImpl::mimetypeHandledInternally(const QString& mime)
324 QStringList supportedImageTypes = khtmlImLoad::ImageManager::loaderDatabase()->supportedMimeTypes();
326 bool newImageLike = supportedImageTypes.contains(mime);
328 if (newImageLike != m_imageLike) {
329 m_imageLike = newImageLike;
330 requestRerender();
333 return newImageLike; // No need for kpart for that.
336 void HTMLObjectBaseElementImpl::computeContent()
338 QStringList params;
339 QString effectiveURL = url; // May be overwritten by some of the <params>
340 // if the URL isn't there
341 QString effectiveServiceType = serviceType;
343 // We need to wait until everything has parsed, since we need the <param>s,
344 // and the embedded <embed>
345 if (!closed()) {
346 setNeedComputeContent();
347 return;
350 // Collect information from <param> children for ...
351 // It also sometimes supplements or replaces some of the element's attributes
352 for (NodeImpl* child = firstChild(); child; child = child->nextSibling()) {
353 if (child->id() == ID_PARAM) {
354 HTMLParamElementImpl *p = static_cast<HTMLParamElementImpl *>( child );
356 QString aStr = p->name();
357 aStr += QLatin1String("=\"");
358 aStr += p->value();
359 aStr += QLatin1String("\"");
360 QString name_lower = p->name().toLower();
361 if (name_lower == QLatin1String("type") && id() != ID_APPLET) {
362 setServiceType(p->value());
363 effectiveServiceType = serviceType;
364 } else if (effectiveURL.isEmpty() &&
365 (name_lower == QLatin1String("src") ||
366 name_lower == QLatin1String("movie") ||
367 name_lower == QLatin1String("code"))) {
368 effectiveURL = p->value();
370 params.append(aStr);
374 // For <applet>(?) and <embed> we also make each attribute a part parameter
375 if (id() != ID_OBJECT) {
376 NamedAttrMapImpl* a = attributes();
377 if (a) {
378 for (unsigned i = 0; i < a->length(); ++i) {
379 NodeImpl::Id id = a->idAt(i);
380 DOMString value = a->valueAt(i);
381 params.append(LocalName::fromId(localNamePart(id)).toString().string() + "=\"" + value.string() + "\"");
386 params.append( QLatin1String("__KHTML__PLUGINEMBED=\"YES\"") );
387 params.append( QString::fromLatin1("__KHTML__PLUGINBASEURL=\"%1\"").arg(document()->baseURL().url()));
389 // Non-embed elements parse a bunch of attributes and inherit things off <embed>, if any
390 HTMLEmbedElementImpl* embed = relevantEmbed();
391 if (id() != ID_EMBED) {
392 params.append( QString::fromLatin1("__KHTML__CLASSID=\"%1\"").arg( classId ) );
393 params.append( QString::fromLatin1("__KHTML__CODEBASE=\"%1\"").arg( getAttribute(ATTR_CODEBASE).string() ) );
395 if (embed && !embed->getAttribute(ATTR_WIDTH).isEmpty())
396 setAttribute(ATTR_WIDTH, embed->getAttribute(ATTR_WIDTH));
398 if (embed && !embed->getAttribute(ATTR_HEIGHT).isEmpty())
399 setAttribute(ATTR_HEIGHT, embed->getAttribute(ATTR_HEIGHT));
401 if (!getAttribute(ATTR_WIDTH).isEmpty())
402 params.append( QString::fromLatin1("WIDTH=\"%1\"").arg( getAttribute(ATTR_WIDTH).string() ) );
404 if (!getAttribute(ATTR_HEIGHT).isEmpty())
405 params.append( QString::fromLatin1("HEIGHT=\"%1\"").arg( getAttribute(ATTR_HEIGHT).string() ) );
407 // Fix up the serviceType from embed, or applet info..
408 if (embed) {
409 effectiveURL = embed->url;
410 if (!embed->serviceType.isEmpty())
411 effectiveServiceType = embed->serviceType;
412 } else if (effectiveURL.isEmpty() &&
413 classId.startsWith(QLatin1String("java:"))) {
414 effectiveServiceType = "application/x-java-applet";
415 effectiveURL = classId.mid(5);
418 // Translate ActiveX gibberish into mimetypes
419 if ((effectiveServiceType.isEmpty() || serviceType == "application/x-oleobject") && !classId.isEmpty()) {
420 if(classId.indexOf(QString::fromLatin1("D27CDB6E-AE6D-11cf-96B8-444553540000")) >= 0)
421 effectiveServiceType = "application/x-shockwave-flash";
422 else if(classId.indexOf(QLatin1String("CFCDAA03-8BE4-11cf-B84B-0020AFBBCCFA")) >= 0)
423 effectiveServiceType = "audio/x-pn-realaudio-plugin";
424 else if(classId.indexOf(QLatin1String("8AD9C840-044E-11D1-B3E9-00805F499D93")) >= 0 ||
425 classId.indexOf(QLatin1String("CAFEEFAC-0014-0000-0000-ABCDEFFEDCBA")) >= 0)
426 effectiveServiceType = "application/x-java-applet";
427 // http://www.apple.com/quicktime/tools_tips/tutorials/activex.html
428 else if(classId.indexOf(QLatin1String("02BF25D5-8C17-4B23-BC80-D3488ABDDC6B")) >= 0)
429 effectiveServiceType = "video/quicktime";
430 // http://msdn.microsoft.com/library/en-us/dnwmt/html/adding_windows_media_to_web_pages__etse.asp?frame=true
431 else if(classId.indexOf(QString::fromLatin1("6BF52A52-394A-11d3-B153-00C04F79FAA6")) >= 0 ||
432 classId.indexOf(QString::fromLatin1("22D6f312-B0F6-11D0-94AB-0080C74C7E95")) >= 0)
433 effectiveServiceType = "video/x-msvideo";
434 else
435 kDebug(6031) << "ActiveX classId " << classId;
437 // TODO: add more plugins here
441 if (effectiveServiceType.isEmpty() &&
442 effectiveURL.startsWith(QLatin1String("data:"))) {
443 // Extract the MIME type from the data URL.
444 int index = effectiveURL.indexOf(';');
445 if (index == -1)
446 index = effectiveURL.indexOf(',');
447 if (index != -1) {
448 int len = index - 5;
449 if (len > 0)
450 effectiveServiceType = effectiveURL.mid(5, len);
451 else
452 effectiveServiceType = "text/plain"; // Data URLs with no MIME type are considered text/plain.
456 // Figure out if may be we're image-like. In this case, we don't need to load anything,
457 // but may need to do a detach/attach
458 QStringList supportedImageTypes = khtmlImLoad::ImageManager::loaderDatabase()->supportedMimeTypes();
460 bool newImageLike = effectiveServiceType.startsWith(QLatin1String("image/")) && supportedImageTypes.contains(effectiveServiceType);
462 if (newImageLike != m_imageLike) {
463 m_imageLike = newImageLike;
464 requestRerender();
467 if (m_imageLike)
468 return;
470 // Now see if we have to render alternate content.
471 bool newRenderAlternative = false;
473 // If we aren't permitted to load this by security policy, render alternative content instead.
474 if (!document()->isURLAllowed(effectiveURL))
475 newRenderAlternative = true;
477 // If Java is off, render alternative as well...
478 if (effectiveServiceType == "application/x-java-applet") {
479 KHTMLPart* p = document()->part();
480 if (!p || !p->javaEnabled())
481 newRenderAlternative = true;
484 // If there is no <embed> (here or as a child), and we don't have a type + url to go on,
485 // we need to render alternative as well
486 if (!embed && effectiveURL.isEmpty() && (effectiveServiceType.isEmpty() || classId.isEmpty()))
487 newRenderAlternative = true;
489 if (newRenderAlternative != m_renderAlternative) {
490 m_renderAlternative = newRenderAlternative;
491 requestRerender();
494 if (m_renderAlternative)
495 return;
497 KHTMLPart* part = document()->part();
498 clearChildWidget();
500 kDebug(6031) << effectiveURL << effectiveServiceType << params;
502 if (!part->requestObject( this, effectiveURL, effectiveServiceType, params)) {
503 // Looks like we are gonna need alternative content after all...
504 m_renderAlternative = true;
507 // Either way, we need to re-attach, either for alternative content, or because
508 // we got the part..
509 requestRerender();
512 void HTMLObjectBaseElementImpl::setWidgetNotify(QWidget *widget)
514 // Ick.
515 if(m_render && strcmp( m_render->renderName(), "RenderPartObject" ) == 0 )
516 static_cast<RenderPartObject*>(m_render)->setWidget(widget);
519 void HTMLObjectBaseElementImpl::renderAlternative()
521 if (m_renderAlternative)
522 return;
524 m_renderAlternative = true;
525 requestRerender();
528 void HTMLObjectBaseElementImpl::partLoadingErrorNotify()
530 // Defer ourselves from the current event loop (to prevent crashes due to the message box staying up)
531 QTimer::singleShot(0, this, SLOT(slotPartLoadingErrorNotify()));
533 // Either way, we don't have stuff to display, so have to render alternative content.
534 if (!m_renderAlternative) {
535 m_renderAlternative = true;
536 requestRerender();
539 clearChildWidget();
542 void HTMLObjectBaseElementImpl::slotPartLoadingErrorNotify()
544 // If we have an embed, we may be able to tell the user where to
545 // download the plugin.
547 HTMLEmbedElementImpl *embed = relevantEmbed();
548 QString serviceType; // shadows ours, but we don't care.
550 if (!embed)
551 return;
553 serviceType = embed->serviceType;
555 KHTMLPart* part = document()->part();
556 KParts::BrowserExtension *ext = part->browserExtension();
558 if(!embed->pluginPage.isEmpty() && ext) {
559 // Prepare the mimetype to show in the question (comment if available, name as fallback)
560 QString mimeName = serviceType;
561 KMimeType::Ptr mime = KMimeType::mimeType(serviceType, KMimeType::ResolveAliases);
562 if ( mime && mime->name() != KMimeType::defaultMimeType() )
563 mimeName = mime->comment();
565 // Check if we already asked the user, for this page
566 if (!mimeName.isEmpty() && !part->pluginPageQuestionAsked(serviceType))
568 part->setPluginPageQuestionAsked(serviceType);
570 // Prepare the URL to show in the question (host only if http, to make it short)
571 KUrl pluginPageURL(embed->pluginPage);
572 QString shortURL = pluginPageURL.protocol() == "http" ? pluginPageURL.host() : pluginPageURL.prettyUrl();
573 int res = KMessageBox::questionYesNo( part->view(),
574 i18n("No plugin found for '%1'.\nDo you want to download one from %2?", mimeName, shortURL),
575 i18n("Missing Plugin"), KGuiItem(i18n("Download")), KGuiItem(i18n("Do Not Download")), QString("plugin-")+serviceType);
576 if (res == KMessageBox::Yes)
578 // Display vendor download page
579 ext->createNewWindow(pluginPageURL);
580 return;
587 // -------------------------------------------------------------------------
589 HTMLAppletElementImpl::HTMLAppletElementImpl(DocumentImpl *doc)
590 : HTMLObjectBaseElementImpl(doc)
592 serviceType = "application/x-java-applet";
595 HTMLAppletElementImpl::~HTMLAppletElementImpl()
599 NodeImpl::Id HTMLAppletElementImpl::id() const
601 return ID_APPLET;
604 void HTMLAppletElementImpl::parseAttribute(AttributeImpl *attr)
606 switch( attr->id() )
608 case ATTR_CODEBASE:
609 case ATTR_ARCHIVE:
610 case ATTR_CODE:
611 case ATTR_OBJECT:
612 case ATTR_ALT:
613 break;
614 case ATTR_ALIGN:
615 addHTMLAlignment( attr->value() );
616 break;
617 case ATTR_VSPACE:
618 addCSSLength(CSS_PROP_MARGIN_TOP, attr->value());
619 addCSSLength(CSS_PROP_MARGIN_BOTTOM, attr->value());
620 break;
621 case ATTR_HSPACE:
622 addCSSLength(CSS_PROP_MARGIN_LEFT, attr->value());
623 addCSSLength(CSS_PROP_MARGIN_RIGHT, attr->value());
624 break;
625 case ATTR_VALIGN:
626 addCSSProperty(CSS_PROP_VERTICAL_ALIGN, attr->value().lower() );
627 break;
628 default:
629 HTMLObjectBaseElementImpl::parseAttribute(attr);
633 void HTMLAppletElementImpl::computeContent()
635 DOMString codeBase = getAttribute( ATTR_CODEBASE );
636 DOMString code = getAttribute( ATTR_CODE );
637 if ( !codeBase.isEmpty() )
638 url = codeBase.string();
639 if ( !code.isEmpty() )
640 url = code.string();
641 HTMLObjectBaseElementImpl::computeContent();
644 // -------------------------------------------------------------------------
646 HTMLEmbedElementImpl::HTMLEmbedElementImpl(DocumentImpl *doc)
647 : HTMLObjectBaseElementImpl(doc)
651 HTMLEmbedElementImpl::~HTMLEmbedElementImpl()
655 NodeImpl::Id HTMLEmbedElementImpl::id() const
657 return ID_EMBED;
660 HTMLEmbedElementImpl* HTMLEmbedElementImpl::relevantEmbed()
662 return this;
665 void HTMLEmbedElementImpl::parseAttribute(AttributeImpl *attr)
667 switch ( attr->id() )
669 case ATTR_CODE:
670 case ATTR_SRC:
671 url = khtml::parseURL(attr->val()).string();
672 setNeedComputeContent();
673 break;
674 case ATTR_BORDER:
675 addCSSLength(CSS_PROP_BORDER_WIDTH, attr->value());
676 addCSSProperty( CSS_PROP_BORDER_TOP_STYLE, CSS_VAL_SOLID );
677 addCSSProperty( CSS_PROP_BORDER_RIGHT_STYLE, CSS_VAL_SOLID );
678 addCSSProperty( CSS_PROP_BORDER_BOTTOM_STYLE, CSS_VAL_SOLID );
679 addCSSProperty( CSS_PROP_BORDER_LEFT_STYLE, CSS_VAL_SOLID );
680 break;
681 case ATTR_VSPACE:
682 addCSSLength(CSS_PROP_MARGIN_TOP, attr->value());
683 addCSSLength(CSS_PROP_MARGIN_BOTTOM, attr->value());
684 break;
685 case ATTR_HSPACE:
686 addCSSLength(CSS_PROP_MARGIN_LEFT, attr->value());
687 addCSSLength(CSS_PROP_MARGIN_RIGHT, attr->value());
688 break;
689 case ATTR_ALIGN:
690 addHTMLAlignment( attr->value() );
691 break;
692 case ATTR_VALIGN:
693 addCSSProperty(CSS_PROP_VERTICAL_ALIGN, attr->value().lower() );
694 break;
695 case ATTR_PLUGINPAGE:
696 case ATTR_PLUGINSPAGE: {
697 pluginPage = attr->value().string();
698 break;
700 case ATTR_HIDDEN:
701 if (strcasecmp( attr->value(), "yes" ) == 0 || strcasecmp( attr->value() , "true") == 0 )
702 hidden = true;
703 else
704 hidden = false;
705 break;
706 default:
707 HTMLObjectBaseElementImpl::parseAttribute( attr );
711 void HTMLEmbedElementImpl::attach()
713 KHTMLPart* p = document()->part();
715 if (!p || !p->pluginsEnabled())
716 m_renderAlternative = true;
718 if (parentNode()->id() == ID_OBJECT)
719 NodeBaseImpl::attach();
720 else
721 HTMLObjectBaseElementImpl::attach();
724 void HTMLEmbedElementImpl::computeContent()
726 if (parentNode()->id() != ID_OBJECT)
727 HTMLObjectBaseElementImpl::computeContent();
730 // -------------------------------------------------------------------------
732 HTMLObjectElementImpl::HTMLObjectElementImpl(DocumentImpl *doc)
733 : HTMLObjectBaseElementImpl(doc)
737 HTMLObjectElementImpl::~HTMLObjectElementImpl()
741 NodeImpl::Id HTMLObjectElementImpl::id() const
743 return ID_OBJECT;
746 HTMLFormElementImpl *HTMLObjectElementImpl::form() const
748 return 0;
751 void HTMLObjectElementImpl::parseAttribute(AttributeImpl *attr)
753 switch ( attr->id() )
755 case ATTR_DATA:
756 url = khtml::parseURL( attr->val() ).string();
757 setNeedComputeContent();
758 break;
759 case ATTR_CLASSID:
760 classId = attr->value().string();
761 setNeedComputeContent();
762 break;
763 case ATTR_ONLOAD: // ### support load/unload on object elements
764 setHTMLEventListener(EventImpl::LOAD_EVENT,
765 document()->createHTMLEventListener(attr->value().string(), "onload", this));
766 break;
767 case ATTR_ONUNLOAD:
768 setHTMLEventListener(EventImpl::UNLOAD_EVENT,
769 document()->createHTMLEventListener(attr->value().string(), "onunload", this));
770 break;
771 case ATTR_VSPACE:
772 addCSSLength(CSS_PROP_MARGIN_TOP, attr->value());
773 addCSSLength(CSS_PROP_MARGIN_BOTTOM, attr->value());
774 break;
775 case ATTR_HSPACE:
776 addCSSLength(CSS_PROP_MARGIN_LEFT, attr->value());
777 addCSSLength(CSS_PROP_MARGIN_RIGHT, attr->value());
778 break;
779 case ATTR_ALIGN:
780 addHTMLAlignment( attr->value() );
781 break;
782 case ATTR_VALIGN:
783 addCSSProperty(CSS_PROP_VERTICAL_ALIGN, attr->value().lower() );
784 break;
785 default:
786 HTMLObjectBaseElementImpl::parseAttribute( attr );
790 DocumentImpl* HTMLObjectElementImpl::contentDocument() const
792 if ( !m_render ) return 0;
793 if ( !m_render->isWidget() ) return 0;
794 QWidget* widget = static_cast<RenderWidget*>( m_render )->widget();
795 if( widget && qobject_cast<KHTMLView*>( widget ) )
796 return static_cast<KHTMLView*>( widget )->part()->xmlDocImpl();
797 return 0;
800 void HTMLObjectElementImpl::attach()
802 KHTMLPart* p = document()->part();
804 if (!p || !p->pluginsEnabled())
805 m_renderAlternative = true;
807 HTMLObjectBaseElementImpl::attach();
810 // -------------------------------------------------------------------------
812 NodeImpl::Id HTMLParamElementImpl::id() const
814 return ID_PARAM;
817 void HTMLParamElementImpl::parseAttribute(AttributeImpl *attr)
819 switch( attr->id() )
821 case ATTR_VALUE:
822 m_value = attr->value().string();
823 break;
824 case ATTR_ID:
825 if (document()->htmlMode() != DocumentImpl::XHtml) break;
826 // fall through
827 case ATTR_NAME:
828 m_name = attr->value().string();
829 // fall through
830 default:
831 HTMLElementImpl::parseAttribute(attr);
835 #include "html_objectimpl.moc"