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/MediaListBinding.h"
14 #include "mozilla/ServoBindings.h"
15 #include "mozilla/ServoStyleSet.h"
16 #include "mozilla/StyleSheetInlines.h"
18 namespace mozilla::dom
{
20 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(MediaList
)
21 NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
22 NS_INTERFACE_MAP_ENTRY(nsISupports
)
25 NS_IMPL_CYCLE_COLLECTING_ADDREF(MediaList
)
26 NS_IMPL_CYCLE_COLLECTING_RELEASE(MediaList
)
28 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(MediaList
)
30 JSObject
* MediaList::WrapObject(JSContext
* aCx
,
31 JS::Handle
<JSObject
*> aGivenProto
) {
32 return MediaList_Binding::Wrap(aCx
, this, aGivenProto
);
35 void MediaList::SetStyleSheet(StyleSheet
* aSheet
) {
36 MOZ_ASSERT(aSheet
== mStyleSheet
|| !aSheet
|| !mStyleSheet
,
37 "Multiple style sheets competing for one media list");
41 nsISupports
* MediaList::GetParentObject() const { return mStyleSheet
; }
43 template <typename Func
>
44 void MediaList::DoMediaChange(Func aCallback
, ErrorResult
& aRv
) {
50 mStyleSheet
->WillDirty();
59 // FIXME(emilio): We should discern between "owned by a rule" (as in @media)
60 // and "owned by a sheet" (as in <style media>), and then pass something
62 mStyleSheet
->RuleChanged(nullptr, StyleRuleChangeKind::Generic
);
66 already_AddRefed
<MediaList
> MediaList::Clone() {
67 RefPtr
<MediaList
> clone
=
68 new MediaList(Servo_MediaList_DeepClone(mRawList
).Consume());
69 return clone
.forget();
72 MediaList::MediaList() : mRawList(Servo_MediaList_Create().Consume()) {}
74 MediaList::MediaList(const nsACString
& aMedia
, CallerType aCallerType
)
76 SetTextInternal(aMedia
, aCallerType
);
79 void MediaList::GetText(nsACString
& aMediaText
) const {
80 Servo_MediaList_GetText(mRawList
, &aMediaText
);
84 already_AddRefed
<MediaList
> MediaList::Create(const nsACString
& aMedia
,
85 CallerType aCallerType
) {
86 return do_AddRef(new MediaList(aMedia
, aCallerType
));
89 void MediaList::SetText(const nsACString
& aMediaText
) {
94 SetTextInternal(aMediaText
, CallerType::NonSystem
);
97 void MediaList::SetTextInternal(const nsACString
& aMediaText
,
98 CallerType aCallerType
) {
99 Servo_MediaList_SetText(mRawList
, &aMediaText
, aCallerType
);
102 uint32_t MediaList::Length() const {
103 return Servo_MediaList_GetLength(mRawList
);
106 bool MediaList::IsViewportDependent() const {
107 return Servo_MediaList_IsViewportDependent(mRawList
);
110 void MediaList::IndexedGetter(uint32_t aIndex
, bool& aFound
,
111 nsACString
& aReturn
) const {
112 aFound
= Servo_MediaList_GetMediumAt(mRawList
, aIndex
, &aReturn
);
114 aReturn
.SetIsVoid(true);
118 void MediaList::Delete(const nsACString
& aOldMedium
, ErrorResult
& aRv
) {
119 MOZ_ASSERT(!IsReadOnly());
120 if (Servo_MediaList_DeleteMedium(mRawList
, &aOldMedium
)) {
123 aRv
.ThrowNotFoundError("Medium not in list");
126 bool MediaList::Matches(const Document
& aDocument
) const {
127 const auto* rawData
=
128 aDocument
.StyleSetForPresShellOrMediaQueryEvaluation()->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