blob: 0b42d52294a591f2d3f5bcfa4744502bf4ea30f8 [file] [log] [blame]
darin9efc76e2007-05-29 17:41:17 +00001/*
eseideld2f36a12006-05-12 18:14:17 +00002 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 1999 Antti Koivisto (koivisto@kde.org)
4 * (C) 2000 Stefan Schimanski (1Stein@gmx.de)
aestes@apple.com5e143732011-03-25 23:07:43 +00005 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2011 Apple Inc. All rights reserved.
hausmann@webkit.orgf6964472008-09-29 12:47:08 +00006 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
eseideld2f36a12006-05-12 18:14:17 +00007 *
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.
12 *
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.
17 *
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
ddkilzerc8eccec2007-09-26 02:29:57 +000020 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
eseideld2f36a12006-05-12 18:14:17 +000022 */
darin9efc76e2007-05-29 17:41:17 +000023
eseideld2f36a12006-05-12 18:14:17 +000024#include "config.h"
25#include "HTMLObjectElement.h"
26
weinig@apple.comc3608932010-05-19 17:48:06 +000027#include "Attribute.h"
ddkilzer@apple.com3c250112011-01-04 06:20:17 +000028#include "CSSValueKeywords.h"
abarth@webkit.org401a3792013-03-03 10:12:59 +000029#include "CachedImage.h"
jer.noble@apple.com63353b72012-07-26 19:01:20 +000030#include "Chrome.h"
31#include "ChromeClient.h"
antti@apple.com0494cf82013-08-31 14:12:00 +000032#include "ElementIterator.h"
eseideld2f36a12006-05-12 18:14:17 +000033#include "EventNames.h"
eseidel3764f872006-07-27 05:26:00 +000034#include "ExceptionCode.h"
bashi@chromium.orgdcda5d92011-07-11 02:28:59 +000035#include "FormDataList.h"
eseideld2f36a12006-05-12 18:14:17 +000036#include "Frame.h"
eseideld2f36a12006-05-12 18:14:17 +000037#include "HTMLDocument.h"
weinige7918082007-07-18 19:56:40 +000038#include "HTMLFormElement.h"
eseidel84943622006-05-15 23:23:42 +000039#include "HTMLImageLoader.h"
aestes@apple.com96eecde2011-05-25 00:48:00 +000040#include "HTMLMetaElement.h"
eseideld2f36a12006-05-12 18:14:17 +000041#include "HTMLNames.h"
eric@webkit.org918affb2010-09-03 04:04:29 +000042#include "HTMLParamElement.h"
darin@apple.com7b7981b2010-10-01 00:04:02 +000043#include "HTMLParserIdioms.h"
weinig62f94be2007-07-18 20:37:20 +000044#include "MIMETypeRegistry.h"
aestes@apple.com96eecde2011-05-25 00:48:00 +000045#include "NodeList.h"
46#include "Page.h"
bashi@chromium.orgdcda5d92011-07-11 02:28:59 +000047#include "PluginViewBase.h"
simon.fraser@apple.com385f97e2010-01-07 21:57:12 +000048#include "RenderEmbeddedObject.h"
eseideld2f36a12006-05-12 18:14:17 +000049#include "RenderImage.h"
eseidel409f4302006-05-12 22:56:41 +000050#include "RenderWidget.h"
aestes@apple.com96eecde2011-05-25 00:48:00 +000051#include "Settings.h"
akling@apple.com7f81b1e2013-09-06 17:23:03 +000052#include "SubframeLoader.h"
eseideld2f36a12006-05-12 18:14:17 +000053#include "Text.h"
bashi@chromium.orgdcda5d92011-07-11 02:28:59 +000054#include "Widget.h"
akling@apple.comf8515982013-09-02 18:50:01 +000055#include <wtf/Ref.h>
eseideld2f36a12006-05-12 18:14:17 +000056
dbates@webkit.org1edd81d2013-12-18 00:15:02 +000057#if PLATFORM(IOS)
58#include "RuntimeApplicationChecksIOS.h"
59#include "WebCoreSystemInterface.h"
60#endif
61
eseideld2f36a12006-05-12 18:14:17 +000062namespace WebCore {
63
eseideld2f36a12006-05-12 18:14:17 +000064using namespace HTMLNames;
65
weinig@apple.com49178832013-09-15 00:39:29 +000066inline HTMLObjectElement::HTMLObjectElement(const QualifiedName& tagName, Document& document, HTMLFormElement* form, bool createdByParser)
weinig@apple.comdedf67e2013-09-15 05:23:01 +000067 : HTMLPlugInImageElement(tagName, document, createdByParser, ShouldNotPreferPlugInsForImages)
ddkilzer@apple.comd44054d2008-06-30 21:12:55 +000068 , m_docNamedItem(true)
eseidel3764f872006-07-27 05:26:00 +000069 , m_useFallbackContent(false)
eseideld2f36a12006-05-12 18:14:17 +000070{
jchaffraix@webkit.org94d95b02008-12-04 22:39:05 +000071 ASSERT(hasTagName(objectTag));
rniwa@webkit.orgf7bf3762013-08-29 01:35:21 +000072 setForm(form ? form : HTMLFormElement::findClosestFormAncestor(*this));
eseideld2f36a12006-05-12 18:14:17 +000073}
74
tkent@chromium.org995765c2010-12-07 09:40:23 +000075inline HTMLObjectElement::~HTMLObjectElement()
darin@apple.comcf9dd0f2009-08-23 06:55:57 +000076{
tkent@chromium.org995765c2010-12-07 09:40:23 +000077}
78
weinig@apple.com49178832013-09-15 00:39:29 +000079PassRefPtr<HTMLObjectElement> HTMLObjectElement::create(const QualifiedName& tagName, Document& document, HTMLFormElement* form, bool createdByParser)
tkent@chromium.org995765c2010-12-07 09:40:23 +000080{
81 return adoptRef(new HTMLObjectElement(tagName, document, form, createdByParser));
darin@apple.comcf9dd0f2009-08-23 06:55:57 +000082}
83
fsamuel@chromium.org8ecfba32012-08-08 00:54:36 +000084RenderWidget* HTMLObjectElement::renderWidgetForJSBindings() const
eseideld2f36a12006-05-12 18:14:17 +000085{
akling@apple.com622b1a42013-08-30 14:30:12 +000086 document().updateLayoutIgnorePendingStylesheets();
akling@apple.comb95111f2013-09-12 05:21:14 +000087 return renderWidget(); // This will return 0 if the renderer is not a RenderWidget.
eseideld2f36a12006-05-12 18:14:17 +000088}
eseideld2f36a12006-05-12 18:14:17 +000089
kling@webkit.org44bc0dd2012-02-28 22:21:02 +000090bool HTMLObjectElement::isPresentationAttribute(const QualifiedName& name) const
kling@webkit.org11f25562012-02-13 10:36:55 +000091{
kling@webkit.org44bc0dd2012-02-28 22:21:02 +000092 if (name == borderAttr)
kling@webkit.org11f25562012-02-13 10:36:55 +000093 return true;
kling@webkit.org44bc0dd2012-02-28 22:21:02 +000094 return HTMLPlugInImageElement::isPresentationAttribute(name);
kling@webkit.org11f25562012-02-13 10:36:55 +000095}
96
antti@apple.come5428c52013-11-28 20:53:22 +000097void HTMLObjectElement::collectStyleForPresentationAttribute(const QualifiedName& name, const AtomicString& value, MutableStyleProperties& style)
kling@webkit.org8b0e8432012-02-11 19:29:49 +000098{
akling@apple.comb75eeea2013-02-23 17:57:50 +000099 if (name == borderAttr)
100 applyBorderAttributeToStyle(value, style);
kling@webkit.org8b0e8432012-02-11 19:29:49 +0000101 else
akling@apple.comb75eeea2013-02-23 17:57:50 +0000102 HTMLPlugInImageElement::collectStyleForPresentationAttribute(name, value, style);
kling@webkit.org8b0e8432012-02-11 19:29:49 +0000103}
104
akling@apple.com43e9d042012-11-18 16:55:06 +0000105void HTMLObjectElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
eseideld2f36a12006-05-12 18:14:17 +0000106{
akling@apple.com43e9d042012-11-18 16:55:06 +0000107 if (name == formAttr)
adamk@chromium.orgf0236532011-08-18 10:22:01 +0000108 formAttributeChanged();
akling@apple.com43e9d042012-11-18 16:55:06 +0000109 else if (name == typeAttr) {
110 m_serviceType = value.lower();
eric@webkit.org1402eb42010-09-02 09:10:21 +0000111 size_t pos = m_serviceType.find(";");
barraclough@apple.comd643fde2010-08-16 23:31:33 +0000112 if (pos != notFound)
eric@webkit.org1402eb42010-09-02 09:10:21 +0000113 m_serviceType = m_serviceType.left(pos);
eseideld2f36a12006-05-12 18:14:17 +0000114 if (renderer())
eric@webkit.org1402eb42010-09-02 09:10:21 +0000115 setNeedsWidgetUpdate(true);
akling@apple.com43e9d042012-11-18 16:55:06 +0000116 } else if (name == dataAttr) {
117 m_url = stripLeadingAndTrailingHTMLSpaces(value);
antti@apple.com4942ea52013-12-20 14:44:23 +0000118 document().updateStyleIfNeeded();
eric@webkit.org1402eb42010-09-02 09:10:21 +0000119 if (renderer()) {
120 setNeedsWidgetUpdate(true);
121 if (isImageType()) {
122 if (!m_imageLoader)
akling@apple.com68b7ee02014-02-05 18:25:26 +0000123 m_imageLoader = adoptPtr(new HTMLImageLoader(*this));
eric@webkit.org1402eb42010-09-02 09:10:21 +0000124 m_imageLoader->updateFromElementIgnoringPreviousError();
125 }
eseideld2f36a12006-05-12 18:14:17 +0000126 }
akling@apple.com43e9d042012-11-18 16:55:06 +0000127 } else if (name == classidAttr) {
128 m_classId = value;
eseideld2f36a12006-05-12 18:14:17 +0000129 if (renderer())
eric@webkit.org1402eb42010-09-02 09:10:21 +0000130 setNeedsWidgetUpdate(true);
keishi@webkit.orgb61c3832013-03-29 09:59:09 +0000131 } else if (name == onbeforeloadAttr)
darin@apple.com197597bb2013-09-21 18:25:43 +0000132 setAttributeEventListener(eventNames().beforeloadEvent, name, value);
kling@webkit.orgb8972772011-12-23 21:36:59 +0000133 else
akling@apple.com43e9d042012-11-18 16:55:06 +0000134 HTMLPlugInImageElement::parseAttribute(name, value);
eseideld2f36a12006-05-12 18:14:17 +0000135}
136
eric@webkit.org918affb2010-09-03 04:04:29 +0000137static void mapDataParamToSrc(Vector<String>* paramNames, Vector<String>* paramValues)
138{
139 // Some plugins don't understand the "data" attribute of the OBJECT tag (i.e. Real and WMP
140 // require "src" attribute).
141 int srcIndex = -1, dataIndex = -1;
142 for (unsigned int i = 0; i < paramNames->size(); ++i) {
143 if (equalIgnoringCase((*paramNames)[i], "src"))
144 srcIndex = i;
145 else if (equalIgnoringCase((*paramNames)[i], "data"))
146 dataIndex = i;
147 }
148
149 if (srcIndex == -1 && dataIndex != -1) {
150 paramNames->append("src");
151 paramValues->append((*paramValues)[dataIndex]);
152 }
153}
154
dbates@webkit.org1edd81d2013-12-18 00:15:02 +0000155#if PLATFORM(IOS)
156static bool shouldNotPerformURLAdjustment()
157{
158 static bool shouldNotPerformURLAdjustment = applicationIsNASAHD() && !iosExecutableWasLinkedOnOrAfterVersion(wkIOSSystemVersion_5_0);
159 return shouldNotPerformURLAdjustment;
160}
161#endif
162
eric@webkit.org918affb2010-09-03 04:04:29 +0000163// FIXME: This function should not deal with url or serviceType!
164void HTMLObjectElement::parametersForPlugin(Vector<String>& paramNames, Vector<String>& paramValues, String& url, String& serviceType)
165{
166 HashSet<StringImpl*, CaseFoldingHash> uniqueParamNames;
dpranke@chromium.org9a91c972010-09-10 07:48:20 +0000167 String urlParameter;
eric@webkit.org918affb2010-09-03 04:04:29 +0000168
169 // Scan the PARAM children and store their name/value pairs.
170 // Get the URL and type from the params if we don't already have them.
weinig@apple.comc77041e2013-12-14 18:05:45 +0000171 for (auto& param : childrenOfType<HTMLParamElement>(*this)) {
172 String name = param.name();
eric@webkit.org918affb2010-09-03 04:04:29 +0000173 if (name.isEmpty())
174 continue;
175
176 uniqueParamNames.add(name.impl());
weinig@apple.comc77041e2013-12-14 18:05:45 +0000177 paramNames.append(param.name());
178 paramValues.append(param.value());
eric@webkit.org918affb2010-09-03 04:04:29 +0000179
180 // FIXME: url adjustment does not belong in this function.
dpranke@chromium.org9a91c972010-09-10 07:48:20 +0000181 if (url.isEmpty() && urlParameter.isEmpty() && (equalIgnoringCase(name, "src") || equalIgnoringCase(name, "movie") || equalIgnoringCase(name, "code") || equalIgnoringCase(name, "url")))
weinig@apple.comc77041e2013-12-14 18:05:45 +0000182 urlParameter = stripLeadingAndTrailingHTMLSpaces(param.value());
eric@webkit.org918affb2010-09-03 04:04:29 +0000183 // FIXME: serviceType calculation does not belong in this function.
184 if (serviceType.isEmpty() && equalIgnoringCase(name, "type")) {
weinig@apple.comc77041e2013-12-14 18:05:45 +0000185 serviceType = param.value();
eric@webkit.org918affb2010-09-03 04:04:29 +0000186 size_t pos = serviceType.find(";");
187 if (pos != notFound)
188 serviceType = serviceType.left(pos);
189 }
190 }
191
192 // When OBJECT is used for an applet via Sun's Java plugin, the CODEBASE attribute in the tag
193 // points to the Java plugin itself (an ActiveX component) while the actual applet CODEBASE is
194 // in a PARAM tag. See <http://java.sun.com/products/plugin/1.2/docs/tags.html>. This means
195 // we have to explicitly suppress the tag's CODEBASE attribute if there is none in a PARAM,
196 // else our Java plugin will misinterpret it. [4004531]
197 String codebase;
198 if (MIMETypeRegistry::isJavaAppletMIMEType(serviceType)) {
199 codebase = "codebase";
200 uniqueParamNames.add(codebase.impl()); // pretend we found it in a PARAM already
201 }
202
203 // Turn the attributes of the <object> element into arrays, but don't override <param> values.
caio.oliveira@openbossa.org5fc3ab922012-02-06 20:42:40 +0000204 if (hasAttributes()) {
benjamin@webkit.org64c95332014-01-21 01:31:37 +0000205 for (const Attribute& attribute : attributesIterator()) {
akling@apple.comae4fef12013-08-08 17:25:50 +0000206 const AtomicString& name = attribute.name().localName();
eric@webkit.org918affb2010-09-03 04:04:29 +0000207 if (!uniqueParamNames.contains(name.impl())) {
208 paramNames.append(name.string());
akling@apple.comae4fef12013-08-08 17:25:50 +0000209 paramValues.append(attribute.value().string());
eric@webkit.org918affb2010-09-03 04:04:29 +0000210 }
211 }
212 }
213
214 mapDataParamToSrc(&paramNames, &paramValues);
215
dpranke@chromium.org9a91c972010-09-10 07:48:20 +0000216 // HTML5 says that an object resource's URL is specified by the object's data
217 // attribute, not by a param element. However, for compatibility, allow the
218 // resource's URL to be given by a param named "src", "movie", "code" or "url"
219 // if we know that resource points to a plug-in.
dbates@webkit.org1edd81d2013-12-18 00:15:02 +0000220#if PLATFORM(IOS)
221 if (shouldNotPerformURLAdjustment())
222 return;
223#endif
224
dpranke@chromium.org9a91c972010-09-10 07:48:20 +0000225 if (url.isEmpty() && !urlParameter.isEmpty()) {
akling@apple.com7f81b1e2013-09-06 17:23:03 +0000226 SubframeLoader& loader = document().frame()->loader().subframeLoader();
227 if (loader.resourceWillUsePlugin(urlParameter, serviceType, shouldPreferPlugInsForImages()))
dpranke@chromium.org9a91c972010-09-10 07:48:20 +0000228 url = urlParameter;
229 }
eric@webkit.org918affb2010-09-03 04:04:29 +0000230}
231
232
233bool HTMLObjectElement::hasFallbackContent() const
234{
235 for (Node* child = firstChild(); child; child = child->nextSibling()) {
236 // Ignore whitespace-only text, and <param> tags, any other content is fallback content.
237 if (child->isTextNode()) {
commit-queue@webkit.org9b335e42012-02-12 11:27:56 +0000238 if (!toText(child)->containsOnlyWhitespace())
eric@webkit.org918affb2010-09-03 04:04:29 +0000239 return true;
240 } else if (!child->hasTagName(paramTag))
241 return true;
242 }
243 return false;
244}
aestes@apple.comad6310a2010-10-28 07:47:56 +0000245
aestes@apple.com96eecde2011-05-25 00:48:00 +0000246bool HTMLObjectElement::shouldAllowQuickTimeClassIdQuirk()
247{
248 // This site-specific hack maintains compatibility with Mac OS X Wiki Server,
249 // which embeds QuickTime movies using an object tag containing QuickTime's
250 // ActiveX classid. Treat this classid as valid only if OS X Server's unique
251 // 'generator' meta tag is present. Only apply this quirk if there is no
252 // fallback content, which ensures the quirk will disable itself if Wiki
253 // Server is updated to generate an alternate embed tag as fallback content.
akling@apple.com622b1a42013-08-30 14:30:12 +0000254 if (!document().page()
255 || !document().page()->settings().needsSiteSpecificQuirks()
aestes@apple.com96eecde2011-05-25 00:48:00 +0000256 || hasFallbackContent()
257 || !equalIgnoringCase(classId(), "clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B"))
258 return false;
259
akling@apple.com622b1a42013-08-30 14:30:12 +0000260 RefPtr<NodeList> metaElements = document().getElementsByTagName(HTMLNames::metaTag.localName());
aestes@apple.com96eecde2011-05-25 00:48:00 +0000261 unsigned length = metaElements->length();
262 for (unsigned i = 0; i < length; ++i) {
gyuyoung.kim@samsung.comb86fc582013-11-21 04:45:49 +0000263 HTMLMetaElement& metaElement = toHTMLMetaElement(*metaElements->item(i));
264 if (equalIgnoringCase(metaElement.name(), "generator") && metaElement.content().startsWith("Mac OS X Server Web Services Server", false))
aestes@apple.com96eecde2011-05-25 00:48:00 +0000265 return true;
266 }
267
268 return false;
269}
270
aestes@apple.com07b47f12011-04-01 00:12:53 +0000271bool HTMLObjectElement::hasValidClassId()
aestes@apple.comad6310a2010-10-28 07:47:56 +0000272{
aestes@apple.com07b47f12011-04-01 00:12:53 +0000273 if (MIMETypeRegistry::isJavaAppletMIMEType(serviceType()) && classId().startsWith("java:", false))
274 return true;
aestes@apple.com96eecde2011-05-25 00:48:00 +0000275
276 if (shouldAllowQuickTimeClassIdQuirk())
277 return true;
aestes@apple.com07b47f12011-04-01 00:12:53 +0000278
aestes@apple.com9339cb02010-10-28 08:16:33 +0000279 // HTML5 says that fallback content should be rendered if a non-empty
280 // classid is specified for which the UA can't find a suitable plug-in.
commit-queue@webkit.org2d9e5b72011-05-24 01:52:11 +0000281 return classId().isEmpty();
aestes@apple.comad6310a2010-10-28 07:47:56 +0000282}
eric@webkit.org918affb2010-09-03 04:04:29 +0000283
eric@webkit.org4ffb1fe2010-09-03 04:28:12 +0000284// FIXME: This should be unified with HTMLEmbedElement::updateWidget and
285// moved down into HTMLPluginImageElement.cpp
abarth@webkit.org12c7af02011-02-02 08:00:19 +0000286void HTMLObjectElement::updateWidget(PluginCreationOption pluginCreationOption)
eric@webkit.org4ffb1fe2010-09-03 04:28:12 +0000287{
timothy_horton@apple.com7adfc612013-07-23 01:02:59 +0000288 ASSERT(!renderEmbeddedObject()->isPluginUnavailable());
eric@webkit.orga4c02082011-12-15 22:00:09 +0000289 ASSERT(needsWidgetUpdate());
eric@webkit.org4ffb1fe2010-09-03 04:28:12 +0000290 setNeedsWidgetUpdate(false);
291 // FIXME: This should ASSERT isFinishedParsingChildren() instead.
292 if (!isFinishedParsingChildren())
293 return;
commit-queue@webkit.org5cbb9f82012-11-14 04:25:11 +0000294
295 // FIXME: I'm not sure it's ever possible to get into updateWidget during a
296 // removal, but just in case we should avoid loading the frame to prevent
297 // security bugs.
weinig@apple.com2e067212013-09-23 03:40:47 +0000298 if (!SubframeLoadingDisabler::canLoadFrame(*this))
commit-queue@webkit.org5cbb9f82012-11-14 04:25:11 +0000299 return;
300
aestes@apple.com11778492010-10-28 06:15:09 +0000301 String url = this->url();
eric@webkit.org4ffb1fe2010-09-03 04:28:12 +0000302 String serviceType = this->serviceType();
303
304 // FIXME: These should be joined into a PluginParameters class.
305 Vector<String> paramNames;
306 Vector<String> paramValues;
307 parametersForPlugin(paramNames, paramValues, url, serviceType);
308
309 // Note: url is modified above by parametersForPlugin.
310 if (!allowedToLoadFrameURL(url))
311 return;
312
aestes@apple.com87b89d12012-02-08 20:20:41 +0000313 // FIXME: It's sadness that we have this special case here.
314 // See http://trac.webkit.org/changeset/25128 and
315 // plugins/netscape-plugin-setwindow-size.html
316 if (pluginCreationOption == CreateOnlyNonNetscapePlugins && wouldLoadAsNetscapePlugin(url, serviceType)) {
317 // Ensure updateWidget() is called again during layout to create the Netscape plug-in.
318 setNeedsWidgetUpdate(true);
eric@webkit.org4ffb1fe2010-09-03 04:28:12 +0000319 return;
aestes@apple.com87b89d12012-02-08 20:20:41 +0000320 }
eric@webkit.org4ffb1fe2010-09-03 04:28:12 +0000321
akling@apple.comf8515982013-09-02 18:50:01 +0000322 Ref<HTMLObjectElement> protect(*this); // beforeload and plugin loading can make arbitrary DOM mutations.
eric@webkit.orgce447522012-01-25 23:29:53 +0000323 bool beforeLoadAllowedLoad = guardedDispatchBeforeLoadEvent(url);
eric@webkit.org1f8035c32012-01-26 00:00:03 +0000324 if (!renderer()) // Do not load the plugin if beforeload removed this element or its renderer.
eric@webkit.org4ffb1fe2010-09-03 04:28:12 +0000325 return;
326
eric.carlson@apple.com6bfffe02013-11-28 01:05:35 +0000327 bool success = beforeLoadAllowedLoad && hasValidClassId();
328 if (success)
329 success = requestObject(url, serviceType, paramNames, paramValues);
akling@apple.com2cbd1e92013-11-05 09:29:50 +0000330 if (!success && hasFallbackContent())
eric@webkit.org4ffb1fe2010-09-03 04:28:12 +0000331 renderFallbackContent();
332}
333
akling@apple.com2e55ebf2013-10-04 18:51:32 +0000334Node::InsertionNotificationRequest HTMLObjectElement::insertedInto(ContainerNode& insertionPoint)
eseideld2f36a12006-05-12 18:14:17 +0000335{
commit-queue@webkit.org9ea00802012-04-17 06:40:55 +0000336 HTMLPlugInImageElement::insertedInto(insertionPoint);
337 FormAssociatedElement::insertedInto(insertionPoint);
338 return InsertionDone;
eseideld2f36a12006-05-12 18:14:17 +0000339}
340
akling@apple.com2e55ebf2013-10-04 18:51:32 +0000341void HTMLObjectElement::removedFrom(ContainerNode& insertionPoint)
eseideld2f36a12006-05-12 18:14:17 +0000342{
commit-queue@webkit.org9ea00802012-04-17 06:40:55 +0000343 HTMLPlugInImageElement::removedFrom(insertionPoint);
344 FormAssociatedElement::removedFrom(insertionPoint);
eseideld2f36a12006-05-12 18:14:17 +0000345}
346
antti@apple.com1acee922013-09-02 15:17:50 +0000347void HTMLObjectElement::childrenChanged(const ChildChange& change)
eseideld2f36a12006-05-12 18:14:17 +0000348{
349 updateDocNamedItem();
eric@webkit.org03892922010-09-02 10:05:36 +0000350 if (inDocument() && !useFallbackContent()) {
eric@webkit.org1402eb42010-09-02 09:10:21 +0000351 setNeedsWidgetUpdate(true);
hyatt@apple.comf6d72f32009-04-10 00:05:02 +0000352 setNeedsStyleRecalc();
eseideld2f36a12006-05-12 18:14:17 +0000353 }
antti@apple.com1acee922013-09-02 15:17:50 +0000354 HTMLPlugInImageElement::childrenChanged(change);
eseideld2f36a12006-05-12 18:14:17 +0000355}
356
kling@webkit.orgd8a6d152012-05-08 16:27:04 +0000357bool HTMLObjectElement::isURLAttribute(const Attribute& attribute) const
eseideld2f36a12006-05-12 18:14:17 +0000358{
kling@webkit.orgd8a6d152012-05-08 16:27:04 +0000359 return attribute.name() == dataAttr || (attribute.name() == usemapAttr && attribute.value().string()[0] != '#') || HTMLPlugInImageElement::isURLAttribute(attribute);
eseideld2f36a12006-05-12 18:14:17 +0000360}
361
commit-queue@webkit.org25fd37e2013-03-13 21:16:50 +0000362const AtomicString& HTMLObjectElement::imageSourceURL() const
adeleae488bf2007-11-06 05:43:16 +0000363{
commit-queue@webkit.org25fd37e2013-03-13 21:16:50 +0000364 return getAttribute(dataAttr);
adeleae488bf2007-11-06 05:43:16 +0000365}
366
eseideld2f36a12006-05-12 18:14:17 +0000367void HTMLObjectElement::renderFallbackContent()
368{
eric@webkit.org03892922010-09-02 10:05:36 +0000369 if (useFallbackContent())
eseideld2f36a12006-05-12 18:14:17 +0000370 return;
aestes@apple.com4000bef2010-06-23 20:03:40 +0000371
372 if (!inDocument())
373 return;
eseideld2f36a12006-05-12 18:14:17 +0000374
antti@apple.comef239762014-01-01 21:20:51 +0000375 setNeedsStyleRecalc(ReconstructRenderTree);
376
hyatt@apple.com8be62252008-02-21 01:59:14 +0000377 // Before we give up and use fallback content, check to see if this is a MIME type issue.
inferno@chromium.org28ad8d82010-11-17 20:11:56 +0000378 if (m_imageLoader && m_imageLoader->image() && m_imageLoader->image()->status() != CachedResource::LoadError) {
hyatt@apple.com8be62252008-02-21 01:59:14 +0000379 m_serviceType = m_imageLoader->image()->response().mimeType();
380 if (!isImageType()) {
cdn@chromium.org88285f82011-05-18 00:53:22 +0000381 // If we don't think we have an image type anymore, then clear the image from the loader.
morrita@google.com75203b42011-05-24 03:31:34 +0000382 m_imageLoader->setImage(0);
hyatt@apple.com8be62252008-02-21 01:59:14 +0000383 return;
384 }
385 }
386
eseideld2f36a12006-05-12 18:14:17 +0000387 m_useFallbackContent = true;
antti@apple.com83cd80d2014-01-08 07:33:10 +0000388
389 // This is here mainly to keep acid2 non-flaky. A style recalc is required to make fallback resources to load. Without forcing
390 // this may happen after all the other resources have been loaded and the document is already considered complete.
391 // FIXME: Disentangle fallback content handling from style recalcs.
392 document().updateStyleIfNeeded();
eseideld2f36a12006-05-12 18:14:17 +0000393}
394
eric@webkit.orgef17f4b2010-08-25 06:57:14 +0000395// FIXME: This should be removed, all callers are almost certainly wrong.
396static bool isRecognizedTagName(const QualifiedName& tagName)
397{
398 DEFINE_STATIC_LOCAL(HashSet<AtomicStringImpl*>, tagList, ());
399 if (tagList.isEmpty()) {
darin@apple.com5b7f3072013-09-15 08:50:06 +0000400 const QualifiedName* const * tags = HTMLNames::getHTMLTags();
benjamin@webkit.orga7a9b072012-07-26 22:41:04 +0000401 for (size_t i = 0; i < HTMLNames::HTMLTagsCount; i++) {
eric@webkit.orgef17f4b2010-08-25 06:57:14 +0000402 if (*tags[i] == bgsoundTag
403 || *tags[i] == commandTag
404 || *tags[i] == detailsTag
405 || *tags[i] == figcaptionTag
406 || *tags[i] == figureTag
407 || *tags[i] == summaryTag
408 || *tags[i] == trackTag) {
409 // Even though we have atoms for these tags, we don't want to
410 // treat them as "recognized tags" for the purpose of parsing
411 // because that changes how we parse documents.
412 continue;
413 }
414 tagList.add(tags[i]->localName().impl());
415 }
416 }
417 return tagList.contains(tagName.localName().impl());
418}
419
eseideld2f36a12006-05-12 18:14:17 +0000420void HTMLObjectElement::updateDocNamedItem()
421{
422 // The rule is "<object> elements with no children other than
andersca30bcc782007-07-18 23:31:38 +0000423 // <param> elements, unknown elements and whitespace can be
424 // found by name in a document, and other <object> elements cannot."
eseideld2f36a12006-05-12 18:14:17 +0000425 bool wasNamedItem = m_docNamedItem;
426 bool isNamedItem = true;
427 Node* child = firstChild();
428 while (child && isNamedItem) {
429 if (child->isElementNode()) {
inferno@chromium.org9aa9e8d2013-03-14 16:08:06 +0000430 Element* element = toElement(child);
eric@webkit.orgef17f4b2010-08-25 06:57:14 +0000431 // FIXME: Use of isRecognizedTagName is almost certainly wrong here.
432 if (isRecognizedTagName(element->tagQName()) && !element->hasTagName(paramTag))
eseideld2f36a12006-05-12 18:14:17 +0000433 isNamedItem = false;
434 } else if (child->isTextNode()) {
commit-queue@webkit.org9b335e42012-02-12 11:27:56 +0000435 if (!toText(child)->containsOnlyWhitespace())
eseideld2f36a12006-05-12 18:14:17 +0000436 isNamedItem = false;
437 } else
438 isNamedItem = false;
439 child = child->nextSibling();
440 }
akling@apple.com622b1a42013-08-30 14:30:12 +0000441 if (isNamedItem != wasNamedItem && inDocument() && document().isHTMLDocument()) {
442 HTMLDocument* document = toHTMLDocument(&this->document());
rniwa@webkit.org068215b2013-05-07 00:20:05 +0000443
444 const AtomicString& id = getIdAttribute();
445 if (!id.isEmpty()) {
446 if (isNamedItem)
rniwa@webkit.org01ebac52013-10-05 02:59:02 +0000447 document->addDocumentNamedItem(*id.impl(), *this);
rniwa@webkit.org068215b2013-05-07 00:20:05 +0000448 else
rniwa@webkit.org01ebac52013-10-05 02:59:02 +0000449 document->removeDocumentNamedItem(*id.impl(), *this);
rniwa@webkit.org068215b2013-05-07 00:20:05 +0000450 }
451
452 const AtomicString& name = getNameAttribute();
rniwa@webkit.orgb9e8c3f2013-05-10 16:38:21 +0000453 if (!name.isEmpty() && id != name) {
rniwa@webkit.org068215b2013-05-07 00:20:05 +0000454 if (isNamedItem)
rniwa@webkit.org01ebac52013-10-05 02:59:02 +0000455 document->addDocumentNamedItem(*name.impl(), *this);
rniwa@webkit.org068215b2013-05-07 00:20:05 +0000456 else
rniwa@webkit.org01ebac52013-10-05 02:59:02 +0000457 document->removeDocumentNamedItem(*name.impl(), *this);
eseideld2f36a12006-05-12 18:14:17 +0000458 }
459 }
460 m_docNamedItem = isNamedItem;
461}
462
beidson1564c5e2007-05-10 08:55:44 +0000463bool HTMLObjectElement::containsJavaApplet() const
464{
commit-queue@webkit.org03477c82011-09-02 17:07:51 +0000465 if (MIMETypeRegistry::isJavaAppletMIMEType(getAttribute(typeAttr)))
beidson1564c5e2007-05-10 08:55:44 +0000466 return true;
antti@apple.com60057942013-08-28 19:43:51 +0000467
antti@apple.com3eb8fea2014-01-01 21:48:13 +0000468 for (auto& child : childrenOfType<Element>(*this)) {
weinig@apple.comc77041e2013-12-14 18:05:45 +0000469 if (child.hasTagName(paramTag) && equalIgnoringCase(child.getNameAttribute(), "type")
470 && MIMETypeRegistry::isJavaAppletMIMEType(child.getAttribute(valueAttr).string()))
darin@apple.comcf9dd0f2009-08-23 06:55:57 +0000471 return true;
weinig@apple.comc77041e2013-12-14 18:05:45 +0000472 if (child.hasTagName(objectTag) && toHTMLObjectElement(child).containsJavaApplet())
darin@apple.comcf9dd0f2009-08-23 06:55:57 +0000473 return true;
weinig@apple.comc77041e2013-12-14 18:05:45 +0000474 if (child.hasTagName(appletTag))
darin@apple.comcf9dd0f2009-08-23 06:55:57 +0000475 return true;
beidson1564c5e2007-05-10 08:55:44 +0000476 }
477
478 return false;
479}
480
darin@apple.com5ffbb5c2013-09-27 16:39:41 +0000481void HTMLObjectElement::addSubresourceAttributeURLs(ListHashSet<URL>& urls) const
beidson@apple.coma4fb38f2008-03-27 04:08:17 +0000482{
commit-queue@webkit.orgbd9bc9a2012-05-30 20:50:31 +0000483 HTMLPlugInImageElement::addSubresourceAttributeURLs(urls);
ddkilzer@apple.come9a55042008-12-23 00:00:14 +0000484
akling@apple.com622b1a42013-08-30 14:30:12 +0000485 addSubresourceURL(urls, document().completeURL(getAttribute(dataAttr)));
darin@apple.com3a3edd42009-08-19 00:17:59 +0000486
487 // FIXME: Passing a string that starts with "#" to the completeURL function does
488 // not seem like it would work. The image element has similar but not identical code.
commit-queue@webkit.org03477c82011-09-02 17:07:51 +0000489 const AtomicString& useMap = getAttribute(usemapAttr);
benjamin@webkit.org127cec2c2012-04-30 21:32:44 +0000490 if (useMap.startsWith('#'))
akling@apple.com622b1a42013-08-30 14:30:12 +0000491 addSubresourceURL(urls, document().completeURL(useMap));
beidson@apple.coma4fb38f2008-03-27 04:08:17 +0000492}
493
commit-queue@webkit.org774c7f62011-12-26 07:05:00 +0000494void HTMLObjectElement::didMoveToNewDocument(Document* oldDocument)
tkent@chromium.orgd408e112011-01-13 03:48:42 +0000495{
commit-queue@webkit.org774c7f62011-12-26 07:05:00 +0000496 FormAssociatedElement::didMoveToNewDocument(oldDocument);
497 HTMLPlugInImageElement::didMoveToNewDocument(oldDocument);
tkent@chromium.orgd408e112011-01-13 03:48:42 +0000498}
499
bashi@chromium.orgdcda5d92011-07-11 02:28:59 +0000500bool HTMLObjectElement::appendFormData(FormDataList& encoding, bool)
tkent@chromium.org995765c2010-12-07 09:40:23 +0000501{
bashi@chromium.orgdcda5d92011-07-11 02:28:59 +0000502 if (name().isEmpty())
503 return false;
504
505 Widget* widget = pluginWidget();
506 if (!widget || !widget->isPluginViewBase())
507 return false;
508 String value;
inferno@chromium.org92242cb2013-03-15 17:31:20 +0000509 if (!toPluginViewBase(widget)->getFormValue(value))
bashi@chromium.orgdcda5d92011-07-11 02:28:59 +0000510 return false;
511 encoding.appendData(name(), value);
512 return true;
tkent@chromium.org995765c2010-12-07 09:40:23 +0000513}
514
tkent@chromium.org38d5f632011-02-08 05:28:19 +0000515HTMLFormElement* HTMLObjectElement::virtualForm() const
516{
517 return FormAssociatedElement::form();
518}
519
eseideld2f36a12006-05-12 18:14:17 +0000520}