Don't dispatch 'beforeload' event inside FrameView::layout()
[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, ShouldNotPreferPlugInsForImages)
45 {
46     ASSERT(hasTagName(appletTag));
47
48     m_serviceType = "application/x-java-applet";
49 }
50
51 PassRefPtr<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::rendererIsNeeded(const RenderStyle& style)
72 {
73     if (!fastHasAttribute(codeAttr))
74         return false;
75     return HTMLPlugInImageElement::rendererIsNeeded(style);
76 }
77
78 RenderPtr<RenderElement> HTMLAppletElement::createElementRenderer(PassRef<RenderStyle> style)
79 {
80     if (!canEmbedJava())
81         return RenderElement::createFor(*this, std::move(style));
82
83     return RenderEmbeddedObject::createForApplet(*this, std::move(style));
84 }
85
86 RenderWidget* HTMLAppletElement::renderWidgetForJSBindings() const
87 {
88     if (!canEmbedJava())
89         return 0;
90
91     // Needs to load the plugin immediatedly because this function is called
92     // when JavaScript code accesses the plugin.
93     // FIXME: <rdar://16893708> Check if dispatching events here is safe.
94     document().updateLayoutIgnorePendingStylesheets(Document::RunPostLayoutTasksSynchronously);
95     return renderWidget();
96 }
97
98 void HTMLAppletElement::updateWidget(PluginCreationOption pluginCreationOption)
99 {
100     setNeedsWidgetUpdate(false);
101     // FIXME: This should ASSERT isFinishedParsingChildren() instead.
102     if (!isFinishedParsingChildren())
103         return;
104
105 #if PLATFORM(IOS)
106     UNUSED_PARAM(pluginCreationOption);
107 #else
108     // FIXME: It's sadness that we have this special case here.
109     //        See http://trac.webkit.org/changeset/25128 and
110     //        plugins/netscape-plugin-setwindow-size.html
111     if (pluginCreationOption == CreateOnlyNonNetscapePlugins) {
112         // Ensure updateWidget() is called again during layout to create the Netscape plug-in.
113         setNeedsWidgetUpdate(true);
114         return;
115     }
116
117     RenderEmbeddedObject* renderer = renderEmbeddedObject();
118
119     LayoutUnit contentWidth = renderer->style().width().isFixed() ? LayoutUnit(renderer->style().width().value()) :
120         renderer->width() - renderer->horizontalBorderAndPaddingExtent();
121     LayoutUnit contentHeight = renderer->style().height().isFixed() ? LayoutUnit(renderer->style().height().value()) :
122         renderer->height() - renderer->verticalBorderAndPaddingExtent();
123
124     Vector<String> paramNames;
125     Vector<String> paramValues;
126
127     paramNames.append("code");
128     paramValues.append(getAttribute(codeAttr).string());
129
130     const AtomicString& codeBase = getAttribute(codebaseAttr);
131     if (!codeBase.isNull()) {
132         paramNames.append("codeBase");
133         paramValues.append(codeBase.string());
134     }
135
136     const AtomicString& name = document().isHTMLDocument() ? getNameAttribute() : getIdAttribute();
137     if (!name.isNull()) {
138         paramNames.append("name");
139         paramValues.append(name.string());
140     }
141
142     const AtomicString& archive = getAttribute(archiveAttr);
143     if (!archive.isNull()) {
144         paramNames.append("archive");
145         paramValues.append(archive.string());
146     }
147
148     paramNames.append("baseURL");
149     paramValues.append(document().baseURL().string());
150
151     const AtomicString& mayScript = getAttribute(mayscriptAttr);
152     if (!mayScript.isNull()) {
153         paramNames.append("mayScript");
154         paramValues.append(mayScript.string());
155     }
156
157     for (auto& param : childrenOfType<HTMLParamElement>(*this)) {
158         if (param.name().isEmpty())
159             continue;
160
161         paramNames.append(param.name());
162         paramValues.append(param.value());
163     }
164
165     Frame* frame = document().frame();
166     ASSERT(frame);
167
168     renderer->setWidget(frame->loader().subframeLoader().createJavaAppletWidget(roundedIntSize(LayoutSize(contentWidth, contentHeight)), *this, paramNames, paramValues));
169 #endif // !PLATFORM(IOS)
170 }
171
172 bool HTMLAppletElement::canEmbedJava() const
173 {
174     if (document().isSandboxed(SandboxPlugins))
175         return false;
176
177     Settings* settings = document().settings();
178     if (!settings)
179         return false;
180
181     if (!settings->isJavaEnabled())
182         return false;
183
184     if (document().securityOrigin()->isLocal() && !settings->isJavaEnabledForLocalFiles())
185         return false;
186
187     return true;
188 }
189
190 }