tor-browser

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

FragmentOrElement.h (12223B)


      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 * Base class for all element classes as well as nsDocumentFragment.  This
      9 * provides an implementation of nsINode, implements nsIContent, provides
     10 * utility methods for subclasses, and so forth.
     11 */
     12 
     13 #ifndef FragmentOrElement_h___
     14 #define FragmentOrElement_h___
     15 
     16 #include "mozilla/Attributes.h"
     17 #include "mozilla/EnumSet.h"
     18 #include "mozilla/MemoryReporting.h"
     19 #include "mozilla/UniquePtr.h"
     20 #include "mozilla/dom/RadioGroupContainer.h"
     21 #include "nsAtomHashKeys.h"
     22 #include "nsCycleCollectionParticipant.h"  // NS_DECL_CYCLE_*
     23 #include "nsIContent.h"                    // base class
     24 #include "nsIHTMLCollection.h"
     25 #include "nsIWeakReferenceUtils.h"
     26 
     27 class ContentUnbinder;
     28 class nsContentList;
     29 class nsLabelsNodeList;
     30 class nsDOMAttributeMap;
     31 class nsDOMTokenList;
     32 class nsIControllers;
     33 class nsDOMCSSAttributeDeclaration;
     34 class nsDOMCSSDeclaration;
     35 class nsDOMStringMap;
     36 class nsIURI;
     37 
     38 namespace mozilla {
     39 class DeclarationBlock;
     40 enum class ContentRelevancyReason;
     41 using ContentRelevancy = EnumSet<ContentRelevancyReason, uint8_t>;
     42 class ElementAnimationData;
     43 namespace dom {
     44 struct CustomElementData;
     45 class Element;
     46 class PopoverData;
     47 class StylePropertyMap;
     48 class StylePropertyMapReadOnly;
     49 }  // namespace dom
     50 }  // namespace mozilla
     51 
     52 /**
     53 * Tearoff to use for nodes to implement nsISupportsWeakReference
     54 */
     55 class nsNodeSupportsWeakRefTearoff final : public nsISupportsWeakReference {
     56 public:
     57  explicit nsNodeSupportsWeakRefTearoff(nsINode* aNode) : mNode(aNode) {}
     58 
     59  // nsISupports
     60  NS_DECL_CYCLE_COLLECTING_ISUPPORTS_FINAL
     61 
     62  // nsISupportsWeakReference
     63  NS_DECL_NSISUPPORTSWEAKREFERENCE
     64 
     65  NS_DECL_CYCLE_COLLECTION_CLASS(nsNodeSupportsWeakRefTearoff)
     66 
     67 private:
     68  ~nsNodeSupportsWeakRefTearoff() = default;
     69 
     70  nsCOMPtr<nsINode> mNode;
     71 };
     72 
     73 /**
     74 * A generic base class for DOM elements and document fragments,
     75 * implementing many nsIContent, nsINode and Element methods.
     76 */
     77 namespace mozilla::dom {
     78 
     79 class DOMIntersectionObserver;
     80 class ShadowRoot;
     81 
     82 class FragmentOrElement : public nsIContent {
     83 public:
     84  explicit FragmentOrElement(
     85      already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
     86  explicit FragmentOrElement(
     87      already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
     88 
     89  // We want to avoid the overhead of extra function calls for
     90  // refcounting when we're not doing refcount logging, so we can't
     91  // NS_DECL_ISUPPORTS_INHERITED.
     92  NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr) override;
     93  NS_INLINE_DECL_REFCOUNTING_INHERITED(FragmentOrElement, nsIContent);
     94 
     95  NS_DECL_ADDSIZEOFEXCLUDINGTHIS
     96 
     97  // nsINode interface methods
     98  virtual void GetTextContentInternal(nsAString& aTextContent,
     99                                      mozilla::OOMReporter& aError) override;
    100  virtual void SetTextContentInternal(
    101      const nsAString& aTextContent, nsIPrincipal* aSubjectPrincipal,
    102      mozilla::ErrorResult& aError,
    103      MutationEffectOnScript aMutationEffectOnScript) override;
    104 
    105  // nsIContent interface methods
    106  const CharacterDataBuffer* GetCharacterDataBuffer() const override;
    107  uint32_t TextLength() const override;
    108  bool TextIsOnlyWhitespace() override;
    109  bool ThreadSafeTextIsOnlyWhitespace() const override;
    110 
    111  void DestroyContent() override;
    112  void SaveSubtreeState() override;
    113 
    114  nsIHTMLCollection* Children();
    115  uint32_t ChildElementCount() {
    116    if (!HasChildren()) {
    117      return 0;
    118    }
    119    return Children()->Length();
    120  }
    121 
    122  RadioGroupContainer& OwnedRadioGroupContainer() {
    123    auto* slots = ExtendedDOMSlots();
    124    if (!slots->mRadioGroupContainer) {
    125      slots->mRadioGroupContainer = MakeUnique<RadioGroupContainer>();
    126    }
    127    return *slots->mRadioGroupContainer;
    128  }
    129 
    130 public:
    131  NS_DECL_CYCLE_COLLECTION_SKIPPABLE_WRAPPERCACHE_CLASS_INHERITED(
    132      FragmentOrElement, nsIContent)
    133 
    134  static void ClearContentUnbinder();
    135  static bool CanSkip(nsINode* aNode, bool aRemovingAllowed);
    136  static bool CanSkipInCC(nsINode* aNode);
    137  static bool CanSkipThis(nsINode* aNode);
    138  static void RemoveBlackMarkedNode(nsINode* aNode);
    139  static void MarkNodeChildren(nsINode* aNode);
    140  static void InitCCCallbacks();
    141 
    142  /**
    143   * Is the HTML local name a void element?
    144   */
    145  static bool IsHTMLVoid(const nsAtom* aLocalName);
    146 
    147 protected:
    148  virtual ~FragmentOrElement();
    149 
    150  /**
    151   * Dummy CopyInnerTo so that we can use the same macros for
    152   * Elements and DocumentFragments.
    153   */
    154  nsresult CopyInnerTo(FragmentOrElement* aDest) { return NS_OK; }
    155 
    156 public:
    157  /**
    158   * There are a set of DOM- and scripting-specific instance variables
    159   * that may only be instantiated when a content object is accessed
    160   * through the DOM. Rather than burn actual slots in the content
    161   * objects for each of these instance variables, we put them off
    162   * in a side structure that's only allocated when the content is
    163   * accessed through the DOM.
    164   */
    165 
    166  class nsExtendedDOMSlots : public nsIContent::nsExtendedContentSlots {
    167   public:
    168    nsExtendedDOMSlots();
    169    ~nsExtendedDOMSlots();
    170 
    171    void TraverseExtendedSlots(nsCycleCollectionTraversalCallback&) final;
    172    void UnlinkExtendedSlots(nsIContent&) final;
    173 
    174    size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const final;
    175 
    176    /**
    177     * SMIL Overridde style rules (for SMIL animation of CSS properties)
    178     * @see Element::GetSMILOverrideStyle
    179     */
    180    RefPtr<nsDOMCSSAttributeDeclaration> mSMILOverrideStyle;
    181 
    182    /**
    183     * Holds any SMIL override style declaration for this element.
    184     */
    185    RefPtr<DeclarationBlock> mSMILOverrideStyleDeclaration;
    186 
    187    /**
    188     * The controllers of the XUL Element.
    189     */
    190    nsCOMPtr<nsIControllers> mControllers;
    191 
    192    /**
    193     * An object implementing the .labels property for this element.
    194     */
    195    RefPtr<nsLabelsNodeList> mLabelsList;
    196 
    197    /**
    198     * ShadowRoot bound to the element.
    199     */
    200    RefPtr<ShadowRoot> mShadowRoot;
    201 
    202    /**
    203     * Web components custom element data.
    204     */
    205    UniquePtr<CustomElementData> mCustomElementData;
    206 
    207    /**
    208     * Web animations data.
    209     */
    210    UniquePtr<ElementAnimationData> mAnimations;
    211 
    212    /**
    213     * PopoverData for the element.
    214     */
    215    UniquePtr<PopoverData> mPopoverData;
    216 
    217    /**
    218     * The association to a popover that this element was the source
    219     * showing a popover, e.g. the source in `el.showPopover({source})`.
    220     */
    221    nsWeakPtr mAssociatedPopover;
    222 
    223    /**
    224     * CustomStates for the element.
    225     */
    226    nsTArray<RefPtr<nsAtom>> mCustomStates;
    227 
    228    /**
    229     * RadioGroupContainer for radio buttons grouped under this disconnected
    230     * element.
    231     */
    232    UniquePtr<RadioGroupContainer> mRadioGroupContainer;
    233 
    234    /**
    235     * Last remembered size (in CSS pixels) for the element.
    236     * @see {@link https://drafts.csswg.org/css-sizing-4/#last-remembered}
    237     */
    238    Maybe<float> mLastRememberedBSize;
    239    Maybe<float> mLastRememberedISize;
    240 
    241    /**
    242     * Whether the content of this element is relevant for the purposes
    243     * of `content-visibility: auto.
    244     * Reflects 'relevant to the user' concept, see
    245     * https://drafts.csswg.org/css-contain/#relevant-to-the-user.
    246     */
    247    Maybe<ContentRelevancy> mContentRelevancy;
    248 
    249    /**
    250     * Whether the content of this element is considered visible for
    251     * the purposes of `content-visibility: auto.
    252     * Reflects 'proximity to the viewport' concept, see
    253     * https://drafts.csswg.org/css-contain/#proximity-to-the-viewport.
    254     */
    255    Maybe<bool> mVisibleForContentVisibility;
    256 
    257    /**
    258     * Whether content-visibility: auto is temporarily visible for
    259     * the purposes of the descendant of scrollIntoView.
    260     */
    261    bool mTemporarilyVisibleForScrolledIntoViewDescendant = false;
    262 
    263    /**
    264     * The .dataset attribute.
    265     * @see nsGenericHTMLElement::GetDataset
    266     */
    267    nsDOMStringMap* MOZ_UNSAFE_REF("ClearDataSet clears it") mDataset = nullptr;
    268 
    269    /** An object implementing the .part property for this element. */
    270    RefPtr<nsDOMTokenList> mPart;
    271 
    272    /**
    273     * Explicitly set attr-element, see
    274     * https://html.spec.whatwg.org/#explicitly-set-attr-element
    275     */
    276    nsTHashMap<RefPtr<nsAtom>, nsWeakPtr> mExplicitlySetAttrElementMap;
    277    /**
    278     * Explicitly set attr-elements, see
    279     * https://html.spec.whatwg.org/#explicitly-set-attr-elements
    280     *
    281     * The first member of the pair are the explicitly set attr-elements. The
    282     * second member is the cached attr-associated elements.
    283     */
    284 
    285    nsTHashMap<RefPtr<nsAtom>, std::pair<Maybe<nsTArray<nsWeakPtr>>,
    286                                         Maybe<nsTArray<RefPtr<Element>>>>>
    287        mAttrElementsMap;
    288  };
    289 
    290  class nsDOMSlots : public nsIContent::nsContentSlots {
    291   public:
    292    nsDOMSlots();
    293    ~nsDOMSlots();
    294 
    295    void Traverse(nsCycleCollectionTraversalCallback&) final;
    296    void Unlink(nsINode&) final;
    297 
    298    size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
    299 
    300    /**
    301     * The .style attribute (an interface that forwards to the actual
    302     * style rules)
    303     * @see nsGenericHTMLElement::GetStyle
    304     */
    305    nsCOMPtr<nsDOMCSSDeclaration> mStyle;
    306 
    307    /**
    308     * @see Element::Attributes
    309     */
    310    RefPtr<nsDOMAttributeMap> mAttributeMap;
    311 
    312    /**
    313     * An object implementing the .children property for this element.
    314     */
    315    RefPtr<nsContentList> mChildrenList;
    316 
    317    /**
    318     * An object implementing the .classList property for this element.
    319     */
    320    RefPtr<nsDOMTokenList> mClassList;
    321 
    322    /**
    323     * An object implementing the .computedStyleMap() method for this element.
    324     */
    325    RefPtr<StylePropertyMapReadOnly> mComputedStyleMap;
    326 
    327    /**
    328     * An object implementing the .attributeStyleMap property for this element.
    329     */
    330    RefPtr<StylePropertyMap> mAttributeStyleMap;
    331  };
    332 
    333  /**
    334   * In case ExtendedDOMSlots is needed before normal DOMSlots, an instance of
    335   * FatSlots class, which combines those two slot types, is created.
    336   * This way we can avoid extra allocation for ExtendedDOMSlots.
    337   * FatSlots is useful for example when creating Custom Elements.
    338   */
    339  class FatSlots final : public nsDOMSlots, public nsExtendedDOMSlots {
    340   public:
    341    FatSlots() : nsDOMSlots(), nsExtendedDOMSlots() {
    342      MOZ_COUNT_CTOR(FatSlots);
    343      SetExtendedContentSlots(this, false);
    344    }
    345 
    346    ~FatSlots() final { MOZ_COUNT_DTOR(FatSlots); }
    347  };
    348 
    349 protected:
    350  void GetMarkup(bool aIncludeSelf, nsAString& aMarkup);
    351  void SetInnerHTMLInternal(const nsAString& aInnerHTML, ErrorResult& aError);
    352 
    353  // Override from nsINode
    354  nsIContent::nsContentSlots* CreateSlots() override {
    355    return new nsDOMSlots();
    356  }
    357 
    358  nsIContent::nsExtendedContentSlots* CreateExtendedSlots() final {
    359    return new nsExtendedDOMSlots();
    360  }
    361 
    362  nsDOMSlots* DOMSlots() { return static_cast<nsDOMSlots*>(Slots()); }
    363 
    364  nsDOMSlots* GetExistingDOMSlots() const {
    365    return static_cast<nsDOMSlots*>(GetExistingSlots());
    366  }
    367 
    368  nsExtendedDOMSlots* ExtendedDOMSlots() {
    369    nsContentSlots* slots = GetExistingContentSlots();
    370    if (!slots) {
    371      FatSlots* fatSlots = new FatSlots();
    372      mSlots = fatSlots;
    373      return fatSlots;
    374    }
    375 
    376    if (!slots->GetExtendedContentSlots()) {
    377      slots->SetExtendedContentSlots(CreateExtendedSlots(), true);
    378    }
    379 
    380    return static_cast<nsExtendedDOMSlots*>(slots->GetExtendedContentSlots());
    381  }
    382 
    383  const nsExtendedDOMSlots* GetExistingExtendedDOMSlots() const {
    384    return static_cast<const nsExtendedDOMSlots*>(
    385        GetExistingExtendedContentSlots());
    386  }
    387 
    388  nsExtendedDOMSlots* GetExistingExtendedDOMSlots() {
    389    return static_cast<nsExtendedDOMSlots*>(GetExistingExtendedContentSlots());
    390  }
    391 
    392  friend class ::ContentUnbinder;
    393 };
    394 
    395 }  // namespace mozilla::dom
    396 
    397 #define NS_ELEMENT_INTERFACE_TABLE_TO_MAP_SEGUE               \
    398  if (NS_SUCCEEDED(rv)) return rv;                            \
    399                                                              \
    400  rv = FragmentOrElement::QueryInterface(aIID, aInstancePtr); \
    401  NS_INTERFACE_TABLE_TO_MAP_SEGUE
    402 
    403 #endif /* FragmentOrElement_h___ */