• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 Apple Computer, Inc.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public License
18  * along with this library; see the file COPYING.LIB.  If not, write to
19  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20  * Boston, MA 02110-1301, USA.
21  */
22 
23 #include "config.h"
24 #include "HTMLPlugInElement.h"
25 
26 #include "Attribute.h"
27 #include "Chrome.h"
28 #include "ChromeClient.h"
29 #include "CSSPropertyNames.h"
30 #include "Document.h"
31 #include "Frame.h"
32 #include "FrameLoader.h"
33 #include "FrameTree.h"
34 #include "HTMLNames.h"
35 #include "Page.h"
36 #include "RenderEmbeddedObject.h"
37 #include "RenderWidget.h"
38 #include "ScriptController.h"
39 #include "Settings.h"
40 #include "Widget.h"
41 
42 #if ENABLE(NETSCAPE_PLUGIN_API)
43 #include "npruntime_impl.h"
44 #endif
45 
46 namespace WebCore {
47 
48 using namespace HTMLNames;
49 
HTMLPlugInElement(const QualifiedName & tagName,Document * doc)50 HTMLPlugInElement::HTMLPlugInElement(const QualifiedName& tagName, Document* doc)
51     : HTMLFrameOwnerElement(tagName, doc)
52     , m_inBeforeLoadEventHandler(false)
53 #if ENABLE(NETSCAPE_PLUGIN_API)
54     , m_NPObject(0)
55 #endif
56     , m_isCapturingMouseEvents(false)
57 {
58 }
59 
~HTMLPlugInElement()60 HTMLPlugInElement::~HTMLPlugInElement()
61 {
62     ASSERT(!m_instance); // cleared in detach()
63 
64 #if ENABLE(NETSCAPE_PLUGIN_API)
65     if (m_NPObject) {
66         _NPN_ReleaseObject(m_NPObject);
67         m_NPObject = 0;
68     }
69 #endif
70 }
71 
detach()72 void HTMLPlugInElement::detach()
73 {
74     m_instance.clear();
75 
76     if (m_isCapturingMouseEvents) {
77         if (Frame* frame = document()->frame())
78             frame->eventHandler()->setCapturingMouseEventsNode(0);
79         m_isCapturingMouseEvents = false;
80     }
81 
82     HTMLFrameOwnerElement::detach();
83 }
84 
getInstance() const85 PassScriptInstance HTMLPlugInElement::getInstance() const
86 {
87     Frame* frame = document()->frame();
88     if (!frame)
89         return 0;
90 
91     // If the host dynamically turns off JavaScript (or Java) we will still return
92     // the cached allocated Bindings::Instance.  Not supporting this edge-case is OK.
93     if (m_instance)
94         return m_instance;
95 
96     if (Widget* widget = pluginWidget())
97         m_instance = frame->script()->createScriptInstanceForWidget(widget);
98 
99     return m_instance;
100 }
101 
pluginWidget() const102 Widget* HTMLPlugInElement::pluginWidget() const
103 {
104     if (m_inBeforeLoadEventHandler) {
105         // 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.
106         // That would recursively call beforeload for the same element.
107         return 0;
108     }
109 
110     RenderWidget* renderWidget = renderWidgetForJSBindings();
111     if (!renderWidget)
112         return 0;
113 
114     return renderWidget->widget();
115 }
116 
mapToEntry(const QualifiedName & attrName,MappedAttributeEntry & result) const117 bool HTMLPlugInElement::mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const
118 {
119     if (attrName == widthAttr ||
120         attrName == heightAttr ||
121         attrName == vspaceAttr ||
122         attrName == hspaceAttr) {
123             result = eUniversal;
124             return false;
125     }
126 
127     if (attrName == alignAttr) {
128         result = eReplaced; // Share with <img> since the alignment behavior is the same.
129         return false;
130     }
131 
132     return HTMLFrameOwnerElement::mapToEntry(attrName, result);
133 }
134 
parseMappedAttribute(Attribute * attr)135 void HTMLPlugInElement::parseMappedAttribute(Attribute* attr)
136 {
137     if (attr->name() == widthAttr)
138         addCSSLength(attr, CSSPropertyWidth, attr->value());
139     else if (attr->name() == heightAttr)
140         addCSSLength(attr, CSSPropertyHeight, attr->value());
141     else if (attr->name() == vspaceAttr) {
142         addCSSLength(attr, CSSPropertyMarginTop, attr->value());
143         addCSSLength(attr, CSSPropertyMarginBottom, attr->value());
144     } else if (attr->name() == hspaceAttr) {
145         addCSSLength(attr, CSSPropertyMarginLeft, attr->value());
146         addCSSLength(attr, CSSPropertyMarginRight, attr->value());
147     } else if (attr->name() == alignAttr)
148         addHTMLAlignment(attr);
149     else
150         HTMLFrameOwnerElement::parseMappedAttribute(attr);
151 }
152 
defaultEventHandler(Event * event)153 void HTMLPlugInElement::defaultEventHandler(Event* event)
154 {
155     // Firefox seems to use a fake event listener to dispatch events to plug-in (tested with mouse events only).
156     // This is observable via different order of events - in Firefox, event listeners specified in HTML attributes fires first, then an event
157     // gets dispatched to plug-in, and only then other event listeners fire. Hopefully, this difference does not matter in practice.
158 
159     // FIXME: Mouse down and scroll events are passed down to plug-in via custom code in EventHandler; these code paths should be united.
160 
161     RenderObject* r = renderer();
162     if (r && r->isEmbeddedObject() && toRenderEmbeddedObject(r)->showsMissingPluginIndicator()) {
163         toRenderEmbeddedObject(r)->handleMissingPluginIndicatorEvent(event);
164         return;
165     }
166 
167     if (!r || !r->isWidget())
168         return;
169     RefPtr<Widget> widget = toRenderWidget(r)->widget();
170     if (!widget)
171         return;
172     widget->handleEvent(event);
173 }
174 
175 #if ENABLE(NETSCAPE_PLUGIN_API)
176 
getNPObject()177 NPObject* HTMLPlugInElement::getNPObject()
178 {
179     ASSERT(document()->frame());
180     if (!m_NPObject)
181         m_NPObject = document()->frame()->script()->createScriptObjectForPluginElement(this);
182     return m_NPObject;
183 }
184 
185 #endif /* ENABLE(NETSCAPE_PLUGIN_API) */
186 
187 #if PLATFORM(ANDROID)
supportsFocus() const188 bool HTMLPlugInElement::supportsFocus() const
189 {
190     return true;
191 }
192 #endif
193 
194 }
195