Bug 1871127 - Add tsconfig, basic types, and fix or ignore remaining type errors...
[gecko.git] / toolkit / components / extensions / MatchPattern.h
blobebfd1c62a113985001583079d64c9a633b62707f
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #ifndef mozilla_extensions_MatchPattern_h
7 #define mozilla_extensions_MatchPattern_h
9 #include <utility>
11 #include "mozilla/dom/BindingDeclarations.h"
12 #include "mozilla/dom/MatchPatternBinding.h"
13 #include "mozilla/extensions/MatchGlob.h"
15 #include "jspubtd.h"
17 #include "mozilla/ClearOnShutdown.h"
18 #include "mozilla/Likely.h"
19 #include "mozilla/Maybe.h"
20 #include "mozilla/RefCounted.h"
21 #include "nsCOMPtr.h"
22 #include "nsCycleCollectionParticipant.h"
23 #include "nsTArray.h"
24 #include "nsAtom.h"
25 #include "nsICookie.h"
26 #include "nsISupports.h"
27 #include "nsIURI.h"
28 #include "nsWrapperCache.h"
30 namespace mozilla {
31 namespace extensions {
33 using dom::MatchPatternOptions;
35 // A sorted, immutable, binary-search-backed set of atoms, optimized for
36 // frequent lookups.
37 class AtomSet final {
38 public:
39 using ArrayType = AutoTArray<RefPtr<nsAtom>, 1>;
41 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(AtomSet)
43 explicit AtomSet(const nsTArray<nsString>& aElems);
45 MOZ_IMPLICIT AtomSet(std::initializer_list<nsAtom*> aIL);
47 bool Contains(const nsAString& elem) const {
48 RefPtr<nsAtom> atom = NS_Atomize(elem);
49 return Contains(atom);
52 bool Contains(const nsACString& aElem) const {
53 RefPtr<nsAtom> atom = NS_Atomize(aElem);
54 return Contains(atom);
57 bool Contains(const nsAtom* aAtom) const {
58 return mElems.ContainsSorted(aAtom);
61 bool Intersects(const AtomSet& aOther) const;
63 void Get(nsTArray<nsString>& aResult) const {
64 aResult.SetCapacity(mElems.Length());
66 for (const auto& atom : mElems) {
67 aResult.AppendElement(nsDependentAtomString(atom));
71 auto begin() const -> decltype(std::declval<const ArrayType>().begin()) {
72 return mElems.begin();
75 auto end() const -> decltype(std::declval<const ArrayType>().end()) {
76 return mElems.end();
79 private:
80 ~AtomSet() = default;
82 const ArrayType mElems;
85 // A helper class to lazily retrieve, transcode, and atomize certain URI
86 // properties the first time they're used, and cache the results, so that they
87 // can be used across multiple match operations.
88 class URLInfo final {
89 public:
90 MOZ_IMPLICIT URLInfo(nsIURI* aURI) : mURI(aURI) { mHost.SetIsVoid(true); }
92 URLInfo(nsIURI* aURI, bool aNoRef) : URLInfo(aURI) {
93 if (aNoRef) {
94 mURINoRef = mURI;
98 URLInfo(const URLInfo& aOther) : URLInfo(aOther.mURI.get()) {}
100 nsIURI* URI() const { return mURI; }
102 nsAtom* Scheme() const;
103 const nsCString& Host() const;
104 const nsAtom* HostAtom() const;
105 const nsCString& Path() const;
106 const nsCString& FilePath() const;
107 const nsString& Spec() const;
108 const nsCString& CSpec() const;
110 bool InheritsPrincipal() const;
112 private:
113 nsIURI* URINoRef() const;
115 nsCOMPtr<nsIURI> mURI;
116 mutable nsCOMPtr<nsIURI> mURINoRef;
118 mutable RefPtr<nsAtom> mScheme;
119 mutable nsCString mHost;
120 mutable RefPtr<nsAtom> mHostAtom;
122 mutable nsCString mPath;
123 mutable nsCString mFilePath;
124 mutable nsString mSpec;
125 mutable nsCString mCSpec;
127 mutable Maybe<bool> mInheritsPrincipal;
130 // Similar to URLInfo, but for cookies.
131 class MOZ_STACK_CLASS CookieInfo final {
132 public:
133 MOZ_IMPLICIT CookieInfo(nsICookie* aCookie) : mCookie(aCookie) {}
135 bool IsSecure() const;
136 bool IsDomain() const;
138 const nsCString& Host() const;
139 const nsCString& RawHost() const;
141 private:
142 nsCOMPtr<nsICookie> mCookie;
144 mutable Maybe<bool> mIsSecure;
145 mutable Maybe<bool> mIsDomain;
147 mutable nsCString mHost;
148 mutable nsCString mRawHost;
151 class MatchPatternCore final {
152 public:
153 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MatchPatternCore)
155 // NOTE: Must be constructed on the main thread!
156 MatchPatternCore(const nsAString& aPattern, bool aIgnorePath,
157 bool aRestrictSchemes, ErrorResult& aRv);
159 bool Matches(const nsAString& aURL, bool aExplicit, ErrorResult& aRv) const;
161 bool Matches(const URLInfo& aURL, bool aExplicit = false) const;
163 bool MatchesAllWebUrls() const;
164 // Helper for MatchPatternSetCore::MatchesAllWebUrls:
165 bool MatchesAllUrlsWithScheme(const nsAtom* aScheme) const;
167 bool MatchesCookie(const CookieInfo& aCookie) const;
169 bool MatchesDomain(const nsACString& aDomain) const;
171 bool Subsumes(const MatchPatternCore& aPattern) const;
173 bool SubsumesDomain(const MatchPatternCore& aPattern) const;
175 bool Overlaps(const MatchPatternCore& aPattern) const;
177 bool DomainIsWildcard() const { return mMatchSubdomain && mDomain.IsEmpty(); }
179 void GetPattern(nsAString& aPattern) const { aPattern = mPattern; }
181 private:
182 ~MatchPatternCore() = default;
184 // The normalized match pattern string that this object represents.
185 nsString mPattern;
187 // The set of atomized URI schemes that this pattern matches.
188 RefPtr<AtomSet> mSchemes;
190 // The domain that this matcher matches. If mMatchSubdomain is false, only
191 // matches the exact domain. If it's true, matches the domain or any
192 // subdomain.
194 // For instance, "*.foo.com" gives mDomain = "foo.com" and mMatchSubdomain =
195 // true, and matches "foo.com" or "bar.foo.com" but not "barfoo.com".
197 // While "foo.com" gives mDomain = "foo.com" and mMatchSubdomain = false,
198 // and matches "foo.com" but not "bar.foo.com".
199 nsCString mDomain;
200 bool mMatchSubdomain = false;
202 // The glob against which the URL path must match. If null, the path is
203 // ignored entirely. If non-null, the path must match this glob.
204 RefPtr<MatchGlobCore> mPath;
207 class MatchPattern final : public nsISupports, public nsWrapperCache {
208 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
209 NS_DECL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS(MatchPattern)
211 static already_AddRefed<MatchPattern> Constructor(
212 dom::GlobalObject& aGlobal, const nsAString& aPattern,
213 const MatchPatternOptions& aOptions, ErrorResult& aRv);
215 bool Matches(const nsAString& aURL, bool aExplicit, ErrorResult& aRv) const {
216 return Core()->Matches(aURL, aExplicit, aRv);
219 bool MatchesAllWebUrls() const { return Core()->MatchesAllWebUrls(); }
221 bool Matches(const URLInfo& aURL, bool aExplicit = false) const {
222 return Core()->Matches(aURL, aExplicit);
225 bool Matches(const URLInfo& aURL, bool aExplicit, ErrorResult& aRv) const {
226 return Matches(aURL, aExplicit);
229 bool MatchesCookie(const CookieInfo& aCookie) const {
230 return Core()->MatchesCookie(aCookie);
233 bool MatchesDomain(const nsACString& aDomain) const {
234 return Core()->MatchesDomain(aDomain);
237 bool Subsumes(const MatchPattern& aPattern) const {
238 return Core()->Subsumes(*aPattern.Core());
241 bool SubsumesDomain(const MatchPattern& aPattern) const {
242 return Core()->SubsumesDomain(*aPattern.Core());
245 bool Overlaps(const MatchPattern& aPattern) const {
246 return Core()->Overlaps(*aPattern.Core());
249 bool DomainIsWildcard() const { return Core()->DomainIsWildcard(); }
251 void GetPattern(nsAString& aPattern) const { Core()->GetPattern(aPattern); }
253 MatchPatternCore* Core() const { return mCore; }
255 nsISupports* GetParentObject() const { return mParent; }
257 virtual JSObject* WrapObject(JSContext* aCx,
258 JS::Handle<JSObject*> aGivenProto) override;
260 protected:
261 virtual ~MatchPattern() = default;
263 private:
264 friend class MatchPatternSet;
266 explicit MatchPattern(nsISupports* aParent,
267 already_AddRefed<MatchPatternCore> aCore)
268 : mParent(aParent), mCore(std::move(aCore)) {}
270 void Init(JSContext* aCx, const nsAString& aPattern, bool aIgnorePath,
271 bool aRestrictSchemes, ErrorResult& aRv);
273 nsCOMPtr<nsISupports> mParent;
275 RefPtr<MatchPatternCore> mCore;
277 public:
278 // A quick way to check if a particular URL matches <all_urls> without
279 // actually instantiating a MatchPattern
280 static bool MatchesAllURLs(const URLInfo& aURL);
283 class MatchPatternSetCore final {
284 public:
285 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MatchPatternSetCore)
287 using ArrayType = nsTArray<RefPtr<MatchPatternCore>>;
289 explicit MatchPatternSetCore(ArrayType&& aPatterns)
290 : mPatterns(std::move(aPatterns)) {}
292 static already_AddRefed<MatchPatternSet> Constructor(
293 dom::GlobalObject& aGlobal,
294 const nsTArray<dom::OwningStringOrMatchPattern>& aPatterns,
295 const MatchPatternOptions& aOptions, ErrorResult& aRv);
297 bool Matches(const nsAString& aURL, bool aExplicit, ErrorResult& aRv) const;
299 bool Matches(const URLInfo& aURL, bool aExplicit = false) const;
301 bool MatchesAllWebUrls() const;
303 bool MatchesCookie(const CookieInfo& aCookie) const;
305 bool Subsumes(const MatchPatternCore& aPattern) const;
307 bool SubsumesDomain(const MatchPatternCore& aPattern) const;
309 bool Overlaps(const MatchPatternCore& aPattern) const;
311 bool Overlaps(const MatchPatternSetCore& aPatternSet) const;
313 bool OverlapsAll(const MatchPatternSetCore& aPatternSet) const;
315 void GetPatterns(ArrayType& aPatterns) {
316 aPatterns.AppendElements(mPatterns);
319 private:
320 friend class MatchPatternSet;
322 ~MatchPatternSetCore() = default;
324 ArrayType mPatterns;
327 class MatchPatternSet final : public nsISupports, public nsWrapperCache {
328 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
329 NS_DECL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS(MatchPatternSet)
331 using ArrayType = nsTArray<RefPtr<MatchPattern>>;
333 static already_AddRefed<MatchPatternSet> Constructor(
334 dom::GlobalObject& aGlobal,
335 const nsTArray<dom::OwningStringOrMatchPattern>& aPatterns,
336 const MatchPatternOptions& aOptions, ErrorResult& aRv);
338 bool Matches(const nsAString& aURL, bool aExplicit, ErrorResult& aRv) const {
339 return Core()->Matches(aURL, aExplicit, aRv);
342 bool Matches(const URLInfo& aURL, bool aExplicit = false) const {
343 return Core()->Matches(aURL, aExplicit);
346 bool Matches(const URLInfo& aURL, bool aExplicit, ErrorResult& aRv) const {
347 return Matches(aURL, aExplicit);
350 bool MatchesAllWebUrls() const { return Core()->MatchesAllWebUrls(); }
352 bool MatchesCookie(const CookieInfo& aCookie) const {
353 return Core()->MatchesCookie(aCookie);
356 bool Subsumes(const MatchPattern& aPattern) const {
357 return Core()->Subsumes(*aPattern.Core());
360 bool SubsumesDomain(const MatchPattern& aPattern) const {
361 return Core()->SubsumesDomain(*aPattern.Core());
364 bool Overlaps(const MatchPattern& aPattern) const {
365 return Core()->Overlaps(*aPattern.Core());
368 bool Overlaps(const MatchPatternSet& aPatternSet) const {
369 return Core()->Overlaps(*aPatternSet.Core());
372 bool OverlapsAll(const MatchPatternSet& aPatternSet) const {
373 return Core()->OverlapsAll(*aPatternSet.Core());
376 void GetPatterns(ArrayType& aPatterns);
378 MatchPatternSetCore* Core() const { return mCore; }
380 nsISupports* GetParentObject() const { return mParent; }
382 virtual JSObject* WrapObject(JSContext* aCx,
383 JS::Handle<JSObject*> aGivenProto) override;
385 protected:
386 virtual ~MatchPatternSet() = default;
388 private:
389 explicit MatchPatternSet(nsISupports* aParent,
390 already_AddRefed<MatchPatternSetCore> aCore)
391 : mParent(aParent), mCore(std::move(aCore)) {}
393 nsCOMPtr<nsISupports> mParent;
395 RefPtr<MatchPatternSetCore> mCore;
397 mozilla::Maybe<ArrayType> mPatternsCache;
400 } // namespace extensions
401 } // namespace mozilla
403 #endif // mozilla_extensions_MatchPattern_h