tor-browser

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

FragmentDirective.h (5527B)


      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 DOM_FRAGMENTDIRECTIVE_H_
      8 #define DOM_FRAGMENTDIRECTIVE_H_
      9 
     10 #include "js/TypeDecls.h"
     11 #include "mozilla/UniquePtr.h"
     12 #include "mozilla/dom/BindingDeclarations.h"
     13 #include "mozilla/dom/fragmentdirectives_ffi_generated.h"
     14 #include "nsCycleCollectionParticipant.h"
     15 #include "nsStringFwd.h"
     16 #include "nsWrapperCache.h"
     17 
     18 class nsINode;
     19 class nsIURI;
     20 class nsRange;
     21 namespace mozilla::dom {
     22 class Document;
     23 class Promise;
     24 class Text;
     25 class TextDirectiveFinder;
     26 
     27 /**
     28 * @brief The `FragmentDirective` class is the C++ representation of the
     29 * `Document.fragmentDirective` webidl property.
     30 *
     31 * This class also serves as the main interface to interact with the fragment
     32 * directive from the C++ side. It allows to find text fragment ranges from a
     33 * given list of `TextDirective`s using
     34 * `FragmentDirective::FindTextFragmentsInDocument()`.
     35 * To avoid Text Directives being applied multiple times, this class implements
     36 * the `uninvoked directive` mechanism, which in the spec is defined to be part
     37 * of the `Document` [0], by encapsuling the code in a lazily constructed
     38 * helper, which is destroyed when all text directives have been found.
     39 *
     40 * [0]
     41 * https://wicg.github.io/scroll-to-text-fragment/#document-uninvoked-directives
     42 */
     43 class FragmentDirective final : public nsISupports, public nsWrapperCache {
     44 public:
     45  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
     46  NS_DECL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS(FragmentDirective)
     47 
     48 public:
     49  explicit FragmentDirective(Document* aDocument);
     50 
     51 protected:
     52  ~FragmentDirective();
     53 
     54 public:
     55  Document* GetParentObject() const { return mDocument; };
     56 
     57  JSObject* WrapObject(JSContext* aCx,
     58                       JS::Handle<JSObject*> aGivenProto) override;
     59 
     60  /**
     61   * @brief Sets Text Directives as "uninvoked directive".
     62   */
     63  void SetTextDirectives(nsTArray<TextDirective>&& aTextDirectives);
     64 
     65  /** Returns true if there are Text Directives that have not been applied to
     66   * the `Document`.
     67   */
     68  bool HasUninvokedDirectives() const;
     69 
     70  /** Clears all uninvoked directives. */
     71  void ClearUninvokedDirectives();
     72 
     73  /** Inserts all text directive ranges into a `eTargetText` `Selection`. */
     74  MOZ_CAN_RUN_SCRIPT
     75  void HighlightTextDirectives(
     76      const nsTArray<RefPtr<nsRange>>& aTextDirectiveRanges);
     77 
     78  /** Searches for the current uninvoked text directives and creates a range for
     79   * each one that is found.
     80   *
     81   * When this method returns, the uninvoked directives for this document are
     82   * cleared.
     83   *
     84   * This method tries to follow the specification as close as possible in how
     85   * to find a matching range for a text directive. However, instead of using
     86   * collator-based search, the Gecko find-in-page algorithm is used (`nsFind`).
     87   */
     88  nsTArray<RefPtr<nsRange>> FindTextFragmentsInDocument();
     89 
     90  /** Utility function which parses the fragment directive and removes it from
     91   * the hash of the given URI. This operation happens in-place.
     92   *
     93   * If aTextDirectives is nullptr, the parsed fragment directive is discarded.
     94   */
     95  static void ParseAndRemoveFragmentDirectiveFromFragment(
     96      nsCOMPtr<nsIURI>& aURI,
     97      nsTArray<TextDirective>* aTextDirectives = nullptr);
     98 
     99  /** Parses the fragment directive and removes it from the hash, given as
    100   * string. This operation happens in-place.
    101   *
    102   * This function is called internally by
    103   * `ParseAndRemoveFragmentDirectiveFromFragment()`.
    104   *
    105   * This function returns true if it modified `aFragment`.
    106   *
    107   * Note: the parameter `aURI` is only used for logging purposes.
    108   */
    109  static bool ParseAndRemoveFragmentDirectiveFromFragmentString(
    110      nsCString& aFragment, nsTArray<TextDirective>* aTextDirectives = nullptr,
    111      nsIURI* aURI = nullptr);
    112 
    113  /** Utility function than returns a string for `aURI` ignoring all fragment
    114   * directives.
    115   */
    116  static nsresult GetSpecIgnoringFragmentDirective(
    117      nsCOMPtr<nsIURI>& aURI, nsACString& aSpecIgnoringFragmentDirective);
    118 
    119  /** Performs various checks to determine if a text directive is allowed to be
    120   * scrolled to.
    121   *
    122   * This follows the algorithm "check if a text directive can be scrolled" in
    123   * section 3.5.4 of the text fragment spec
    124   * (https://wicg.github.io/scroll-to-text-fragment/#restricting-the-text-fragment).
    125   */
    126  bool IsTextDirectiveAllowedToBeScrolledTo();
    127 
    128  /** Return an array of all current text directive ranges.
    129   *
    130   * This is exposed as a Chrome-Only API.
    131   */
    132  void GetTextDirectiveRanges(nsTArray<RefPtr<nsRange>>& aRanges) const;
    133 
    134  /** Removes all text directive ranges.
    135   *
    136   * Under the hood this method only calls `Selection::RemoveAllRanges()`.
    137   * This is exposed as a Chrome-Only API.
    138   */
    139  MOZ_CAN_RUN_SCRIPT void RemoveAllTextDirectives(ErrorResult& aRv);
    140 
    141  /** Creates a text directive string for the current selection.
    142   *
    143   * @return Returns the created text directive as resolved promise, or a
    144   *         rejected promise in case of an error.
    145   */
    146  already_AddRefed<Promise> CreateTextDirectiveForRanges(
    147      const Sequence<OwningNonNull<nsRange>>& aRanges);
    148 
    149 private:
    150  RefPtr<Document> mDocument;
    151  UniquePtr<TextDirectiveFinder> mFinder;
    152 };
    153 
    154 }  // namespace mozilla::dom
    155 
    156 #endif  // DOM_FRAGMENTDIRECTIVE_H_