gecko-dev/dom/html/HTMLSourceElement.h
Emilio Cobos Álvarez 51758cfc9b Bug 1829189 - Make OnAttrSetButNotChanged and AfterSetAttr infallible. r=smaug
Same rg + sed shenanigans as the first patch.

There were two that could fail, both due to OOM:

 * HTMLInputElement::AfterSetAttr: If we fail (only in the type=range
   case) we end up with an old value without it being clamped by
   min/max/step.

 * HTMLBodyElement::AfterSetAttr: If we fail we won't peek up the
   DocShell's frame margins and styling could be incorrect.

That seems better than having to deal with broken states after we've
already set the attribute.

Depends on D176069

Differential Revision: https://phabricator.services.mozilla.com/D176070
2023-04-21 08:56:27 +00:00

158 lines
5.2 KiB
C++

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_HTMLSourceElement_h
#define mozilla_dom_HTMLSourceElement_h
#include "mozilla/Attributes.h"
#include "nsGenericHTMLElement.h"
#include "mozilla/dom/HTMLMediaElement.h"
class nsAttrValue;
namespace mozilla::dom {
class MediaList;
class HTMLSourceElement final : public nsGenericHTMLElement {
public:
explicit HTMLSourceElement(
already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
// nsISupports
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(HTMLSourceElement,
nsGenericHTMLElement)
NS_IMPL_FROMNODE_HTML_WITH_TAG(HTMLSourceElement, source)
nsresult Clone(dom::NodeInfo*, nsINode** aResult) const override;
// Override BindToTree() so that we can trigger a load when we add a
// child source element.
nsresult BindToTree(BindContext&, nsINode& aParent) override;
void UnbindFromTree(bool aNullParent) override;
// If this element's media attr matches for its owner document. Returns true
// if no media attr was set.
bool MatchesCurrentMedia();
// True if a source tag would match the given media attribute for the
// specified document. Used by the preloader to determine valid <source> tags
// prior to DOM creation.
static bool WouldMatchMediaForDocument(const nsAString& aMediaStr,
const Document* aDocument);
// Return the MediaSource object if any associated with the src attribute
// when it was set.
MediaSource* GetSrcMediaSource() { return mSrcMediaSource; };
// WebIDL
void GetSrc(nsString& aSrc) { GetURIAttr(nsGkAtoms::src, nullptr, aSrc); }
void SetSrc(const nsAString& aSrc, nsIPrincipal* aTriggeringPrincipal,
mozilla::ErrorResult& rv) {
SetHTMLAttr(nsGkAtoms::src, aSrc, aTriggeringPrincipal, rv);
}
nsIPrincipal* GetSrcTriggeringPrincipal() const {
return mSrcTriggeringPrincipal;
}
nsIPrincipal* GetSrcsetTriggeringPrincipal() const {
return mSrcsetTriggeringPrincipal;
}
void GetType(DOMString& aType) { GetHTMLAttr(nsGkAtoms::type, aType); }
void SetType(const nsAString& aType, ErrorResult& rv) {
SetHTMLAttr(nsGkAtoms::type, aType, rv);
}
void GetSrcset(DOMString& aSrcset) {
GetHTMLAttr(nsGkAtoms::srcset, aSrcset);
}
void SetSrcset(const nsAString& aSrcset, nsIPrincipal* aTriggeringPrincipal,
mozilla::ErrorResult& rv) {
SetHTMLAttr(nsGkAtoms::srcset, aSrcset, aTriggeringPrincipal, rv);
}
void GetSizes(DOMString& aSizes) { GetHTMLAttr(nsGkAtoms::sizes, aSizes); }
void SetSizes(const nsAString& aSizes, mozilla::ErrorResult& rv) {
SetHTMLAttr(nsGkAtoms::sizes, aSizes, rv);
}
void GetMedia(DOMString& aMedia) { GetHTMLAttr(nsGkAtoms::media, aMedia); }
void SetMedia(const nsAString& aMedia, mozilla::ErrorResult& rv) {
SetHTMLAttr(nsGkAtoms::media, aMedia, rv);
}
uint32_t Width() const {
return GetDimensionAttrAsUnsignedInt(nsGkAtoms::width, 0);
}
void SetWidth(uint32_t aWidth, ErrorResult& aRv) {
SetUnsignedIntAttr(nsGkAtoms::width, aWidth, 0, aRv);
}
uint32_t Height() const {
return GetDimensionAttrAsUnsignedInt(nsGkAtoms::height, 0);
}
void SetHeight(uint32_t aHeight, ErrorResult& aRv) {
SetUnsignedIntAttr(nsGkAtoms::height, aHeight, 0, aRv);
}
const nsMappedAttributes* GetAttributesMappedForImage() const {
return mMappedAttributesForImage;
}
static bool IsAttributeMappedToImages(const nsAtom* aAttribute) {
return aAttribute == nsGkAtoms::width || aAttribute == nsGkAtoms::height;
}
protected:
virtual ~HTMLSourceElement();
JSObject* WrapNode(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto) override;
bool ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
const nsAString& aValue,
nsIPrincipal* aMaybeScriptedPrincipal,
nsAttrValue& aResult) override;
void AfterSetAttr(int32_t aNameSpaceID, nsAtom* aName,
const nsAttrValue* aValue, const nsAttrValue* aOldValue,
nsIPrincipal* aMaybeScriptedPrincipal,
bool aNotify) override;
private:
// Generates a new MediaList using the given input
void UpdateMediaList(const nsAttrValue* aValue);
void BuildMappedAttributesForImage();
bool IsInPicture() const {
return GetParentElement() &&
GetParentElement()->IsHTMLElement(nsGkAtoms::picture);
}
RefPtr<MediaList> mMediaList;
RefPtr<MediaSource> mSrcMediaSource;
// The triggering principal for the src attribute.
nsCOMPtr<nsIPrincipal> mSrcTriggeringPrincipal;
// The triggering principal for the srcset attribute.
nsCOMPtr<nsIPrincipal> mSrcsetTriggeringPrincipal;
// The mapped attributes to HTMLImageElement if we are associated with a
// <picture> with a valid <img>.
RefPtr<nsMappedAttributes> mMappedAttributesForImage;
};
} // namespace mozilla::dom
#endif // mozilla_dom_HTMLSourceElement_h