tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

AnimatedPropertyIDSet.h (7387B)


      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 #ifndef mozilla_AnimatedPropertyIDSet_h
      8 #define mozilla_AnimatedPropertyIDSet_h
      9 
     10 #include "CSSPropertyId.h"
     11 #include "mozilla/ServoBindings.h"
     12 #include "nsCSSPropertyIDSet.h"
     13 #include "nsTHashSet.h"
     14 
     15 namespace mozilla {
     16 
     17 class AnimatedPropertyIDSet {
     18 public:
     19  using CustomNameSet = nsTHashSet<RefPtr<nsAtom>>;
     20 
     21  AnimatedPropertyIDSet() = default;
     22  AnimatedPropertyIDSet(AnimatedPropertyIDSet&& aOther) = default;
     23  AnimatedPropertyIDSet(nsCSSPropertyIDSet&& aIDs, CustomNameSet&& aNames)
     24      : mIDs(std::move(aIDs)), mCustomNames(std::move(aNames)) {}
     25 
     26  AnimatedPropertyIDSet& operator=(AnimatedPropertyIDSet&& aRhs) {
     27    MOZ_ASSERT(&aRhs != this);
     28    this->~AnimatedPropertyIDSet();
     29    new (this) AnimatedPropertyIDSet(std::move(aRhs));
     30    return *this;
     31  }
     32 
     33  void AddProperty(const CSSPropertyId& aProperty) {
     34    if (aProperty.IsCustom()) {
     35      mCustomNames.Insert(aProperty.mCustomName);
     36    } else {
     37      mIDs.AddProperty(aProperty.mId);
     38    }
     39  }
     40 
     41  void RemoveProperty(const CSSPropertyId& aProperty) {
     42    if (aProperty.IsCustom()) {
     43      mCustomNames.Remove(aProperty.mCustomName);
     44    } else {
     45      mIDs.RemoveProperty(aProperty.mId);
     46    }
     47  }
     48 
     49  bool HasProperty(const CSSPropertyId& aProperty) const {
     50    if (aProperty.IsCustom()) {
     51      return mCustomNames.Contains(aProperty.mCustomName);
     52    }
     53    return mIDs.HasProperty(aProperty.mId);
     54  }
     55 
     56  bool Intersects(const nsCSSPropertyIDSet& aIDs) const {
     57    return mIDs.Intersects(aIDs);
     58  }
     59 
     60  bool IsSubsetOf(const AnimatedPropertyIDSet& aOther) const {
     61    if (!mIDs.IsSubsetOf(aOther.mIDs) ||
     62        mCustomNames.Count() > aOther.mCustomNames.Count()) {
     63      return false;
     64    }
     65    for (const auto& name : mCustomNames) {
     66      if (!aOther.mCustomNames.Contains(name)) {
     67        return false;
     68      }
     69    }
     70    return true;
     71  }
     72 
     73  bool IsEmpty() const { return mIDs.IsEmpty() && mCustomNames.IsEmpty(); }
     74 
     75  void AddProperties(const AnimatedPropertyIDSet& aOther) {
     76    mIDs |= aOther.mIDs;
     77    for (const auto& name : aOther.mCustomNames) {
     78      mCustomNames.Insert(name);
     79    }
     80  }
     81 
     82  // Returns a new nsCSSPropertyIDSet with all properties that are both in this
     83  // set and |aOther|.
     84  nsCSSPropertyIDSet Intersect(const nsCSSPropertyIDSet& aOther) const {
     85    return mIDs.Intersect(aOther);
     86  }
     87 
     88  // Returns a new AnimatedPropertyIDSet with all properties that are both in
     89  // this set and |aOther|.
     90  AnimatedPropertyIDSet Intersect(const AnimatedPropertyIDSet& aOther) const {
     91    nsCSSPropertyIDSet ids = mIDs.Intersect(aOther.mIDs);
     92    CustomNameSet names;
     93    for (const auto& name : mCustomNames) {
     94      if (!aOther.mCustomNames.Contains(name)) {
     95        continue;
     96      }
     97      names.Insert(name);
     98    }
     99    return AnimatedPropertyIDSet(std::move(ids), std::move(names));
    100  }
    101 
    102  // Returns a new AnimatedPropertyIDSet with all properties that are in either
    103  // this set or |aOther| but not both.
    104  AnimatedPropertyIDSet Xor(const AnimatedPropertyIDSet& aOther) const {
    105    nsCSSPropertyIDSet ids = mIDs.Xor(aOther.mIDs);
    106    CustomNameSet names;
    107    for (const auto& name : mCustomNames) {
    108      if (aOther.mCustomNames.Contains(name)) {
    109        continue;
    110      }
    111      names.Insert(name);
    112    }
    113 
    114    for (const auto& name : aOther.mCustomNames) {
    115      if (mCustomNames.Contains(name)) {
    116        continue;
    117      }
    118      names.Insert(name);
    119    }
    120    return AnimatedPropertyIDSet(std::move(ids), std::move(names));
    121  }
    122 
    123  // Iterator for use in range-based for loops
    124  class Iterator {
    125   public:
    126    Iterator(Iterator&& aOther)
    127        : mPropertySet(aOther.mPropertySet),
    128          mIDIterator(std::move(aOther.mIDIterator)),
    129          mCustomNameIterator(std::move(aOther.mCustomNameIterator)),
    130          mPropertyId(eCSSProperty_UNKNOWN) {}
    131    Iterator() = delete;
    132    Iterator(const Iterator&) = delete;
    133    Iterator& operator=(const Iterator&) = delete;
    134    Iterator& operator=(const Iterator&&) = delete;
    135 
    136    static Iterator BeginIterator(const AnimatedPropertyIDSet& aPropertySet) {
    137      return Iterator(aPropertySet, aPropertySet.mIDs.begin(),
    138                      aPropertySet.mCustomNames.begin());
    139    }
    140 
    141    static Iterator EndIterator(const AnimatedPropertyIDSet& aPropertySet) {
    142      return Iterator(aPropertySet, aPropertySet.mIDs.end(),
    143                      aPropertySet.mCustomNames.end());
    144    }
    145 
    146    bool operator!=(const Iterator& aOther) const {
    147      return mIDIterator != aOther.mIDIterator ||
    148             mCustomNameIterator != aOther.mCustomNameIterator;
    149    }
    150 
    151    Iterator& operator++() {
    152      MOZ_ASSERT(mIDIterator != mPropertySet.mIDs.end() ||
    153                     mCustomNameIterator != mPropertySet.mCustomNames.end(),
    154                 "Should not iterate beyond end");
    155      if (mIDIterator != mPropertySet.mIDs.end()) {
    156        ++mIDIterator;
    157      } else {
    158        ++mCustomNameIterator;
    159      }
    160      return *this;
    161    }
    162 
    163    CSSPropertyId operator*() {
    164      if (mIDIterator != mPropertySet.mIDs.end()) {
    165        mPropertyId.mId = *mIDIterator;
    166        mPropertyId.mCustomName = nullptr;
    167      } else if (mCustomNameIterator != mPropertySet.mCustomNames.end()) {
    168        mPropertyId.mId = eCSSPropertyExtra_variable;
    169        mPropertyId.mCustomName = *mCustomNameIterator;
    170      } else {
    171        MOZ_ASSERT_UNREACHABLE("Should not dereference beyond end");
    172        mPropertyId.mId = eCSSProperty_UNKNOWN;
    173        mPropertyId.mCustomName = nullptr;
    174      }
    175      return mPropertyId;
    176    }
    177 
    178   private:
    179    Iterator(const AnimatedPropertyIDSet& aPropertySet,
    180             nsCSSPropertyIDSet::Iterator aIDIterator,
    181             CustomNameSet::const_iterator aCustomNameIterator)
    182        : mPropertySet(aPropertySet),
    183          mIDIterator(std::move(aIDIterator)),
    184          mCustomNameIterator(std::move(aCustomNameIterator)),
    185          mPropertyId(eCSSProperty_UNKNOWN) {}
    186 
    187    const AnimatedPropertyIDSet& mPropertySet;
    188    nsCSSPropertyIDSet::Iterator mIDIterator;
    189    CustomNameSet::const_iterator mCustomNameIterator;
    190    CSSPropertyId mPropertyId;
    191  };
    192 
    193  Iterator begin() const { return Iterator::BeginIterator(*this); }
    194  Iterator end() const { return Iterator::EndIterator(*this); }
    195 
    196 private:
    197  AnimatedPropertyIDSet(const AnimatedPropertyIDSet&) = delete;
    198  AnimatedPropertyIDSet& operator=(const AnimatedPropertyIDSet&) = delete;
    199 
    200  nsCSSPropertyIDSet mIDs;
    201  CustomNameSet mCustomNames;
    202 };
    203 
    204 // A wrapper to support the inversion of AnimatedPropertyIDSet.
    205 //
    206 // We are using this struct (for convenience) to check if we should skip the
    207 // AnimatedPropertyIDs when composing an animation rule, on either
    208 // CascadeLevel::Animations or CascadeLevel::Tranistions.
    209 struct InvertibleAnimatedPropertyIDSet {
    210  const AnimatedPropertyIDSet* mSet = nullptr;
    211  bool mIsInverted = false;
    212 
    213  void Setup(const AnimatedPropertyIDSet* aSet, bool aIsInverted) {
    214    mSet = aSet;
    215    mIsInverted = aIsInverted;
    216  }
    217 
    218  bool HasProperty(const CSSPropertyId& aProperty) const {
    219    return mSet && mIsInverted != mSet->HasProperty(aProperty);
    220  }
    221 };
    222 
    223 }  // namespace mozilla
    224 
    225 #endif  // mozilla_AnimatedPropertyIDSet_h