1/*
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, 2008, 2009, 2012 Apple Inc. All rights reserved.
6 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
7 *
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
20 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
22 */
23
24#include "config.h"
25#include "HTMLAppletElement.h"
26
27#include "ElementIterator.h"
28#include "Frame.h"
29#include "FrameLoader.h"
30#include "HTMLNames.h"
31#include "HTMLParamElement.h"
32#include "RenderEmbeddedObject.h"
33#include "SecurityOrigin.h"
34#include "Settings.h"
35#include "SubframeLoader.h"
36#include "Widget.h"
37#include <wtf/IsoMallocInlines.h>
38
39namespace WebCore {
40
41WTF_MAKE_ISO_ALLOCATED_IMPL(HTMLAppletElement);
42
43using namespace HTMLNames;
44
45inline HTMLAppletElement::HTMLAppletElement(const QualifiedName& tagName, Document& document)
46 : HTMLPlugInImageElement(tagName, document)
47{
48 ASSERT(hasTagName(appletTag));
49
50 m_serviceType = "application/x-java-applet"_s;
51}
52
53Ref<HTMLAppletElement> HTMLAppletElement::create(const QualifiedName& tagName, Document& document)
54{
55 auto result = adoptRef(*new HTMLAppletElement(tagName, document));
56 result->finishCreating();
57 return result;
58}
59
60void HTMLAppletElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
61{
62 if (name == altAttr
63 || name == archiveAttr
64 || name == codeAttr
65 || name == codebaseAttr
66 || name == mayscriptAttr
67 || name == objectAttr) {
68 // Do nothing.
69 return;
70 }
71
72 HTMLPlugInImageElement::parseAttribute(name, value);
73}
74
75bool HTMLAppletElement::isURLAttribute(const Attribute& attribute) const
76{
77 return attribute.name().localName() == codebaseAttr
78 || attribute.name().localName() == objectAttr
79 || HTMLPlugInImageElement::isURLAttribute(attribute);
80}
81
82bool HTMLAppletElement::rendererIsNeeded(const RenderStyle& style)
83{
84 if (!hasAttributeWithoutSynchronization(codeAttr))
85 return false;
86 return HTMLPlugInImageElement::rendererIsNeeded(style);
87}
88
89RenderPtr<RenderElement> HTMLAppletElement::createElementRenderer(RenderStyle&& style, const RenderTreePosition&)
90{
91 if (!canEmbedJava())
92 return RenderElement::createFor(*this, WTFMove(style));
93
94 return RenderEmbeddedObject::createForApplet(*this, WTFMove(style));
95}
96
97RenderWidget* HTMLAppletElement::renderWidgetLoadingPlugin() const
98{
99 if (!canEmbedJava())
100 return nullptr;
101
102 // Needs to load the plugin immediatedly because this function is called
103 // when JavaScript code accesses the plugin.
104 // FIXME: <rdar://16893708> Check if dispatching events here is safe.
105 document().updateLayoutIgnorePendingStylesheets(Document::RunPostLayoutTasks::Synchronously);
106 return renderWidget();
107}
108
109void HTMLAppletElement::updateWidget(CreatePlugins createPlugins)
110{
111 // FIXME: This should ASSERT isFinishedParsingChildren() instead.
112 if (!isFinishedParsingChildren()) {
113 setNeedsWidgetUpdate(false);
114 return;
115 }
116
117#if PLATFORM(IOS_FAMILY)
118 UNUSED_PARAM(createPlugins);
119#else
120 // FIXME: It's sadness that we have this special case here.
121 // See http://trac.webkit.org/changeset/25128 and
122 // plugins/netscape-plugin-setwindow-size.html
123 if (createPlugins == CreatePlugins::No)
124 return;
125
126 setNeedsWidgetUpdate(false);
127
128 RenderEmbeddedObject* renderer = renderEmbeddedObject();
129
130 LayoutUnit contentWidth = renderer->style().width().isFixed() ? LayoutUnit(renderer->style().width().value()) :
131 renderer->width() - renderer->horizontalBorderAndPaddingExtent();
132 LayoutUnit contentHeight = renderer->style().height().isFixed() ? LayoutUnit(renderer->style().height().value()) :
133 renderer->height() - renderer->verticalBorderAndPaddingExtent();
134
135 Vector<String> paramNames;
136 Vector<String> paramValues;
137
138 paramNames.append("code");
139 paramValues.append(attributeWithoutSynchronization(codeAttr).string());
140
141 const AtomicString& codeBase = attributeWithoutSynchronization(codebaseAttr);
142 if (!codeBase.isNull()) {
143 paramNames.append("codeBase"_s);
144 paramValues.append(codeBase.string());
145 }
146
147 const AtomicString& name = document().isHTMLDocument() ? getNameAttribute() : getIdAttribute();
148 if (!name.isNull()) {
149 paramNames.append("name");
150 paramValues.append(name.string());
151 }
152
153 const AtomicString& archive = attributeWithoutSynchronization(archiveAttr);
154 if (!archive.isNull()) {
155 paramNames.append("archive"_s);
156 paramValues.append(archive.string());
157 }
158
159 paramNames.append("baseURL"_s);
160 paramValues.append(document().baseURL().string());
161
162 const AtomicString& mayScript = attributeWithoutSynchronization(mayscriptAttr);
163 if (!mayScript.isNull()) {
164 paramNames.append("mayScript"_s);
165 paramValues.append(mayScript.string());
166 }
167
168 for (auto& param : childrenOfType<HTMLParamElement>(*this)) {
169 if (param.name().isEmpty())
170 continue;
171
172 paramNames.append(param.name());
173 paramValues.append(param.value());
174 }
175
176 RefPtr<Frame> frame = document().frame();
177 ASSERT(frame);
178
179 renderer->setWidget(frame->loader().subframeLoader().createJavaAppletWidget(roundedIntSize(LayoutSize(contentWidth, contentHeight)), *this, paramNames, paramValues));
180#endif // !PLATFORM(IOS_FAMILY)
181}
182
183bool HTMLAppletElement::canEmbedJava() const
184{
185 if (document().isSandboxed(SandboxPlugins))
186 return false;
187
188 if (!document().settings().isJavaEnabled())
189 return false;
190
191 if (document().securityOrigin().isLocal() && !document().settings().isJavaEnabledForLocalFiles())
192 return false;
193
194 return true;
195}
196
197}
198