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"
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
) {
81 Servo_MediaList_GetText(mRawList
, &aMediaText
);
85 already_AddRefed
<MediaList
> MediaList::Create(const nsACString
& aMedia
,
86 CallerType aCallerType
) {
87 RefPtr
<MediaList
> mediaList
= new MediaList(aMedia
, aCallerType
);
88 return mediaList
.forget();
91 void MediaList::SetText(const nsACString
& aMediaText
) {
96 SetTextInternal(aMediaText
, CallerType::NonSystem
);
99 void MediaList::GetMediaText(nsACString
& aMediaText
) { GetText(aMediaText
); }
101 void MediaList::SetTextInternal(const nsACString
& aMediaText
,
102 CallerType aCallerType
) {
103 Servo_MediaList_SetText(mRawList
, &aMediaText
, aCallerType
);
106 uint32_t MediaList::Length() { return Servo_MediaList_GetLength(mRawList
); }
108 void MediaList::IndexedGetter(uint32_t aIndex
, bool& aFound
,
109 nsACString
& aReturn
) {
110 aFound
= Servo_MediaList_GetMediumAt(mRawList
, aIndex
, &aReturn
);
112 aReturn
.SetIsVoid(true);
116 void MediaList::Delete(const nsACString
& aOldMedium
, ErrorResult
& aRv
) {
117 MOZ_ASSERT(!IsReadOnly());
118 if (Servo_MediaList_DeleteMedium(mRawList
, &aOldMedium
)) {
121 aRv
.ThrowNotFoundError("Medium not in list");
124 bool MediaList::Matches(const Document
& aDocument
) const {
125 const RawServoStyleSet
* rawSet
=
126 aDocument
.StyleSetForPresShellOrMediaQueryEvaluation()->RawSet();
127 MOZ_ASSERT(rawSet
, "The RawServoStyleSet should be valid!");
128 return Servo_MediaList_Matches(mRawList
, rawSet
);
131 void MediaList::Append(const nsACString
& aNewMedium
, ErrorResult
& aRv
) {
132 MOZ_ASSERT(!IsReadOnly());
133 if (aNewMedium
.IsEmpty()) {
134 // XXXbz per spec there should not be an exception here, as far as
136 aRv
.ThrowNotFoundError("Empty medium");
139 Servo_MediaList_AppendMedium(mRawList
, &aNewMedium
);
142 void MediaList::SetMediaText(const nsACString
& aMediaText
) {
143 DoMediaChange([&](ErrorResult
& aRv
) { SetText(aMediaText
); }, IgnoreErrors());
146 void MediaList::Item(uint32_t aIndex
, nsACString
& aReturn
) {
148 IndexedGetter(aIndex
, dummy
, aReturn
);
151 void MediaList::DeleteMedium(const nsACString
& aOldMedium
, ErrorResult
& aRv
) {
152 DoMediaChange([&](ErrorResult
& aRv
) { Delete(aOldMedium
, aRv
); }, aRv
);
155 void MediaList::AppendMedium(const nsACString
& aNewMedium
, ErrorResult
& aRv
) {
156 DoMediaChange([&](ErrorResult
& aRv
) { Append(aNewMedium
, aRv
); }, aRv
);
159 MOZ_DEFINE_MALLOC_SIZE_OF(ServoMediaListMallocSizeOf
)
160 MOZ_DEFINE_MALLOC_ENCLOSING_SIZE_OF(ServoMediaListMallocEnclosingSizeOf
)
162 size_t MediaList::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf
) const {
164 n
+= Servo_MediaList_SizeOfIncludingThis(ServoMediaListMallocSizeOf
,
165 ServoMediaListMallocEnclosingSizeOf
,
170 bool MediaList::IsReadOnly() const {
171 return mStyleSheet
&& mStyleSheet
->IsReadOnly();
175 } // namespace mozilla