summaryrefslogtreecommitdiffstats
path: root/dom/base/Highlight.h
diff options
context:
space:
mode:
Diffstat (limited to 'dom/base/Highlight.h')
-rw-r--r--dom/base/Highlight.h213
1 files changed, 213 insertions, 0 deletions
diff --git a/dom/base/Highlight.h b/dom/base/Highlight.h
new file mode 100644
index 0000000000..7c542ff4f3
--- /dev/null
+++ b/dom/base/Highlight.h
@@ -0,0 +1,213 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_dom_Highlight_h
+#define mozilla_dom_Highlight_h
+
+#include "mozilla/Attributes.h"
+#include "mozilla/dom/BindingDeclarations.h"
+#include "mozilla/dom/HighlightBinding.h"
+
+#include "nsCycleCollectionParticipant.h"
+#include "nsAtomHashKeys.h"
+#include "nsTHashSet.h"
+#include "nsTArray.h"
+#include "nsWrapperCache.h"
+
+class nsFrameSelection;
+class nsPIDOMWindowInner;
+namespace mozilla {
+class ErrorResult;
+}
+
+namespace mozilla::dom {
+class AbstractRange;
+class Document;
+class HighlightRegistry;
+class Selection;
+
+/**
+ * @brief Collection of all data of a highlight instance.
+ *
+ * This struct is intended to be allocated on the stack and passed on
+ * to the `nsFrameSelection` and layout code.
+ */
+struct HighlightSelectionData {
+ RefPtr<nsAtom> mHighlightName;
+ RefPtr<Highlight> mHighlight;
+};
+
+/**
+ * @brief Representation of a custom `Highlight`.
+ *
+ * A `Highlight` is defined in JS as a collection of `AbstractRange`s.
+ * Furthermore, a custom highlight contains the highlight type and priority.
+ *
+ * A highlight is added to a document using the `HighlightRegistry` interface.
+ * A highlight can be added to a document using different names as well as to
+ * multiple `HighlightRegistries`.
+ * To propagate runtime changes of the highlight to its registries, an
+ * observer pattern is implemented.
+ *
+ * The spec defines this class as a `setlike`. To allow access and iteration
+ * of the setlike contents from C++, the insertion and deletion operations are
+ * overridden and the Ranges are also stored internally in an Array.
+ *
+ * @see https://drafts.csswg.org/css-highlight-api-1/#creation
+ */
+class Highlight final : public nsISupports, public nsWrapperCache {
+ public:
+ NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+ NS_DECL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS(Highlight)
+
+ protected:
+ MOZ_CAN_RUN_SCRIPT Highlight(
+ const Sequence<OwningNonNull<AbstractRange>>& aInitialRanges,
+ nsPIDOMWindowInner* aWindow, ErrorResult& aRv);
+ ~Highlight() = default;
+
+ public:
+ /**
+ * @brief Adds `this` to `aHighlightRegistry`.
+ *
+ * Highlights must know of all registry objects which contain them, so that
+ * the registries can be notified when a property of the Highlight changes.
+ *
+ * Since a Highlight can be part of a registry using different names,
+ * the name has to be provided as well.
+ */
+ void AddToHighlightRegistry(HighlightRegistry& aHighlightRegistry,
+ nsAtom& aHighlightName);
+
+ /**
+ * @brief Removes `this` from `aHighlightRegistry`.
+ */
+ void RemoveFromHighlightRegistry(HighlightRegistry& aHighlightRegistry,
+ nsAtom& aHighlightName);
+
+ /**
+ * @brief Creates a Highlight Selection using the given ranges.
+ */
+ MOZ_CAN_RUN_SCRIPT already_AddRefed<Selection> CreateHighlightSelection(
+ nsAtom* aHighlightName, nsFrameSelection* aFrameSelection);
+
+ // WebIDL interface
+ nsPIDOMWindowInner* GetParentObject() const { return mWindow; }
+
+ JSObject* WrapObject(JSContext* aCx,
+ JS::Handle<JSObject*> aGivenProto) override;
+
+ static MOZ_CAN_RUN_SCRIPT_BOUNDARY already_AddRefed<Highlight> Constructor(
+ const GlobalObject& aGlobal,
+ const Sequence<OwningNonNull<AbstractRange>>& aInitialRanges,
+ ErrorResult& aRv);
+
+ /**
+ * @brief Priority of this highlight.
+ *
+ * Priority is used to stack overlapping highlights.
+ */
+ int32_t Priority() const { return mPriority; }
+
+ /**
+ * @brief Set the priority of this Highlight.
+ *
+ * Priority is used to stack overlapping highlights.
+ */
+ void SetPriority(int32_t aPriority) { mPriority = aPriority; }
+
+ /**
+ * @brief The HighlightType of this Highlight (Highlight, Spelling Error,
+ * Grammar Error)
+ */
+ HighlightType Type() const { return mHighlightType; }
+
+ /**
+ * @brief Sets the HighlightType (Highlight, Spelling Error, Grammar Error)
+ */
+ void SetType(HighlightType aHighlightType) {
+ mHighlightType = aHighlightType;
+ }
+
+ /**
+ * @brief This mirrors the `size` property in JS world (_not_ exposed via
+ * webIDL)
+ */
+ uint32_t Size() const { return mRanges.Length(); }
+
+ /**
+ * @brief Adds a `Range` to this highlight.
+ *
+ * This adds `aRange` both to the setlike data storage and the internal one
+ * needed for iteration, if it is not yet present.
+ *
+ * Also notifies all `HighlightRegistry` instances.
+ */
+ MOZ_CAN_RUN_SCRIPT void Add(AbstractRange& aRange, ErrorResult& aRv);
+
+ /**
+ * @brief Removes all ranges from this highlight.
+ *
+ * This removes all highlights from the setlike data structure as well as from
+ * the internal one.
+ *
+ * Also notifies all `HighlightRegistry` instances.
+ */
+ MOZ_CAN_RUN_SCRIPT void Clear(ErrorResult& aRv);
+
+ /**
+ * @brief Removes `aRange` from this highlight.
+ *
+ * This removes `aRange` from the setlike data structure as well as from the
+ * internal one.
+ *
+ * Also notifies all `HighlightRegistry` instances.
+ *
+ * @return As per spec, returns true if the range was deleted.
+ */
+ MOZ_CAN_RUN_SCRIPT bool Delete(AbstractRange& aRange, ErrorResult& aRv);
+
+ private:
+ RefPtr<nsPIDOMWindowInner> mWindow;
+
+ /**
+ * All Range objects contained in this highlight.
+ */
+ nsTArray<RefPtr<AbstractRange>> mRanges;
+
+ /**
+ * Type of this highlight.
+ * @see HighlightType
+ */
+ HighlightType mHighlightType{HighlightType::Highlight};
+
+ /**
+ * Priority of this highlight.
+ *
+ * If highlights are overlapping, the priority can
+ * be used to prioritize. If the priorities of all
+ * Highlights involved are equal, the highlights are
+ * stacked in order of ther insertion into the
+ * `HighlightRegistry`.
+ */
+ int32_t mPriority{0};
+
+ /**
+ * All highlight registries that contain this Highlight.
+ *
+ * A highlight can be included in several registries
+ * using several names.
+ *
+ * Note: Storing `HighlightRegistry` as raw pointer is safe here
+ * because it unregisters itself from `this` when it is destroyed/CC'd
+ */
+ nsTHashMap<nsPtrHashKey<HighlightRegistry>, nsTHashSet<RefPtr<nsAtom>>>
+ mHighlightRegistries;
+};
+
+} // namespace mozilla::dom
+
+#endif // mozilla_dom_Highlight_h