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 /* base class for representation of media lists */
9 #include "mozilla/dom/MediaList.h"
11 #include "mozAutoDocUpdate.h"
12 #include "mozilla/dom/Document.h"
13 #include "mozilla/dom/DocumentInlines.h"
14 #include "mozilla/dom/MediaListBinding.h"
15 #include "mozilla/ServoBindings.h"
16 #include "mozilla/ServoStyleSet.h"
17 #include "mozilla/StyleSheetInlines.h"
19 namespace mozilla::dom
{
21 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(MediaList
)
22 NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
23 NS_INTERFACE_MAP_ENTRY(nsISupports
)
26 NS_IMPL_CYCLE_COLLECTING_ADDREF(MediaList
)
27 NS_IMPL_CYCLE_COLLECTING_RELEASE(MediaList
)
29 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(MediaList
)
31 JSObject
* MediaList::WrapObject(JSContext
* aCx
,
32 JS::Handle
<JSObject
*> aGivenProto
) {
33 return MediaList_Binding::Wrap(aCx
, this, aGivenProto
);
36 void MediaList::SetStyleSheet(StyleSheet
* aSheet
) {
37 MOZ_ASSERT(aSheet
== mStyleSheet
|| !aSheet
|| !mStyleSheet
,
38 "Multiple style sheets competing for one media list");
42 nsISupports
* MediaList::GetParentObject() const { return mStyleSheet
; }
44 template <typename Func
>
45 void MediaList::DoMediaChange(Func aCallback
, ErrorResult
& aRv
) {
51 mStyleSheet
->WillDirty();
60 // FIXME(emilio): We should discern between "owned by a rule" (as in @media)
61 // and "owned by a sheet" (as in <style media>), and then pass something
63 mStyleSheet
->RuleChanged(nullptr, StyleRuleChangeKind::Generic
);
67 already_AddRefed
<MediaList
> MediaList::Clone() {
68 RefPtr
<MediaList
> clone
=
69 new MediaList(Servo_MediaList_DeepClone(mRawList
).Consume());
70 return clone
.forget();
73 MediaList::MediaList() : mRawList(Servo_MediaList_Create().Consume()) {}
75 MediaList::MediaList(const nsACString
& aMedia
, CallerType aCallerType
)
77 SetTextInternal(aMedia
, aCallerType
);
80 void MediaList::GetText(nsACString
& aMediaText
) const {
81 Servo_MediaList_GetText(mRawList
, &aMediaText
);
85 already_AddRefed
<MediaList
> MediaList::Create(const nsACString
& aMedia
,
86 CallerType aCallerType
) {
87 return do_AddRef(new MediaList(aMedia
, aCallerType
));
90 void MediaList::SetText(const nsACString
& aMediaText
) {
95 SetTextInternal(aMediaText
, CallerType::NonSystem
);
98 void MediaList::SetTextInternal(const nsACString
& aMediaText
,
99 CallerType aCallerType
) {
100 Servo_MediaList_SetText(mRawList
, &aMediaText
, aCallerType
);
103 uint32_t MediaList::Length() const {
104 return Servo_MediaList_GetLength(mRawList
);
107 bool MediaList::IsViewportDependent() const {
108 return Servo_MediaList_IsViewportDependent(mRawList
);
111 void MediaList::IndexedGetter(uint32_t aIndex
, bool& aFound
,
112 nsACString
& aReturn
) const {
113 aFound
= Servo_MediaList_GetMediumAt(mRawList
, aIndex
, &aReturn
);
115 aReturn
.SetIsVoid(true);
119 void MediaList::Delete(const nsACString
& aOldMedium
, ErrorResult
& aRv
) {
120 MOZ_ASSERT(!IsReadOnly());
121 if (Servo_MediaList_DeleteMedium(mRawList
, &aOldMedium
)) {
124 aRv
.ThrowNotFoundError("Medium not in list");
127 bool MediaList::Matches(const Document
& aDocument
) const {
128 const auto* rawData
= aDocument
.EnsureStyleSet().RawData();
129 MOZ_ASSERT(rawData
, "The per doc data should be valid!");
130 return Servo_MediaList_Matches(mRawList
, rawData
);
133 void MediaList::Append(const nsACString
& aNewMedium
, ErrorResult
& aRv
) {
134 MOZ_ASSERT(!IsReadOnly());
135 if (aNewMedium
.IsEmpty()) {
136 // XXXbz per spec there should not be an exception here, as far as
138 aRv
.ThrowNotFoundError("Empty medium");
141 Servo_MediaList_AppendMedium(mRawList
, &aNewMedium
);
144 void MediaList::SetMediaText(const nsACString
& aMediaText
) {
145 DoMediaChange([&](ErrorResult
& aRv
) { SetText(aMediaText
); }, IgnoreErrors());
148 void MediaList::Item(uint32_t aIndex
, nsACString
& aReturn
) {
150 IndexedGetter(aIndex
, dummy
, aReturn
);
153 void MediaList::DeleteMedium(const nsACString
& aOldMedium
, ErrorResult
& aRv
) {
154 DoMediaChange([&](ErrorResult
& aRv
) { Delete(aOldMedium
, aRv
); }, aRv
);
157 void MediaList::AppendMedium(const nsACString
& aNewMedium
, ErrorResult
& aRv
) {
158 DoMediaChange([&](ErrorResult
& aRv
) { Append(aNewMedium
, aRv
); }, aRv
);
161 MOZ_DEFINE_MALLOC_SIZE_OF(ServoMediaListMallocSizeOf
)
162 MOZ_DEFINE_MALLOC_ENCLOSING_SIZE_OF(ServoMediaListMallocEnclosingSizeOf
)
164 size_t MediaList::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf
) const {
166 n
+= Servo_MediaList_SizeOfIncludingThis(ServoMediaListMallocSizeOf
,
167 ServoMediaListMallocEnclosingSizeOf
,
172 bool MediaList::IsReadOnly() const {
173 return mStyleSheet
&& mStyleSheet
->IsReadOnly();
176 } // namespace mozilla::dom