LCOV - code coverage report
Current view: top level - layout/style - nsMediaList.h (source / functions) Hit Total Coverage
Test: output.info Lines: 33 67 49.3 %
Date: 2017-07-14 16:53:18 Functions: 24 37 64.9 %
Legend: Lines: hit not hit

          Line data    Source code
       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/. */
       6             : 
       7             : /*
       8             :  * representation of media lists used when linking to style sheets or by
       9             :  * @media rules
      10             :  */
      11             : 
      12             : #ifndef nsMediaList_h_
      13             : #define nsMediaList_h_
      14             : 
      15             : #include "nsAutoPtr.h"
      16             : #include "nsTArray.h"
      17             : #include "nsIAtom.h"
      18             : #include "nsCSSValue.h"
      19             : #include "mozilla/Attributes.h"
      20             : #include "mozilla/dom/MediaList.h"
      21             : 
      22             : class nsPresContext;
      23             : class nsAString;
      24             : struct nsMediaFeature;
      25             : 
      26             : namespace mozilla {
      27             : namespace css {
      28             : class DocumentRule;
      29             : } // namespace css
      30             : } // namespace mozilla
      31             : 
      32         551 : struct nsMediaExpression {
      33             :   enum Range { eMin, eMax, eEqual };
      34             : 
      35             :   const nsMediaFeature *mFeature;
      36             :   Range mRange;
      37             :   nsCSSValue mValue;
      38             : 
      39             :   // aActualValue must be obtained from mFeature->mGetter
      40             :   bool Matches(nsPresContext* aPresContext,
      41             :                const nsCSSValue& aActualValue) const;
      42             : 
      43           0 :   bool operator==(const nsMediaExpression& aOther) const {
      44           0 :     return mFeature == aOther.mFeature && // pointer equality fine (atom-like)
      45           0 :            mRange == aOther.mRange &&
      46           0 :            mValue == aOther.mValue;
      47             :   }
      48             :   bool operator!=(const nsMediaExpression& aOther) const {
      49             :     return !(*this == aOther);
      50             :   }
      51             : };
      52             : 
      53             : /**
      54             :  * An nsMediaQueryResultCacheKey records what feature/value combinations
      55             :  * a set of media query results are valid for.  This allows the caller
      56             :  * to quickly learn whether a prior result of media query evaluation is
      57             :  * still valid (e.g., due to a window size change) without rerunning all
      58             :  * of the evaluation and rebuilding the list of rules.
      59             :  *
      60             :  * This object may not be used after any media rules in any of the
      61             :  * sheets it was given to have been modified.  However, this is
      62             :  * generally not a problem since ClearRuleCascades is called on the
      63             :  * sheet whenever this happens, and these objects are stored inside the
      64             :  * rule cascades.  (FIXME: We're not actually doing this all the time.)
      65             :  *
      66             :  * The implementation could be further optimized in the future to store
      67             :  * ranges (combinations of less-than, less-than-or-equal, greater-than,
      68             :  * greater-than-or-equal, equal, not-equal, present, not-present) for
      69             :  * each feature rather than simply storing the list of expressions.
      70             :  * However, this requires combining any such ranges.
      71             :  */
      72          11 : class nsMediaQueryResultCacheKey {
      73             : public:
      74          42 :   explicit nsMediaQueryResultCacheKey(nsIAtom* aMedium)
      75          42 :     : mMedium(aMedium)
      76          42 :   {}
      77             : 
      78             :   /**
      79             :    * Record that aExpression was tested while building the cached set
      80             :    * that this cache key is for, and that aExpressionMatches was whether
      81             :    * it matched.
      82             :    */
      83             :   void AddExpression(const nsMediaExpression* aExpression,
      84             :                      bool aExpressionMatches);
      85             :   bool Matches(nsPresContext* aPresContext) const;
      86           5 :   bool HasFeatureConditions() const {
      87           5 :     return !mFeatureCache.IsEmpty();
      88             :   }
      89             : 
      90             :   /**
      91             :    * An operator== that implements list equality, which isn't quite as
      92             :    * good as set equality, but catches the trivial equality cases.
      93             :    */
      94           0 :   bool operator==(const nsMediaQueryResultCacheKey& aOther) const {
      95           0 :     return mMedium == aOther.mMedium &&
      96           0 :            mFeatureCache == aOther.mFeatureCache;
      97             :   }
      98           0 :   bool operator!=(const nsMediaQueryResultCacheKey& aOther) const {
      99           0 :     return !(*this == aOther);
     100             :   }
     101             : private:
     102         381 :   struct ExpressionEntry {
     103             :     // FIXME: if we were better at maintaining invariants about clearing
     104             :     // rule cascades when media lists change, this could be a |const
     105             :     // nsMediaExpression*| instead.
     106             :     nsMediaExpression mExpression;
     107             :     bool mExpressionMatches;
     108             : 
     109           0 :     bool operator==(const ExpressionEntry& aOther) const {
     110           0 :       return mExpression == aOther.mExpression &&
     111           0 :              mExpressionMatches == aOther.mExpressionMatches;
     112             :     }
     113             :     bool operator!=(const ExpressionEntry& aOther) const {
     114             :       return !(*this == aOther);
     115             :     }
     116             :   };
     117          59 :   struct FeatureEntry {
     118             :     const nsMediaFeature *mFeature;
     119             :     InfallibleTArray<ExpressionEntry> mExpressions;
     120             : 
     121           0 :     bool operator==(const FeatureEntry& aOther) const {
     122           0 :       return mFeature == aOther.mFeature &&
     123           0 :              mExpressions == aOther.mExpressions;
     124             :     }
     125             :     bool operator!=(const FeatureEntry& aOther) const {
     126             :       return !(*this == aOther);
     127             :     }
     128             :   };
     129             :   nsCOMPtr<nsIAtom> mMedium;
     130             :   nsTArray<FeatureEntry> mFeatureCache;
     131             : };
     132             : 
     133             : /**
     134             :  * nsDocumentRuleResultCacheKey is analagous to nsMediaQueryResultCacheKey
     135             :  * and stores the result of matching the @-moz-document rules from a set
     136             :  * of style sheets.  nsCSSRuleProcessor builds up an
     137             :  * nsDocumentRuleResultCacheKey as it visits the @-moz-document rules
     138             :  * while building its RuleCascadeData.
     139             :  *
     140             :  * Rather than represent the result using a list of both the matching and
     141             :  * non-matching rules, we just store the matched rules.  The assumption is
     142             :  * that in situations where we have a large number of rules -- such as the
     143             :  * thousands added by AdBlock Plus -- that only a small number will be
     144             :  * matched.  Thus to check if the nsDocumentRuleResultCacheKey matches a
     145             :  * given nsPresContext, we also need the entire list of @-moz-document
     146             :  * rules to know which rules must not match.
     147             :  */
     148          35 : class nsDocumentRuleResultCacheKey
     149             : {
     150             : public:
     151             : #ifdef DEBUG
     152          74 :   nsDocumentRuleResultCacheKey()
     153          74 :     : mFinalized(false) {}
     154             : #endif
     155             : 
     156             :   bool AddMatchingRule(mozilla::css::DocumentRule* aRule);
     157             :   bool Matches(nsPresContext* aPresContext,
     158             :                const nsTArray<mozilla::css::DocumentRule*>& aRules) const;
     159             : 
     160           0 :   bool operator==(const nsDocumentRuleResultCacheKey& aOther) const {
     161           0 :     MOZ_ASSERT(mFinalized);
     162           0 :     MOZ_ASSERT(aOther.mFinalized);
     163           0 :     return mMatchingRules == aOther.mMatchingRules;
     164             :   }
     165           0 :   bool operator!=(const nsDocumentRuleResultCacheKey& aOther) const {
     166           0 :     return !(*this == aOther);
     167             :   }
     168             : 
     169          10 :   void Swap(nsDocumentRuleResultCacheKey& aOther) {
     170          10 :     mMatchingRules.SwapElements(aOther.mMatchingRules);
     171             : #ifdef DEBUG
     172          10 :     std::swap(mFinalized, aOther.mFinalized);
     173             : #endif
     174          10 :   }
     175             : 
     176             :   void Finalize();
     177             : 
     178             : #ifdef DEBUG
     179             :   void List(FILE* aOut = stdout, int32_t aIndex = 0) const;
     180             : #endif
     181             : 
     182             :   size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
     183             : 
     184             : private:
     185             :   nsTArray<mozilla::css::DocumentRule*> mMatchingRules;
     186             : #ifdef DEBUG
     187             :   bool mFinalized;
     188             : #endif
     189             : };
     190             : 
     191           0 : class nsMediaQuery {
     192             : public:
     193          51 :   nsMediaQuery()
     194          51 :     : mNegated(false)
     195             :     , mHasOnly(false)
     196             :     , mTypeOmitted(false)
     197          51 :     , mHadUnknownExpression(false)
     198             :   {
     199          51 :   }
     200             : 
     201             : private:
     202             :   // for Clone only
     203           0 :   nsMediaQuery(const nsMediaQuery& aOther)
     204           0 :     : mNegated(aOther.mNegated)
     205           0 :     , mHasOnly(aOther.mHasOnly)
     206           0 :     , mTypeOmitted(aOther.mTypeOmitted)
     207           0 :     , mHadUnknownExpression(aOther.mHadUnknownExpression)
     208             :     , mMediaType(aOther.mMediaType)
     209           0 :     , mExpressions(aOther.mExpressions)
     210             :   {
     211           0 :     MOZ_ASSERT(mExpressions.Length() == aOther.mExpressions.Length());
     212           0 :   }
     213             : 
     214             : public:
     215             : 
     216           2 :   void SetNegated()                     { mNegated = true; }
     217           0 :   void SetHasOnly()                     { mHasOnly = true; }
     218          35 :   void SetTypeOmitted()                 { mTypeOmitted = true; }
     219           0 :   void SetHadUnknownExpression()        { mHadUnknownExpression = true; }
     220          51 :   void SetType(nsIAtom* aMediaType)     {
     221          51 :                                           NS_ASSERTION(aMediaType,
     222             :                                                        "expected non-null");
     223          51 :                                           mMediaType = aMediaType;
     224          51 :                                         }
     225             : 
     226             :   // Return a new nsMediaExpression in the array for the caller to fill
     227             :   // in.  The caller must either fill it in completely, or call
     228             :   // SetHadUnknownExpression on this nsMediaQuery.
     229             :   // Returns null on out-of-memory.
     230          45 :   nsMediaExpression* NewExpression()    { return mExpressions.AppendElement(); }
     231             : 
     232             :   void AppendToString(nsAString& aString) const;
     233             : 
     234             :   nsMediaQuery* Clone() const;
     235             : 
     236             :   // Does this query apply to the presentation?
     237             :   // If |aKey| is non-null, add cache information to it.
     238             :   bool Matches(nsPresContext* aPresContext,
     239             :                nsMediaQueryResultCacheKey* aKey) const;
     240             : 
     241             : private:
     242             :   bool mNegated;
     243             :   bool mHasOnly; // only needed for serialization
     244             :   bool mTypeOmitted; // only needed for serialization
     245             :   bool mHadUnknownExpression;
     246             :   nsCOMPtr<nsIAtom> mMediaType;
     247             :   nsTArray<nsMediaExpression> mExpressions;
     248             : };
     249             : 
     250             : class nsMediaList final : public mozilla::dom::MediaList
     251             : {
     252             : public:
     253             :   nsMediaList();
     254             : 
     255             :   void GetText(nsAString& aMediaText) final;
     256             :   void SetText(const nsAString& aMediaText) final;
     257             : 
     258           4 :   bool Matches(nsPresContext* aPresContext) const final {
     259           4 :     return Matches(aPresContext, nullptr);
     260             :   }
     261             : 
     262             :   // Does this query apply to the presentation?
     263             :   // If |aKey| is non-null, add cache information to it.
     264             :   bool Matches(nsPresContext* aPresContext,
     265             :                nsMediaQueryResultCacheKey* aKey) const;
     266             : 
     267             : #ifdef DEBUG
     268           0 :   bool IsServo() const final { return false; }
     269             : #endif
     270             : 
     271          51 :   void AppendQuery(nsAutoPtr<nsMediaQuery>& aQuery) {
     272             :     // Takes ownership of aQuery
     273          51 :     mArray.AppendElement(aQuery.forget());
     274          51 :   }
     275             : 
     276             :   already_AddRefed<mozilla::dom::MediaList> Clone() final;
     277             : 
     278             :   nsMediaQuery* MediumAt(int32_t aIndex) { return mArray[aIndex]; }
     279           3 :   void Clear() { mArray.Clear(); }
     280             : 
     281             :   // WebIDL
     282           0 :   uint32_t Length() final { return mArray.Length(); }
     283             :   void IndexedGetter(uint32_t aIndex, bool& aFound,
     284             :                      nsAString& aReturn) final;
     285             : 
     286             : protected:
     287             :   ~nsMediaList();
     288             : 
     289             :   nsresult Delete(const nsAString & aOldMedium) final;
     290             :   nsresult Append(const nsAString & aOldMedium) final;
     291             : 
     292             :   InfallibleTArray<nsAutoPtr<nsMediaQuery> > mArray;
     293             : };
     294             : #endif /* !defined(nsMediaList_h_) */

Generated by: LCOV version 1.13