Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/html/HTMLEmbedElement.cpp
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
3
/* This Source Code Form is subject to the terms of the Mozilla Public
4
 * License, v. 2.0. If a copy of the MPL was not distributed with this
5
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7
#include "mozilla/EventStates.h"
8
#include "mozilla/dom/HTMLEmbedElement.h"
9
#include "mozilla/dom/HTMLEmbedElementBinding.h"
10
#include "mozilla/dom/ElementInlines.h"
11
12
#include "nsIDocument.h"
13
#include "nsIPluginDocument.h"
14
#include "nsThreadUtils.h"
15
#include "nsIScriptError.h"
16
#include "nsIWidget.h"
17
#include "nsContentUtils.h"
18
#ifdef XP_MACOSX
19
#include "mozilla/EventDispatcher.h"
20
#include "mozilla/dom/Event.h"
21
#endif
22
#include "mozilla/dom/HTMLObjectElement.h"
23
24
25
NS_IMPL_NS_NEW_HTML_ELEMENT_CHECK_PARSER(Embed)
26
27
namespace mozilla {
28
namespace dom {
29
30
HTMLEmbedElement::HTMLEmbedElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
31
                                   FromParser aFromParser)
32
  : nsGenericHTMLElement(std::move(aNodeInfo))
33
0
{
34
0
  RegisterActivityObserver();
35
0
  SetIsNetworkCreated(aFromParser == FROM_PARSER_NETWORK);
36
0
37
0
  // By default we're in the loading state
38
0
  AddStatesSilently(NS_EVENT_STATE_LOADING);
39
0
}
40
41
HTMLEmbedElement::~HTMLEmbedElement()
42
0
{
43
#ifdef XP_MACOSX
44
  HTMLObjectElement::OnFocusBlurPlugin(this, false);
45
#endif
46
  UnregisterActivityObserver();
47
0
  DestroyImageLoadingContent();
48
0
}
49
50
NS_IMPL_CYCLE_COLLECTION_CLASS(HTMLEmbedElement)
51
52
0
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(HTMLEmbedElement,
53
0
                                                  nsGenericHTMLElement)
54
0
nsObjectLoadingContent::Traverse(tmp, cb);
55
0
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
56
57
NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED(HTMLEmbedElement,
58
                                             nsGenericHTMLElement,
59
                                             nsIRequestObserver,
60
                                             nsIStreamListener,
61
                                             nsIFrameLoaderOwner,
62
                                             nsIObjectLoadingContent,
63
                                             imgINotificationObserver,
64
                                             nsIImageLoadingContent,
65
                                             nsIChannelEventSink)
66
67
NS_IMPL_ELEMENT_CLONE(HTMLEmbedElement)
68
69
#ifdef XP_MACOSX
70
71
NS_IMETHODIMP
72
HTMLEmbedElement::PostHandleEvent(EventChainPostVisitor& aVisitor)
73
{
74
  HTMLObjectElement::HandleFocusBlurPlugin(this, aVisitor.mEvent);
75
  return NS_OK;
76
}
77
78
#endif // #ifdef XP_MACOSX
79
80
void
81
HTMLEmbedElement::AsyncEventRunning(AsyncEventDispatcher* aEvent)
82
0
{
83
0
  nsImageLoadingContent::AsyncEventRunning(aEvent);
84
0
}
85
86
nsresult
87
HTMLEmbedElement::BindToTree(nsIDocument *aDocument,
88
                             nsIContent *aParent,
89
                             nsIContent *aBindingParent)
90
0
{
91
0
  nsresult rv = nsGenericHTMLElement::BindToTree(aDocument, aParent,
92
0
                                                 aBindingParent);
93
0
  NS_ENSURE_SUCCESS(rv, rv);
94
0
95
0
  rv = nsObjectLoadingContent::BindToTree(aDocument, aParent,
96
0
                                          aBindingParent);
97
0
  NS_ENSURE_SUCCESS(rv, rv);
98
0
99
0
  // Don't kick off load from being bound to a plugin document - the plugin
100
0
  // document will call nsObjectLoadingContent::InitializeFromChannel() for the
101
0
  // initial load.
102
0
  nsCOMPtr<nsIPluginDocument> pluginDoc = do_QueryInterface(aDocument);
103
0
104
0
  if (!pluginDoc) {
105
0
    void (HTMLEmbedElement::*start)() = &HTMLEmbedElement::StartObjectLoad;
106
0
    nsContentUtils::AddScriptRunner(NewRunnableMethod(
107
0
                                      "dom::HTMLEmbedElement::BindToTree", this, start));
108
0
  }
109
0
110
0
  return NS_OK;
111
0
}
112
113
void
114
HTMLEmbedElement::UnbindFromTree(bool aDeep,
115
                                 bool aNullParent)
116
0
{
117
#ifdef XP_MACOSX
118
  // When a page is reloaded (when an nsIDocument's content is removed), the
119
  // focused element isn't necessarily sent an eBlur event. See
120
  // nsFocusManager::ContentRemoved(). This means that a widget may think it
121
  // still contains a focused plugin when it doesn't -- which in turn can
122
  // disable text input in the browser window. See bug 1137229.
123
  HTMLObjectElement::OnFocusBlurPlugin(this, false);
124
#endif
125
  nsObjectLoadingContent::UnbindFromTree(aDeep, aNullParent);
126
0
  nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);
127
0
}
128
129
nsresult
130
HTMLEmbedElement::AfterSetAttr(int32_t aNamespaceID, nsAtom* aName,
131
                               const nsAttrValue* aValue,
132
                               const nsAttrValue* aOldValue,
133
                               nsIPrincipal* aSubjectPrincipal,
134
                               bool aNotify)
135
0
{
136
0
  if (aValue) {
137
0
    nsresult rv = AfterMaybeChangeAttr(aNamespaceID, aName, aNotify);
138
0
    NS_ENSURE_SUCCESS(rv, rv);
139
0
  }
140
0
141
0
  return nsGenericHTMLElement::AfterSetAttr(aNamespaceID, aName, aValue,
142
0
                                            aOldValue, aSubjectPrincipal, aNotify);
143
0
}
144
145
nsresult
146
HTMLEmbedElement::OnAttrSetButNotChanged(int32_t aNamespaceID,
147
                                         nsAtom* aName,
148
                                         const nsAttrValueOrString& aValue,
149
                                         bool aNotify)
150
0
{
151
0
  nsresult rv = AfterMaybeChangeAttr(aNamespaceID, aName, aNotify);
152
0
  NS_ENSURE_SUCCESS(rv, rv);
153
0
154
0
  return nsGenericHTMLElement::OnAttrSetButNotChanged(aNamespaceID, aName,
155
0
                                                      aValue, aNotify);
156
0
}
157
158
nsresult
159
HTMLEmbedElement::AfterMaybeChangeAttr(int32_t aNamespaceID,
160
                                       nsAtom* aName,
161
                                       bool aNotify)
162
0
{
163
0
  if (aNamespaceID == kNameSpaceID_None) {
164
0
    if (aName == nsGkAtoms::src) {
165
0
      // If aNotify is false, we are coming from the parser or some such place;
166
0
      // we'll get bound after all the attributes have been set, so we'll do the
167
0
      // object load from BindToTree.
168
0
      // Skip the LoadObject call in that case.
169
0
      // We also don't want to start loading the object when we're not yet in
170
0
      // a document, just in case that the caller wants to set additional
171
0
      // attributes before inserting the node into the document.
172
0
      if (aNotify && IsInComposedDoc() &&
173
0
          !BlockEmbedOrObjectContentLoading()) {
174
0
        nsresult rv = LoadObject(aNotify, true);
175
0
        NS_ENSURE_SUCCESS(rv, rv);
176
0
      }
177
0
    }
178
0
  }
179
0
180
0
  return NS_OK;
181
0
}
182
183
bool
184
HTMLEmbedElement::IsHTMLFocusable(bool aWithMouse,
185
                                  bool *aIsFocusable,
186
                                  int32_t *aTabIndex)
187
0
{
188
0
  // Has plugin content: let the plugin decide what to do in terms of
189
0
  // internal focus from mouse clicks
190
0
  if (aTabIndex) {
191
0
    *aTabIndex = TabIndex();
192
0
  }
193
0
194
0
  *aIsFocusable = true;
195
0
196
0
  // Let the plugin decide, so override.
197
0
  return true;
198
0
}
199
200
nsIContent::IMEState
201
HTMLEmbedElement::GetDesiredIMEState()
202
0
{
203
0
  if (Type() == eType_Plugin) {
204
0
    return IMEState(IMEState::PLUGIN);
205
0
  }
206
0
207
0
  return nsGenericHTMLElement::GetDesiredIMEState();
208
0
}
209
210
int32_t
211
HTMLEmbedElement::TabIndexDefault()
212
0
{
213
0
  return -1;
214
0
}
215
216
bool
217
HTMLEmbedElement::ParseAttribute(int32_t aNamespaceID,
218
                                 nsAtom *aAttribute,
219
                                 const nsAString &aValue,
220
                                 nsIPrincipal* aMaybeScriptedPrincipal,
221
                                 nsAttrValue &aResult)
222
0
{
223
0
  if (aNamespaceID == kNameSpaceID_None) {
224
0
    if (aAttribute == nsGkAtoms::align) {
225
0
      return ParseAlignValue(aValue, aResult);
226
0
    }
227
0
    if (ParseImageAttribute(aAttribute, aValue, aResult)) {
228
0
      return true;
229
0
    }
230
0
  }
231
0
232
0
  return nsGenericHTMLElement::ParseAttribute(aNamespaceID, aAttribute, aValue,
233
0
                                              aMaybeScriptedPrincipal, aResult);
234
0
}
235
236
static void
237
MapAttributesIntoRuleBase(const nsMappedAttributes *aAttributes,
238
                          MappedDeclarations& aDecls)
239
0
{
240
0
  nsGenericHTMLElement::MapImageBorderAttributeInto(aAttributes, aDecls);
241
0
  nsGenericHTMLElement::MapImageMarginAttributeInto(aAttributes, aDecls);
242
0
  nsGenericHTMLElement::MapImageSizeAttributesInto(aAttributes, aDecls);
243
0
  nsGenericHTMLElement::MapImageAlignAttributeInto(aAttributes, aDecls);
244
0
}
245
246
static void
247
MapAttributesIntoRuleExceptHidden(const nsMappedAttributes *aAttributes,
248
                                  MappedDeclarations& aDecls)
249
0
{
250
0
  MapAttributesIntoRuleBase(aAttributes, aDecls);
251
0
  nsGenericHTMLElement::MapCommonAttributesIntoExceptHidden(aAttributes, aDecls);
252
0
}
253
254
void
255
HTMLEmbedElement::MapAttributesIntoRule(const nsMappedAttributes *aAttributes,
256
                                        MappedDeclarations& aDecls)
257
0
{
258
0
  MapAttributesIntoRuleBase(aAttributes, aDecls);
259
0
  nsGenericHTMLElement::MapCommonAttributesInto(aAttributes, aDecls);
260
0
}
261
262
NS_IMETHODIMP_(bool)
263
HTMLEmbedElement::IsAttributeMapped(const nsAtom *aAttribute) const
264
0
{
265
0
  static const MappedAttributeEntry* const map[] = {
266
0
    sCommonAttributeMap,
267
0
    sImageMarginSizeAttributeMap,
268
0
    sImageBorderAttributeMap,
269
0
    sImageAlignAttributeMap,
270
0
  };
271
0
272
0
  return FindAttributeDependence(aAttribute, map);
273
0
}
274
275
276
nsMapRuleToAttributesFunc
277
HTMLEmbedElement::GetAttributeMappingFunction() const
278
0
{
279
0
  return &MapAttributesIntoRuleExceptHidden;
280
0
}
281
282
void
283
HTMLEmbedElement::StartObjectLoad(bool aNotify, bool aForceLoad)
284
0
{
285
0
  // BindToTree can call us asynchronously, and we may be removed from the tree
286
0
  // in the interim
287
0
  if (!IsInComposedDoc() || !OwnerDoc()->IsActive() ||
288
0
      BlockEmbedOrObjectContentLoading()) {
289
0
    return;
290
0
  }
291
0
292
0
  LoadObject(aNotify, aForceLoad);
293
0
  SetIsNetworkCreated(false);
294
0
}
295
296
EventStates
297
HTMLEmbedElement::IntrinsicState() const
298
0
{
299
0
  return nsGenericHTMLElement::IntrinsicState() | ObjectState();
300
0
}
301
302
uint32_t
303
HTMLEmbedElement::GetCapabilities() const
304
0
{
305
0
  return eSupportPlugins | eAllowPluginSkipChannel | eSupportImages | eSupportDocuments;
306
0
}
307
308
void
309
HTMLEmbedElement::DestroyContent()
310
0
{
311
0
  nsObjectLoadingContent::DestroyContent();
312
0
  nsGenericHTMLElement::DestroyContent();
313
0
}
314
315
nsresult
316
HTMLEmbedElement::CopyInnerTo(HTMLEmbedElement* aDest)
317
0
{
318
0
  nsresult rv = nsGenericHTMLElement::CopyInnerTo(aDest);
319
0
  NS_ENSURE_SUCCESS(rv, rv);
320
0
321
0
  if (aDest->OwnerDoc()->IsStaticDocument()) {
322
0
    CreateStaticClone(aDest);
323
0
  }
324
0
325
0
  return rv;
326
0
}
327
328
JSObject*
329
HTMLEmbedElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
330
0
{
331
0
  JSObject* obj;
332
0
  obj = HTMLEmbedElement_Binding::Wrap(aCx, this, aGivenProto);
333
0
334
0
  if (!obj) {
335
0
    return nullptr;
336
0
  }
337
0
  JS::Rooted<JSObject*> rootedObj(aCx, obj);
338
0
  SetupProtoChain(aCx, rootedObj);
339
0
  return rootedObj;
340
0
}
341
342
nsContentPolicyType
343
HTMLEmbedElement::GetContentPolicyType() const
344
0
{
345
0
  return nsIContentPolicy::TYPE_INTERNAL_EMBED;
346
0
}
347
348
} // namespace dom
349
} // namespace mozilla