LCOV - code coverage report
Current view: top level - layout/style - nsMediaList.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 108 296 36.5 %
Date: 2017-07-14 16:53:18 Functions: 12 25 48.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       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/. */
       5             : 
       6             : /*
       7             :  * representation of media lists used when linking to style sheets or by
       8             :  * @media rules
       9             :  */
      10             : 
      11             : #include "nsMediaList.h"
      12             : 
      13             : #include "nsCSSParser.h"
      14             : #include "nsCSSRules.h"
      15             : #include "nsMediaFeatures.h"
      16             : #include "nsRuleNode.h"
      17             : 
      18             : using namespace mozilla;
      19             : 
      20             : template <class Numeric>
      21         238 : int32_t DoCompare(Numeric a, Numeric b)
      22             : {
      23         238 :   if (a == b)
      24          86 :     return 0;
      25         152 :   if (a < b)
      26          33 :     return -1;
      27         119 :   return 1;
      28             : }
      29             : 
      30             : bool
      31         375 : nsMediaExpression::Matches(nsPresContext *aPresContext,
      32             :                            const nsCSSValue& aActualValue) const
      33             : {
      34         375 :   const nsCSSValue& actual = aActualValue;
      35         375 :   const nsCSSValue& required = mValue;
      36             : 
      37             :   // If we don't have the feature, the match fails.
      38         375 :   if (actual.GetUnit() == eCSSUnit_Null) {
      39           1 :     return false;
      40             :   }
      41             : 
      42             :   // If the expression had no value to match, the match succeeds,
      43             :   // unless the value is an integer 0 or a zero length.
      44         374 :   if (required.GetUnit() == eCSSUnit_Null) {
      45         136 :     if (actual.GetUnit() == eCSSUnit_Integer)
      46         136 :       return actual.GetIntValue() != 0;
      47           0 :     if (actual.IsLengthUnit())
      48           0 :       return actual.GetFloatValue() != 0;
      49           0 :     return true;
      50             :   }
      51             : 
      52         238 :   NS_ASSERTION(mFeature->mRangeType == nsMediaFeature::eMinMaxAllowed ||
      53             :                mRange == nsMediaExpression::eEqual, "yikes");
      54             :   int32_t cmp; // -1 (actual < required)
      55             :                //  0 (actual == required)
      56             :                //  1 (actual > required)
      57         238 :   switch (mFeature->mValueType) {
      58             :     case nsMediaFeature::eLength:
      59             :       {
      60          31 :         NS_ASSERTION(actual.IsLengthUnit(), "bad actual value");
      61          31 :         NS_ASSERTION(required.IsLengthUnit(), "bad required value");
      62             :         nscoord actualCoord = nsRuleNode::CalcLengthWithInitialFont(
      63          31 :                                 aPresContext, actual);
      64             :         nscoord requiredCoord = nsRuleNode::CalcLengthWithInitialFont(
      65          31 :                                   aPresContext, required);
      66          31 :         cmp = DoCompare(actualCoord, requiredCoord);
      67             :       }
      68          31 :       break;
      69             :     case nsMediaFeature::eInteger:
      70             :     case nsMediaFeature::eBoolInteger:
      71             :       {
      72           0 :         NS_ASSERTION(actual.GetUnit() == eCSSUnit_Integer,
      73             :                      "bad actual value");
      74           0 :         NS_ASSERTION(required.GetUnit() == eCSSUnit_Integer,
      75             :                      "bad required value");
      76           0 :         NS_ASSERTION(mFeature->mValueType != nsMediaFeature::eBoolInteger ||
      77             :                      actual.GetIntValue() == 0 || actual.GetIntValue() == 1,
      78             :                      "bad actual bool integer value");
      79           0 :         NS_ASSERTION(mFeature->mValueType != nsMediaFeature::eBoolInteger ||
      80             :                      required.GetIntValue() == 0 || required.GetIntValue() == 1,
      81             :                      "bad required bool integer value");
      82           0 :         cmp = DoCompare(actual.GetIntValue(), required.GetIntValue());
      83             :       }
      84           0 :       break;
      85             :     case nsMediaFeature::eFloat:
      86             :       {
      87           0 :         NS_ASSERTION(actual.GetUnit() == eCSSUnit_Number,
      88             :                      "bad actual value");
      89           0 :         NS_ASSERTION(required.GetUnit() == eCSSUnit_Number,
      90             :                      "bad required value");
      91           0 :         cmp = DoCompare(actual.GetFloatValue(), required.GetFloatValue());
      92             :       }
      93           0 :       break;
      94             :     case nsMediaFeature::eIntRatio:
      95             :       {
      96           0 :         NS_ASSERTION(actual.GetUnit() == eCSSUnit_Array &&
      97             :                      actual.GetArrayValue()->Count() == 2 &&
      98             :                      actual.GetArrayValue()->Item(0).GetUnit() ==
      99             :                        eCSSUnit_Integer &&
     100             :                      actual.GetArrayValue()->Item(1).GetUnit() ==
     101             :                        eCSSUnit_Integer,
     102             :                      "bad actual value");
     103           0 :         NS_ASSERTION(required.GetUnit() == eCSSUnit_Array &&
     104             :                      required.GetArrayValue()->Count() == 2 &&
     105             :                      required.GetArrayValue()->Item(0).GetUnit() ==
     106             :                        eCSSUnit_Integer &&
     107             :                      required.GetArrayValue()->Item(1).GetUnit() ==
     108             :                        eCSSUnit_Integer,
     109             :                      "bad required value");
     110             :         // Convert to int64_t so we can multiply without worry.  Note
     111             :         // that while the spec requires that both halves of |required|
     112             :         // be positive, the numerator or denominator of |actual| might
     113             :         // be zero (e.g., when testing 'aspect-ratio' on a 0-width or
     114             :         // 0-height iframe).
     115           0 :         int64_t actualNum = actual.GetArrayValue()->Item(0).GetIntValue(),
     116           0 :                 actualDen = actual.GetArrayValue()->Item(1).GetIntValue(),
     117           0 :                 requiredNum = required.GetArrayValue()->Item(0).GetIntValue(),
     118           0 :                 requiredDen = required.GetArrayValue()->Item(1).GetIntValue();
     119           0 :         cmp = DoCompare(actualNum * requiredDen, requiredNum * actualDen);
     120             :       }
     121           0 :       break;
     122             :     case nsMediaFeature::eResolution:
     123             :       {
     124         207 :         NS_ASSERTION(actual.GetUnit() == eCSSUnit_Inch ||
     125             :                      actual.GetUnit() == eCSSUnit_Pixel ||
     126             :                      actual.GetUnit() == eCSSUnit_Centimeter,
     127             :                      "bad actual value");
     128         207 :         NS_ASSERTION(required.GetUnit() == eCSSUnit_Inch ||
     129             :                      required.GetUnit() == eCSSUnit_Pixel ||
     130             :                      required.GetUnit() == eCSSUnit_Centimeter,
     131             :                      "bad required value");
     132         207 :         float actualDPI = actual.GetFloatValue();
     133         207 :         float overrideDPPX = aPresContext->GetOverrideDPPX();
     134             : 
     135         207 :         if (overrideDPPX > 0) {
     136           0 :           actualDPI = overrideDPPX * 96.0f;
     137         207 :         } else if (actual.GetUnit() == eCSSUnit_Centimeter) {
     138           0 :           actualDPI = actualDPI * 2.54f;
     139         207 :         } else if (actual.GetUnit() == eCSSUnit_Pixel) {
     140           0 :           actualDPI = actualDPI * 96.0f;
     141             :         }
     142         207 :         float requiredDPI = required.GetFloatValue();
     143         207 :         if (required.GetUnit() == eCSSUnit_Centimeter) {
     144           0 :           requiredDPI = requiredDPI * 2.54f;
     145         207 :         } else if (required.GetUnit() == eCSSUnit_Pixel) {
     146         207 :           requiredDPI = requiredDPI * 96.0f;
     147             :         }
     148         207 :         cmp = DoCompare(actualDPI, requiredDPI);
     149             :       }
     150         207 :       break;
     151             :     case nsMediaFeature::eEnumerated:
     152             :       {
     153           0 :         NS_ASSERTION(actual.GetUnit() == eCSSUnit_Enumerated,
     154             :                      "bad actual value");
     155           0 :         NS_ASSERTION(required.GetUnit() == eCSSUnit_Enumerated,
     156             :                      "bad required value");
     157           0 :         NS_ASSERTION(mFeature->mRangeType == nsMediaFeature::eMinMaxNotAllowed,
     158             :                      "bad range"); // we asserted above about mRange
     159             :         // We don't really need DoCompare, but it doesn't hurt (and
     160             :         // maybe the compiler will condense this case with eInteger).
     161           0 :         cmp = DoCompare(actual.GetIntValue(), required.GetIntValue());
     162             :       }
     163           0 :       break;
     164             :     case nsMediaFeature::eIdent:
     165             :       {
     166           0 :         NS_ASSERTION(actual.GetUnit() == eCSSUnit_Ident,
     167             :                      "bad actual value");
     168           0 :         NS_ASSERTION(required.GetUnit() == eCSSUnit_Ident,
     169             :                      "bad required value");
     170           0 :         NS_ASSERTION(mFeature->mRangeType == nsMediaFeature::eMinMaxNotAllowed,
     171             :                      "bad range");
     172           0 :         cmp = !(actual == required); // string comparison
     173             :       }
     174           0 :       break;
     175             :   }
     176         238 :   switch (mRange) {
     177             :     case nsMediaExpression::eMin:
     178         153 :       return cmp != -1;
     179             :     case nsMediaExpression::eMax:
     180          31 :       return cmp != 1;
     181             :     case nsMediaExpression::eEqual:
     182          54 :       return cmp == 0;
     183             :   }
     184           0 :   NS_NOTREACHED("unexpected mRange");
     185           0 :   return false;
     186             : }
     187             : 
     188             : void
     189         125 : nsMediaQueryResultCacheKey::AddExpression(const nsMediaExpression* aExpression,
     190             :                                           bool aExpressionMatches)
     191             : {
     192         125 :   const nsMediaFeature *feature = aExpression->mFeature;
     193         125 :   FeatureEntry *entry = nullptr;
     194         165 :   for (uint32_t i = 0; i < mFeatureCache.Length(); ++i) {
     195         128 :     if (mFeatureCache[i].mFeature == feature) {
     196          88 :       entry = &mFeatureCache[i];
     197          88 :       break;
     198             :     }
     199             :   }
     200         125 :   if (!entry) {
     201          37 :     entry = mFeatureCache.AppendElement();
     202          37 :     if (!entry) {
     203           0 :       return; /* out of memory */
     204             :     }
     205          37 :     entry->mFeature = feature;
     206             :   }
     207             : 
     208         250 :   ExpressionEntry eentry = { *aExpression, aExpressionMatches };
     209         125 :   entry->mExpressions.AppendElement(eentry);
     210             : }
     211             : 
     212             : bool
     213         136 : nsMediaQueryResultCacheKey::Matches(nsPresContext* aPresContext) const
     214             : {
     215         136 :   if (aPresContext->Medium() != mMedium) {
     216           0 :     return false;
     217             :   }
     218             : 
     219         292 :   for (uint32_t i = 0; i < mFeatureCache.Length(); ++i) {
     220         158 :     const FeatureEntry *entry = &mFeatureCache[i];
     221         314 :     nsCSSValue actual;
     222             : 
     223         158 :     entry->mFeature->mGetter(aPresContext, entry->mFeature, actual);
     224             : 
     225         402 :     for (uint32_t j = 0; j < entry->mExpressions.Length(); ++j) {
     226         246 :       const ExpressionEntry &eentry = entry->mExpressions[j];
     227         492 :       if (eentry.mExpression.Matches(aPresContext, actual) !=
     228         246 :           eentry.mExpressionMatches) {
     229           2 :         return false;
     230             :       }
     231             :     }
     232             :   }
     233             : 
     234         134 :   return true;
     235             : }
     236             : 
     237             : bool
     238           4 : nsDocumentRuleResultCacheKey::AddMatchingRule(css::DocumentRule* aRule)
     239             : {
     240           4 :   MOZ_ASSERT(!mFinalized);
     241           4 :   return mMatchingRules.AppendElement(aRule);
     242             : }
     243             : 
     244             : void
     245          10 : nsDocumentRuleResultCacheKey::Finalize()
     246             : {
     247          10 :   mMatchingRules.Sort();
     248             : #ifdef DEBUG
     249          10 :   mFinalized = true;
     250             : #endif
     251          10 : }
     252             : 
     253             : #ifdef DEBUG
     254             : static bool
     255          48 : ArrayIsSorted(const nsTArray<css::DocumentRule*>& aRules)
     256             : {
     257          48 :   for (size_t i = 1; i < aRules.Length(); i++) {
     258           0 :     if (aRules[i - 1] > aRules[i]) {
     259           0 :       return false;
     260             :     }
     261             :   }
     262          48 :   return true;
     263             : }
     264             : #endif
     265             : 
     266             : bool
     267          24 : nsDocumentRuleResultCacheKey::Matches(
     268             :                        nsPresContext* aPresContext,
     269             :                        const nsTArray<css::DocumentRule*>& aRules) const
     270             : {
     271          24 :   MOZ_ASSERT(mFinalized);
     272          24 :   MOZ_ASSERT(ArrayIsSorted(mMatchingRules));
     273          24 :   MOZ_ASSERT(ArrayIsSorted(aRules));
     274             : 
     275             : #ifdef DEBUG
     276          24 :   for (css::DocumentRule* rule : mMatchingRules) {
     277           0 :     MOZ_ASSERT(aRules.BinaryIndexOf(rule) != aRules.NoIndex,
     278             :                "aRules must contain all rules in mMatchingRules");
     279             :   }
     280             : #endif
     281             : 
     282             :   // First check that aPresContext matches all the rules listed in
     283             :   // mMatchingRules.
     284          24 :   for (css::DocumentRule* rule : mMatchingRules) {
     285           0 :     if (!rule->UseForPresentation(aPresContext)) {
     286           0 :       return false;
     287             :     }
     288             :   }
     289             : 
     290             :   // Then check that all the rules in aRules that aren't also in
     291             :   // mMatchingRules do not match.
     292             : 
     293             :   // pointer to matching rules
     294          24 :   auto pm     = mMatchingRules.begin();
     295          24 :   auto pm_end = mMatchingRules.end();
     296             : 
     297             :   // pointer to all rules
     298          24 :   auto pr     = aRules.begin();
     299          24 :   auto pr_end = aRules.end();
     300             : 
     301             :   // mMatchingRules and aRules are both sorted by their pointer values,
     302             :   // so we can iterate over the two lists simultaneously.
     303          30 :   while (pr < pr_end) {
     304           3 :     while (pm < pm_end && *pm < *pr) {
     305           0 :       ++pm;
     306             :     }
     307           3 :     if (pm >= pm_end || *pm != *pr) {
     308           3 :       if ((*pr)->UseForPresentation(aPresContext)) {
     309           0 :         return false;
     310             :       }
     311             :     }
     312           3 :     ++pr;
     313             :   }
     314          24 :   return true;
     315             : }
     316             : 
     317             : #ifdef DEBUG
     318             : void
     319           0 : nsDocumentRuleResultCacheKey::List(FILE* aOut, int32_t aIndent) const
     320             : {
     321           0 :   for (css::DocumentRule* rule : mMatchingRules) {
     322           0 :     nsCString str;
     323             : 
     324           0 :     for (int32_t i = 0; i < aIndent; i++) {
     325           0 :       str.AppendLiteral("  ");
     326             :     }
     327           0 :     str.AppendLiteral("{ ");
     328             : 
     329           0 :     nsString condition;
     330           0 :     rule->GetConditionText(condition);
     331           0 :     AppendUTF16toUTF8(condition, str);
     332             : 
     333           0 :     str.AppendLiteral(" }\n");
     334           0 :     fprintf_stderr(aOut, "%s", str.get());
     335             :   }
     336           0 : }
     337             : #endif
     338             : 
     339             : size_t
     340           0 : nsDocumentRuleResultCacheKey::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const
     341             : {
     342           0 :   size_t n = 0;
     343           0 :   n += mMatchingRules.ShallowSizeOfExcludingThis(aMallocSizeOf);
     344           0 :   return n;
     345             : }
     346             : 
     347             : void
     348           0 : nsMediaQuery::AppendToString(nsAString& aString) const
     349             : {
     350           0 :   if (mHadUnknownExpression) {
     351           0 :     aString.AppendLiteral("not all");
     352           0 :     return;
     353             :   }
     354             : 
     355           0 :   NS_ASSERTION(!mNegated || !mHasOnly, "can't have not and only");
     356           0 :   NS_ASSERTION(!mTypeOmitted || (!mNegated && !mHasOnly),
     357             :                "can't have not or only when type is omitted");
     358           0 :   if (!mTypeOmitted) {
     359           0 :     if (mNegated) {
     360           0 :       aString.AppendLiteral("not ");
     361           0 :     } else if (mHasOnly) {
     362           0 :       aString.AppendLiteral("only ");
     363             :     }
     364           0 :     aString.Append(nsDependentAtomString(mMediaType));
     365             :   }
     366             : 
     367           0 :   for (uint32_t i = 0, i_end = mExpressions.Length(); i < i_end; ++i) {
     368           0 :     if (i > 0 || !mTypeOmitted)
     369           0 :       aString.AppendLiteral(" and ");
     370           0 :     aString.Append('(');
     371             : 
     372           0 :     const nsMediaExpression &expr = mExpressions[i];
     373           0 :     const nsMediaFeature *feature = expr.mFeature;
     374           0 :     if (feature->mReqFlags & nsMediaFeature::eHasWebkitPrefix) {
     375           0 :       aString.AppendLiteral("-webkit-");
     376             :     }
     377           0 :     if (expr.mRange == nsMediaExpression::eMin) {
     378           0 :       aString.AppendLiteral("min-");
     379           0 :     } else if (expr.mRange == nsMediaExpression::eMax) {
     380           0 :       aString.AppendLiteral("max-");
     381             :     }
     382             : 
     383           0 :     aString.Append(nsDependentAtomString(*feature->mName));
     384             : 
     385           0 :     if (expr.mValue.GetUnit() != eCSSUnit_Null) {
     386           0 :       aString.AppendLiteral(": ");
     387           0 :       switch (feature->mValueType) {
     388             :         case nsMediaFeature::eLength:
     389           0 :           NS_ASSERTION(expr.mValue.IsLengthUnit(), "bad unit");
     390             :           // Use 'width' as a property that takes length values
     391             :           // written in the normal way.
     392           0 :           expr.mValue.AppendToString(eCSSProperty_width, aString,
     393           0 :                                      nsCSSValue::eNormalized);
     394           0 :           break;
     395             :         case nsMediaFeature::eInteger:
     396             :         case nsMediaFeature::eBoolInteger:
     397           0 :           NS_ASSERTION(expr.mValue.GetUnit() == eCSSUnit_Integer,
     398             :                        "bad unit");
     399             :           // Use 'z-index' as a property that takes integer values
     400             :           // written without anything extra.
     401           0 :           expr.mValue.AppendToString(eCSSProperty_z_index, aString,
     402           0 :                                      nsCSSValue::eNormalized);
     403           0 :           break;
     404             :         case nsMediaFeature::eFloat:
     405             :           {
     406           0 :             NS_ASSERTION(expr.mValue.GetUnit() == eCSSUnit_Number,
     407             :                          "bad unit");
     408             :             // Use 'line-height' as a property that takes float values
     409             :             // written in the normal way.
     410           0 :             expr.mValue.AppendToString(eCSSProperty_line_height, aString,
     411           0 :                                        nsCSSValue::eNormalized);
     412             :           }
     413           0 :           break;
     414             :         case nsMediaFeature::eIntRatio:
     415             :           {
     416           0 :             NS_ASSERTION(expr.mValue.GetUnit() == eCSSUnit_Array,
     417             :                          "bad unit");
     418           0 :             nsCSSValue::Array *array = expr.mValue.GetArrayValue();
     419           0 :             NS_ASSERTION(array->Count() == 2, "unexpected length");
     420           0 :             NS_ASSERTION(array->Item(0).GetUnit() == eCSSUnit_Integer,
     421             :                          "bad unit");
     422           0 :             NS_ASSERTION(array->Item(1).GetUnit() == eCSSUnit_Integer,
     423             :                          "bad unit");
     424           0 :             array->Item(0).AppendToString(eCSSProperty_z_index, aString,
     425           0 :                                           nsCSSValue::eNormalized);
     426           0 :             aString.Append('/');
     427           0 :             array->Item(1).AppendToString(eCSSProperty_z_index, aString,
     428           0 :                                           nsCSSValue::eNormalized);
     429             :           }
     430           0 :           break;
     431             :         case nsMediaFeature::eResolution:
     432             :           {
     433           0 :             aString.AppendFloat(expr.mValue.GetFloatValue());
     434           0 :             if (expr.mValue.GetUnit() == eCSSUnit_Inch) {
     435           0 :               aString.AppendLiteral("dpi");
     436           0 :             } else if (expr.mValue.GetUnit() == eCSSUnit_Pixel) {
     437           0 :               aString.AppendLiteral("dppx");
     438             :             } else {
     439           0 :               NS_ASSERTION(expr.mValue.GetUnit() == eCSSUnit_Centimeter,
     440             :                            "bad unit");
     441           0 :               aString.AppendLiteral("dpcm");
     442             :             }
     443             :           }
     444           0 :           break;
     445             :         case nsMediaFeature::eEnumerated:
     446           0 :           NS_ASSERTION(expr.mValue.GetUnit() == eCSSUnit_Enumerated,
     447             :                        "bad unit");
     448           0 :           AppendASCIItoUTF16(
     449             :               nsCSSProps::ValueToKeyword(expr.mValue.GetIntValue(),
     450           0 :                                          feature->mData.mKeywordTable),
     451           0 :               aString);
     452           0 :           break;
     453             :         case nsMediaFeature::eIdent:
     454           0 :           NS_ASSERTION(expr.mValue.GetUnit() == eCSSUnit_Ident,
     455             :                        "bad unit");
     456           0 :           aString.Append(expr.mValue.GetStringBufferValue());
     457           0 :           break;
     458             :       }
     459             :     }
     460             : 
     461           0 :     aString.Append(')');
     462             :   }
     463             : }
     464             : 
     465             : nsMediaQuery*
     466           0 : nsMediaQuery::Clone() const
     467             : {
     468           0 :   return new nsMediaQuery(*this);
     469             : }
     470             : 
     471             : bool
     472         153 : nsMediaQuery::Matches(nsPresContext* aPresContext,
     473             :                       nsMediaQueryResultCacheKey* aKey) const
     474             : {
     475         153 :   if (mHadUnknownExpression)
     476           0 :     return false;
     477             : 
     478             :   bool match =
     479         153 :     mMediaType == aPresContext->Medium() || mMediaType == nsGkAtoms::all;
     480         282 :   for (uint32_t i = 0, i_end = mExpressions.Length(); match && i < i_end; ++i) {
     481         129 :     const nsMediaExpression &expr = mExpressions[i];
     482         258 :     nsCSSValue actual;
     483         129 :     expr.mFeature->mGetter(aPresContext, expr.mFeature, actual);
     484             : 
     485         129 :     match = expr.Matches(aPresContext, actual);
     486         129 :     if (aKey) {
     487         125 :       aKey->AddExpression(&expr, match);
     488             :     }
     489             :   }
     490             : 
     491         153 :   return match == !mNegated;
     492             : }
     493             : 
     494          54 : nsMediaList::nsMediaList()
     495             : {
     496          54 : }
     497             : 
     498           0 : nsMediaList::~nsMediaList()
     499             : {
     500           0 : }
     501             : 
     502             : void
     503           0 : nsMediaList::GetText(nsAString& aMediaText)
     504             : {
     505           0 :   aMediaText.Truncate();
     506             : 
     507           0 :   for (int32_t i = 0, i_end = mArray.Length(); i < i_end; ++i) {
     508           0 :     nsMediaQuery* query = mArray[i];
     509             : 
     510           0 :     query->AppendToString(aMediaText);
     511             : 
     512           0 :     if (i + 1 < i_end) {
     513           0 :       aMediaText.AppendLiteral(", ");
     514             :     }
     515             :   }
     516           0 : }
     517             : 
     518             : // XXXbz this is so ill-defined in the spec, it's not clear quite what
     519             : // it should be doing....
     520             : void
     521           0 : nsMediaList::SetText(const nsAString& aMediaText)
     522             : {
     523           0 :   nsCSSParser parser;
     524           0 :   parser.ParseMediaList(aMediaText, nullptr, 0, this);
     525           0 : }
     526             : 
     527             : bool
     528         161 : nsMediaList::Matches(nsPresContext* aPresContext,
     529             :                      nsMediaQueryResultCacheKey* aKey) const
     530             : {
     531         222 :   for (int32_t i = 0, i_end = mArray.Length(); i < i_end; ++i) {
     532         153 :     if (mArray[i]->Matches(aPresContext, aKey)) {
     533          92 :       return true;
     534             :     }
     535             :   }
     536          69 :   return mArray.IsEmpty();
     537             : }
     538             : 
     539             : already_AddRefed<dom::MediaList>
     540           0 : nsMediaList::Clone()
     541             : {
     542           0 :   RefPtr<nsMediaList> result = new nsMediaList();
     543           0 :   result->mArray.AppendElements(mArray.Length());
     544           0 :   for (uint32_t i = 0, i_end = mArray.Length(); i < i_end; ++i) {
     545           0 :     result->mArray[i] = mArray[i]->Clone();
     546           0 :     MOZ_ASSERT(result->mArray[i]);
     547             :   }
     548           0 :   return result.forget();
     549             : }
     550             : 
     551             : void
     552           0 : nsMediaList::IndexedGetter(uint32_t aIndex, bool& aFound, nsAString& aReturn)
     553             : {
     554           0 :   if (aIndex < Length()) {
     555           0 :     aFound = true;
     556           0 :     aReturn.Truncate();
     557           0 :     mArray[aIndex]->AppendToString(aReturn);
     558             :   } else {
     559           0 :     aFound = false;
     560           0 :     SetDOMStringToNull(aReturn);
     561             :   }
     562           0 : }
     563             : 
     564             : nsresult
     565           0 : nsMediaList::Delete(const nsAString& aOldMedium)
     566             : {
     567           0 :   if (aOldMedium.IsEmpty())
     568           0 :     return NS_ERROR_DOM_NOT_FOUND_ERR;
     569             : 
     570           0 :   for (int32_t i = 0, i_end = mArray.Length(); i < i_end; ++i) {
     571           0 :     nsMediaQuery* query = mArray[i];
     572             : 
     573           0 :     nsAutoString buf;
     574           0 :     query->AppendToString(buf);
     575           0 :     if (buf == aOldMedium) {
     576           0 :       mArray.RemoveElementAt(i);
     577           0 :       return NS_OK;
     578             :     }
     579             :   }
     580             : 
     581           0 :   return NS_ERROR_DOM_NOT_FOUND_ERR;
     582             : }
     583             : 
     584             : nsresult
     585           0 : nsMediaList::Append(const nsAString& aNewMedium)
     586             : {
     587           0 :   if (aNewMedium.IsEmpty())
     588           0 :     return NS_ERROR_DOM_NOT_FOUND_ERR;
     589             : 
     590           0 :   Delete(aNewMedium);
     591             : 
     592           0 :   nsresult rv = NS_OK;
     593           0 :   nsTArray<nsAutoPtr<nsMediaQuery> > buf;
     594           0 :   mArray.SwapElements(buf);
     595           0 :   SetText(aNewMedium);
     596           0 :   if (mArray.Length() == 1) {
     597           0 :     nsMediaQuery *query = mArray[0].forget();
     598           0 :     if (!buf.AppendElement(query)) {
     599           0 :       delete query;
     600           0 :       rv = NS_ERROR_OUT_OF_MEMORY;
     601             :     }
     602             :   }
     603             : 
     604           0 :   mArray.SwapElements(buf);
     605           0 :   return rv;
     606             : }

Generated by: LCOV version 1.13