tor-browser

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

ServoElementSnapshot.h (4998B)


      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_ServoElementSnapshot_h
      8 #define mozilla_ServoElementSnapshot_h
      9 
     10 #include "AttrArray.h"
     11 #include "MainThreadUtils.h"
     12 #include "mozilla/TypedEnumBits.h"
     13 #include "mozilla/dom/BorrowedAttrInfo.h"
     14 #include "mozilla/dom/RustTypes.h"
     15 #include "nsAtom.h"
     16 #include "nsAttrName.h"
     17 #include "nsAttrValue.h"
     18 #include "nsChangeHint.h"
     19 #include "nsGkAtoms.h"
     20 
     21 namespace mozilla {
     22 namespace dom {
     23 class Element;
     24 }
     25 
     26 /**
     27 * A bitflags enum class used to determine what data does a ServoElementSnapshot
     28 * contains.
     29 */
     30 enum class ServoElementSnapshotFlags : uint8_t {
     31  State = 1 << 0,
     32  Attributes = 1 << 1,
     33  Id = 1 << 2,
     34  MaybeClass = 1 << 3,
     35  OtherPseudoClassState = 1 << 4,
     36  CustomState = 1 << 5,
     37 };
     38 
     39 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(ServoElementSnapshotFlags)
     40 
     41 /**
     42 * This class holds all non-tree-structural state of an element that might be
     43 * used for selector matching eventually.
     44 *
     45 * This means the attributes, and the element state, such as :hover, :active,
     46 * etc...
     47 */
     48 class ServoElementSnapshot {
     49  typedef dom::BorrowedAttrInfo BorrowedAttrInfo;
     50  typedef dom::Element Element;
     51 
     52  // TODO: Now that the element state shares a representation with rust we
     53  // should be able to do better and not use the internal type.
     54  typedef dom::ElementState::InternalType ServoStateType;
     55 
     56 public:
     57  typedef ServoElementSnapshotFlags Flags;
     58 
     59  explicit ServoElementSnapshot(const Element&);
     60 
     61  ~ServoElementSnapshot() {
     62    MOZ_ASSERT(NS_IsMainThread());
     63    MOZ_COUNT_DTOR(ServoElementSnapshot);
     64  }
     65 
     66  bool HasAttrs() const { return HasAny(Flags::Attributes); }
     67 
     68  bool HasState() const { return HasAny(Flags::State); }
     69 
     70  bool HasOtherPseudoClassState() const {
     71    return HasAny(Flags::OtherPseudoClassState);
     72  }
     73 
     74  /**
     75   * Captures the given state (if not previously captured).
     76   */
     77  void AddState(dom::ElementState aState) {
     78    if (!HasAny(Flags::State)) {
     79      mState = aState.GetInternalValue();
     80      mContains |= Flags::State;
     81    }
     82  }
     83 
     84  /**
     85   * Captures the given element attributes (if not previously captured).
     86   *
     87   * The attribute name and namespace are used to note which kind of attribute
     88   * has changed.
     89   */
     90  void AddAttrs(const Element&, int32_t aNameSpaceID, nsAtom* aAttribute);
     91 
     92  /**
     93   * Captures the given element custom states.
     94   */
     95  void AddCustomStates(Element&);
     96 
     97  /**
     98   * Captures some other pseudo-class matching state not included in
     99   * ElementState.
    100   */
    101  void AddOtherPseudoClassState(const Element&);
    102 
    103  /**
    104   * Needed methods for attribute matching.
    105   */
    106  BorrowedAttrInfo GetAttrInfoAt(uint32_t aIndex) const {
    107    MOZ_ASSERT(HasAttrs());
    108    if (aIndex >= mAttrs.Length()) {
    109      return BorrowedAttrInfo(nullptr, nullptr);
    110    }
    111    return BorrowedAttrInfo(&mAttrs[aIndex].mName, &mAttrs[aIndex].mValue);
    112  }
    113 
    114  const nsAttrValue* GetParsedAttr(nsAtom* aLocalName) const {
    115    return GetParsedAttr(aLocalName, kNameSpaceID_None);
    116  }
    117 
    118  const nsAttrValue* GetParsedAttr(nsAtom* aLocalName,
    119                                   int32_t aNamespaceID) const {
    120    MOZ_ASSERT(HasAttrs());
    121    uint32_t i, len = mAttrs.Length();
    122    if (aNamespaceID == kNameSpaceID_None) {
    123      // This should be the common case so lets make an optimized loop
    124      for (i = 0; i < len; ++i) {
    125        if (mAttrs[i].mName.Equals(aLocalName)) {
    126          return &mAttrs[i].mValue;
    127        }
    128      }
    129 
    130      return nullptr;
    131    }
    132 
    133    for (i = 0; i < len; ++i) {
    134      if (mAttrs[i].mName.Equals(aLocalName, aNamespaceID)) {
    135        return &mAttrs[i].mValue;
    136      }
    137    }
    138 
    139    return nullptr;
    140  }
    141 
    142  bool IsInChromeDocument() const { return mIsInChromeDocument; }
    143  bool SupportsLangAttr() const { return mSupportsLangAttr; }
    144 
    145  bool HasAny(Flags aFlags) const { return bool(mContains & aFlags); }
    146 
    147  bool IsTableBorderNonzero() const {
    148    MOZ_ASSERT(HasOtherPseudoClassState());
    149    return mIsTableBorderNonzero;
    150  }
    151 
    152  bool IsSelectListBox() const {
    153    MOZ_ASSERT(HasOtherPseudoClassState());
    154    return mIsSelectListBox;
    155  }
    156 
    157 private:
    158  // TODO: Profile, a 1 or 2 element AutoTArray could be worth it, given we know
    159  // we're dealing with attribute changes when we take snapshots of attributes,
    160  // though it can be wasted space if we deal with a lot of state-only
    161  // snapshots.
    162  nsTArray<AttrArray::InternalAttr> mAttrs;
    163  nsTArray<RefPtr<nsAtom>> mChangedAttrNames;
    164  nsTArray<RefPtr<nsAtom>> mCustomStates;
    165  nsAttrValue mClass;
    166  ServoStateType mState;
    167  Flags mContains;
    168  bool mIsInChromeDocument : 1;
    169  bool mSupportsLangAttr : 1;
    170  bool mIsTableBorderNonzero : 1;
    171  bool mIsSelectListBox : 1;
    172  bool mClassAttributeChanged : 1;
    173  bool mIdAttributeChanged : 1;
    174 };
    175 
    176 }  // namespace mozilla
    177 
    178 #endif