18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/**
28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *           (C) 1999 Antti Koivisto (koivisto@kde.org)
48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *           (C) 2000 Stefan Schimanski (1Stein@gmx.de)
58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc.
68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This library is free software; you can redistribute it and/or
88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modify it under the terms of the GNU Library General Public
98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * License as published by the Free Software Foundation; either
108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * version 2 of the License, or (at your option) any later version.
118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This library is distributed in the hope that it will be useful,
138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * but WITHOUT ANY WARRANTY; without even the implied warranty of
148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Library General Public License for more details.
168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * You should have received a copy of the GNU Library General Public License
188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * along with this library; see the file COPYING.LIB.  If not, write to
198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Boston, MA 02110-1301, USA.
218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */
225f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h"
248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLPlugInElement.h"
258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
26e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block#include "Attribute.h"
27ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block#include "Chrome.h"
28ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block#include "ChromeClient.h"
298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "CSSPropertyNames.h"
308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Document.h"
318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Frame.h"
328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "FrameLoader.h"
338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "FrameTree.h"
348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLNames.h"
358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Page.h"
36ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block#include "RenderEmbeddedObject.h"
378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RenderWidget.h"
38635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "ScriptController.h"
398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Settings.h"
408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Widget.h"
418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if ENABLE(NETSCAPE_PLUGIN_API)
438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "npruntime_impl.h"
448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore {
478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing namespace HTMLNames;
498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectHTMLPlugInElement::HTMLPlugInElement(const QualifiedName& tagName, Document* doc)
515f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    : HTMLFrameOwnerElement(tagName, doc)
52a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    , m_inBeforeLoadEventHandler(false)
538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if ENABLE(NETSCAPE_PLUGIN_API)
548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_NPObject(0)
558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
56a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    , m_isCapturingMouseEvents(false)
578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectHTMLPlugInElement::~HTMLPlugInElement()
618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(!m_instance); // cleared in detach()
638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if ENABLE(NETSCAPE_PLUGIN_API)
658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_NPObject) {
668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        _NPN_ReleaseObject(m_NPObject);
678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_NPObject = 0;
688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid HTMLPlugInElement::detach()
738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_instance.clear();
75e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
76e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    if (m_isCapturingMouseEvents) {
77e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        if (Frame* frame = document()->frame())
78e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke            frame->eventHandler()->setCapturingMouseEventsNode(0);
79e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        m_isCapturingMouseEvents = false;
80e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    }
81e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    HTMLFrameOwnerElement::detach();
838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
85635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectPassScriptInstance HTMLPlugInElement::getInstance() const
868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Frame* frame = document()->frame();
888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!frame)
898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // If the host dynamically turns off JavaScript (or Java) we will still return
928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // the cached allocated Bindings::Instance.  Not supporting this edge-case is OK.
938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_instance)
94635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        return m_instance;
958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
960617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen    if (Widget* widget = pluginWidget())
970617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        m_instance = frame->script()->createScriptInstanceForWidget(widget);
988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
99635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    return m_instance;
1008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1020617145a89917ae7735fe1c9538688ab9a577df5Kristian MonsenWidget* HTMLPlugInElement::pluginWidget() const
1030617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen{
104a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (m_inBeforeLoadEventHandler) {
105a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        // The plug-in hasn't loaded yet, and it makes no sense to try to load if beforeload handler happened to touch the plug-in element.
106a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        // That would recursively call beforeload for the same element.
107a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return 0;
108a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
109a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
1100617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen    RenderWidget* renderWidget = renderWidgetForJSBindings();
1110617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen    if (!renderWidget)
1120617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen        return 0;
1130617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen
1140617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen    return renderWidget->widget();
1150617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen}
1160617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen
1178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool HTMLPlugInElement::mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const
1188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (attrName == widthAttr ||
1208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        attrName == heightAttr ||
1218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        attrName == vspaceAttr ||
1228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        attrName == hspaceAttr) {
1238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            result = eUniversal;
1248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return false;
1258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (attrName == alignAttr) {
1288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        result = eReplaced; // Share with <img> since the alignment behavior is the same.
1298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
1308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return HTMLFrameOwnerElement::mapToEntry(attrName, result);
1338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
135e78cbe89e6f337f2f1fe40315be88f742b547151Steve Blockvoid HTMLPlugInElement::parseMappedAttribute(Attribute* attr)
1368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (attr->name() == widthAttr)
1388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        addCSSLength(attr, CSSPropertyWidth, attr->value());
1398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else if (attr->name() == heightAttr)
1408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        addCSSLength(attr, CSSPropertyHeight, attr->value());
1418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else if (attr->name() == vspaceAttr) {
1428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        addCSSLength(attr, CSSPropertyMarginTop, attr->value());
1438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        addCSSLength(attr, CSSPropertyMarginBottom, attr->value());
1448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else if (attr->name() == hspaceAttr) {
1458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        addCSSLength(attr, CSSPropertyMarginLeft, attr->value());
1468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        addCSSLength(attr, CSSPropertyMarginRight, attr->value());
1478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else if (attr->name() == alignAttr)
1488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        addHTMLAlignment(attr);
1498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else
1508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        HTMLFrameOwnerElement::parseMappedAttribute(attr);
1518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid HTMLPlugInElement::defaultEventHandler(Event* event)
1548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
155692e5dbf12901edacf14812a6fae25462920af42Steve Block    // Firefox seems to use a fake event listener to dispatch events to plug-in (tested with mouse events only).
156692e5dbf12901edacf14812a6fae25462920af42Steve Block    // This is observable via different order of events - in Firefox, event listeners specified in HTML attributes fires first, then an event
157692e5dbf12901edacf14812a6fae25462920af42Steve Block    // gets dispatched to plug-in, and only then other event listeners fire. Hopefully, this difference does not matter in practice.
158692e5dbf12901edacf14812a6fae25462920af42Steve Block
159692e5dbf12901edacf14812a6fae25462920af42Steve Block    // FIXME: Mouse down and scroll events are passed down to plug-in via custom code in EventHandler; these code paths should be united.
160692e5dbf12901edacf14812a6fae25462920af42Steve Block
1618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RenderObject* r = renderer();
162ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    if (r && r->isEmbeddedObject() && toRenderEmbeddedObject(r)->showsMissingPluginIndicator()) {
163e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        toRenderEmbeddedObject(r)->handleMissingPluginIndicatorEvent(event);
164ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        return;
165ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    }
166ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
1678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!r || !r->isWidget())
1688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
1692bde8e466a4451c7319e3a072d118917957d6554Steve Block    RefPtr<Widget> widget = toRenderWidget(r)->widget();
1700bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (!widget)
1710bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return;
1720bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    widget->handleEvent(event);
1738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if ENABLE(NETSCAPE_PLUGIN_API)
1768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectNPObject* HTMLPlugInElement::getNPObject()
1788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(document()->frame());
1808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_NPObject)
1818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_NPObject = document()->frame()->script()->createScriptObjectForPluginElement(this);
1828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return m_NPObject;
1838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif /* ENABLE(NETSCAPE_PLUGIN_API) */
1868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
187a622a48d6cc2bea33d2467de9d31feb1b03b03ebGrace Kloba#if PLATFORM(ANDROID)
188a622a48d6cc2bea33d2467de9d31feb1b03b03ebGrace Klobabool HTMLPlugInElement::supportsFocus() const
189a622a48d6cc2bea33d2467de9d31feb1b03b03ebGrace Kloba{
190a622a48d6cc2bea33d2467de9d31feb1b03b03ebGrace Kloba    return true;
191a622a48d6cc2bea33d2467de9d31feb1b03b03ebGrace Kloba}
192a622a48d6cc2bea33d2467de9d31feb1b03b03ebGrace Kloba#endif
193a622a48d6cc2bea33d2467de9d31feb1b03b03ebGrace Kloba
1948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
195