tor-browser

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

CSSKeyframeRule.cpp (6307B)


      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/dom/CSSKeyframeRule.h"
      8 
      9 #include "mozilla/DeclarationBlock.h"
     10 #include "mozilla/dom/CSSKeyframeRuleBinding.h"
     11 #include "nsDOMCSSDeclaration.h"
     12 
     13 namespace mozilla::dom {
     14 
     15 // -------------------------------------------
     16 // CSSKeyframeDeclaration
     17 //
     18 
     19 class CSSKeyframeDeclaration final : public nsDOMCSSDeclaration {
     20 public:
     21  explicit CSSKeyframeDeclaration(CSSKeyframeRule* aRule) : mRule(aRule) {
     22    mDecls =
     23        new DeclarationBlock(Servo_Keyframe_GetStyle(aRule->Raw()).Consume());
     24    mDecls->SetOwningRule(aRule);
     25  }
     26 
     27  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
     28  NS_DECL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS_AMBIGUOUS(CSSKeyframeDeclaration,
     29                                                        nsICSSDeclaration)
     30 
     31  css::Rule* GetParentRule() final { return mRule; }
     32 
     33  void DropReference() {
     34    mRule = nullptr;
     35    mDecls->SetOwningRule(nullptr);
     36  }
     37 
     38  DeclarationBlock* GetOrCreateCSSDeclaration(
     39      Operation aOperation, DeclarationBlock** aCreated) final {
     40    if (aOperation != Operation::Read && mRule) {
     41      if (StyleSheet* sheet = mRule->GetStyleSheet()) {
     42        sheet->WillDirty();
     43      }
     44    }
     45    return mDecls;
     46  }
     47  nsresult SetCSSDeclaration(DeclarationBlock* aDecls,
     48                             MutationClosureData* aClosureData) final {
     49    if (!mRule) {
     50      return NS_OK;
     51    }
     52    mRule->UpdateRule([this, aDecls]() {
     53      if (mDecls != aDecls) {
     54        mDecls->SetOwningRule(nullptr);
     55        mDecls = aDecls;
     56        mDecls->SetOwningRule(mRule);
     57        Servo_Keyframe_SetStyle(mRule->Raw(), mDecls->Raw());
     58      }
     59    });
     60    return NS_OK;
     61  }
     62  ParsingEnvironment GetParsingEnvironment(
     63      nsIPrincipal* aSubjectPrincipal) const final {
     64    return GetParsingEnvironmentForRule(mRule, StyleCssRuleType::Keyframe);
     65  }
     66 
     67  nsINode* GetAssociatedNode() const final {
     68    return mRule ? mRule->GetAssociatedDocumentOrShadowRoot() : nullptr;
     69  }
     70 
     71  nsISupports* GetParentObject() const final {
     72    return mRule ? mRule->GetParentObject() : nullptr;
     73  }
     74 
     75  size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const {
     76    size_t n = aMallocSizeOf(this);
     77    // TODO we may want to add size of mDecls as well
     78    return n;
     79  }
     80 
     81  void SetRawAfterClone(StyleLockedKeyframe* aKeyframe) {
     82    mDecls->SetOwningRule(nullptr);
     83    mDecls = new DeclarationBlock(Servo_Keyframe_GetStyle(aKeyframe).Consume());
     84    mDecls->SetOwningRule(mRule);
     85  }
     86 
     87 private:
     88  virtual ~CSSKeyframeDeclaration() {
     89    MOZ_ASSERT(!mRule, "Backpointer should have been cleared");
     90  }
     91 
     92  CSSKeyframeRule* mRule;
     93  RefPtr<DeclarationBlock> mDecls;
     94 };
     95 
     96 NS_IMPL_CYCLE_COLLECTING_ADDREF(CSSKeyframeDeclaration)
     97 NS_IMPL_CYCLE_COLLECTING_RELEASE(CSSKeyframeDeclaration)
     98 
     99 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(CSSKeyframeDeclaration)
    100 
    101 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(CSSKeyframeDeclaration)
    102  NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
    103 NS_INTERFACE_MAP_END_INHERITING(nsDOMCSSDeclaration)
    104 
    105 // -------------------------------------------
    106 // CSSKeyframeRule
    107 //
    108 
    109 CSSKeyframeRule::CSSKeyframeRule(already_AddRefed<StyleLockedKeyframe> aRaw,
    110                                 StyleSheet* aSheet, css::Rule* aParentRule,
    111                                 uint32_t aLine, uint32_t aColumn)
    112    : css::Rule(aSheet, aParentRule, aLine, aColumn), mRaw(aRaw) {}
    113 
    114 CSSKeyframeRule::~CSSKeyframeRule() {
    115  if (mDeclaration) {
    116    mDeclaration->DropReference();
    117  }
    118 }
    119 
    120 NS_IMPL_ADDREF_INHERITED(CSSKeyframeRule, css::Rule)
    121 NS_IMPL_RELEASE_INHERITED(CSSKeyframeRule, css::Rule)
    122 
    123 // QueryInterface implementation for nsCSSKeyframeRule
    124 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(CSSKeyframeRule)
    125 NS_INTERFACE_MAP_END_INHERITING(css::Rule)
    126 
    127 NS_IMPL_CYCLE_COLLECTION_CLASS(CSSKeyframeRule)
    128 
    129 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(CSSKeyframeRule, css::Rule)
    130  if (tmp->mDeclaration) {
    131    tmp->mDeclaration->DropReference();
    132    tmp->mDeclaration = nullptr;
    133  }
    134 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
    135 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(CSSKeyframeRule, css::Rule)
    136  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDeclaration)
    137 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
    138 
    139 bool CSSKeyframeRule::IsCCLeaf() const {
    140  return Rule::IsCCLeaf() && !mDeclaration;
    141 }
    142 
    143 StyleCssRuleType CSSKeyframeRule::Type() const {
    144  return StyleCssRuleType::Keyframe;
    145 }
    146 
    147 void CSSKeyframeRule::SetRawAfterClone(RefPtr<StyleLockedKeyframe> aRaw) {
    148  mRaw = std::move(aRaw);
    149 
    150  if (mDeclaration) {
    151    mDeclaration->SetRawAfterClone(mRaw);
    152  }
    153 }
    154 
    155 #ifdef DEBUG
    156 /* virtual */
    157 void CSSKeyframeRule::List(FILE* out, int32_t aIndent) const {
    158  nsAutoCString str;
    159  for (int32_t i = 0; i < aIndent; i++) {
    160    str.AppendLiteral("  ");
    161  }
    162  Servo_Keyframe_Debug(mRaw, &str);
    163  fprintf_stderr(out, "%s\n", str.get());
    164 }
    165 #endif
    166 
    167 template <typename Func>
    168 void CSSKeyframeRule::UpdateRule(Func aCallback) {
    169  if (IsReadOnly()) {
    170    return;
    171  }
    172 
    173  StyleSheet* sheet = GetStyleSheet();
    174  if (sheet) {
    175    sheet->WillDirty();
    176  }
    177 
    178  aCallback();
    179 
    180  if (sheet) {
    181    sheet->RuleChanged(this, StyleRuleChangeKind::Generic);
    182  }
    183 }
    184 
    185 void CSSKeyframeRule::GetKeyText(nsACString& aKeyText) {
    186  Servo_Keyframe_GetKeyText(mRaw, &aKeyText);
    187 }
    188 
    189 void CSSKeyframeRule::SetKeyText(const nsACString& aKeyText) {
    190  UpdateRule(
    191      [this, &aKeyText]() { Servo_Keyframe_SetKeyText(mRaw, &aKeyText); });
    192 }
    193 
    194 void CSSKeyframeRule::GetCssText(nsACString& aCssText) const {
    195  Servo_Keyframe_GetCssText(mRaw, &aCssText);
    196 }
    197 
    198 nsDOMCSSDeclaration* CSSKeyframeRule::Style() {
    199  if (!mDeclaration) {
    200    mDeclaration = new CSSKeyframeDeclaration(this);
    201  }
    202  return mDeclaration;
    203 }
    204 
    205 size_t CSSKeyframeRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const {
    206  size_t n = aMallocSizeOf(this);
    207  if (mDeclaration) {
    208    n += mDeclaration->SizeOfIncludingThis(aMallocSizeOf);
    209  }
    210  return n;
    211 }
    212 
    213 /* virtual */
    214 JSObject* CSSKeyframeRule::WrapObject(JSContext* aCx,
    215                                      JS::Handle<JSObject*> aGivenProto) {
    216  return CSSKeyframeRule_Binding::Wrap(aCx, this, aGivenProto);
    217 }
    218 
    219 }  // namespace mozilla::dom