Backed out changeset 2450366cf7ca (bug 1891629) for causing win msix mochitest failures
[gecko.git] / dom / html / HTMLObjectElement.cpp
blobf77a1f3ba25563781a55fb0e9a280b7f8f85b05c
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/Document.h"
9 #include "mozilla/dom/HTMLObjectElement.h"
10 #include "mozilla/dom/HTMLObjectElementBinding.h"
11 #include "mozilla/dom/ElementInlines.h"
12 #include "mozilla/dom/WindowProxyHolder.h"
13 #include "nsAttrValueInlines.h"
14 #include "nsGkAtoms.h"
15 #include "nsError.h"
16 #include "nsIContentInlines.h"
17 #include "nsIWidget.h"
18 #include "nsContentUtils.h"
19 #ifdef XP_MACOSX
20 # include "mozilla/EventDispatcher.h"
21 # include "mozilla/dom/Event.h"
22 # include "nsFocusManager.h"
23 #endif
25 namespace mozilla::dom {
27 HTMLObjectElement::HTMLObjectElement(
28 already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
29 FromParser aFromParser)
30 : nsGenericHTMLFormControlElement(std::move(aNodeInfo),
31 FormControlType::Object),
32 mIsDoneAddingChildren(!aFromParser) {
33 SetIsNetworkCreated(aFromParser == FROM_PARSER_NETWORK);
35 // <object> is always barred from constraint validation.
36 SetBarredFromConstraintValidation(true);
39 HTMLObjectElement::~HTMLObjectElement() = default;
41 bool HTMLObjectElement::IsInteractiveHTMLContent() const {
42 return HasAttr(nsGkAtoms::usemap) ||
43 nsGenericHTMLFormControlElement::IsInteractiveHTMLContent();
46 void HTMLObjectElement::DoneAddingChildren(bool aHaveNotified) {
47 mIsDoneAddingChildren = true;
49 // If we're already in a document, we need to trigger the load
50 // Otherwise, BindToTree takes care of that.
51 if (IsInComposedDoc()) {
52 StartObjectLoad(aHaveNotified, false);
56 NS_IMPL_CYCLE_COLLECTION_CLASS(HTMLObjectElement)
58 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(
59 HTMLObjectElement, nsGenericHTMLFormControlElement)
60 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mValidity)
61 nsObjectLoadingContent::Traverse(tmp, cb);
62 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
64 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(HTMLObjectElement,
65 nsGenericHTMLFormControlElement)
66 NS_IMPL_CYCLE_COLLECTION_UNLINK(mValidity)
67 nsObjectLoadingContent::Unlink(tmp);
68 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
70 NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED(
71 HTMLObjectElement, nsGenericHTMLFormControlElement, nsIRequestObserver,
72 nsIStreamListener, nsFrameLoaderOwner, nsIObjectLoadingContent,
73 nsIChannelEventSink, nsIConstraintValidation)
75 NS_IMPL_ELEMENT_CLONE(HTMLObjectElement)
77 nsresult HTMLObjectElement::BindToTree(BindContext& aContext,
78 nsINode& aParent) {
79 nsresult rv = nsGenericHTMLFormControlElement::BindToTree(aContext, aParent);
80 NS_ENSURE_SUCCESS(rv, rv);
82 // If we already have all the children, start the load.
83 if (IsInComposedDoc() && mIsDoneAddingChildren) {
84 void (HTMLObjectElement::*start)() = &HTMLObjectElement::StartObjectLoad;
85 nsContentUtils::AddScriptRunner(
86 NewRunnableMethod("dom::HTMLObjectElement::BindToTree", this, start));
89 return NS_OK;
92 void HTMLObjectElement::UnbindFromTree(UnbindContext& aContext) {
93 nsObjectLoadingContent::UnbindFromTree();
94 nsGenericHTMLFormControlElement::UnbindFromTree(aContext);
97 void HTMLObjectElement::AfterSetAttr(int32_t aNamespaceID, nsAtom* aName,
98 const nsAttrValue* aValue,
99 const nsAttrValue* aOldValue,
100 nsIPrincipal* aSubjectPrincipal,
101 bool aNotify) {
102 AfterMaybeChangeAttr(aNamespaceID, aName, aNotify);
103 return nsGenericHTMLFormControlElement::AfterSetAttr(
104 aNamespaceID, aName, aValue, aOldValue, aSubjectPrincipal, aNotify);
107 void HTMLObjectElement::OnAttrSetButNotChanged(
108 int32_t aNamespaceID, nsAtom* aName, const nsAttrValueOrString& aValue,
109 bool aNotify) {
110 AfterMaybeChangeAttr(aNamespaceID, aName, aNotify);
111 return nsGenericHTMLFormControlElement::OnAttrSetButNotChanged(
112 aNamespaceID, aName, aValue, aNotify);
115 void HTMLObjectElement::AfterMaybeChangeAttr(int32_t aNamespaceID,
116 nsAtom* aName, bool aNotify) {
117 // if aNotify is false, we are coming from the parser or some such place;
118 // we'll get bound after all the attributes have been set, so we'll do the
119 // object load from BindToTree/DoneAddingChildren.
120 // Skip the LoadObject call in that case.
121 // We also don't want to start loading the object when we're not yet in
122 // a document, just in case that the caller wants to set additional
123 // attributes before inserting the node into the document.
124 if (aNamespaceID != kNameSpaceID_None || aName != nsGkAtoms::data ||
125 !aNotify || !IsInComposedDoc() || !mIsDoneAddingChildren ||
126 BlockEmbedOrObjectContentLoading()) {
127 return;
129 nsContentUtils::AddScriptRunner(NS_NewRunnableFunction(
130 "HTMLObjectElement::LoadObject",
131 [self = RefPtr<HTMLObjectElement>(this), aNotify]() {
132 if (self->IsInComposedDoc()) {
133 self->LoadObject(aNotify, true);
135 }));
138 bool HTMLObjectElement::IsHTMLFocusable(bool aWithMouse, bool* aIsFocusable,
139 int32_t* aTabIndex) {
140 // TODO: this should probably be managed directly by IsHTMLFocusable.
141 // See bug 597242.
142 Document* doc = GetComposedDoc();
143 if (!doc || IsInDesignMode()) {
144 if (aTabIndex) {
145 *aTabIndex = -1;
148 *aIsFocusable = false;
149 return false;
152 const nsAttrValue* attrVal = mAttrs.GetAttr(nsGkAtoms::tabindex);
153 bool isFocusable = attrVal && attrVal->Type() == nsAttrValue::eInteger;
155 // This method doesn't call nsGenericHTMLFormControlElement intentionally.
156 // TODO: It should probably be changed when bug 597242 will be fixed.
157 if (IsEditingHost() || Type() == ObjectType::Document) {
158 if (aTabIndex) {
159 *aTabIndex = isFocusable ? attrVal->GetIntegerValue() : 0;
162 *aIsFocusable = true;
163 return false;
166 // TODO: this should probably be managed directly by IsHTMLFocusable.
167 // See bug 597242.
168 if (aTabIndex && isFocusable) {
169 *aTabIndex = attrVal->GetIntegerValue();
170 *aIsFocusable = true;
173 return false;
176 int32_t HTMLObjectElement::TabIndexDefault() { return 0; }
178 Nullable<WindowProxyHolder> HTMLObjectElement::GetContentWindow(
179 nsIPrincipal& aSubjectPrincipal) {
180 Document* doc = GetContentDocument(aSubjectPrincipal);
181 if (doc) {
182 nsPIDOMWindowOuter* win = doc->GetWindow();
183 if (win) {
184 return WindowProxyHolder(win->GetBrowsingContext());
188 return nullptr;
191 bool HTMLObjectElement::ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
192 const nsAString& aValue,
193 nsIPrincipal* aMaybeScriptedPrincipal,
194 nsAttrValue& aResult) {
195 if (aNamespaceID == kNameSpaceID_None) {
196 if (aAttribute == nsGkAtoms::align) {
197 return ParseAlignValue(aValue, aResult);
199 if (ParseImageAttribute(aAttribute, aValue, aResult)) {
200 return true;
204 return nsGenericHTMLFormControlElement::ParseAttribute(
205 aNamespaceID, aAttribute, aValue, aMaybeScriptedPrincipal, aResult);
208 void HTMLObjectElement::MapAttributesIntoRule(
209 MappedDeclarationsBuilder& aBuilder) {
210 MapImageAlignAttributeInto(aBuilder);
211 MapImageBorderAttributeInto(aBuilder);
212 MapImageMarginAttributeInto(aBuilder);
213 MapImageSizeAttributesInto(aBuilder);
214 MapCommonAttributesInto(aBuilder);
217 NS_IMETHODIMP_(bool)
218 HTMLObjectElement::IsAttributeMapped(const nsAtom* aAttribute) const {
219 static const MappedAttributeEntry* const map[] = {
220 sCommonAttributeMap,
221 sImageMarginSizeAttributeMap,
222 sImageBorderAttributeMap,
223 sImageAlignAttributeMap,
226 return FindAttributeDependence(aAttribute, map);
229 nsMapRuleToAttributesFunc HTMLObjectElement::GetAttributeMappingFunction()
230 const {
231 return &MapAttributesIntoRule;
234 void HTMLObjectElement::StartObjectLoad(bool aNotify, bool aForce) {
235 // BindToTree can call us asynchronously, and we may be removed from the tree
236 // in the interim
237 if (!IsInComposedDoc() || !OwnerDoc()->IsActive() ||
238 BlockEmbedOrObjectContentLoading()) {
239 return;
242 LoadObject(aNotify, aForce);
243 SetIsNetworkCreated(false);
246 uint32_t HTMLObjectElement::GetCapabilities() const {
247 return nsObjectLoadingContent::GetCapabilities() | eFallbackIfClassIDPresent;
250 void HTMLObjectElement::DestroyContent() {
251 nsObjectLoadingContent::Destroy();
252 nsGenericHTMLFormControlElement::DestroyContent();
255 nsresult HTMLObjectElement::CopyInnerTo(Element* aDest) {
256 nsresult rv = nsGenericHTMLFormControlElement::CopyInnerTo(aDest);
257 NS_ENSURE_SUCCESS(rv, rv);
259 if (aDest->OwnerDoc()->IsStaticDocument()) {
260 CreateStaticClone(static_cast<HTMLObjectElement*>(aDest));
263 return rv;
266 JSObject* HTMLObjectElement::WrapNode(JSContext* aCx,
267 JS::Handle<JSObject*> aGivenProto) {
268 return HTMLObjectElement_Binding::Wrap(aCx, this, aGivenProto);
271 } // namespace mozilla::dom
273 NS_IMPL_NS_NEW_HTML_ELEMENT_CHECK_PARSER(Object)