summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/core/html/html_plugin_element.h
blob: a13a29c4b9010975f37c14f3d6764b9823fc94cf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
/*
 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
 *           (C) 1999 Antti Koivisto (koivisto@kde.org)
 * Copyright (C) 2004, 2006, 2007, 2008, 2009, 2012 Apple Inc. All rights
 * reserved.
 *
 * 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.
 *
 */

#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_HTML_HTML_PLUGIN_ELEMENT_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_HTML_PLUGIN_ELEMENT_H_

#include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/dom/create_element_flags.h"
#include "third_party/blink/renderer/core/html/html_frame_owner_element.h"
#include "v8/include/v8.h"

namespace blink {

class HTMLImageLoader;
class LayoutEmbeddedContent;
class LayoutEmbeddedObject;
class WebPluginContainerImpl;

class PluginParameters {
 public:
  PluginParameters() {}
  PluginParameters(Vector<String>& param_names, Vector<String>& param_values)
      : names_(param_names), values_(param_values) {}

  const Vector<String>& Names() const;
  const Vector<String>& Values() const;
  void AppendAttribute(const Attribute&);
  void AppendNameWithValue(const String& name, const String& value);
  void MapDataParamToSrc();

 private:
  Vector<String> names_;
  Vector<String> values_;
};

class CORE_EXPORT HTMLPlugInElement
    : public HTMLFrameOwnerElement,
      public ActiveScriptWrappable<HTMLPlugInElement> {
 public:
  ~HTMLPlugInElement() override;
  void Trace(Visitor*) const override;

  bool IsPlugin() const final { return true; }

  bool HasPendingActivity() const final;

  void SetFocused(bool, mojom::blink::FocusType) override;
  void ResetInstance();
  // TODO(dcheng): Consider removing this, since HTMLEmbedElementLegacyCall
  // and HTMLObjectElementLegacyCall usage is extremely low.
  v8::Local<v8::Object> PluginWrapper();
  // TODO(joelhockey): Clean up PluginEmbeddedContentView and
  // OwnedEmbeddedContentView (maybe also PluginWrapper).  It would be good to
  // remove and/or rename some of these. PluginEmbeddedContentView and
  // OwnedPlugin both return the plugin that is stored as
  // HTMLFrameOwnerElement::embedded_content_view_.  However
  // PluginEmbeddedContentView will synchronously create the plugin if required
  // by calling LayoutEmbeddedContentForJSBindings. Possibly the
  // PluginEmbeddedContentView code can be inlined into PluginWrapper.
  WebPluginContainerImpl* PluginEmbeddedContentView() const;
  WebPluginContainerImpl* OwnedPlugin() const;
  bool CanProcessDrag() const;
  const String& Url() const { return url_; }

  // Public for FrameView::addPartToUpdate()
  bool NeedsPluginUpdate() const { return needs_plugin_update_; }
  void SetNeedsPluginUpdate(bool needs_plugin_update) {
    needs_plugin_update_ = needs_plugin_update;
  }
  void UpdatePlugin();

  bool ShouldAccelerate() const;

  ParsedPermissionsPolicy ConstructContainerPolicy() const override;

  bool IsImageType() const;
  HTMLImageLoader* ImageLoader() const { return image_loader_.Get(); }

 protected:
  HTMLPlugInElement(const QualifiedName& tag_name,
                    Document&,
                    const CreateElementFlags);

  // Node functions:
  InsertionNotificationRequest InsertedInto(
      ContainerNode& insertion_point) override;
  void RemovedFrom(ContainerNode& insertion_point) override;
  void DidMoveToNewDocument(Document& old_document) override;
  void AttachLayoutTree(AttachContext&) override;

  // Element functions:
  bool IsPresentationAttribute(const QualifiedName&) const override;
  void CollectStyleForPresentationAttribute(
      const QualifiedName&,
      const AtomicString&,
      MutableCSSPropertyValueSet*) override;

  virtual bool HasFallbackContent() const;
  virtual bool UseFallbackContent() const;
  // Create or update the LayoutEmbeddedContent and return it, triggering layout
  // if necessary.
  virtual LayoutEmbeddedContent* LayoutEmbeddedContentForJSBindings() const;

  LayoutEmbeddedObject* GetLayoutEmbeddedObject() const;
  bool AllowedToLoadFrameURL(const String& url);
  bool RequestObject(const PluginParameters& plugin_params);

  void DispatchErrorEvent();
  bool IsErrorplaceholder();
  void ReattachOnPluginChangeIfNeeded();

  void SetUrl(const String& url) {
    url_ = url;
    UpdateServiceTypeIfEmpty();
  }

  void SetServiceType(const String& service_type) {
    service_type_ = service_type;
    UpdateServiceTypeIfEmpty();
  }

  // Set when the current view cannot be re-used on reattach. This is the case
  // e.g. when attributes (e.g. src) change.
  void SetDisposeView() { dispose_view_ = true; }

  String service_type_;
  String url_;
  KURL loaded_url_;
  Member<HTMLImageLoader> image_loader_;
  bool is_delaying_load_event_;

 private:
  // EventTarget overrides:
  void RemoveAllEventListeners() final;

  // Node overrides:
  bool CanContainRangeEndPoint() const override { return false; }
  bool CanStartSelection() const override;
  bool WillRespondToMouseClickEvents() final;
  void DefaultEventHandler(Event&) final;
  void DetachLayoutTree(bool performing_reattach) final;
  void FinishParsingChildren() final;

  // Element overrides:
  LayoutObject* CreateLayoutObject(const ComputedStyle&, LegacyLayout) override;
  bool SupportsFocus() const final { return true; }
  bool IsFocusableStyle() const final;
  bool IsKeyboardFocusable() const final;
  void DidAddUserAgentShadowRoot(ShadowRoot&) final;
  scoped_refptr<ComputedStyle> CustomStyleForLayoutObject(
      const StyleRecalcContext&) final;

  // HTMLElement overrides:
  bool HasCustomFocusLogic() const override;
  bool IsPluginElement() const final;

  // HTMLFrameOwnerElement overrides:
  void DisconnectContentFrame() override;
  void IntrinsicSizingInfoChanged() final;

  // Return any existing LayoutEmbeddedContent without triggering relayout, or 0
  // if it doesn't yet exist.
  virtual LayoutEmbeddedContent* ExistingLayoutEmbeddedContent() const = 0;
  virtual void UpdatePluginInternal() = 0;

  bool LoadPlugin(const KURL&,
                  const String& mime_type,
                  const PluginParameters& plugin_params,
                  bool use_fallback);
  // Perform checks after we have determined that a plugin will be used to
  // show the object (i.e after allowedToLoadObject).
  bool AllowedToLoadPlugin(const KURL&, const String& mime_type);
  // Perform checks based on the URL and MIME-type of the object to load.
  bool AllowedToLoadObject(const KURL&, const String& mime_type);
  void RemovePluginFromFrameView(WebPluginContainerImpl* plugin);

  enum class ObjectContentType {
    kNone,
    kImage,
    kFrame,
    kPlugin,
    kExternalPlugin,
  };
  ObjectContentType GetObjectContentType() const;

  void SetPersistedPlugin(WebPluginContainerImpl*);

  void UpdateServiceTypeIfEmpty();

  v8::Global<v8::Object> plugin_wrapper_;
  bool needs_plugin_update_;
  // Represents |layoutObject() && layoutObject()->isEmbeddedObject() &&
  // !layoutEmbeddedItem().showsUnavailablePluginIndicator()|.  We want to
  // avoid accessing |layoutObject()| in layoutObjectIsFocusable().
  bool plugin_is_available_ = false;

  // Normally the plugin is stored in
  // HTMLFrameOwnerElement::embedded_content_view. However, plugins can persist
  // even when not rendered. In order to prevent confusing code which may assume
  // that OwnedEmbeddedContentView() != null means the frame is active, we save
  // off embedded_content_view_ here while the plugin is persisting but not
  // being displayed.
  Member<WebPluginContainerImpl> persisted_plugin_;

  // True when the element has changed in such a way (new URL, for instance)
  // that we cannot re-use the old view when re-attaching.
  bool dispose_view_ = false;
};

template <>
inline bool IsElementOfType<const HTMLPlugInElement>(const Node& node) {
  return IsA<HTMLPlugInElement>(node);
}
template <>
struct DowncastTraits<HTMLPlugInElement> {
  static bool AllowFrom(const Node& node) {
    auto* html_element = DynamicTo<HTMLElement>(node);
    return html_element && AllowFrom(*html_element);
  }
  static bool AllowFrom(const HTMLElement& html_element) {
    return html_element.IsPluginElement();
  }
};

}  // namespace blink

#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_HTML_PLUGIN_ELEMENT_H_