2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 1999 Antti Koivisto (koivisto@kde.org)
4 * (C) 2000 Stefan Schimanski (1Stein@gmx.de)
5 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2011 Apple Inc. All rights reserved.
6 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Library General Public License for more details.
18 * You should have received a copy of the GNU Library General Public License
19 * along with this library; see the file COPYING.LIB. If not, write to
20 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
25 #include "HTMLObjectElement.h"
27 #include "Attribute.h"
28 #include "CSSValueKeywords.h"
29 #include "EventNames.h"
30 #include "ExceptionCode.h"
31 #include "FormDataList.h"
33 #include "HTMLDocument.h"
34 #include "HTMLFormElement.h"
35 #include "HTMLImageLoader.h"
36 #include "HTMLMetaElement.h"
37 #include "HTMLNames.h"
38 #include "HTMLParamElement.h"
39 #include "HTMLParserIdioms.h"
40 #include "MIMETypeRegistry.h"
43 #include "PluginViewBase.h"
44 #include "RenderEmbeddedObject.h"
45 #include "RenderImage.h"
46 #include "RenderWidget.h"
47 #include "ScriptEventListener.h"
51 #include "FrameView.h"
55 using namespace HTMLNames;
57 inline HTMLObjectElement::HTMLObjectElement(const QualifiedName& tagName, Document* document, HTMLFormElement* form, bool createdByParser)
58 : HTMLPlugInImageElement(tagName, document, createdByParser, ShouldNotPreferPlugInsForImages)
59 , FormAssociatedElement(form)
60 , m_docNamedItem(true)
61 , m_useFallbackContent(false)
63 , m_oipfType( NO_OIPF_OBJ )
66 fprintf( stderr, "HTMLObject Constructor this %x\n", this );
68 ASSERT(hasTagName(objectTag));
70 setForm(findFormAncestor());
72 this->form()->registerFormElement(this);
75 inline HTMLObjectElement::~HTMLObjectElement()
78 form()->removeFormElement(this);
80 fprintf( stderr, "HTMLObject Destructor %x\n", ( m_widget == 0 ) );
83 if( document() && document()->view() )
85 document()->view()->removeChild( m_widget.get() );
89 m_widget->setParent( NULL );
96 PassRefPtr<HTMLObjectElement> HTMLObjectElement::create(const QualifiedName& tagName, Document* document, HTMLFormElement* form, bool createdByParser)
98 return adoptRef(new HTMLObjectElement(tagName, document, form, createdByParser));
101 RenderWidget* HTMLObjectElement::renderWidgetForJSBindings()
103 document()->updateLayoutIgnorePendingStylesheets();
104 return renderPart(); // This will return 0 if the renderer is not a RenderPart.
107 void HTMLObjectElement::parseMappedAttribute(Attribute* attr)
109 if (attr->name() == formAttr)
110 formAttributeChanged();
111 else if (attr->name() == typeAttr) {
112 m_serviceType = attr->value().lower();
113 size_t pos = m_serviceType.find(";");
115 m_serviceType = m_serviceType.left(pos);
117 setNeedsWidgetUpdate(true);
118 if (!isImageType() && m_imageLoader)
119 m_imageLoader.clear();
123 if (equalIgnoringCase( m_serviceType, "application/oipfobjectfactory") )
125 m_oipfType = OIPF_OBJ_FACTORY;
127 else if( equalIgnoringCase(serviceType(), "application/oipfapplicationmanager" ) )
129 m_oipfType = OIPF_APP_MANANGER;
131 else if( equalIgnoringCase(serviceType(), "application/oipfconfiguration"))
133 m_oipfType = OIPF_CONFIGURATION;
135 else if( equalIgnoringCase(serviceType(), "application/oipfcapabilities"))
137 m_oipfType = OIPF_CAPABILITIES;
139 else if( equalIgnoringCase(serviceType(), "application/oipfdrmagent"))
141 m_oipfType = OIPF_DRMAGENT;
143 else if( equalIgnoringCase(serviceType(), "video/broadcast") )
145 m_oipfType = OIPF_VIDEO_BC;
147 else if( equalIgnoringCase(serviceType(), "valups/system") )
149 m_oipfType = VALUPS_SYSTEM;
151 else if( equalIgnoringCase(serviceType(), "humax/portalprofile") )
153 m_oipfType = H_PORTAL_PROFILE;
155 else if( equalIgnoringCase(serviceType(), "video/mp4")
156 || equalIgnoringCase(serviceType(), "video/mpeg")
157 || equalIgnoringCase(serviceType(), "video/mpeg4")
158 || equalIgnoringCase(serviceType(), "application/x-mpegURL"))
160 m_oipfType = OIPF_VIDEO_MPEG;
162 } else if (attr->name() == dataAttr) {
163 m_url = stripLeadingAndTrailingHTMLSpaces(attr->value());
165 setNeedsWidgetUpdate(true);
168 m_imageLoader = adoptPtr(new HTMLImageLoader(this));
169 m_imageLoader->updateFromElementIgnoringPreviousError();
172 } else if (attr->name() == classidAttr) {
173 m_classId = attr->value();
175 setNeedsWidgetUpdate(true);
176 } else if (attr->name() == onloadAttr)
177 setAttributeEventListener(eventNames().loadEvent, createAttributeEventListener(this, attr));
178 else if (attr->name() == onbeforeloadAttr)
179 setAttributeEventListener(eventNames().beforeloadEvent, createAttributeEventListener(this, attr));
180 else if (attr->name() == nameAttr) {
181 const AtomicString& newName = attr->value();
182 if (isDocNamedItem() && inDocument() && document()->isHTMLDocument()) {
183 HTMLDocument* document = static_cast<HTMLDocument*>(this->document());
184 document->removeNamedItem(m_name);
185 document->addNamedItem(newName);
188 } else if (attr->name() == borderAttr)
189 applyBorderAttribute(attr);
190 else if (isIdAttributeName(attr->name())) {
191 const AtomicString& newId = attr->value();
192 if (isDocNamedItem() && inDocument() && document()->isHTMLDocument()) {
193 HTMLDocument* document = static_cast<HTMLDocument*>(this->document());
194 document->removeExtraNamedItem(m_id);
195 document->addExtraNamedItem(newId);
198 // also call superclass
199 HTMLPlugInImageElement::parseMappedAttribute(attr);
201 HTMLPlugInImageElement::parseMappedAttribute(attr);
204 static void mapDataParamToSrc(Vector<String>* paramNames, Vector<String>* paramValues)
206 // Some plugins don't understand the "data" attribute of the OBJECT tag (i.e. Real and WMP
207 // require "src" attribute).
208 int srcIndex = -1, dataIndex = -1;
209 for (unsigned int i = 0; i < paramNames->size(); ++i) {
210 if (equalIgnoringCase((*paramNames)[i], "src"))
212 else if (equalIgnoringCase((*paramNames)[i], "data"))
216 if (srcIndex == -1 && dataIndex != -1) {
217 paramNames->append("src");
218 paramValues->append((*paramValues)[dataIndex]);
222 // FIXME: This function should not deal with url or serviceType!
223 void HTMLObjectElement::parametersForPlugin(Vector<String>& paramNames, Vector<String>& paramValues, String& url, String& serviceType)
225 HashSet<StringImpl*, CaseFoldingHash> uniqueParamNames;
228 // Scan the PARAM children and store their name/value pairs.
229 // Get the URL and type from the params if we don't already have them.
230 for (Node* child = firstChild(); child; child = child->nextSibling()) {
231 if (!child->hasTagName(paramTag))
234 HTMLParamElement* p = static_cast<HTMLParamElement*>(child);
235 String name = p->name();
239 uniqueParamNames.add(name.impl());
240 paramNames.append(p->name());
241 paramValues.append(p->value());
243 // FIXME: url adjustment does not belong in this function.
244 if (url.isEmpty() && urlParameter.isEmpty() && (equalIgnoringCase(name, "src") ||
245 equalIgnoringCase(name, "movie") || equalIgnoringCase(name, "code") || equalIgnoringCase(name, "url")|| equalIgnoringCase(name, "FileName")))
246 urlParameter = stripLeadingAndTrailingHTMLSpaces(p->value());
247 // FIXME: serviceType calculation does not belong in this function.
248 if (serviceType.isEmpty() && equalIgnoringCase(name, "type")) {
249 serviceType = p->value();
250 size_t pos = serviceType.find(";");
252 serviceType = serviceType.left(pos);
256 // When OBJECT is used for an applet via Sun's Java plugin, the CODEBASE attribute in the tag
257 // points to the Java plugin itself (an ActiveX component) while the actual applet CODEBASE is
258 // in a PARAM tag. See <http://java.sun.com/products/plugin/1.2/docs/tags.html>. This means
259 // we have to explicitly suppress the tag's CODEBASE attribute if there is none in a PARAM,
260 // else our Java plugin will misinterpret it. [4004531]
262 if (MIMETypeRegistry::isJavaAppletMIMEType(serviceType)) {
263 codebase = "codebase";
264 uniqueParamNames.add(codebase.impl()); // pretend we found it in a PARAM already
267 // Turn the attributes of the <object> element into arrays, but don't override <param> values.
268 NamedNodeMap* attributes = this->attributes(true);
270 for (unsigned i = 0; i < attributes->length(); ++i) {
271 Attribute* it = attributes->attributeItem(i);
272 const AtomicString& name = it->name().localName();
273 if (!uniqueParamNames.contains(name.impl())) {
274 paramNames.append(name.string());
275 paramValues.append(it->value().string());
280 mapDataParamToSrc(¶mNames, ¶mValues);
282 // HTML5 says that an object resource's URL is specified by the object's data
283 // attribute, not by a param element. However, for compatibility, allow the
284 // resource's URL to be given by a param named "src", "movie", "code" or "url"
285 // if we know that resource points to a plug-in.
286 if (url.isEmpty() && !urlParameter.isEmpty()) {
287 SubframeLoader* loader = document()->frame()->loader()->subframeLoader();
288 if (loader->resourceWillUsePlugin(urlParameter, serviceType, shouldPreferPlugInsForImages()))
294 bool HTMLObjectElement::hasFallbackContent() const
296 for (Node* child = firstChild(); child; child = child->nextSibling()) {
297 // Ignore whitespace-only text, and <param> tags, any other content is fallback content.
298 if (child->isTextNode()) {
299 if (!static_cast<Text*>(child)->containsOnlyWhitespace())
301 } else if (!child->hasTagName(paramTag))
307 bool HTMLObjectElement::shouldAllowQuickTimeClassIdQuirk()
309 // This site-specific hack maintains compatibility with Mac OS X Wiki Server,
310 // which embeds QuickTime movies using an object tag containing QuickTime's
311 // ActiveX classid. Treat this classid as valid only if OS X Server's unique
312 // 'generator' meta tag is present. Only apply this quirk if there is no
313 // fallback content, which ensures the quirk will disable itself if Wiki
314 // Server is updated to generate an alternate embed tag as fallback content.
315 if (!document()->page()
316 || !document()->page()->settings()->needsSiteSpecificQuirks()
317 || hasFallbackContent()
318 || !equalIgnoringCase(classId(), "clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B"))
321 RefPtr<NodeList> metaElements = document()->getElementsByTagName(HTMLNames::metaTag.localName());
322 unsigned length = metaElements->length();
323 for (unsigned i = 0; i < length; ++i) {
324 ASSERT(metaElements->item(i)->isHTMLElement());
325 HTMLMetaElement* metaElement = static_cast<HTMLMetaElement*>(metaElements->item(i));
326 if (equalIgnoringCase(metaElement->name(), "generator") && metaElement->content().startsWith("Mac OS X Server Web Services Server", false))
333 bool HTMLObjectElement::hasValidClassId()
336 if (equalIgnoringCase(serviceType(), "application/x-qt-plugin") || equalIgnoringCase(serviceType(), "application/x-qt-styled-widget"))
340 if (MIMETypeRegistry::isJavaAppletMIMEType(serviceType()) && classId().startsWith("java:", false))
343 if (shouldAllowQuickTimeClassIdQuirk())
346 if (equalIgnoringCase(serviceType(), "application/x-oleobject")&&
347 equalIgnoringCase( classId(), "CLSID:22d6f312-b0f6-11d0-94ab-0080c74c7e95" ))
354 // HTML5 says that fallback content should be rendered if a non-empty
355 // classid is specified for which the UA can't find a suitable plug-in.
356 return classId().isEmpty();
359 Widget* HTMLObjectElement::pluginWidget()
361 if( m_widget && m_widget.get() )
363 return m_widget.get();
366 return HTMLPlugInImageElement::pluginWidget();
370 void HTMLObjectElement::setWidget(PassRefPtr<Widget> widget)
372 if( m_oipfType == NO_OIPF_OBJ )
374 fprintf( stderr, "!!!!!! NO_OIPF_OBJ!!!!!!!\n" );
378 if ( widget == m_widget )
384 #define OIPF_HAS_NO_DISPLAY( a ) (( a == OIPF_APP_MANANGER ) ||\
385 ( a == OIPF_CONFIGURATION ) || \
386 ( a == OIPF_CAPABILITIES ) || \
387 ( a == OIPF_DRMAGENT ) || \
388 ( a == OIPF_OBJ_FACTORY ) || \
389 ( a == VALUPS_SYSTEM ) || \
390 ( a == H_PORTAL_PROFILE ) )
392 void HTMLObjectElement::updateWidgetIfNecessary()
394 document()->updateStyleIfNeeded();
396 // fprintf( stderr, "serviceType = %s\n", m_serviceType.ascii().data() );
398 if ((!needsWidgetUpdate() || useFallbackContent() || isImageType()) &&
399 ( m_oipfType == NO_OIPF_OBJ ) )
404 if( m_oipfType != NO_OIPF_OBJ ) //( renderEmbeddedObject() == NULL && m_oipfType != NO_OIPF_OBJ ) || ( OIPF_HAS_NO_DISPLAY( m_oipfType ) ) )
408 setNeedsWidgetUpdate(false);
409 // FIXME: This should ASSERT isFinishedParsingChildren() instead.
410 if (!isFinishedParsingChildren() && !OIPF_HAS_NO_DISPLAY( m_oipfType ) )
415 String url = this->url();
416 String serviceType = this->serviceType();
418 // FIXME: These should be joined into a PluginParameters class.
419 Vector<String> paramNames;
420 Vector<String> paramValues;
421 parametersForPlugin(paramNames, paramValues, url, serviceType);
423 // Note: url is modified above by parametersForPlugin.
424 if (!allowedToLoadFrameURL(url))
429 ASSERT(!m_inBeforeLoadEventHandler);
430 m_inBeforeLoadEventHandler = true;
431 bool beforeLoadAllowedLoad = dispatchBeforeLoadEvent(url);
432 m_inBeforeLoadEventHandler = false;
434 // beforeload events can modify the DOM, potentially causing
435 // RenderWidget::destroy() to be called. Ensure we haven't been
436 // destroyed before continuing.
437 // FIXME: Should this render fallback content?
441 RefPtr<HTMLObjectElement> protect(this); // Loading the plugin might remove us from the document.
442 SubframeLoader* loader = document()->frame()->loader()->subframeLoader();
444 if( beforeLoadAllowedLoad && hasValidClassId() )
445 loader->requestObjectWithoutRenderer(this, url, getAttribute(nameAttr), serviceType, paramNames, paramValues);
449 if( document() && document()->view() )
451 document()->view()->addChild( m_widget );
459 if (!needsWidgetUpdate() || useFallbackContent() || isImageType())
464 return HTMLPlugInImageElement::updateWidgetIfNecessary();
468 // FIXME: This should be unified with HTMLEmbedElement::updateWidget and
469 // moved down into HTMLPluginImageElement.cpp
470 void HTMLObjectElement::updateWidget(PluginCreationOption pluginCreationOption)
472 // if(( m_oipfType != NO_OIPF_OBJ ))// OIPF_HAS_NO_DISPLAY( m_oipfType ) )
474 // fprintf( stderr, "ERROR>>>>>>>>>>>>>>>>> oipfType = %d\n", m_oipfType );
478 ASSERT(!renderEmbeddedObject()->pluginCrashedOrWasMissing());
479 // FIXME: We should ASSERT(needsWidgetUpdate()), but currently
480 // FrameView::updateWidget() calls updateWidget(false) without checking if
481 // the widget actually needs updating!
482 setNeedsWidgetUpdate(false);
483 // FIXME: This should ASSERT isFinishedParsingChildren() instead.
484 if (!isFinishedParsingChildren())
487 String url = this->url();
488 String serviceType = this->serviceType();
490 // FIXME: These should be joined into a PluginParameters class.
491 Vector<String> paramNames;
492 Vector<String> paramValues;
493 parametersForPlugin(paramNames, paramValues, url, serviceType);
495 // Note: url is modified above by parametersForPlugin.
496 if (!allowedToLoadFrameURL(url))
499 bool fallbackContent = hasFallbackContent();
500 renderEmbeddedObject()->setHasFallbackContent(fallbackContent);
502 if (pluginCreationOption == CreateOnlyNonNetscapePlugins && wouldLoadAsNetscapePlugin(url, serviceType))
505 ASSERT(!m_inBeforeLoadEventHandler);
506 m_inBeforeLoadEventHandler = true;
507 bool beforeLoadAllowedLoad = dispatchBeforeLoadEvent(url);
508 m_inBeforeLoadEventHandler = false;
510 // beforeload events can modify the DOM, potentially causing
511 // RenderWidget::destroy() to be called. Ensure we haven't been
512 // destroyed before continuing.
513 // FIXME: Should this render fallback content?
517 RefPtr<HTMLObjectElement> protect(this); // Loading the plugin might remove us from the document.
518 SubframeLoader* loader = document()->frame()->loader()->subframeLoader();
519 bool success = beforeLoadAllowedLoad && hasValidClassId() && loader->requestObject(this, url, getAttribute(nameAttr), serviceType, paramNames, paramValues);
521 if (!success && fallbackContent)
522 renderFallbackContent();
525 bool HTMLObjectElement::rendererIsNeeded(const NodeRenderingContext& context)
527 // FIXME: This check should not be needed, detached documents never render!
528 Frame* frame = document()->frame();
532 /* hbbtv Object for OIPF will be always rendered
533 if (equalIgnoringCase(serviceType(), "application/oipfobjectfactory")
534 || equalIgnoringCase(serviceType(), "application/oipfapplicationmanager")
535 || equalIgnoringCase(serviceType(), "application/oipfconfiguration")
536 || equalIgnoringCase(serviceType(), "video/broadcast")
537 || equalIgnoringCase(serviceType(), "video/mp4")
538 || equalIgnoringCase(serviceType(), "video/mpeg")
539 || equalIgnoringCase(serviceType(), "video/mpeg4")
542 fprintf( stderr, "%s %s %d\n", __FILE__, __func__, __LINE__ );
545 /* hbbtv Object for OIPF will be always rendered */
547 // if( m_oipfType != NO_OIPF_OBJ &&
550 // fprintf( stderr, "Do not render - m_widget exists\n" );
554 return HTMLPlugInImageElement::rendererIsNeeded(context);
557 PassRefPtr<Widget> HTMLObjectElement::getPredefinedWidget()
562 #if ENABLE(NETSCAPE_PLUGIN_API)
564 NPObject* HTMLObjectElement::getNPObject()
566 if( !document() || !document()->frame() )
569 return HTMLPlugInElement::getNPObject();
572 #endif /* ENABLE(NETSCAPE_PLUGIN_API) */
575 void HTMLObjectElement::insertedIntoDocument()
577 HTMLPlugInImageElement::insertedIntoDocument();
581 if (isDocNamedItem() && document()->isHTMLDocument()) {
582 HTMLDocument* document = static_cast<HTMLDocument*>(this->document());
583 document->addNamedItem(m_name);
584 document->addExtraNamedItem(m_id);
587 FormAssociatedElement::insertedIntoDocument();
590 void HTMLObjectElement::removedFromDocument()
592 if (isDocNamedItem() && document()->isHTMLDocument()) {
593 HTMLDocument* document = static_cast<HTMLDocument*>(this->document());
594 document->removeNamedItem(m_name);
595 document->removeExtraNamedItem(m_id);
598 HTMLPlugInImageElement::removedFromDocument();
599 FormAssociatedElement::removedFromDocument();
602 void HTMLObjectElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
604 updateDocNamedItem();
605 if (inDocument() && !useFallbackContent()) {
606 setNeedsWidgetUpdate(true);
607 setNeedsStyleRecalc();
609 HTMLPlugInImageElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
612 bool HTMLObjectElement::isURLAttribute(Attribute *attr) const
614 return (attr->name() == dataAttr || (attr->name() == usemapAttr && attr->value().string()[0] != '#'));
617 const QualifiedName& HTMLObjectElement::imageSourceAttributeName() const
622 void HTMLObjectElement::renderFallbackContent()
624 if (useFallbackContent())
630 // Before we give up and use fallback content, check to see if this is a MIME type issue.
631 if (m_imageLoader && m_imageLoader->image() && m_imageLoader->image()->status() != CachedResource::LoadError) {
632 m_serviceType = m_imageLoader->image()->response().mimeType();
633 if (!isImageType()) {
634 // If we don't think we have an image type anymore, then clear the image from the loader.
635 m_imageLoader->setImage(0);
641 m_useFallbackContent = true;
643 // FIXME: Style gets recalculated which is suboptimal.
648 // FIXME: This should be removed, all callers are almost certainly wrong.
649 static bool isRecognizedTagName(const QualifiedName& tagName)
651 DEFINE_STATIC_LOCAL(HashSet<AtomicStringImpl*>, tagList, ());
652 if (tagList.isEmpty()) {
654 QualifiedName** tags = HTMLNames::getHTMLTags(&tagCount);
655 for (size_t i = 0; i < tagCount; i++) {
656 if (*tags[i] == bgsoundTag
657 || *tags[i] == commandTag
658 || *tags[i] == detailsTag
659 || *tags[i] == figcaptionTag
660 || *tags[i] == figureTag
661 || *tags[i] == summaryTag
662 || *tags[i] == trackTag) {
663 // Even though we have atoms for these tags, we don't want to
664 // treat them as "recognized tags" for the purpose of parsing
665 // because that changes how we parse documents.
668 tagList.add(tags[i]->localName().impl());
671 return tagList.contains(tagName.localName().impl());
674 void HTMLObjectElement::updateDocNamedItem()
676 // The rule is "<object> elements with no children other than
677 // <param> elements, unknown elements and whitespace can be
678 // found by name in a document, and other <object> elements cannot."
679 bool wasNamedItem = m_docNamedItem;
680 bool isNamedItem = true;
681 Node* child = firstChild();
682 while (child && isNamedItem) {
683 if (child->isElementNode()) {
684 Element* element = static_cast<Element*>(child);
685 // FIXME: Use of isRecognizedTagName is almost certainly wrong here.
686 if (isRecognizedTagName(element->tagQName()) && !element->hasTagName(paramTag))
688 } else if (child->isTextNode()) {
689 if (!static_cast<Text*>(child)->containsOnlyWhitespace())
693 child = child->nextSibling();
695 if (isNamedItem != wasNamedItem && document()->isHTMLDocument()) {
696 HTMLDocument* document = static_cast<HTMLDocument*>(this->document());
698 document->addNamedItem(m_name);
699 document->addExtraNamedItem(m_id);
701 document->removeNamedItem(m_name);
702 document->removeExtraNamedItem(m_id);
705 m_docNamedItem = isNamedItem;
708 bool HTMLObjectElement::containsJavaApplet() const
710 if (MIMETypeRegistry::isJavaAppletMIMEType(getAttribute(typeAttr)))
713 for (Element* child = firstElementChild(); child; child = child->nextElementSibling()) {
714 if (child->hasTagName(paramTag)
715 && equalIgnoringCase(child->getAttribute(nameAttr), "type")
716 && MIMETypeRegistry::isJavaAppletMIMEType(child->getAttribute(valueAttr).string()))
718 if (child->hasTagName(objectTag)
719 && static_cast<HTMLObjectElement*>(child)->containsJavaApplet())
721 if (child->hasTagName(appletTag))
728 void HTMLObjectElement::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) const
730 HTMLPlugInImageElement::addSubresourceAttributeURLs(urls);
732 addSubresourceURL(urls, document()->completeURL(getAttribute(dataAttr)));
734 // FIXME: Passing a string that starts with "#" to the completeURL function does
735 // not seem like it would work. The image element has similar but not identical code.
736 const AtomicString& useMap = getAttribute(usemapAttr);
737 if (useMap.startsWith("#"))
738 addSubresourceURL(urls, document()->completeURL(useMap));
741 void HTMLObjectElement::willMoveToNewOwnerDocument()
743 FormAssociatedElement::willMoveToNewOwnerDocument();
744 HTMLPlugInImageElement::willMoveToNewOwnerDocument();
747 void HTMLObjectElement::insertedIntoTree(bool deep)
749 FormAssociatedElement::insertedIntoTree();
750 HTMLPlugInImageElement::insertedIntoTree(deep);
753 void HTMLObjectElement::removedFromTree(bool deep)
755 FormAssociatedElement::removedFromTree();
756 HTMLPlugInImageElement::removedFromTree(deep);
759 bool HTMLObjectElement::appendFormData(FormDataList& encoding, bool)
761 if (name().isEmpty())
764 Widget* widget = pluginWidget();
765 if (!widget || !widget->isPluginViewBase())
768 if (!static_cast<PluginViewBase*>(widget)->getFormValue(value))
770 encoding.appendData(name(), value);
774 const AtomicString& HTMLObjectElement::formControlName() const
776 return m_name.isNull() ? emptyAtom : m_name;
779 HTMLFormElement* HTMLObjectElement::virtualForm() const
781 return FormAssociatedElement::form();