LCOV - code coverage report
Current view: top level - layout/style - ServoKeyframesRule.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 172 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 50 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
       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             : #include "mozilla/ServoKeyframesRule.h"
       8             : 
       9             : #include "mozAutoDocUpdate.h"
      10             : #include "mozilla/ServoBindings.h"
      11             : #include "mozilla/ServoKeyframeRule.h"
      12             : 
      13             : #include <limits>
      14             : 
      15             : namespace mozilla {
      16             : 
      17             : // -------------------------------------------
      18             : // ServoKeyframeList
      19             : //
      20             : 
      21             : class ServoKeyframeList : public dom::CSSRuleList
      22             : {
      23             : public:
      24           0 :   explicit ServoKeyframeList(already_AddRefed<RawServoKeyframesRule> aRawRule)
      25           0 :     : mRawRule(aRawRule)
      26             :   {
      27           0 :     mRules.SetCount(Servo_KeyframesRule_GetCount(mRawRule));
      28           0 :   }
      29             : 
      30             :   NS_DECL_ISUPPORTS_INHERITED
      31           0 :   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ServoKeyframeList, dom::CSSRuleList)
      32             : 
      33           0 :   void SetParentRule(ServoKeyframesRule* aParentRule)
      34             :   {
      35           0 :     mParentRule = aParentRule;
      36           0 :     for (css::Rule* rule : mRules) {
      37           0 :       if (rule) {
      38           0 :         rule->SetParentRule(aParentRule);
      39             :       }
      40             :     }
      41           0 :   }
      42           0 :   void SetStyleSheet(ServoStyleSheet* aSheet)
      43             :   {
      44           0 :     mStyleSheet = aSheet;
      45           0 :     for (css::Rule* rule : mRules) {
      46           0 :       if (rule) {
      47           0 :         rule->SetStyleSheet(aSheet);
      48             :       }
      49             :     }
      50           0 :   }
      51             : 
      52           0 :   ServoStyleSheet* GetParentObject() final { return mStyleSheet; }
      53             : 
      54           0 :   ServoKeyframeRule* GetRule(uint32_t aIndex) {
      55           0 :     if (!mRules[aIndex]) {
      56             :       ServoKeyframeRule* rule = new ServoKeyframeRule(
      57           0 :         Servo_KeyframesRule_GetKeyframe(mRawRule, aIndex).Consume());
      58           0 :       mRules.ReplaceObjectAt(rule, aIndex);
      59           0 :       rule->SetStyleSheet(mStyleSheet);
      60           0 :       rule->SetParentRule(mParentRule);
      61             :     }
      62           0 :     return static_cast<ServoKeyframeRule*>(mRules[aIndex]);
      63             :   }
      64             : 
      65           0 :   ServoKeyframeRule* IndexedGetter(uint32_t aIndex, bool& aFound) final
      66             :   {
      67           0 :     if (aIndex >= mRules.Length()) {
      68           0 :       aFound = false;
      69           0 :       return nullptr;
      70             :     }
      71           0 :     aFound = true;
      72           0 :     return GetRule(aIndex);
      73             :   }
      74             : 
      75           0 :   void AppendRule() {
      76           0 :     mRules.AppendObject(nullptr);
      77           0 :   }
      78             : 
      79           0 :   void RemoveRule(uint32_t aIndex) {
      80           0 :     mRules.RemoveObjectAt(aIndex);
      81           0 :   }
      82             : 
      83           0 :   uint32_t Length() final { return mRules.Length(); }
      84             : 
      85           0 :   void DropReference()
      86             :   {
      87           0 :     mStyleSheet = nullptr;
      88           0 :     mParentRule = nullptr;
      89           0 :     DropAllRules();
      90           0 :   }
      91             : 
      92           0 :   size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
      93             :   {
      94           0 :     size_t n = aMallocSizeOf(this);
      95           0 :     for (const css::Rule* rule : mRules) {
      96           0 :       n += rule ? rule->SizeOfIncludingThis(aMallocSizeOf) : 0;
      97             :     }
      98           0 :     return n;
      99             :   }
     100             : 
     101             : private:
     102           0 :   virtual ~ServoKeyframeList() {}
     103             : 
     104           0 :   void DropAllRules()
     105             :   {
     106           0 :     for (css::Rule* rule : mRules) {
     107           0 :       if (rule) {
     108           0 :         rule->SetStyleSheet(nullptr);
     109           0 :         rule->SetParentRule(nullptr);
     110             :       }
     111             :     }
     112           0 :     mRules.Clear();
     113           0 :     mRawRule = nullptr;
     114           0 :   }
     115             : 
     116             :   // may be nullptr when the style sheet drops the reference to us.
     117             :   ServoStyleSheet* mStyleSheet = nullptr;
     118             :   ServoKeyframesRule* mParentRule = nullptr;
     119             :   RefPtr<RawServoKeyframesRule> mRawRule;
     120             :   nsCOMArray<css::Rule> mRules;
     121             : };
     122             : 
     123             : // QueryInterface implementation for ServoKeyframeList
     124           0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(ServoKeyframeList)
     125           0 : NS_INTERFACE_MAP_END_INHERITING(dom::CSSRuleList)
     126             : 
     127           0 : NS_IMPL_ADDREF_INHERITED(ServoKeyframeList, dom::CSSRuleList)
     128           0 : NS_IMPL_RELEASE_INHERITED(ServoKeyframeList, dom::CSSRuleList)
     129             : 
     130             : NS_IMPL_CYCLE_COLLECTION_CLASS(ServoKeyframeList)
     131             : 
     132           0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ServoKeyframeList)
     133           0 :   tmp->DropAllRules();
     134           0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_END_INHERITED(dom::CSSRuleList)
     135           0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(ServoKeyframeList,
     136             :                                                   dom::CSSRuleList)
     137           0 :   for (css::Rule* rule : tmp->mRules) {
     138           0 :     if (rule) {
     139           0 :       NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mRules[i]");
     140           0 :       cb.NoteXPCOMChild(rule);
     141             :     }
     142             :   }
     143           0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
     144             : 
     145             : // -------------------------------------------
     146             : // ServoKeyframesRule
     147             : //
     148             : 
     149           0 : ServoKeyframesRule::ServoKeyframesRule(RefPtr<RawServoKeyframesRule> aRawRule,
     150           0 :                                        uint32_t aLine, uint32_t aColumn)
     151             :   // Although this class inherits from GroupRule, we don't want to use
     152             :   // it at all, so it is fine to call the constructor for Gecko. We can
     153             :   // make CSSKeyframesRule inherit from Rule directly once we can get
     154             :   // rid of nsCSSKeyframeRule.
     155             :   : dom::CSSKeyframesRule(aLine, aColumn)
     156           0 :   , mRawRule(Move(aRawRule))
     157             : {
     158           0 : }
     159             : 
     160           0 : ServoKeyframesRule::~ServoKeyframesRule()
     161             : {
     162           0 : }
     163             : 
     164           0 : NS_IMPL_ADDREF_INHERITED(ServoKeyframesRule, dom::CSSKeyframesRule)
     165           0 : NS_IMPL_RELEASE_INHERITED(ServoKeyframesRule, dom::CSSKeyframesRule)
     166             : 
     167           0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(ServoKeyframesRule)
     168           0 : NS_INTERFACE_MAP_END_INHERITING(dom::CSSKeyframesRule)
     169             : 
     170             : NS_IMPL_CYCLE_COLLECTION_CLASS(ServoKeyframesRule)
     171             : 
     172           0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(ServoKeyframesRule,
     173             :                                                 dom::CSSKeyframesRule)
     174           0 :   if (tmp->mKeyframeList) {
     175           0 :     tmp->mKeyframeList->DropReference();
     176           0 :     tmp->mKeyframeList = nullptr;
     177             :   }
     178           0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_END
     179             : 
     180           0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(ServoKeyframesRule, Rule)
     181           0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mKeyframeList)
     182           0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
     183             : 
     184             : /* virtual */ bool
     185           0 : ServoKeyframesRule::IsCCLeaf() const
     186             : {
     187             :   // If we don't have rule list constructed, we are a leaf.
     188           0 :   return Rule::IsCCLeaf() && !mKeyframeList;
     189             : }
     190             : 
     191             : /* virtual */ already_AddRefed<css::Rule>
     192           0 : ServoKeyframesRule::Clone() const
     193             : {
     194             :   // Rule::Clone is only used when CSSStyleSheetInner is cloned in
     195             :   // preparation of being mutated. However, ServoStyleSheet never clones
     196             :   // anything, so this method should never be called.
     197           0 :   MOZ_ASSERT_UNREACHABLE("Shouldn't be cloning ServoKeyframesRule");
     198             :   return nullptr;
     199             : }
     200             : 
     201             : #ifdef DEBUG
     202             : /* virtual */ void
     203           0 : ServoKeyframesRule::List(FILE* out, int32_t aIndent) const
     204             : {
     205           0 :   nsAutoCString str;
     206           0 :   for (int32_t i = 0; i < aIndent; i++) {
     207           0 :     str.AppendLiteral("  ");
     208             :   }
     209           0 :   Servo_KeyframesRule_Debug(mRawRule, &str);
     210           0 :   fprintf_stderr(out, "%s\n", str.get());
     211           0 : }
     212             : #endif
     213             : 
     214             : /* virtual */ void
     215           0 : ServoKeyframesRule::SetStyleSheet(StyleSheet* aSheet)
     216             : {
     217           0 :   if (mKeyframeList) {
     218           0 :     mKeyframeList->SetStyleSheet(aSheet ? aSheet->AsServo() : nullptr);
     219             :   }
     220           0 :   dom::CSSKeyframesRule::SetStyleSheet(aSheet);
     221           0 : }
     222             : 
     223             : static const uint32_t kRuleNotFound = std::numeric_limits<uint32_t>::max();
     224             : 
     225             : uint32_t
     226           0 : ServoKeyframesRule::FindRuleIndexForKey(const nsAString& aKey)
     227             : {
     228           0 :   NS_ConvertUTF16toUTF8 key(aKey);
     229           0 :   return Servo_KeyframesRule_FindRule(mRawRule, &key);
     230             : }
     231             : 
     232             : template<typename Func>
     233             : void
     234           0 : ServoKeyframesRule::UpdateRule(Func aCallback)
     235             : {
     236           0 :   nsIDocument* doc = GetDocument();
     237           0 :   MOZ_AUTO_DOC_UPDATE(doc, UPDATE_STYLE, true);
     238             : 
     239           0 :   aCallback();
     240             : 
     241           0 :   if (StyleSheet* sheet = GetStyleSheet()) {
     242             :     // FIXME sheet->AsGecko()->SetModifiedByChildRule();
     243           0 :     if (doc) {
     244           0 :       doc->StyleRuleChanged(sheet, this);
     245             :     }
     246             :   }
     247           0 : }
     248             : 
     249             : NS_IMETHODIMP
     250           0 : ServoKeyframesRule::GetName(nsAString& aName)
     251             : {
     252           0 :   nsIAtom* name = Servo_KeyframesRule_GetName(mRawRule);
     253           0 :   aName = nsDependentAtomString(name);
     254           0 :   return NS_OK;
     255             : }
     256             : 
     257             : NS_IMETHODIMP
     258           0 : ServoKeyframesRule::SetName(const nsAString& aName)
     259             : {
     260           0 :   nsCOMPtr<nsIAtom> name = NS_Atomize(aName);
     261           0 :   nsIAtom* oldName = Servo_KeyframesRule_GetName(mRawRule);
     262           0 :   if (name == oldName) {
     263           0 :     return NS_OK;
     264             :   }
     265             : 
     266           0 :   UpdateRule([this, &name]() {
     267           0 :     Servo_KeyframesRule_SetName(mRawRule, name.forget().take());
     268           0 :   });
     269           0 :   return NS_OK;
     270             : }
     271             : 
     272             : NS_IMETHODIMP
     273           0 : ServoKeyframesRule::AppendRule(const nsAString& aRule)
     274             : {
     275           0 :   StyleSheet* sheet = GetStyleSheet();
     276           0 :   if (!sheet) {
     277             :     // We cannot parse the rule if we don't have a stylesheet.
     278           0 :     return NS_OK;
     279             :   }
     280             : 
     281           0 :   NS_ConvertUTF16toUTF8 rule(aRule);
     282           0 :   UpdateRule([this, sheet, &rule]() {
     283           0 :     bool parsedOk = Servo_KeyframesRule_AppendRule(
     284           0 :       mRawRule, sheet->AsServo()->RawContents(), &rule);
     285           0 :     if (parsedOk && mKeyframeList) {
     286           0 :       mKeyframeList->AppendRule();
     287             :     }
     288           0 :   });
     289           0 :   return NS_OK;
     290             : }
     291             : 
     292             : NS_IMETHODIMP
     293           0 : ServoKeyframesRule::DeleteRule(const nsAString& aKey)
     294             : {
     295           0 :   auto index = FindRuleIndexForKey(aKey);
     296           0 :   if (index == kRuleNotFound) {
     297           0 :     return NS_OK;
     298             :   }
     299             : 
     300           0 :   UpdateRule([this, index]() {
     301           0 :     Servo_KeyframesRule_DeleteRule(mRawRule, index);
     302           0 :     if (mKeyframeList) {
     303           0 :       mKeyframeList->RemoveRule(index);
     304             :     }
     305           0 :   });
     306           0 :   return NS_OK;
     307             : }
     308             : 
     309             : /* virtual */ void
     310           0 : ServoKeyframesRule::GetCssTextImpl(nsAString& aCssText) const
     311             : {
     312           0 :   Servo_KeyframesRule_GetCssText(mRawRule, &aCssText);
     313           0 : }
     314             : 
     315             : /* virtual */ dom::CSSRuleList*
     316           0 : ServoKeyframesRule::CssRules()
     317             : {
     318           0 :   if (!mKeyframeList) {
     319           0 :     mKeyframeList = new ServoKeyframeList(do_AddRef(mRawRule));
     320           0 :     mKeyframeList->SetParentRule(this);
     321           0 :     if (StyleSheet* sheet = GetStyleSheet()) {
     322           0 :       mKeyframeList->SetStyleSheet(sheet->AsServo());
     323             :     }
     324             :   }
     325           0 :   return mKeyframeList;
     326             : }
     327             : 
     328             : /* virtual */ dom::CSSKeyframeRule*
     329           0 : ServoKeyframesRule::FindRule(const nsAString& aKey)
     330             : {
     331           0 :   auto index = FindRuleIndexForKey(aKey);
     332           0 :   if (index != kRuleNotFound) {
     333             :     // Construct mKeyframeList but ignore the result.
     334           0 :     CssRules();
     335           0 :     return mKeyframeList->GetRule(index);
     336             :   }
     337           0 :   return nullptr;
     338             : }
     339             : 
     340             : /* virtual */ size_t
     341           0 : ServoKeyframesRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
     342             : {
     343           0 :   size_t n = aMallocSizeOf(this);
     344           0 :   n += GroupRule::SizeOfExcludingThis(aMallocSizeOf);
     345           0 :   if (mKeyframeList) {
     346           0 :     n += mKeyframeList->SizeOfIncludingThis(aMallocSizeOf);
     347             :   }
     348           0 :   return n;
     349             : }
     350             : 
     351             : } // namespace mozilla

Generated by: LCOV version 1.13