tor-browser

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

nsStubMutationObserver.cpp (6879B)


      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 /*
      8 * nsStubMutationObserver is an implementation of the nsIMutationObserver
      9 * interface (except for the methods on nsISupports) that is intended to be
     10 * used as a base class within the content/layout library.  All methods do
     11 * nothing.
     12 */
     13 
     14 #include "nsStubMutationObserver.h"
     15 
     16 #include "mozilla/RefCountType.h"
     17 #include "nsINode.h"
     18 #include "nsISupports.h"
     19 
     20 /******************************************************************************
     21 * nsStubMutationObserver
     22 *****************************************************************************/
     23 
     24 NS_IMPL_NSIMUTATIONOBSERVER_CORE_STUB(nsStubMutationObserver)
     25 NS_IMPL_NSIMUTATIONOBSERVER_CONTENT(nsStubMutationObserver)
     26 
     27 /******************************************************************************
     28 * MutationObserverWrapper
     29 *****************************************************************************/
     30 
     31 /**
     32 * @brief Wrapper class for a mutation observer that observes multiple nodes.
     33 *
     34 * This wrapper implements all methods of the nsIMutationObserver interface
     35 * and forwards all calls to its owner, which is an instance of
     36 * nsMultiMutationObserver.
     37 *
     38 * This class holds a reference to the owner and AddRefs/Releases its owner
     39 * as well to ensure lifetime.
     40 */
     41 class MutationObserverWrapper final : public nsIMutationObserver {
     42 public:
     43  NS_DECL_ISUPPORTS
     44 
     45  explicit MutationObserverWrapper(nsMultiMutationObserver* aOwner)
     46      : mOwner(aOwner) {}
     47 
     48  void CharacterDataWillChange(nsIContent* aContent,
     49                               const CharacterDataChangeInfo& aInfo) override {
     50    MOZ_ASSERT(mOwner);
     51    mOwner->CharacterDataWillChange(aContent, aInfo);
     52  }
     53 
     54  void CharacterDataChanged(nsIContent* aContent,
     55                            const CharacterDataChangeInfo& aInfo) override {
     56    MOZ_ASSERT(mOwner);
     57    mOwner->CharacterDataChanged(aContent, aInfo);
     58  }
     59 
     60  void AttributeWillChange(mozilla::dom::Element* aElement,
     61                           int32_t aNameSpaceID, nsAtom* aAttribute,
     62                           AttrModType aModType) override {
     63    MOZ_ASSERT(mOwner);
     64    mOwner->AttributeWillChange(aElement, aNameSpaceID, aAttribute, aModType);
     65  }
     66 
     67  void AttributeChanged(mozilla::dom::Element* aElement, int32_t aNameSpaceID,
     68                        nsAtom* aAttribute, AttrModType aModType,
     69                        const nsAttrValue* aOldValue) override {
     70    MOZ_ASSERT(mOwner);
     71    mOwner->AttributeChanged(aElement, aNameSpaceID, aAttribute, aModType,
     72                             aOldValue);
     73  }
     74 
     75  void AttributeSetToCurrentValue(mozilla::dom::Element* aElement,
     76                                  int32_t aNameSpaceID,
     77                                  nsAtom* aAttribute) override {
     78    MOZ_ASSERT(mOwner);
     79    mOwner->AttributeSetToCurrentValue(aElement, aNameSpaceID, aAttribute);
     80  }
     81 
     82  void ContentAppended(nsIContent* aFirstNewContent,
     83                       const ContentAppendInfo& aInfo) override {
     84    MOZ_ASSERT(mOwner);
     85    mOwner->ContentAppended(aFirstNewContent, aInfo);
     86  }
     87 
     88  void ContentInserted(nsIContent* aChild,
     89                       const ContentInsertInfo& aInfo) override {
     90    MOZ_ASSERT(mOwner);
     91    mOwner->ContentInserted(aChild, aInfo);
     92  }
     93 
     94  void ContentWillBeRemoved(nsIContent* aChild,
     95                            const ContentRemoveInfo& aInfo) override {
     96    MOZ_ASSERT(mOwner);
     97    mOwner->ContentWillBeRemoved(aChild, aInfo);
     98  }
     99 
    100  void NodeWillBeDestroyed(nsINode* aNode) override {
    101    MOZ_ASSERT(mOwner);
    102    AddRefWrapper();
    103    RefPtr<nsMultiMutationObserver> owner = mOwner;
    104    owner->NodeWillBeDestroyed(aNode);
    105    owner->RemoveMutationObserverFromNode(aNode);
    106    mOwner = nullptr;
    107    ReleaseWrapper();
    108  }
    109 
    110  void ParentChainChanged(nsIContent* aContent) override {
    111    MOZ_ASSERT(mOwner);
    112    mOwner->ParentChainChanged(aContent);
    113  }
    114 
    115  void ARIAAttributeDefaultWillChange(mozilla::dom::Element* aElement,
    116                                      nsAtom* aAttribute,
    117                                      AttrModType aModType) override {
    118    MOZ_ASSERT(mOwner);
    119    mOwner->ARIAAttributeDefaultWillChange(aElement, aAttribute, aModType);
    120  }
    121 
    122  void ARIAAttributeDefaultChanged(mozilla::dom::Element* aElement,
    123                                   nsAtom* aAttribute,
    124                                   AttrModType aModType) override {
    125    MOZ_ASSERT(mOwner);
    126    mOwner->ARIAAttributeDefaultChanged(aElement, aAttribute, aModType);
    127  }
    128 
    129  MozExternalRefCountType AddRefWrapper() {
    130    nsrefcnt count = ++mRefCnt;
    131    NS_LOG_ADDREF(this, count, "MutationObserverWrapper", sizeof(*this));
    132    return count;
    133  }
    134 
    135  MozExternalRefCountType ReleaseWrapper() {
    136    --mRefCnt;
    137    NS_LOG_RELEASE(this, mRefCnt, "MutationObserverWrapper");
    138    if (mRefCnt == 0) {
    139      mRefCnt = 1;
    140      delete this;
    141      return MozExternalRefCountType(0);
    142    }
    143    return mRefCnt;
    144  }
    145 
    146 private:
    147  ~MutationObserverWrapper() = default;
    148  nsMultiMutationObserver* mOwner{nullptr};
    149 };
    150 
    151 NS_IMPL_QUERY_INTERFACE(MutationObserverWrapper, nsIMutationObserver);
    152 
    153 MozExternalRefCountType MutationObserverWrapper::AddRef() {
    154  MOZ_ASSERT(mOwner);
    155  AddRefWrapper();
    156  mOwner->AddRef();
    157  return mRefCnt;
    158 }
    159 
    160 MozExternalRefCountType MutationObserverWrapper::Release() {
    161  MOZ_ASSERT(mOwner);
    162  mOwner->Release();
    163  return ReleaseWrapper();
    164 }
    165 
    166 /******************************************************************************
    167 * nsMultiMutationObserver
    168 *****************************************************************************/
    169 
    170 void nsMultiMutationObserver::AddMutationObserverToNode(nsINode* aNode) {
    171  if (!aNode) {
    172    return;
    173  }
    174  if (mWrapperForNode.Contains(aNode)) {
    175    return;
    176  }
    177  auto* newWrapper = new MutationObserverWrapper{this};
    178  newWrapper->AddRefWrapper();
    179  mWrapperForNode.InsertOrUpdate(aNode, newWrapper);
    180  aNode->AddMutationObserver(newWrapper);
    181 }
    182 
    183 void nsMultiMutationObserver::RemoveMutationObserverFromNode(nsINode* aNode) {
    184  if (!aNode) {
    185    return;
    186  }
    187 
    188  if (auto obs = mWrapperForNode.MaybeGet(aNode); obs.isSome()) {
    189    aNode->RemoveMutationObserver(*obs);
    190    mWrapperForNode.Remove(aNode);
    191    (*obs)->ReleaseWrapper();
    192  }
    193 }
    194 
    195 bool nsMultiMutationObserver::ContainsNode(const nsINode* aNode) const {
    196  return mWrapperForNode.Contains(const_cast<nsINode*>(aNode));
    197 }
    198 
    199 /******************************************************************************
    200 * nsStubMultiMutationObserver
    201 *****************************************************************************/
    202 
    203 NS_IMPL_NSIMUTATIONOBSERVER_CORE_STUB(nsStubMultiMutationObserver)
    204 NS_IMPL_NSIMUTATIONOBSERVER_CONTENT(nsStubMultiMutationObserver)