Bumping manifests a=b2g-bump
[gecko.git] / layout / style / nsIMediaList.h
blob23b8e24c762a33c30f03d89c8a8b57e70f0d936c
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
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 /*
8 * representation of media lists used when linking to style sheets or by
9 * @media rules
12 #ifndef nsIMediaList_h_
13 #define nsIMediaList_h_
15 #include "nsIDOMMediaList.h"
16 #include "nsTArray.h"
17 #include "nsIAtom.h"
18 #include "nsCSSValue.h"
19 #include "nsWrapperCache.h"
20 #include "mozilla/Attributes.h"
21 #include "mozilla/ErrorResult.h"
23 class nsPresContext;
24 class nsAString;
25 struct nsMediaFeature;
27 namespace mozilla {
28 class CSSStyleSheet;
29 } // namespace mozilla
31 struct nsMediaExpression {
32 enum Range { eMin, eMax, eEqual };
34 const nsMediaFeature *mFeature;
35 Range mRange;
36 nsCSSValue mValue;
38 // aActualValue must be obtained from mFeature->mGetter
39 bool Matches(nsPresContext* aPresContext,
40 const nsCSSValue& aActualValue) const;
42 bool operator==(const nsMediaExpression& aOther) const {
43 return mFeature == aOther.mFeature && // pointer equality fine (atom-like)
44 mRange == aOther.mRange &&
45 mValue == aOther.mValue;
47 bool operator!=(const nsMediaExpression& aOther) const {
48 return !(*this == aOther);
52 /**
53 * An nsMediaQueryResultCacheKey records what feature/value combinations
54 * a set of media query results are valid for. This allows the caller
55 * to quickly learn whether a prior result of media query evaluation is
56 * still valid (e.g., due to a window size change) without rerunning all
57 * of the evaluation and rebuilding the list of rules.
59 * This object may not be used after any media rules in any of the
60 * sheets it was given to have been modified. However, this is
61 * generally not a problem since ClearRuleCascades is called on the
62 * sheet whenever this happens, and these objects are stored inside the
63 * rule cascades. (FIXME: We're not actually doing this all the time.)
65 * The implementation could be further optimized in the future to store
66 * ranges (combinations of less-than, less-than-or-equal, greater-than,
67 * greater-than-or-equal, equal, not-equal, present, not-present) for
68 * each feature rather than simply storing the list of expressions.
69 * However, this requires combining any such ranges.
71 class nsMediaQueryResultCacheKey {
72 public:
73 explicit nsMediaQueryResultCacheKey(nsIAtom* aMedium)
74 : mMedium(aMedium)
77 /**
78 * Record that aExpression was tested while building the cached set
79 * that this cache key is for, and that aExpressionMatches was whether
80 * it matched.
82 void AddExpression(const nsMediaExpression* aExpression,
83 bool aExpressionMatches);
84 bool Matches(nsPresContext* aPresContext) const;
85 bool HasFeatureConditions() const {
86 return !mFeatureCache.IsEmpty();
89 /**
90 * An operator== that implements list equality, which isn't quite as
91 * good as set equality, but catches the trivial equality cases.
93 bool operator==(const nsMediaQueryResultCacheKey& aOther) const {
94 return mMedium == aOther.mMedium &&
95 mFeatureCache == aOther.mFeatureCache;
97 bool operator!=(const nsMediaQueryResultCacheKey& aOther) const {
98 return !(*this == aOther);
100 private:
101 struct ExpressionEntry {
102 // FIXME: if we were better at maintaining invariants about clearing
103 // rule cascades when media lists change, this could be a |const
104 // nsMediaExpression*| instead.
105 nsMediaExpression mExpression;
106 bool mExpressionMatches;
108 bool operator==(const ExpressionEntry& aOther) const {
109 return mExpression == aOther.mExpression &&
110 mExpressionMatches == aOther.mExpressionMatches;
112 bool operator!=(const ExpressionEntry& aOther) const {
113 return !(*this == aOther);
116 struct FeatureEntry {
117 const nsMediaFeature *mFeature;
118 InfallibleTArray<ExpressionEntry> mExpressions;
120 bool operator==(const FeatureEntry& aOther) const {
121 return mFeature == aOther.mFeature &&
122 mExpressions == aOther.mExpressions;
124 bool operator!=(const FeatureEntry& aOther) const {
125 return !(*this == aOther);
128 nsCOMPtr<nsIAtom> mMedium;
129 nsTArray<FeatureEntry> mFeatureCache;
132 class nsMediaQuery {
133 public:
134 nsMediaQuery()
135 : mNegated(false)
136 , mHasOnly(false)
137 , mTypeOmitted(false)
138 , mHadUnknownExpression(false)
142 private:
143 // for Clone only
144 nsMediaQuery(const nsMediaQuery& aOther)
145 : mNegated(aOther.mNegated)
146 , mHasOnly(aOther.mHasOnly)
147 , mTypeOmitted(aOther.mTypeOmitted)
148 , mHadUnknownExpression(aOther.mHadUnknownExpression)
149 , mMediaType(aOther.mMediaType)
150 , mExpressions(aOther.mExpressions)
152 MOZ_ASSERT(mExpressions.Length() == aOther.mExpressions.Length());
155 public:
157 void SetNegated() { mNegated = true; }
158 void SetHasOnly() { mHasOnly = true; }
159 void SetTypeOmitted() { mTypeOmitted = true; }
160 void SetHadUnknownExpression() { mHadUnknownExpression = true; }
161 void SetType(nsIAtom* aMediaType) {
162 NS_ASSERTION(aMediaType,
163 "expected non-null");
164 mMediaType = aMediaType;
167 // Return a new nsMediaExpression in the array for the caller to fill
168 // in. The caller must either fill it in completely, or call
169 // SetHadUnknownExpression on this nsMediaQuery.
170 // Returns null on out-of-memory.
171 nsMediaExpression* NewExpression() { return mExpressions.AppendElement(); }
173 void AppendToString(nsAString& aString) const;
175 nsMediaQuery* Clone() const;
177 // Does this query apply to the presentation?
178 // If |aKey| is non-null, add cache information to it.
179 bool Matches(nsPresContext* aPresContext,
180 nsMediaQueryResultCacheKey* aKey) const;
182 private:
183 bool mNegated;
184 bool mHasOnly; // only needed for serialization
185 bool mTypeOmitted; // only needed for serialization
186 bool mHadUnknownExpression;
187 nsCOMPtr<nsIAtom> mMediaType;
188 nsTArray<nsMediaExpression> mExpressions;
191 class nsMediaList MOZ_FINAL : public nsIDOMMediaList
192 , public nsWrapperCache
194 public:
195 typedef mozilla::ErrorResult ErrorResult;
197 nsMediaList();
199 virtual JSObject*
200 WrapObject(JSContext* aCx) MOZ_OVERRIDE;
201 nsISupports* GetParentObject() const
203 return nullptr;
206 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
207 NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsMediaList)
209 NS_DECL_NSIDOMMEDIALIST
211 void GetText(nsAString& aMediaText);
212 void SetText(const nsAString& aMediaText);
214 // Does this query apply to the presentation?
215 // If |aKey| is non-null, add cache information to it.
216 bool Matches(nsPresContext* aPresContext,
217 nsMediaQueryResultCacheKey* aKey);
219 void SetStyleSheet(mozilla::CSSStyleSheet* aSheet);
220 void AppendQuery(nsAutoPtr<nsMediaQuery>& aQuery) {
221 // Takes ownership of aQuery
222 mArray.AppendElement(aQuery.forget());
225 already_AddRefed<nsMediaList> Clone();
227 nsMediaQuery* MediumAt(int32_t aIndex) { return mArray[aIndex]; }
228 void Clear() { mArray.Clear(); }
230 // WebIDL
231 // XPCOM GetMediaText and SetMediaText are fine.
232 uint32_t Length() { return mArray.Length(); }
233 void IndexedGetter(uint32_t aIndex, bool& aFound, nsAString& aReturn);
234 // XPCOM Item is fine.
235 void DeleteMedium(const nsAString& aMedium, ErrorResult& aRv)
237 aRv = DeleteMedium(aMedium);
239 void AppendMedium(const nsAString& aMedium, ErrorResult& aRv)
241 aRv = AppendMedium(aMedium);
244 protected:
245 ~nsMediaList();
247 nsresult Delete(const nsAString & aOldMedium);
248 nsresult Append(const nsAString & aOldMedium);
250 InfallibleTArray<nsAutoPtr<nsMediaQuery> > mArray;
251 // not refcounted; sheet will let us know when it goes away
252 // mStyleSheet is the sheet that needs to be dirtied when this medialist
253 // changes
254 mozilla::CSSStyleSheet* mStyleSheet;
256 #endif /* !defined(nsIMediaList_h_) */