Bug 473680. Stop crashtest 458637-1.html early (returning success) if it's running...
[mozilla-central.git] / layout / style / nsIMediaList.h
blob358c1e98f5a76ecbb8af9353127fbc0aa2787286
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
3 * ***** BEGIN LICENSE BLOCK *****
4 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6 * The contents of this file are subject to the Mozilla Public License Version
7 * 1.1 (the "License"); you may not use this file except in compliance with
8 * the License. You may obtain a copy of the License at
9 * http://www.mozilla.org/MPL/
11 * Software distributed under the License is distributed on an "AS IS" basis,
12 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 * for the specific language governing rights and limitations under the
14 * License.
16 * The Original Code is mozilla.org code.
18 * The Initial Developer of the Original Code is
19 * Boris Zbarsky <bzbarsky@mit.edu>.
20 * Portions created by the Initial Developer are Copyright (C) 2001
21 * the Initial Developer. All Rights Reserved.
23 * Contributor(s):
24 * L. David Baron <dbaron@dbaron.org>, Mozilla Corporation
26 * Alternatively, the contents of this file may be used under the terms of
27 * either of the GNU General Public License Version 2 or later (the "GPL"),
28 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 * in which case the provisions of the GPL or the LGPL are applicable instead
30 * of those above. If you wish to allow use of your version of this file only
31 * under the terms of either the GPL or the LGPL, and not to allow others to
32 * use your version of this file under the terms of the MPL, indicate your
33 * decision by deleting the provisions above and replace them with the notice
34 * and other provisions required by the GPL or the LGPL. If you do not delete
35 * the provisions above, a recipient may use your version of this file under
36 * the terms of any one of the MPL, the GPL or the LGPL.
38 * ***** END LICENSE BLOCK ***** */
41 * representation of media lists used when linking to style sheets or by
42 * @media rules
45 #ifndef nsIMediaList_h_
46 #define nsIMediaList_h_
48 #include "nsIDOMMediaList.h"
49 #include "nsAString.h"
50 #include "nsTArray.h"
51 #include "nsTPtrArray.h"
52 #include "nsIAtom.h"
53 #include "nsMediaFeatures.h"
54 #include "nsCSSValue.h"
56 class nsPresContext;
57 class nsICSSStyleSheet;
58 class nsCSSStyleSheet;
60 struct nsMediaExpression {
61 enum Range { eMin, eMax, eEqual };
63 const nsMediaFeature *mFeature;
64 Range mRange;
65 nsCSSValue mValue;
67 // aActualValue must be obtained from mFeature->mGetter
68 PRBool Matches(nsPresContext* aPresContext,
69 const nsCSSValue& aActualValue) const;
72 /**
73 * An nsMediaQueryResultCacheKey records what feature/value combinations
74 * a set of media query results are valid for. This allows the caller
75 * to quickly learn whether a prior result of media query evaluation is
76 * still valid (e.g., due to a window size change) without rerunning all
77 * of the evaluation and rebuilding the list of rules.
79 * This object may not be used after any media rules in any of the
80 * sheets it was given to have been modified. However, this is
81 * generally not a problem since ClearRuleCascades is called on the
82 * sheet whenever this happens, and these objects are stored inside the
83 * rule cascades. (FIXME: We're not actually doing this all the time.)
85 * The implementation could be further optimized in the future to store
86 * ranges (combinations of less-than, less-than-or-equal, greater-than,
87 * greater-than-or-equal, equal, not-equal, present, not-present) for
88 * each feature rather than simply storing the list of expressions.
89 * However, this requires combining any such ranges.
91 class nsMediaQueryResultCacheKey {
92 public:
93 nsMediaQueryResultCacheKey(nsIAtom* aMedium)
94 : mMedium(aMedium)
97 /**
98 * Record that aExpression was tested while building the cached set
99 * that this cache key is for, and that aExpressionMatches was whether
100 * it matched.
102 void AddExpression(const nsMediaExpression* aExpression,
103 PRBool aExpressionMatches);
104 PRBool Matches(nsPresContext* aPresContext) const;
105 private:
106 struct ExpressionEntry {
107 // FIXME: if we were better at maintaining invariants about clearing
108 // rule cascades when media lists change, this could be a |const
109 // nsMediaExpression*| instead.
110 nsMediaExpression mExpression;
111 PRBool mExpressionMatches;
113 struct FeatureEntry {
114 const nsMediaFeature *mFeature;
115 nsTArray<ExpressionEntry> mExpressions;
117 nsCOMPtr<nsIAtom> mMedium;
118 nsTArray<FeatureEntry> mFeatureCache;
121 class nsMediaQuery {
122 public:
123 nsMediaQuery()
124 : mNegated(PR_FALSE)
125 , mHasOnly(PR_FALSE)
126 , mTypeOmitted(PR_FALSE)
127 , mHadUnknownExpression(PR_FALSE)
131 private:
132 // for Clone only
133 nsMediaQuery(const nsMediaQuery& aOther)
134 : mNegated(aOther.mNegated)
135 , mHasOnly(aOther.mHasOnly)
136 , mTypeOmitted(aOther.mTypeOmitted)
137 , mHadUnknownExpression(aOther.mHadUnknownExpression)
138 , mMediaType(aOther.mMediaType)
139 // Clone checks the result of this deep copy for allocation failure
140 , mExpressions(aOther.mExpressions)
144 public:
146 void SetNegated() { mNegated = PR_TRUE; }
147 void SetHasOnly() { mHasOnly = PR_TRUE; }
148 void SetTypeOmitted() { mTypeOmitted = PR_TRUE; }
149 void SetHadUnknownExpression() { mHadUnknownExpression = PR_TRUE; }
150 void SetType(nsIAtom* aMediaType) {
151 NS_ASSERTION(aMediaType,
152 "expected non-null");
153 mMediaType = aMediaType;
156 // Return a new nsMediaExpression in the array for the caller to fill
157 // in. The caller must either fill it in completely, or call
158 // SetHadUnknownExpression on this nsMediaQuery.
159 // Returns null on out-of-memory.
160 nsMediaExpression* NewExpression() { return mExpressions.AppendElement(); }
162 void AppendToString(nsAString& aString) const;
164 nsMediaQuery* Clone() const;
166 // Does this query apply to the presentation?
167 PRBool Matches(nsPresContext* aPresContext,
168 nsMediaQueryResultCacheKey& aKey) const;
170 private:
171 PRPackedBool mNegated;
172 PRPackedBool mHasOnly; // only needed for serialization
173 PRPackedBool mTypeOmitted; // only needed for serialization
174 PRPackedBool mHadUnknownExpression;
175 nsCOMPtr<nsIAtom> mMediaType;
176 nsTArray<nsMediaExpression> mExpressions;
179 class nsMediaList : public nsIDOMMediaList {
180 public:
181 nsMediaList();
183 NS_DECL_ISUPPORTS
185 NS_DECL_NSIDOMMEDIALIST
187 nsresult GetText(nsAString& aMediaText);
188 nsresult SetText(const nsAString& aMediaText);
189 PRBool Matches(nsPresContext* aPresContext,
190 nsMediaQueryResultCacheKey& aKey);
191 nsresult SetStyleSheet(nsICSSStyleSheet* aSheet);
192 nsresult AppendQuery(nsAutoPtr<nsMediaQuery>& aQuery) {
193 // Takes ownership of aQuery (if it succeeds)
194 if (!mArray.AppendElement(aQuery.get())) {
195 return NS_ERROR_OUT_OF_MEMORY;
197 aQuery.forget();
198 return NS_OK;
201 nsresult Clone(nsMediaList** aResult);
203 PRInt32 Count() { return mArray.Length(); }
204 nsMediaQuery* MediumAt(PRInt32 aIndex) { return mArray[aIndex]; }
205 void Clear() { mArray.Clear(); mIsEmpty = PR_TRUE; }
206 // a media list with no items may not represent the lack of a media
207 // list; it could represent the empty string or something with parser
208 // errors, which means that the media list should never match
209 void SetNonEmpty() { mIsEmpty = PR_FALSE; }
211 protected:
212 ~nsMediaList();
214 nsresult Delete(const nsAString & aOldMedium);
215 nsresult Append(const nsAString & aOldMedium);
217 nsTArray<nsAutoPtr<nsMediaQuery> > mArray;
218 PRBool mIsEmpty;
219 // not refcounted; sheet will let us know when it goes away
220 // mStyleSheet is the sheet that needs to be dirtied when this medialist
221 // changes
222 nsCSSStyleSheet* mStyleSheet;
224 #endif /* !defined(nsIMediaList_h_) */