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