Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / 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 "core/html/HTMLAppletElement.h"
26
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"
42
43 namespace blink {
44
45 using namespace HTMLNames;
46
47 HTMLAppletElement::HTMLAppletElement(Document& document, bool createdByParser)
48     : HTMLPlugInElement(appletTag, document, createdByParser, ShouldNotPreferPlugInsForImages)
49 {
50     m_serviceType = "application/x-java-applet";
51 }
52
53 PassRefPtrWillBeRawPtr<HTMLAppletElement> HTMLAppletElement::create(Document& document, bool createdByParser)
54 {
55     RefPtrWillBeRawPtr<HTMLAppletElement> element = adoptRefWillBeNoop(new HTMLAppletElement(document, createdByParser));
56     element->ensureUserAgentShadowRoot();
57     return element.release();
58 }
59
60 void 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     HTMLPlugInElement::parseAttribute(name, value);
73 }
74
75 bool HTMLAppletElement::isURLAttribute(const Attribute& attribute) const
76 {
77     return attribute.name() == codebaseAttr || attribute.name() == objectAttr
78         || HTMLPlugInElement::isURLAttribute(attribute);
79 }
80
81 bool HTMLAppletElement::hasLegalLinkAttribute(const QualifiedName& name) const
82 {
83     return name == codebaseAttr || HTMLPlugInElement::hasLegalLinkAttribute(name);
84 }
85
86 bool HTMLAppletElement::rendererIsNeeded(const RenderStyle& style)
87 {
88     if (!fastHasAttribute(codeAttr) && !hasAuthorShadowRoot())
89         return false;
90     return HTMLPlugInElement::rendererIsNeeded(style);
91 }
92
93 RenderObject* HTMLAppletElement::createRenderer(RenderStyle* style)
94 {
95     if (!canEmbedJava() || hasAuthorShadowRoot())
96         return RenderObject::createObject(this, style);
97
98     if (usePlaceholderContent())
99         return new RenderBlockFlow(this);
100
101     return new RenderApplet(this);
102 }
103
104 RenderPart* HTMLAppletElement::renderPartForJSBindings() const
105 {
106     if (!canEmbedJava())
107         return nullptr;
108     return HTMLPlugInElement::renderPartForJSBindings();
109 }
110
111 RenderPart* HTMLAppletElement::existingRenderPart() const
112 {
113     return renderPart();
114 }
115
116 void HTMLAppletElement::updateWidgetInternal()
117 {
118     setNeedsWidgetUpdate(false);
119     // FIXME: This should ASSERT isFinishedParsingChildren() instead.
120     if (!isFinishedParsingChildren())
121         return;
122
123     RenderEmbeddedObject* renderer = renderEmbeddedObject();
124
125     LocalFrame* frame = document().frame();
126     ASSERT(frame);
127
128     Vector<String> paramNames;
129     Vector<String> paramValues;
130
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());
136     }
137
138     const AtomicString& archive = getAttribute(archiveAttr);
139     if (!archive.isNull()) {
140         paramNames.append("archive");
141         paramValues.append(archive.string());
142     }
143
144     const AtomicString& code = getAttribute(codeAttr);
145     paramNames.append("code");
146     paramValues.append(code.string());
147
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'.
153     KURL urlToCheck;
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))
160         return;
161
162     const AtomicString& name = document().isHTMLDocument() ? getNameAttribute() : getIdAttribute();
163     if (!name.isNull()) {
164         paramNames.append("name");
165         paramValues.append(name.string());
166     }
167
168     paramNames.append("baseURL");
169     KURL baseURL = document().baseURL();
170     paramValues.append(baseURL.string());
171
172     const AtomicString& mayScript = getAttribute(mayscriptAttr);
173     if (!mayScript.isNull()) {
174         paramNames.append("mayScript");
175         paramValues.append(mayScript.string());
176     }
177
178     for (HTMLParamElement* param = Traversal<HTMLParamElement>::firstChild(*this); param; param = Traversal<HTMLParamElement>::nextSibling(*param)) {
179         if (param->name().isEmpty())
180             continue;
181
182         paramNames.append(param->name());
183         paramValues.append(param->value());
184     }
185
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);
190         if (!placeholder)
191             widget = frame->loader().client()->createJavaAppletWidget(this, baseURL, paramNames, paramValues);
192     }
193
194     if (!placeholder && !widget) {
195         if (!renderer->showsUnavailablePluginIndicator())
196             renderer->setPluginUnavailabilityReason(RenderEmbeddedObject::PluginMissing);
197         setPlaceholder(nullptr);
198     } else if (placeholder) {
199         setPlaceholder(placeholder.release());
200     } else if (widget) {
201         document().setContainsPlugins();
202         setWidget(widget);
203         setPlaceholder(nullptr);
204     }
205 }
206
207 bool HTMLAppletElement::canEmbedJava() const
208 {
209     if (document().isSandboxed(SandboxPlugins))
210         return false;
211
212     Settings* settings = document().settings();
213     if (!settings)
214         return false;
215
216     if (!settings->javaEnabled())
217         return false;
218
219     return true;
220 }
221
222 bool HTMLAppletElement::canEmbedURL(const KURL& url) const
223 {
224     if (!document().securityOrigin()->canDisplay(url)) {
225         FrameLoader::reportLocalLoadFailed(document().frame(), url.string());
226         return false;
227     }
228
229     if (!document().contentSecurityPolicy()->allowObjectFromSource(url)
230         || !document().contentSecurityPolicy()->allowPluginType(m_serviceType, m_serviceType, url)) {
231         renderEmbeddedObject()->setPluginUnavailabilityReason(RenderEmbeddedObject::PluginBlockedByContentSecurityPolicy);
232         return false;
233     }
234     return true;
235 }
236
237 }