Bumping manifests a=b2g-bump
[gecko.git] / layout / style / MediaQueryList.cpp
blob049c1e2744aa3e32f856029fb98c7c09ccd9df29
1 /* vim: set shiftwidth=2 tabstop=8 autoindent cindent expandtab: */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 /* implements DOM interface for querying and observing media queries */
8 #include "mozilla/dom/MediaQueryList.h"
9 #include "nsPresContext.h"
10 #include "nsIMediaList.h"
11 #include "nsCSSParser.h"
12 #include "nsIDocument.h"
14 namespace mozilla {
15 namespace dom {
17 MediaQueryList::MediaQueryList(nsPresContext *aPresContext,
18 const nsAString &aMediaQueryList)
19 : mPresContext(aPresContext),
20 mMediaList(new nsMediaList),
21 mMatchesValid(false)
23 PR_INIT_CLIST(this);
25 SetIsDOMBinding();
27 nsCSSParser parser;
28 parser.ParseMediaList(aMediaQueryList, nullptr, 0, mMediaList, false);
31 MediaQueryList::~MediaQueryList()
33 if (mPresContext) {
34 PR_REMOVE_LINK(this);
38 NS_IMPL_CYCLE_COLLECTION_CLASS(MediaQueryList)
40 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(MediaQueryList)
41 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPresContext)
42 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCallbacks)
43 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
44 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
46 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(MediaQueryList)
47 if (tmp->mPresContext) {
48 PR_REMOVE_LINK(tmp);
49 NS_IMPL_CYCLE_COLLECTION_UNLINK(mPresContext)
51 tmp->RemoveAllListeners();
52 NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
53 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
55 NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(MediaQueryList)
57 NS_INTERFACE_MAP_BEGIN(MediaQueryList)
58 NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
59 NS_INTERFACE_MAP_ENTRY(nsISupports)
60 NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(MediaQueryList)
61 NS_INTERFACE_MAP_END
63 NS_IMPL_CYCLE_COLLECTING_ADDREF(MediaQueryList)
64 NS_IMPL_CYCLE_COLLECTING_RELEASE(MediaQueryList)
66 void
67 MediaQueryList::GetMedia(nsAString &aMedia)
69 mMediaList->GetText(aMedia);
72 bool
73 MediaQueryList::Matches()
75 if (!mMatchesValid) {
76 NS_ABORT_IF_FALSE(!HasListeners(),
77 "when listeners present, must keep mMatches current");
78 RecomputeMatches();
81 return mMatches;
84 void
85 MediaQueryList::AddListener(MediaQueryListListener& aListener)
87 if (!HasListeners()) {
88 // When we have listeners, the pres context owns a reference to
89 // this. This is a cyclic reference that can only be broken by
90 // cycle collection.
91 NS_ADDREF_THIS();
94 if (!mMatchesValid) {
95 NS_ABORT_IF_FALSE(!HasListeners(),
96 "when listeners present, must keep mMatches current");
97 RecomputeMatches();
100 for (uint32_t i = 0; i < mCallbacks.Length(); ++i) {
101 if (aListener == *mCallbacks[i]) {
102 // Already registered
103 return;
107 mCallbacks.AppendElement(&aListener);
108 if (!HasListeners()) {
109 // Append failed; undo the AddRef above.
110 NS_RELEASE_THIS();
114 void
115 MediaQueryList::RemoveListener(MediaQueryListListener& aListener)
117 for (uint32_t i = 0; i < mCallbacks.Length(); ++i) {
118 if (aListener == *mCallbacks[i]) {
119 mCallbacks.RemoveElementAt(i);
120 if (!HasListeners()) {
121 // See NS_ADDREF_THIS() in AddListener.
122 NS_RELEASE_THIS();
124 break;
129 void
130 MediaQueryList::RemoveAllListeners()
132 bool hadListeners = HasListeners();
133 mCallbacks.Clear();
134 if (hadListeners) {
135 // See NS_ADDREF_THIS() in AddListener.
136 NS_RELEASE_THIS();
140 void
141 MediaQueryList::RecomputeMatches()
143 if (!mPresContext) {
144 return;
147 mMatches = mMediaList->Matches(mPresContext, nullptr);
148 mMatchesValid = true;
151 void
152 MediaQueryList::MediumFeaturesChanged(NotifyList &aListenersToNotify)
154 mMatchesValid = false;
156 if (HasListeners()) {
157 bool oldMatches = mMatches;
158 RecomputeMatches();
159 if (mMatches != oldMatches) {
160 for (uint32_t i = 0, i_end = mCallbacks.Length(); i != i_end; ++i) {
161 HandleChangeData *d = aListenersToNotify.AppendElement();
162 if (d) {
163 d->mql = this;
164 d->callback = mCallbacks[i];
171 nsISupports*
172 MediaQueryList::GetParentObject() const
174 if (!mPresContext) {
175 return nullptr;
177 return mPresContext->Document();
180 JSObject*
181 MediaQueryList::WrapObject(JSContext* aCx)
183 return MediaQueryListBinding::Wrap(aCx, this);
186 } // namespace dom
187 } // namespace mozilla