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 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 "Attribute.h"
28#include "HTMLDocument.h"
29#include "HTMLNames.h"
30#include "RenderApplet.h"
31#include "SecurityOrigin.h"
32#include "Settings.h"
33#include "Widget.h"
34
35namespace WebCore {
36
37using namespace HTMLNames;
38
39inline HTMLAppletElement::HTMLAppletElement(const QualifiedName& tagName, Document* document)
40    : HTMLPlugInElement(tagName, document)
41{
42    ASSERT(hasTagName(appletTag));
43}
44
45PassRefPtr<HTMLAppletElement> HTMLAppletElement::create(const QualifiedName& tagName, Document* document)
46{
47    return adoptRef(new HTMLAppletElement(tagName, document));
48}
49
50void HTMLAppletElement::parseMappedAttribute(Attribute* attr)
51{
52    if (attr->name() == altAttr ||
53        attr->name() == archiveAttr ||
54        attr->name() == codeAttr ||
55        attr->name() == codebaseAttr ||
56        attr->name() == mayscriptAttr ||
57        attr->name() == objectAttr) {
58        // Do nothing.
59    } else if (attr->name() == nameAttr) {
60        const AtomicString& newName = attr->value();
61        if (inDocument() && document()->isHTMLDocument()) {
62            HTMLDocument* document = static_cast<HTMLDocument*>(this->document());
63            document->removeNamedItem(m_name);
64            document->addNamedItem(newName);
65        }
66        m_name = newName;
67    } else if (isIdAttributeName(attr->name())) {
68        const AtomicString& newId = attr->value();
69        if (inDocument() && document()->isHTMLDocument()) {
70            HTMLDocument* document = static_cast<HTMLDocument*>(this->document());
71            document->removeExtraNamedItem(m_id);
72            document->addExtraNamedItem(newId);
73        }
74        m_id = newId;
75        // also call superclass
76        HTMLPlugInElement::parseMappedAttribute(attr);
77    } else
78        HTMLPlugInElement::parseMappedAttribute(attr);
79}
80
81void HTMLAppletElement::insertedIntoDocument()
82{
83    if (document()->isHTMLDocument()) {
84        HTMLDocument* document = static_cast<HTMLDocument*>(this->document());
85        document->addNamedItem(m_name);
86        document->addExtraNamedItem(m_id);
87    }
88
89    HTMLPlugInElement::insertedIntoDocument();
90}
91
92void HTMLAppletElement::removedFromDocument()
93{
94    if (document()->isHTMLDocument()) {
95        HTMLDocument* document = static_cast<HTMLDocument*>(this->document());
96        document->removeNamedItem(m_name);
97        document->removeExtraNamedItem(m_id);
98    }
99
100    HTMLPlugInElement::removedFromDocument();
101}
102
103bool HTMLAppletElement::rendererIsNeeded(RenderStyle* style)
104{
105    if (!fastHasAttribute(codeAttr))
106        return false;
107
108    return HTMLPlugInElement::rendererIsNeeded(style);
109}
110
111RenderObject* HTMLAppletElement::createRenderer(RenderArena*, RenderStyle* style)
112{
113    if (canEmbedJava()) {
114        HashMap<String, String> args;
115
116        args.set("code", getAttribute(codeAttr));
117
118        const AtomicString& codeBase = getAttribute(codebaseAttr);
119        if (!codeBase.isNull())
120            args.set("codeBase", codeBase);
121
122        const AtomicString& name = document()->isHTMLDocument() ? getAttribute(nameAttr) : getIdAttribute();
123        if (!name.isNull())
124            args.set("name", name);
125        const AtomicString& archive = getAttribute(archiveAttr);
126        if (!archive.isNull())
127            args.set("archive", archive);
128
129        args.set("baseURL", document()->baseURL().string());
130
131        const AtomicString& mayScript = getAttribute(mayscriptAttr);
132        if (!mayScript.isNull())
133            args.set("mayScript", mayScript);
134
135        // Other arguments (from <PARAM> tags) are added later.
136
137        return new (document()->renderArena()) RenderApplet(this, args);
138    }
139
140    return RenderObject::createObject(this, style);
141}
142
143void HTMLAppletElement::defaultEventHandler(Event* event)
144{
145    RenderObject* r = renderer();
146    if (!r || !r->isWidget())
147        return;
148    Widget* widget = toRenderWidget(r)->widget();
149    if (!widget)
150        return;
151    widget->handleEvent(event);
152}
153
154RenderWidget* HTMLAppletElement::renderWidgetForJSBindings() const
155{
156    if (!canEmbedJava())
157        return 0;
158
159    RenderApplet* applet = toRenderApplet(renderer());
160    if (applet)
161        applet->createWidgetIfNecessary();
162
163    return applet;
164}
165
166bool HTMLAppletElement::canEmbedJava() const
167{
168    if (document()->securityOrigin()->isSandboxed(SandboxPlugins))
169        return false;
170
171    Settings* settings = document()->settings();
172    return settings && settings->isJavaEnabled();
173}
174
175void HTMLAppletElement::finishParsingChildren()
176{
177    // The parser just reached </applet>, so all the params are available now.
178    HTMLPlugInElement::finishParsingChildren();
179    if (renderer())
180        renderer()->setNeedsLayout(true); // This will cause it to create its widget & the Java applet
181}
182
183}
184