blob: 9140cb391a04488dafa0c80a5273bba22261f214 [file] [log] [blame]
/*
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* (C) 2000 Stefan Schimanski (1Stein@gmx.de)
* Copyright (C) 2004, 2005, 2006, 2008, 2009, 2012 Apple Inc. All rights reserved.
* Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "config.h"
#include "HTMLAppletElement.h"
#include "ElementIterator.h"
#include "Frame.h"
#include "FrameLoader.h"
#include "HTMLNames.h"
#include "HTMLParamElement.h"
#include "RenderEmbeddedObject.h"
#include "SecurityOrigin.h"
#include "Settings.h"
#include "SubframeLoader.h"
#include "Widget.h"
#include <wtf/IsoMallocInlines.h>
namespace WebCore {
WTF_MAKE_ISO_ALLOCATED_IMPL(HTMLAppletElement);
using namespace HTMLNames;
inline HTMLAppletElement::HTMLAppletElement(const QualifiedName& tagName, Document& document)
: HTMLPlugInImageElement(tagName, document)
{
ASSERT(hasTagName(appletTag));
m_serviceType = "application/x-java-applet"_s;
}
Ref<HTMLAppletElement> HTMLAppletElement::create(const QualifiedName& tagName, Document& document)
{
auto result = adoptRef(*new HTMLAppletElement(tagName, document));
result->finishCreating();
return result;
}
void HTMLAppletElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
{
if (name == altAttr
|| name == archiveAttr
|| name == codeAttr
|| name == codebaseAttr
|| name == mayscriptAttr
|| name == objectAttr) {
// Do nothing.
return;
}
HTMLPlugInImageElement::parseAttribute(name, value);
}
bool HTMLAppletElement::isURLAttribute(const Attribute& attribute) const
{
return attribute.name().localName() == codebaseAttr
|| attribute.name().localName() == objectAttr
|| HTMLPlugInImageElement::isURLAttribute(attribute);
}
bool HTMLAppletElement::rendererIsNeeded(const RenderStyle& style)
{
if (!hasAttributeWithoutSynchronization(codeAttr))
return false;
return HTMLPlugInImageElement::rendererIsNeeded(style);
}
RenderPtr<RenderElement> HTMLAppletElement::createElementRenderer(RenderStyle&& style, const RenderTreePosition&)
{
if (!canEmbedJava())
return RenderElement::createFor(*this, WTFMove(style));
return RenderEmbeddedObject::createForApplet(*this, WTFMove(style));
}
RenderWidget* HTMLAppletElement::renderWidgetLoadingPlugin() const
{
if (!canEmbedJava())
return nullptr;
// Needs to load the plugin immediatedly because this function is called
// when JavaScript code accesses the plugin.
// FIXME: <rdar://16893708> Check if dispatching events here is safe.
document().updateLayoutIgnorePendingStylesheets(Document::RunPostLayoutTasks::Synchronously);
return renderWidget();
}
void HTMLAppletElement::updateWidget(CreatePlugins createPlugins)
{
// FIXME: This should ASSERT isFinishedParsingChildren() instead.
if (!isFinishedParsingChildren()) {
setNeedsWidgetUpdate(false);
return;
}
#if PLATFORM(IOS_FAMILY)
UNUSED_PARAM(createPlugins);
#else
// FIXME: It's sadness that we have this special case here.
// See http://trac.webkit.org/changeset/25128 and
// plugins/netscape-plugin-setwindow-size.html
if (createPlugins == CreatePlugins::No)
return;
setNeedsWidgetUpdate(false);
RenderEmbeddedObject* renderer = renderEmbeddedObject();
LayoutUnit contentWidth = renderer->style().width().isFixed() ? LayoutUnit(renderer->style().width().value()) :
renderer->width() - renderer->horizontalBorderAndPaddingExtent();
LayoutUnit contentHeight = renderer->style().height().isFixed() ? LayoutUnit(renderer->style().height().value()) :
renderer->height() - renderer->verticalBorderAndPaddingExtent();
Vector<String> paramNames;
Vector<String> paramValues;
paramNames.append("code");
paramValues.append(attributeWithoutSynchronization(codeAttr).string());
const AtomicString& codeBase = attributeWithoutSynchronization(codebaseAttr);
if (!codeBase.isNull()) {
paramNames.append("codeBase"_s);
paramValues.append(codeBase.string());
}
const AtomicString& name = document().isHTMLDocument() ? getNameAttribute() : getIdAttribute();
if (!name.isNull()) {
paramNames.append("name");
paramValues.append(name.string());
}
const AtomicString& archive = attributeWithoutSynchronization(archiveAttr);
if (!archive.isNull()) {
paramNames.append("archive"_s);
paramValues.append(archive.string());
}
paramNames.append("baseURL"_s);
paramValues.append(document().baseURL().string());
const AtomicString& mayScript = attributeWithoutSynchronization(mayscriptAttr);
if (!mayScript.isNull()) {
paramNames.append("mayScript"_s);
paramValues.append(mayScript.string());
}
for (auto& param : childrenOfType<HTMLParamElement>(*this)) {
if (param.name().isEmpty())
continue;
paramNames.append(param.name());
paramValues.append(param.value());
}
RefPtr<Frame> frame = document().frame();
ASSERT(frame);
renderer->setWidget(frame->loader().subframeLoader().createJavaAppletWidget(roundedIntSize(LayoutSize(contentWidth, contentHeight)), *this, paramNames, paramValues));
#endif // !PLATFORM(IOS_FAMILY)
}
bool HTMLAppletElement::canEmbedJava() const
{
if (document().isSandboxed(SandboxPlugins))
return false;
if (!document().settings().isJavaEnabled())
return false;
if (document().securityOrigin().isLocal() && !document().settings().isJavaEnabledForLocalFiles())
return false;
return true;
}
}