Backed out changeset 62f7af8fe549 (bug 1843981) for causing valgrind bustage. CLOSED...
[gecko.git] / dom / html / HTMLEmbedElement.cpp
blob50a77b732517f0f3c187f79d698ce08f380f11ac
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/. */
7 #include "mozilla/dom/BindContext.h"
8 #include "mozilla/dom/HTMLEmbedElement.h"
9 #include "mozilla/dom/HTMLEmbedElementBinding.h"
10 #include "mozilla/dom/ElementInlines.h"
12 #include "mozilla/dom/Document.h"
13 #include "nsObjectLoadingContent.h"
14 #include "nsThreadUtils.h"
15 #include "nsIWidget.h"
16 #include "nsContentUtils.h"
17 #include "nsFrameLoader.h"
18 #ifdef XP_MACOSX
19 # include "mozilla/EventDispatcher.h"
20 # include "mozilla/dom/Event.h"
21 #endif
23 NS_IMPL_NS_NEW_HTML_ELEMENT_CHECK_PARSER(Embed)
25 namespace mozilla::dom {
27 HTMLEmbedElement::HTMLEmbedElement(
28 already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
29 FromParser aFromParser)
30 : nsGenericHTMLElement(std::move(aNodeInfo)) {
31 RegisterActivityObserver();
32 SetIsNetworkCreated(aFromParser == FROM_PARSER_NETWORK);
35 HTMLEmbedElement::~HTMLEmbedElement() {
36 UnregisterActivityObserver();
37 nsImageLoadingContent::Destroy();
40 NS_IMPL_CYCLE_COLLECTION_CLASS(HTMLEmbedElement)
42 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(HTMLEmbedElement,
43 nsGenericHTMLElement)
44 nsObjectLoadingContent::Traverse(tmp, cb);
45 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
47 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(HTMLEmbedElement,
48 nsGenericHTMLElement)
49 nsObjectLoadingContent::Unlink(tmp);
50 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
52 NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED(
53 HTMLEmbedElement, nsGenericHTMLElement, nsIRequestObserver,
54 nsIStreamListener, nsFrameLoaderOwner, nsIObjectLoadingContent,
55 imgINotificationObserver, nsIImageLoadingContent, nsIChannelEventSink)
57 NS_IMPL_ELEMENT_CLONE(HTMLEmbedElement)
59 void HTMLEmbedElement::AsyncEventRunning(AsyncEventDispatcher* aEvent) {
60 nsImageLoadingContent::AsyncEventRunning(aEvent);
63 nsresult HTMLEmbedElement::BindToTree(BindContext& aContext, nsINode& aParent) {
64 nsresult rv = nsGenericHTMLElement::BindToTree(aContext, aParent);
65 NS_ENSURE_SUCCESS(rv, rv);
67 rv = nsObjectLoadingContent::BindToTree(aContext, aParent);
68 NS_ENSURE_SUCCESS(rv, rv);
70 if (IsInComposedDoc()) {
71 void (HTMLEmbedElement::*start)() = &HTMLEmbedElement::StartObjectLoad;
72 nsContentUtils::AddScriptRunner(
73 NewRunnableMethod("dom::HTMLEmbedElement::BindToTree", this, start));
76 return NS_OK;
79 void HTMLEmbedElement::UnbindFromTree(bool aNullParent) {
80 nsObjectLoadingContent::UnbindFromTree(aNullParent);
81 nsGenericHTMLElement::UnbindFromTree(aNullParent);
84 void HTMLEmbedElement::AfterSetAttr(int32_t aNamespaceID, nsAtom* aName,
85 const nsAttrValue* aValue,
86 const nsAttrValue* aOldValue,
87 nsIPrincipal* aSubjectPrincipal,
88 bool aNotify) {
89 if (aValue) {
90 AfterMaybeChangeAttr(aNamespaceID, aName, aNotify);
93 if (aNamespaceID == kNameSpaceID_None &&
94 aName == nsGkAtoms::allowfullscreen && mFrameLoader) {
95 if (auto* bc = mFrameLoader->GetExtantBrowsingContext()) {
96 MOZ_ALWAYS_SUCCEEDS(bc->SetFullscreenAllowedByOwner(AllowFullscreen()));
100 return nsGenericHTMLElement::AfterSetAttr(
101 aNamespaceID, aName, aValue, aOldValue, aSubjectPrincipal, aNotify);
104 void HTMLEmbedElement::OnAttrSetButNotChanged(int32_t aNamespaceID,
105 nsAtom* aName,
106 const nsAttrValueOrString& aValue,
107 bool aNotify) {
108 AfterMaybeChangeAttr(aNamespaceID, aName, aNotify);
109 return nsGenericHTMLElement::OnAttrSetButNotChanged(aNamespaceID, aName,
110 aValue, aNotify);
113 void HTMLEmbedElement::AfterMaybeChangeAttr(int32_t aNamespaceID, nsAtom* aName,
114 bool aNotify) {
115 if (aNamespaceID != kNameSpaceID_None || aName != nsGkAtoms::src) {
116 return;
118 // If aNotify is false, we are coming from the parser or some such place;
119 // we'll get bound after all the attributes have been set, so we'll do the
120 // object load from BindToTree.
121 // Skip the LoadObject call in that case.
122 // We also don't want to start loading the object when we're not yet in
123 // a document, just in case that the caller wants to set additional
124 // attributes before inserting the node into the document.
125 if (!aNotify || !IsInComposedDoc() || BlockEmbedOrObjectContentLoading()) {
126 return;
128 nsContentUtils::AddScriptRunner(NS_NewRunnableFunction(
129 "HTMLEmbedElement::LoadObject",
130 [self = RefPtr<HTMLEmbedElement>(this), aNotify]() {
131 if (self->IsInComposedDoc()) {
132 self->LoadObject(aNotify, true);
134 }));
137 int32_t HTMLEmbedElement::TabIndexDefault() {
138 // Only when we loaded a sub-document, <embed> should be tabbable by default
139 // because it's a navigable containers mentioned in 6.6.3 The tabindex
140 // attribute in the standard (see "If the value is null" section).
141 // https://html.spec.whatwg.org/#the-tabindex-attribute
142 // Otherwise, the default tab-index of <embed> is expected as -1 in a WPT:
143 // https://searchfox.org/mozilla-central/rev/7d98e651953f3135d91e98fa6d33efa131aec7ea/testing/web-platform/tests/html/interaction/focus/sequential-focus-navigation-and-the-tabindex-attribute/tabindex-getter.html#63
144 return Type() == eType_Document ? 0 : -1;
147 bool HTMLEmbedElement::IsHTMLFocusable(bool aWithMouse, bool* aIsFocusable,
148 int32_t* aTabIndex) {
149 // Plugins that show the empty fallback should not accept focus.
150 if (Type() == eType_Fallback) {
151 if (aTabIndex) {
152 *aTabIndex = -1;
155 *aIsFocusable = false;
156 return false;
159 // Has non-plugin content: let the plugin decide what to do in terms of
160 // internal focus from mouse clicks
161 if (aTabIndex) {
162 *aTabIndex = TabIndex();
165 *aIsFocusable = true;
167 // Let the plugin decide, so override.
168 return true;
171 bool HTMLEmbedElement::ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
172 const nsAString& aValue,
173 nsIPrincipal* aMaybeScriptedPrincipal,
174 nsAttrValue& aResult) {
175 if (aNamespaceID == kNameSpaceID_None) {
176 if (aAttribute == nsGkAtoms::align) {
177 return ParseAlignValue(aValue, aResult);
179 if (aAttribute == nsGkAtoms::width || aAttribute == nsGkAtoms::height ||
180 aAttribute == nsGkAtoms::hspace || aAttribute == nsGkAtoms::vspace) {
181 return aResult.ParseHTMLDimension(aValue);
185 return nsGenericHTMLElement::ParseAttribute(aNamespaceID, aAttribute, aValue,
186 aMaybeScriptedPrincipal, aResult);
189 static void MapAttributesIntoRuleBase(MappedDeclarationsBuilder& aBuilder) {
190 nsGenericHTMLElement::MapImageMarginAttributeInto(aBuilder);
191 nsGenericHTMLElement::MapImageSizeAttributesInto(aBuilder);
192 nsGenericHTMLElement::MapImageAlignAttributeInto(aBuilder);
195 static void MapAttributesIntoRuleExceptHidden(
196 MappedDeclarationsBuilder& aBuilder) {
197 MapAttributesIntoRuleBase(aBuilder);
198 nsGenericHTMLElement::MapCommonAttributesIntoExceptHidden(aBuilder);
201 void HTMLEmbedElement::MapAttributesIntoRule(
202 MappedDeclarationsBuilder& aBuilder) {
203 MapAttributesIntoRuleBase(aBuilder);
204 nsGenericHTMLElement::MapCommonAttributesInto(aBuilder);
207 NS_IMETHODIMP_(bool)
208 HTMLEmbedElement::IsAttributeMapped(const nsAtom* aAttribute) const {
209 static const MappedAttributeEntry* const map[] = {
210 sCommonAttributeMap,
211 sImageMarginSizeAttributeMap,
212 sImageBorderAttributeMap,
213 sImageAlignAttributeMap,
216 return FindAttributeDependence(aAttribute, map);
219 nsMapRuleToAttributesFunc HTMLEmbedElement::GetAttributeMappingFunction()
220 const {
221 return &MapAttributesIntoRuleExceptHidden;
224 void HTMLEmbedElement::StartObjectLoad(bool aNotify, bool aForceLoad) {
225 // BindToTree can call us asynchronously, and we may be removed from the tree
226 // in the interim
227 if (!IsInComposedDoc() || !OwnerDoc()->IsActive() ||
228 BlockEmbedOrObjectContentLoading()) {
229 return;
232 LoadObject(aNotify, aForceLoad);
233 SetIsNetworkCreated(false);
236 uint32_t HTMLEmbedElement::GetCapabilities() const {
237 return eSupportPlugins | eAllowPluginSkipChannel | eSupportImages |
238 eSupportDocuments;
241 void HTMLEmbedElement::DestroyContent() {
242 nsObjectLoadingContent::Destroy();
243 nsGenericHTMLElement::DestroyContent();
246 nsresult HTMLEmbedElement::CopyInnerTo(HTMLEmbedElement* aDest) {
247 nsresult rv = nsGenericHTMLElement::CopyInnerTo(aDest);
248 NS_ENSURE_SUCCESS(rv, rv);
250 if (aDest->OwnerDoc()->IsStaticDocument()) {
251 CreateStaticClone(aDest);
254 return rv;
257 JSObject* HTMLEmbedElement::WrapNode(JSContext* aCx,
258 JS::Handle<JSObject*> aGivenProto) {
259 return HTMLEmbedElement_Binding::Wrap(aCx, this, aGivenProto);
262 nsContentPolicyType HTMLEmbedElement::GetContentPolicyType() const {
263 return nsIContentPolicy::TYPE_INTERNAL_EMBED;
266 } // namespace mozilla::dom