1 /*
2  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
4  * Copyright (C) 2004, 2006, 2007, 2008, 2009, 2012 Apple Inc. All rights
5  * reserved.
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 
24 #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_HTML_HTML_PLUGIN_ELEMENT_H_
25 #define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_HTML_PLUGIN_ELEMENT_H_
26 
27 #include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h"
28 #include "third_party/blink/renderer/core/core_export.h"
29 #include "third_party/blink/renderer/core/dom/create_element_flags.h"
30 #include "third_party/blink/renderer/core/html/html_frame_owner_element.h"
31 #include "v8/include/v8.h"
32 
33 namespace blink {
34 
35 class HTMLImageLoader;
36 class LayoutEmbeddedContent;
37 class LayoutEmbeddedObject;
38 class WebPluginContainerImpl;
39 
40 enum PreferPlugInsForImagesOption {
41   kShouldPreferPlugInsForImages,
42   kShouldNotPreferPlugInsForImages
43 };
44 
45 class PluginParameters {
46  public:
PluginParameters()47   PluginParameters() {}
PluginParameters(Vector<String> & param_names,Vector<String> & param_values)48   PluginParameters(Vector<String>& param_names, Vector<String>& param_values)
49       : names_(param_names), values_(param_values) {}
50 
51   const Vector<String>& Names() const;
52   const Vector<String>& Values() const;
53   void AppendAttribute(const Attribute&);
54   void AppendNameWithValue(const String& name, const String& value);
55   void MapDataParamToSrc();
56 
57  private:
58   Vector<String> names_;
59   Vector<String> values_;
60 };
61 
62 class CORE_EXPORT HTMLPlugInElement
63     : public HTMLFrameOwnerElement,
64       public ActiveScriptWrappable<HTMLPlugInElement> {
65   USING_GARBAGE_COLLECTED_MIXIN(HTMLPlugInElement);
66 
67  public:
68   ~HTMLPlugInElement() override;
69   void Trace(Visitor*) override;
70 
IsPlugin()71   bool IsPlugin() const final { return true; }
72 
73   bool HasPendingActivity() const final;
74 
75   void SetFocused(bool, mojom::blink::FocusType) override;
76   void ResetInstance();
77   // TODO(dcheng): Consider removing this, since HTMLEmbedElementLegacyCall
78   // and HTMLObjectElementLegacyCall usage is extremely low.
79   v8::Local<v8::Object> PluginWrapper();
80   // TODO(joelhockey): Clean up PluginEmbeddedContentView and
81   // OwnedEmbeddedContentView (maybe also PluginWrapper).  It would be good to
82   // remove and/or rename some of these. PluginEmbeddedContentView and
83   // OwnedPlugin both return the plugin that is stored as
84   // HTMLFrameOwnerElement::embedded_content_view_.  However
85   // PluginEmbeddedContentView will synchronously create the plugin if required
86   // by calling LayoutEmbeddedContentForJSBindings. Possibly the
87   // PluginEmbeddedContentView code can be inlined into PluginWrapper.
88   WebPluginContainerImpl* PluginEmbeddedContentView() const;
89   WebPluginContainerImpl* OwnedPlugin() const;
90   bool CanProcessDrag() const;
Url()91   const String& Url() const { return url_; }
92 
93   // Public for FrameView::addPartToUpdate()
NeedsPluginUpdate()94   bool NeedsPluginUpdate() const { return needs_plugin_update_; }
SetNeedsPluginUpdate(bool needs_plugin_update)95   void SetNeedsPluginUpdate(bool needs_plugin_update) {
96     needs_plugin_update_ = needs_plugin_update;
97   }
98   void UpdatePlugin();
99 
100   bool ShouldAccelerate() const;
101 
102   ParsedFeaturePolicy ConstructContainerPolicy(
103       Vector<String>* /* messages */) const override;
104 
105   bool IsImageType() const;
ImageLoader()106   HTMLImageLoader* ImageLoader() const { return image_loader_.Get(); }
107 
108  protected:
109   HTMLPlugInElement(const QualifiedName& tag_name,
110                     Document&,
111                     const CreateElementFlags,
112                     PreferPlugInsForImagesOption);
113 
114   // Node functions:
115   void RemovedFrom(ContainerNode& insertion_point) override;
116   void DidMoveToNewDocument(Document& old_document) override;
117   void AttachLayoutTree(AttachContext&) override;
118 
119   // Element functions:
120   bool IsPresentationAttribute(const QualifiedName&) const override;
121   void CollectStyleForPresentationAttribute(
122       const QualifiedName&,
123       const AtomicString&,
124       MutableCSSPropertyValueSet*) override;
125 
126   virtual bool HasFallbackContent() const;
127   virtual bool UseFallbackContent() const;
128   // Create or update the LayoutEmbeddedContent and return it, triggering layout
129   // if necessary.
130   virtual LayoutEmbeddedContent* LayoutEmbeddedContentForJSBindings() const;
131 
132   LayoutEmbeddedObject* GetLayoutEmbeddedObject() const;
133   bool AllowedToLoadFrameURL(const String& url);
134   bool RequestObject(const PluginParameters& plugin_params);
135 
136   void DispatchErrorEvent();
137   bool IsErrorplaceholder();
138   void ReattachOnPluginChangeIfNeeded();
139 
SetUrl(const String & url)140   void SetUrl(const String& url) {
141     url_ = url;
142     UpdateServiceTypeIfEmpty();
143   }
144 
SetServiceType(const String & service_type)145   void SetServiceType(const String& service_type) {
146     service_type_ = service_type;
147     UpdateServiceTypeIfEmpty();
148   }
149 
150   // Set when the current view cannot be re-used on reattach. This is the case
151   // e.g. when attributes (e.g. src) change.
SetDisposeView()152   void SetDisposeView() { dispose_view_ = true; }
153 
154   String service_type_;
155   String url_;
156   KURL loaded_url_;
157   Member<HTMLImageLoader> image_loader_;
158   bool is_delaying_load_event_;
159 
160  private:
161   // EventTarget overrides:
162   void RemoveAllEventListeners() final;
163 
164   // Node overrides:
CanContainRangeEndPoint()165   bool CanContainRangeEndPoint() const override { return false; }
166   bool CanStartSelection() const override;
167   bool WillRespondToMouseClickEvents() final;
168   void DefaultEventHandler(Event&) final;
169   void DetachLayoutTree(bool performing_reattach) final;
170   void FinishParsingChildren() final;
171 
172   // Element overrides:
173   LayoutObject* CreateLayoutObject(const ComputedStyle&, LegacyLayout) override;
SupportsFocus()174   bool SupportsFocus() const final { return true; }
175   bool IsFocusableStyle() const final;
176   bool IsKeyboardFocusable() const final;
177   void DidAddUserAgentShadowRoot(ShadowRoot&) final;
178   scoped_refptr<ComputedStyle> CustomStyleForLayoutObject() final;
179 
180   // HTMLElement overrides:
181   bool HasCustomFocusLogic() const override;
182   bool IsPluginElement() const final;
183 
184   // HTMLFrameOwnerElement overrides:
185   void DisconnectContentFrame() override;
186   void IntrinsicSizingInfoChanged() final;
187 
188   // Return any existing LayoutEmbeddedContent without triggering relayout, or 0
189   // if it doesn't yet exist.
190   virtual LayoutEmbeddedContent* ExistingLayoutEmbeddedContent() const = 0;
191   virtual void UpdatePluginInternal() = 0;
192 
193   bool LoadPlugin(const KURL&,
194                   const String& mime_type,
195                   const PluginParameters& plugin_params,
196                   bool use_fallback);
197   // Perform checks after we have determined that a plugin will be used to
198   // show the object (i.e after allowedToLoadObject).
199   bool AllowedToLoadPlugin(const KURL&, const String& mime_type);
200   // Perform checks based on the URL and MIME-type of the object to load.
201   bool AllowedToLoadObject(const KURL&, const String& mime_type);
202   void RemovePluginFromFrameView(WebPluginContainerImpl* plugin);
203 
204   enum class ObjectContentType {
205     kNone,
206     kImage,
207     kFrame,
208     kPlugin,
209     kExternalPlugin,
210   };
211   ObjectContentType GetObjectContentType() const;
212 
213   void SetPersistedPlugin(WebPluginContainerImpl*);
214 
215   void UpdateServiceTypeIfEmpty();
216 
217   v8::Global<v8::Object> plugin_wrapper_;
218   bool needs_plugin_update_;
219   bool should_prefer_plug_ins_for_images_;
220   // Represents |layoutObject() && layoutObject()->isEmbeddedObject() &&
221   // !layoutEmbeddedItem().showsUnavailablePluginIndicator()|.  We want to
222   // avoid accessing |layoutObject()| in layoutObjectIsFocusable().
223   bool plugin_is_available_ = false;
224 
225   // Normally the plugin is stored in
226   // HTMLFrameOwnerElement::embedded_content_view. However, plugins can persist
227   // even when not rendered. In order to prevent confusing code which may assume
228   // that OwnedEmbeddedContentView() != null means the frame is active, we save
229   // off embedded_content_view_ here while the plugin is persisting but not
230   // being displayed.
231   Member<WebPluginContainerImpl> persisted_plugin_;
232 
233   // True when the element has changed in such a way (new URL, for instance)
234   // that we cannot re-use the old view when re-attaching.
235   bool dispose_view_ = false;
236 };
237 
238 template <>
239 inline bool IsElementOfType<const HTMLPlugInElement>(const Node& node) {
240   return IsA<HTMLPlugInElement>(node);
241 }
242 template <>
243 struct DowncastTraits<HTMLPlugInElement> {
244   static bool AllowFrom(const Node& node) {
245     auto* html_element = DynamicTo<HTMLElement>(node);
246     return html_element && AllowFrom(*html_element);
247   }
248   static bool AllowFrom(const HTMLElement& html_element) {
249     return html_element.IsPluginElement();
250   }
251 };
252 
253 }  // namespace blink
254 
255 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_HTML_PLUGIN_ELEMENT_H_
256