summaryrefslogtreecommitdiffstats
path: root/dom/html/HTMLSourceElement.h
blob: 6dfc48320fa8e08a91b0931a4b378116f7dfe683 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
/* -*- 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