layout/style/nsIMediaList.h

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

     1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
     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
    10  */
    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 nsCSSStyleSheet;
    25 class nsAString;
    26 struct nsMediaFeature;
    28 struct nsMediaExpression {
    29   enum Range { eMin, eMax, eEqual };
    31   const nsMediaFeature *mFeature;
    32   Range mRange;
    33   nsCSSValue mValue;
    35   // aActualValue must be obtained from mFeature->mGetter
    36   bool Matches(nsPresContext* aPresContext,
    37                  const nsCSSValue& aActualValue) const;
    38 };
    40 /**
    41  * An nsMediaQueryResultCacheKey records what feature/value combinations
    42  * a set of media query results are valid for.  This allows the caller
    43  * to quickly learn whether a prior result of media query evaluation is
    44  * still valid (e.g., due to a window size change) without rerunning all
    45  * of the evaluation and rebuilding the list of rules.
    46  *
    47  * This object may not be used after any media rules in any of the
    48  * sheets it was given to have been modified.  However, this is
    49  * generally not a problem since ClearRuleCascades is called on the
    50  * sheet whenever this happens, and these objects are stored inside the
    51  * rule cascades.  (FIXME: We're not actually doing this all the time.)
    52  *
    53  * The implementation could be further optimized in the future to store
    54  * ranges (combinations of less-than, less-than-or-equal, greater-than,
    55  * greater-than-or-equal, equal, not-equal, present, not-present) for
    56  * each feature rather than simply storing the list of expressions.
    57  * However, this requires combining any such ranges.
    58  */
    59 class nsMediaQueryResultCacheKey {
    60 public:
    61   nsMediaQueryResultCacheKey(nsIAtom* aMedium)
    62     : mMedium(aMedium)
    63   {}
    65   /**
    66    * Record that aExpression was tested while building the cached set
    67    * that this cache key is for, and that aExpressionMatches was whether
    68    * it matched.
    69    */
    70   void AddExpression(const nsMediaExpression* aExpression,
    71                      bool aExpressionMatches);
    72   bool Matches(nsPresContext* aPresContext) const;
    73 private:
    74   struct ExpressionEntry {
    75     // FIXME: if we were better at maintaining invariants about clearing
    76     // rule cascades when media lists change, this could be a |const
    77     // nsMediaExpression*| instead.
    78     nsMediaExpression mExpression;
    79     bool mExpressionMatches;
    80   };
    81   struct FeatureEntry {
    82     const nsMediaFeature *mFeature;
    83     InfallibleTArray<ExpressionEntry> mExpressions;
    84   };
    85   nsCOMPtr<nsIAtom> mMedium;
    86   nsTArray<FeatureEntry> mFeatureCache;
    87 };
    89 class nsMediaQuery {
    90 public:
    91   nsMediaQuery()
    92     : mNegated(false)
    93     , mHasOnly(false)
    94     , mTypeOmitted(false)
    95     , mHadUnknownExpression(false)
    96   {
    97   }
    99 private:
   100   // for Clone only
   101   nsMediaQuery(const nsMediaQuery& aOther)
   102     : mNegated(aOther.mNegated)
   103     , mHasOnly(aOther.mHasOnly)
   104     , mTypeOmitted(aOther.mTypeOmitted)
   105     , mHadUnknownExpression(aOther.mHadUnknownExpression)
   106     , mMediaType(aOther.mMediaType)
   107     , mExpressions(aOther.mExpressions)
   108   {
   109     MOZ_ASSERT(mExpressions.Length() == aOther.mExpressions.Length());
   110   }
   112 public:
   114   void SetNegated()                     { mNegated = true; }
   115   void SetHasOnly()                     { mHasOnly = true; }
   116   void SetTypeOmitted()                 { mTypeOmitted = true; }
   117   void SetHadUnknownExpression()        { mHadUnknownExpression = true; }
   118   void SetType(nsIAtom* aMediaType)     { 
   119                                           NS_ASSERTION(aMediaType,
   120                                                        "expected non-null");
   121                                           mMediaType = aMediaType;
   122                                         }
   124   // Return a new nsMediaExpression in the array for the caller to fill
   125   // in.  The caller must either fill it in completely, or call
   126   // SetHadUnknownExpression on this nsMediaQuery.
   127   // Returns null on out-of-memory.
   128   nsMediaExpression* NewExpression()    { return mExpressions.AppendElement(); }
   130   void AppendToString(nsAString& aString) const;
   132   nsMediaQuery* Clone() const;
   134   // Does this query apply to the presentation?
   135   // If |aKey| is non-null, add cache information to it.
   136   bool Matches(nsPresContext* aPresContext,
   137                  nsMediaQueryResultCacheKey* aKey) const;
   139 private:
   140   bool mNegated;
   141   bool mHasOnly; // only needed for serialization
   142   bool mTypeOmitted; // only needed for serialization
   143   bool mHadUnknownExpression;
   144   nsCOMPtr<nsIAtom> mMediaType;
   145   nsTArray<nsMediaExpression> mExpressions;
   146 };
   148 class nsMediaList MOZ_FINAL : public nsIDOMMediaList
   149                             , public nsWrapperCache
   150 {
   151 public:
   152   typedef mozilla::ErrorResult ErrorResult;
   154   nsMediaList();
   156   virtual JSObject*
   157   WrapObject(JSContext* aCx) MOZ_OVERRIDE;
   158   nsISupports* GetParentObject() const
   159   {
   160     return nullptr;
   161   }
   163   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   164   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsMediaList)
   166   NS_DECL_NSIDOMMEDIALIST
   168   void GetText(nsAString& aMediaText);
   169   void SetText(const nsAString& aMediaText);
   171   // Does this query apply to the presentation?
   172   // If |aKey| is non-null, add cache information to it.
   173   bool Matches(nsPresContext* aPresContext,
   174                  nsMediaQueryResultCacheKey* aKey);
   176   nsresult SetStyleSheet(nsCSSStyleSheet* aSheet);
   177   void AppendQuery(nsAutoPtr<nsMediaQuery>& aQuery) {
   178     // Takes ownership of aQuery
   179     mArray.AppendElement(aQuery.forget());
   180   }
   182   already_AddRefed<nsMediaList> Clone();
   184   nsMediaQuery* MediumAt(int32_t aIndex) { return mArray[aIndex]; }
   185   void Clear() { mArray.Clear(); }
   187   // WebIDL
   188   // XPCOM GetMediaText and SetMediaText are fine.
   189   uint32_t Length() { return mArray.Length(); }
   190   void IndexedGetter(uint32_t aIndex, bool& aFound, nsAString& aReturn);
   191   // XPCOM Item is fine.
   192   void DeleteMedium(const nsAString& aMedium, ErrorResult& aRv)
   193   {
   194     aRv = DeleteMedium(aMedium);
   195   }
   196   void AppendMedium(const nsAString& aMedium, ErrorResult& aRv)
   197   {
   198     aRv = AppendMedium(aMedium);
   199   }
   201 protected:
   202   ~nsMediaList();
   204   nsresult Delete(const nsAString & aOldMedium);
   205   nsresult Append(const nsAString & aOldMedium);
   207   InfallibleTArray<nsAutoPtr<nsMediaQuery> > mArray;
   208   // not refcounted; sheet will let us know when it goes away
   209   // mStyleSheet is the sheet that needs to be dirtied when this medialist
   210   // changes
   211   nsCSSStyleSheet*         mStyleSheet;
   212 };
   213 #endif /* !defined(nsIMediaList_h_) */

mercurial