Backed out changeset f14569b8319b (bug 1850342) for causing dt failures on browser_ru...
[gecko.git] / dom / html / HTMLObjectElement.cpp
blob82c350c7a790d71fa42e57fb93739d1dd8350c55
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 RegisterActivityObserver();
34 SetIsNetworkCreated(aFromParser == FROM_PARSER_NETWORK);
36 // <object> is always barred from constraint validation.
37 SetBarredFromConstraintValidation(true);
39 // By default we're in the loading state
40 AddStatesSilently(ElementState::LOADING);
43 HTMLObjectElement::~HTMLObjectElement() {
44 UnregisterActivityObserver();
45 nsImageLoadingContent::Destroy();
48 bool HTMLObjectElement::IsInteractiveHTMLContent() const {
49 return HasAttr(nsGkAtoms::usemap) ||
50 nsGenericHTMLFormControlElement::IsInteractiveHTMLContent();
53 void HTMLObjectElement::AsyncEventRunning(AsyncEventDispatcher* aEvent) {
54 nsImageLoadingContent::AsyncEventRunning(aEvent);
57 void HTMLObjectElement::DoneAddingChildren(bool aHaveNotified) {
58 mIsDoneAddingChildren = true;
60 // If we're already in a document, we need to trigger the load
61 // Otherwise, BindToTree takes care of that.
62 if (IsInComposedDoc()) {
63 StartObjectLoad(aHaveNotified, false);
67 NS_IMPL_CYCLE_COLLECTION_CLASS(HTMLObjectElement)
69 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(
70 HTMLObjectElement, nsGenericHTMLFormControlElement)
71 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mValidity)
72 nsObjectLoadingContent::Traverse(tmp, cb);
73 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
75 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(HTMLObjectElement,
76 nsGenericHTMLFormControlElement)
77 NS_IMPL_CYCLE_COLLECTION_UNLINK(mValidity)
78 nsObjectLoadingContent::Unlink(tmp);
79 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
81 NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED(
82 HTMLObjectElement, nsGenericHTMLFormControlElement,
83 imgINotificationObserver, nsIRequestObserver, nsIStreamListener,
84 nsFrameLoaderOwner, nsIObjectLoadingContent, nsIImageLoadingContent,
85 nsIChannelEventSink, nsIConstraintValidation)
87 NS_IMPL_ELEMENT_CLONE(HTMLObjectElement)
89 nsresult HTMLObjectElement::BindToTree(BindContext& aContext,
90 nsINode& aParent) {
91 nsresult rv = nsGenericHTMLFormControlElement::BindToTree(aContext, aParent);
92 NS_ENSURE_SUCCESS(rv, rv);
94 rv = nsObjectLoadingContent::BindToTree(aContext, aParent);
95 NS_ENSURE_SUCCESS(rv, rv);
97 // If we already have all the children, start the load.
98 if (IsInComposedDoc() && mIsDoneAddingChildren) {
99 void (HTMLObjectElement::*start)() = &HTMLObjectElement::StartObjectLoad;
100 nsContentUtils::AddScriptRunner(
101 NewRunnableMethod("dom::HTMLObjectElement::BindToTree", this, start));
104 return NS_OK;
107 void HTMLObjectElement::UnbindFromTree(bool aNullParent) {
108 nsObjectLoadingContent::UnbindFromTree(aNullParent);
109 nsGenericHTMLFormControlElement::UnbindFromTree(aNullParent);
112 void HTMLObjectElement::AfterSetAttr(int32_t aNamespaceID, nsAtom* aName,
113 const nsAttrValue* aValue,
114 const nsAttrValue* aOldValue,
115 nsIPrincipal* aSubjectPrincipal,
116 bool aNotify) {
117 AfterMaybeChangeAttr(aNamespaceID, aName, aNotify);
118 return nsGenericHTMLFormControlElement::AfterSetAttr(
119 aNamespaceID, aName, aValue, aOldValue, aSubjectPrincipal, aNotify);
122 void HTMLObjectElement::OnAttrSetButNotChanged(
123 int32_t aNamespaceID, nsAtom* aName, const nsAttrValueOrString& aValue,
124 bool aNotify) {
125 AfterMaybeChangeAttr(aNamespaceID, aName, aNotify);
126 return nsGenericHTMLFormControlElement::OnAttrSetButNotChanged(
127 aNamespaceID, aName, aValue, aNotify);
130 void HTMLObjectElement::AfterMaybeChangeAttr(int32_t aNamespaceID,
131 nsAtom* aName, bool aNotify) {
132 // if aNotify is false, we are coming from the parser or some such place;
133 // we'll get bound after all the attributes have been set, so we'll do the
134 // object load from BindToTree/DoneAddingChildren.
135 // Skip the LoadObject call in that case.
136 // We also don't want to start loading the object when we're not yet in
137 // a document, just in case that the caller wants to set additional
138 // attributes before inserting the node into the document.
139 if (aNamespaceID != kNameSpaceID_None || aName != nsGkAtoms::data ||
140 !aNotify || !IsInComposedDoc() || !mIsDoneAddingChildren ||
141 BlockEmbedOrObjectContentLoading()) {
142 return;
144 nsContentUtils::AddScriptRunner(NS_NewRunnableFunction(
145 "HTMLObjectElement::LoadObject",
146 [self = RefPtr<HTMLObjectElement>(this), aNotify]() {
147 if (self->IsInComposedDoc()) {
148 self->LoadObject(aNotify, true);
150 }));
153 bool HTMLObjectElement::IsHTMLFocusable(bool aWithMouse, bool* aIsFocusable,
154 int32_t* aTabIndex) {
155 // TODO: this should probably be managed directly by IsHTMLFocusable.
156 // See bug 597242.
157 Document* doc = GetComposedDoc();
158 if (!doc || IsInDesignMode()) {
159 if (aTabIndex) {
160 *aTabIndex = -1;
163 *aIsFocusable = false;
164 return false;
167 // Plugins that show the empty fallback should not accept focus.
168 if (Type() == eType_Fallback) {
169 if (aTabIndex) {
170 *aTabIndex = -1;
173 *aIsFocusable = false;
174 return false;
177 const nsAttrValue* attrVal = mAttrs.GetAttr(nsGkAtoms::tabindex);
178 bool isFocusable = attrVal && attrVal->Type() == nsAttrValue::eInteger;
180 // This method doesn't call nsGenericHTMLFormControlElement intentionally.
181 // TODO: It should probably be changed when bug 597242 will be fixed.
182 if (IsEditableRoot() || Type() == eType_Document ||
183 Type() == eType_FakePlugin) {
184 if (aTabIndex) {
185 *aTabIndex = isFocusable ? attrVal->GetIntegerValue() : 0;
188 *aIsFocusable = true;
189 return false;
192 // TODO: this should probably be managed directly by IsHTMLFocusable.
193 // See bug 597242.
194 if (aTabIndex && isFocusable) {
195 *aTabIndex = attrVal->GetIntegerValue();
196 *aIsFocusable = true;
199 return false;
202 int32_t HTMLObjectElement::TabIndexDefault() { return 0; }
204 Nullable<WindowProxyHolder> HTMLObjectElement::GetContentWindow(
205 nsIPrincipal& aSubjectPrincipal) {
206 Document* doc = GetContentDocument(aSubjectPrincipal);
207 if (doc) {
208 nsPIDOMWindowOuter* win = doc->GetWindow();
209 if (win) {
210 return WindowProxyHolder(win->GetBrowsingContext());
214 return nullptr;
217 bool HTMLObjectElement::ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
218 const nsAString& aValue,
219 nsIPrincipal* aMaybeScriptedPrincipal,
220 nsAttrValue& aResult) {
221 if (aNamespaceID == kNameSpaceID_None) {
222 if (aAttribute == nsGkAtoms::align) {
223 return ParseAlignValue(aValue, aResult);
225 if (ParseImageAttribute(aAttribute, aValue, aResult)) {
226 return true;
230 return nsGenericHTMLFormControlElement::ParseAttribute(
231 aNamespaceID, aAttribute, aValue, aMaybeScriptedPrincipal, aResult);
234 void HTMLObjectElement::MapAttributesIntoRule(
235 MappedDeclarationsBuilder& aBuilder) {
236 MapImageAlignAttributeInto(aBuilder);
237 MapImageBorderAttributeInto(aBuilder);
238 MapImageMarginAttributeInto(aBuilder);
239 MapImageSizeAttributesInto(aBuilder);
240 MapCommonAttributesInto(aBuilder);
243 NS_IMETHODIMP_(bool)
244 HTMLObjectElement::IsAttributeMapped(const nsAtom* aAttribute) const {
245 static const MappedAttributeEntry* const map[] = {
246 sCommonAttributeMap,
247 sImageMarginSizeAttributeMap,
248 sImageBorderAttributeMap,
249 sImageAlignAttributeMap,
252 return FindAttributeDependence(aAttribute, map);
255 nsMapRuleToAttributesFunc HTMLObjectElement::GetAttributeMappingFunction()
256 const {
257 return &MapAttributesIntoRule;
260 void HTMLObjectElement::StartObjectLoad(bool aNotify, bool aForce) {
261 // BindToTree can call us asynchronously, and we may be removed from the tree
262 // in the interim
263 if (!IsInComposedDoc() || !OwnerDoc()->IsActive() ||
264 BlockEmbedOrObjectContentLoading()) {
265 return;
268 LoadObject(aNotify, aForce);
269 SetIsNetworkCreated(false);
272 ElementState HTMLObjectElement::IntrinsicState() const {
273 return nsGenericHTMLFormControlElement::IntrinsicState() | ObjectState();
276 uint32_t HTMLObjectElement::GetCapabilities() const {
277 return nsObjectLoadingContent::GetCapabilities() | eFallbackIfClassIDPresent;
280 void HTMLObjectElement::DestroyContent() {
281 nsObjectLoadingContent::Destroy();
282 nsGenericHTMLFormControlElement::DestroyContent();
285 nsresult HTMLObjectElement::CopyInnerTo(Element* aDest) {
286 nsresult rv = nsGenericHTMLFormControlElement::CopyInnerTo(aDest);
287 NS_ENSURE_SUCCESS(rv, rv);
289 if (aDest->OwnerDoc()->IsStaticDocument()) {
290 CreateStaticClone(static_cast<HTMLObjectElement*>(aDest));
293 return rv;
296 JSObject* HTMLObjectElement::WrapNode(JSContext* aCx,
297 JS::Handle<JSObject*> aGivenProto) {
298 return HTMLObjectElement_Binding::Wrap(aCx, this, aGivenProto);
301 } // namespace mozilla::dom
303 NS_IMPL_NS_NEW_HTML_ELEMENT_CHECK_PARSER(Object)