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)
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 "core/html/HTMLAppletElement.h"
27 #include "core/HTMLNames.h"
28 #include "core/dom/ElementTraversal.h"
29 #include "core/dom/shadow/ShadowRoot.h"
30 #include "core/html/HTMLParamElement.h"
31 #include "core/loader/FrameLoader.h"
32 #include "core/loader/FrameLoaderClient.h"
33 #include "core/frame/LocalFrame.h"
34 #include "core/frame/Settings.h"
35 #include "core/frame/csp/ContentSecurityPolicy.h"
36 #include "core/plugins/PluginPlaceholder.h"
37 #include "core/rendering/RenderApplet.h"
38 #include "core/rendering/RenderBlockFlow.h"
39 #include "platform/Widget.h"
40 #include "platform/weborigin/KURL.h"
41 #include "platform/weborigin/SecurityOrigin.h"
45 using namespace HTMLNames;
47 HTMLAppletElement::HTMLAppletElement(Document& document, bool createdByParser)
48 : HTMLPlugInElement(appletTag, document, createdByParser, ShouldNotPreferPlugInsForImages)
50 m_serviceType = "application/x-java-applet";
53 PassRefPtrWillBeRawPtr<HTMLAppletElement> HTMLAppletElement::create(Document& document, bool createdByParser)
55 RefPtrWillBeRawPtr<HTMLAppletElement> element = adoptRefWillBeNoop(new HTMLAppletElement(document, createdByParser));
56 element->ensureUserAgentShadowRoot();
57 return element.release();
60 void HTMLAppletElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
63 || name == archiveAttr
65 || name == codebaseAttr
66 || name == mayscriptAttr
67 || name == objectAttr) {
72 HTMLPlugInElement::parseAttribute(name, value);
75 bool HTMLAppletElement::isURLAttribute(const Attribute& attribute) const
77 return attribute.name() == codebaseAttr || attribute.name() == objectAttr
78 || HTMLPlugInElement::isURLAttribute(attribute);
81 bool HTMLAppletElement::hasLegalLinkAttribute(const QualifiedName& name) const
83 return name == codebaseAttr || HTMLPlugInElement::hasLegalLinkAttribute(name);
86 bool HTMLAppletElement::rendererIsNeeded(const RenderStyle& style)
88 if (!fastHasAttribute(codeAttr) && !hasAuthorShadowRoot())
90 return HTMLPlugInElement::rendererIsNeeded(style);
93 RenderObject* HTMLAppletElement::createRenderer(RenderStyle* style)
95 if (!canEmbedJava() || hasAuthorShadowRoot())
96 return RenderObject::createObject(this, style);
98 if (usePlaceholderContent())
99 return new RenderBlockFlow(this);
101 return new RenderApplet(this);
104 RenderPart* HTMLAppletElement::renderPartForJSBindings() const
108 return HTMLPlugInElement::renderPartForJSBindings();
111 RenderPart* HTMLAppletElement::existingRenderPart() const
116 void HTMLAppletElement::updateWidgetInternal()
118 setNeedsWidgetUpdate(false);
119 // FIXME: This should ASSERT isFinishedParsingChildren() instead.
120 if (!isFinishedParsingChildren())
123 RenderEmbeddedObject* renderer = renderEmbeddedObject();
125 LocalFrame* frame = document().frame();
128 Vector<String> paramNames;
129 Vector<String> paramValues;
131 const AtomicString& codeBase = getAttribute(codebaseAttr);
132 if (!codeBase.isNull()) {
133 KURL codeBaseURL = document().completeURL(codeBase);
134 paramNames.append("codeBase");
135 paramValues.append(codeBase.string());
138 const AtomicString& archive = getAttribute(archiveAttr);
139 if (!archive.isNull()) {
140 paramNames.append("archive");
141 paramValues.append(archive.string());
144 const AtomicString& code = getAttribute(codeAttr);
145 paramNames.append("code");
146 paramValues.append(code.string());
148 // If the 'codebase' attribute is set, it serves as a relative root for the file that the Java
149 // plugin will load. If the 'code' attribute is set, and the 'archive' is not set, then we need
150 // to check the url generated by resolving 'code' against 'codebase'. If the 'archive'
151 // attribute is set, then 'code' points to a class inside the archive, so we need to check the
152 // url generated by resolving 'archive' against 'codebase'.
154 KURL rootURL = codeBase.isNull() ? document().url() : document().completeURL(codeBase);
155 if (!archive.isNull())
156 urlToCheck = KURL(rootURL, archive);
157 else if (!code.isNull())
158 urlToCheck = KURL(rootURL, code);
159 if (!canEmbedURL(urlToCheck))
162 const AtomicString& name = document().isHTMLDocument() ? getNameAttribute() : getIdAttribute();
163 if (!name.isNull()) {
164 paramNames.append("name");
165 paramValues.append(name.string());
168 paramNames.append("baseURL");
169 KURL baseURL = document().baseURL();
170 paramValues.append(baseURL.string());
172 const AtomicString& mayScript = getAttribute(mayscriptAttr);
173 if (!mayScript.isNull()) {
174 paramNames.append("mayScript");
175 paramValues.append(mayScript.string());
178 for (HTMLParamElement* param = Traversal<HTMLParamElement>::firstChild(*this); param; param = Traversal<HTMLParamElement>::nextSibling(*param)) {
179 if (param->name().isEmpty())
182 paramNames.append(param->name());
183 paramValues.append(param->value());
186 OwnPtrWillBeRawPtr<PluginPlaceholder> placeholder = nullptr;
187 RefPtrWillBeRawPtr<Widget> widget = nullptr;
188 if (frame->loader().allowPlugins(AboutToInstantiatePlugin)) {
189 placeholder = frame->loader().client()->createPluginPlaceholder(document(), KURL(), paramNames, paramValues, m_serviceType, false);
191 widget = frame->loader().client()->createJavaAppletWidget(this, baseURL, paramNames, paramValues);
194 if (!placeholder && !widget) {
195 if (!renderer->showsUnavailablePluginIndicator())
196 renderer->setPluginUnavailabilityReason(RenderEmbeddedObject::PluginMissing);
197 setPlaceholder(nullptr);
198 } else if (placeholder) {
199 setPlaceholder(placeholder.release());
201 document().setContainsPlugins();
203 setPlaceholder(nullptr);
207 bool HTMLAppletElement::canEmbedJava() const
209 if (document().isSandboxed(SandboxPlugins))
212 Settings* settings = document().settings();
216 if (!settings->javaEnabled())
222 bool HTMLAppletElement::canEmbedURL(const KURL& url) const
224 if (!document().securityOrigin()->canDisplay(url)) {
225 FrameLoader::reportLocalLoadFailed(document().frame(), url.string());
229 if (!document().contentSecurityPolicy()->allowObjectFromSource(url)
230 || !document().contentSecurityPolicy()->allowPluginType(m_serviceType, m_serviceType, url)) {
231 renderEmbeddedObject()->setPluginUnavailabilityReason(RenderEmbeddedObject::PluginBlockedByContentSecurityPolicy);