1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212
|
/* -*- 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 "nsAtomHashKeys.h"
#include "nsCycleCollectionParticipant.h"
#include "nsTArray.h"
#include "nsTHashSet.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);
/**
* @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);
/**
* @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 Highlight* 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:
void Repaint();
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
|