tor-browser

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

Highlight.h (6459B)


      1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim:set ts=2 sw=2 sts=2 et cindent: */
      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_dom_Highlight_h
      8 #define mozilla_dom_Highlight_h
      9 
     10 #include "mozilla/Attributes.h"
     11 #include "mozilla/dom/BindingDeclarations.h"
     12 #include "mozilla/dom/HighlightBinding.h"
     13 #include "nsAtomHashKeys.h"
     14 #include "nsCycleCollectionParticipant.h"
     15 #include "nsTArray.h"
     16 #include "nsTHashSet.h"
     17 #include "nsWrapperCache.h"
     18 
     19 class nsFrameSelection;
     20 class nsPIDOMWindowInner;
     21 namespace mozilla {
     22 class ErrorResult;
     23 }
     24 
     25 namespace mozilla::dom {
     26 class AbstractRange;
     27 class Document;
     28 class HighlightRegistry;
     29 class Selection;
     30 
     31 /**
     32 * @brief Collection of all data of a highlight instance.
     33 *
     34 * This struct is intended to be allocated on the stack and passed on
     35 * to the `nsFrameSelection` and layout code.
     36 */
     37 struct HighlightSelectionData {
     38  RefPtr<nsAtom> mHighlightName;
     39  RefPtr<Highlight> mHighlight;
     40 };
     41 
     42 /**
     43 * @brief Representation of a custom `Highlight`.
     44 *
     45 * A `Highlight` is defined in JS as a collection of `AbstractRange`s.
     46 * Furthermore, a custom highlight contains the highlight type and priority.
     47 *
     48 * A highlight is added to a document using the `HighlightRegistry` interface.
     49 * A highlight can be added to a document using different names as well as to
     50 * multiple `HighlightRegistries`.
     51 * To propagate runtime changes of the highlight to its registries, an
     52 * observer pattern is implemented.
     53 *
     54 * The spec defines this class as a `setlike`. To allow access and iteration
     55 * of the setlike contents from C++, the insertion and deletion operations are
     56 * overridden and the Ranges are also stored internally in an Array.
     57 *
     58 * @see https://drafts.csswg.org/css-highlight-api-1/#creation
     59 */
     60 class Highlight final : public nsISupports, public nsWrapperCache {
     61 public:
     62  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
     63  NS_DECL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS(Highlight)
     64 
     65 protected:
     66  MOZ_CAN_RUN_SCRIPT Highlight(
     67      const Sequence<OwningNonNull<AbstractRange>>& aInitialRanges,
     68      nsPIDOMWindowInner* aWindow, ErrorResult& aRv);
     69  ~Highlight() = default;
     70 
     71 public:
     72  /**
     73   * @brief Adds `this` to `aHighlightRegistry`.
     74   *
     75   * Highlights must know of all registry objects which contain them, so that
     76   * the registries can be notified when a property of the Highlight changes.
     77   *
     78   * Since a Highlight can be part of a registry using different names,
     79   * the name has to be provided as well.
     80   */
     81  void AddToHighlightRegistry(HighlightRegistry& aHighlightRegistry,
     82                              nsAtom& aHighlightName);
     83 
     84  /**
     85   * @brief Removes `this` from `aHighlightRegistry`.
     86   */
     87  void RemoveFromHighlightRegistry(HighlightRegistry& aHighlightRegistry,
     88                                   nsAtom& aHighlightName);
     89 
     90  /**
     91   * @brief Creates a Highlight Selection using the given ranges.
     92   */
     93  MOZ_CAN_RUN_SCRIPT already_AddRefed<Selection> CreateHighlightSelection(
     94      nsAtom* aHighlightName, nsFrameSelection* aFrameSelection);
     95 
     96  // WebIDL interface
     97  nsPIDOMWindowInner* GetParentObject() const { return mWindow; }
     98 
     99  JSObject* WrapObject(JSContext* aCx,
    100                       JS::Handle<JSObject*> aGivenProto) override;
    101 
    102  static MOZ_CAN_RUN_SCRIPT_BOUNDARY already_AddRefed<Highlight> Constructor(
    103      const GlobalObject& aGlobal,
    104      const Sequence<OwningNonNull<AbstractRange>>& aInitialRanges,
    105      ErrorResult& aRv);
    106 
    107  /**
    108   * @brief Priority of this highlight.
    109   *
    110   * Priority is used to stack overlapping highlights.
    111   */
    112  int32_t Priority() const { return mPriority; }
    113 
    114  /**
    115   * @brief Set the priority of this Highlight.
    116   *
    117   * Priority is used to stack overlapping highlights.
    118   */
    119  void SetPriority(int32_t aPriority);
    120 
    121  /**
    122   * @brief The HighlightType of this Highlight (Highlight, Spelling Error,
    123   * Grammar Error)
    124   */
    125  HighlightType Type() const { return mHighlightType; }
    126 
    127  /**
    128   * @brief Sets the HighlightType (Highlight, Spelling Error, Grammar Error)
    129   */
    130  void SetType(HighlightType aHighlightType);
    131 
    132  /**
    133   * @brief This mirrors the `size` property in JS world (_not_ exposed via
    134   * webIDL)
    135   */
    136  uint32_t Size() const { return mRanges.Length(); }
    137 
    138  /**
    139   * @brief Adds a `Range` to this highlight.
    140   *
    141   * This adds `aRange` both to the setlike data storage and the internal one
    142   * needed for iteration, if it is not yet present.
    143   *
    144   * Also notifies all `HighlightRegistry` instances.
    145   */
    146  MOZ_CAN_RUN_SCRIPT Highlight* Add(AbstractRange& aRange, ErrorResult& aRv);
    147 
    148  /**
    149   * @brief Removes all ranges from this highlight.
    150   *
    151   * This removes all highlights from the setlike data structure as well as from
    152   * the internal one.
    153   *
    154   * Also notifies all `HighlightRegistry` instances.
    155   */
    156  MOZ_CAN_RUN_SCRIPT void Clear(ErrorResult& aRv);
    157 
    158  /**
    159   * @brief Removes `aRange` from this highlight.
    160   *
    161   * This removes `aRange` from the setlike data structure as well as from the
    162   * internal one.
    163   *
    164   * Also notifies all `HighlightRegistry` instances.
    165   *
    166   * @return As per spec, returns true if the range was deleted.
    167   */
    168  MOZ_CAN_RUN_SCRIPT bool Delete(AbstractRange& aRange, ErrorResult& aRv);
    169 
    170 private:
    171  void Repaint();
    172 
    173  RefPtr<nsPIDOMWindowInner> mWindow;
    174 
    175  /**
    176   * All Range objects contained in this highlight.
    177   */
    178  nsTArray<RefPtr<AbstractRange>> mRanges;
    179 
    180  /**
    181   * Type of this highlight.
    182   * @see HighlightType
    183   */
    184  HighlightType mHighlightType{HighlightType::Highlight};
    185 
    186  /**
    187   * Priority of this highlight.
    188   *
    189   * If highlights are overlapping, the priority can
    190   * be used to prioritize. If the priorities of all
    191   * Highlights involved are equal, the highlights are
    192   * stacked in order of ther insertion into the
    193   * `HighlightRegistry`.
    194   */
    195  int32_t mPriority{0};
    196 
    197  /**
    198   * All highlight registries that contain this Highlight.
    199   *
    200   * A highlight can be included in several registries
    201   * using several names.
    202   *
    203   * Note: Storing `HighlightRegistry` as raw pointer is safe here
    204   * because it unregisters itself from `this` when it is destroyed/CC'd
    205   */
    206  nsTHashMap<nsPtrHashKey<HighlightRegistry>, nsTHashSet<RefPtr<nsAtom>>>
    207      mHighlightRegistries;
    208 };
    209 
    210 }  // namespace mozilla::dom
    211 
    212 #endif  // mozilla_dom_Highlight_h