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/. */
5 
6 #ifndef mozilla_extensions_WebExtensionContentScript_h
7 #define mozilla_extensions_WebExtensionContentScript_h
8 
9 #include "mozilla/dom/BindingDeclarations.h"
10 #include "mozilla/dom/WebExtensionContentScriptBinding.h"
11 
12 #include "jspubtd.h"
13 
14 #include "mozilla/Maybe.h"
15 #include "mozilla/Variant.h"
16 #include "mozilla/extensions/MatchGlob.h"
17 #include "mozilla/extensions/MatchPattern.h"
18 #include "nsCOMPtr.h"
19 #include "nsCycleCollectionParticipant.h"
20 #include "nsISupports.h"
21 #include "nsWrapperCache.h"
22 
23 class nsILoadInfo;
24 class nsPIDOMWindowOuter;
25 
26 namespace mozilla {
27 namespace extensions {
28 
29 using dom::Nullable;
30 using ContentScriptInit = dom::WebExtensionContentScriptInit;
31 
32 class WebExtensionPolicy;
33 
34 class MOZ_STACK_CLASS DocInfo final {
35  public:
36   DocInfo(const URLInfo& aURL, nsILoadInfo* aLoadInfo);
37 
38   MOZ_IMPLICIT DocInfo(nsPIDOMWindowOuter* aWindow);
39 
URL()40   const URLInfo& URL() const { return mURL; }
41 
42   // The principal of the document, or the expected principal of a request.
43   // May be null for non-DOMWindow DocInfo objects unless
44   // URL().InheritsPrincipal() is true.
45   nsIPrincipal* Principal() const;
46 
47   // Returns the URL of the document's principal. Note that this must *only*
48   // be called for codebase principals.
49   const URLInfo& PrincipalURL() const;
50 
51   bool IsTopLevel() const;
52   bool ShouldMatchActiveTabPermission() const;
53 
54   uint64_t FrameID() const;
55 
GetWindow()56   nsPIDOMWindowOuter* GetWindow() const {
57     if (mObj.is<Window>()) {
58       return mObj.as<Window>();
59     }
60     return nullptr;
61   }
62 
63  private:
64   void SetURL(const URLInfo& aURL);
65 
66   const URLInfo mURL;
67   mutable Maybe<const URLInfo> mPrincipalURL;
68 
69   mutable Maybe<bool> mIsTopLevel;
70 
71   mutable Maybe<nsCOMPtr<nsIPrincipal>> mPrincipal;
72   mutable Maybe<uint64_t> mFrameID;
73 
74   using Window = nsPIDOMWindowOuter*;
75   using LoadInfo = nsILoadInfo*;
76 
77   const Variant<LoadInfo, Window> mObj;
78 };
79 
80 class WebExtensionContentScript final : public nsISupports,
81                                         public nsWrapperCache {
82   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
83   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(WebExtensionContentScript)
84 
85   using MatchGlobArray = nsTArray<RefPtr<MatchGlob>>;
86   using RunAtEnum = dom::ContentScriptRunAt;
87 
88   static already_AddRefed<WebExtensionContentScript> Constructor(
89       dom::GlobalObject& aGlobal, WebExtensionPolicy& aExtension,
90       const ContentScriptInit& aInit, ErrorResult& aRv);
91 
92   bool Matches(const DocInfo& aDoc) const;
93   bool MatchesURI(const URLInfo& aURL) const;
94 
MatchesLoadInfo(const URLInfo & aURL,nsILoadInfo * aLoadInfo)95   bool MatchesLoadInfo(const URLInfo& aURL, nsILoadInfo* aLoadInfo) const {
96     return Matches({aURL, aLoadInfo});
97   }
MatchesWindow(nsPIDOMWindowOuter * aWindow)98   bool MatchesWindow(nsPIDOMWindowOuter* aWindow) const {
99     return Matches(aWindow);
100   }
101 
Extension()102   WebExtensionPolicy* Extension() { return mExtension; }
Extension()103   const WebExtensionPolicy* Extension() const { return mExtension; }
104 
AllFrames()105   bool AllFrames() const { return mAllFrames; }
MatchAboutBlank()106   bool MatchAboutBlank() const { return mMatchAboutBlank; }
RunAt()107   RunAtEnum RunAt() const { return mRunAt; }
108 
GetFrameID()109   Nullable<uint64_t> GetFrameID() const { return mFrameID; }
110 
Matches()111   MatchPatternSet* Matches() { return mMatches; }
GetMatches()112   const MatchPatternSet* GetMatches() const { return mMatches; }
113 
GetExcludeMatches()114   MatchPatternSet* GetExcludeMatches() { return mExcludeMatches; }
GetExcludeMatches()115   const MatchPatternSet* GetExcludeMatches() const { return mExcludeMatches; }
116 
GetIncludeGlobs(Nullable<MatchGlobArray> & aGlobs)117   void GetIncludeGlobs(Nullable<MatchGlobArray>& aGlobs) {
118     ToNullable(mExcludeGlobs, aGlobs);
119   }
GetExcludeGlobs(Nullable<MatchGlobArray> & aGlobs)120   void GetExcludeGlobs(Nullable<MatchGlobArray>& aGlobs) {
121     ToNullable(mExcludeGlobs, aGlobs);
122   }
123 
GetCssPaths(nsTArray<nsString> & aPaths)124   void GetCssPaths(nsTArray<nsString>& aPaths) const {
125     aPaths.AppendElements(mCssPaths);
126   }
GetJsPaths(nsTArray<nsString> & aPaths)127   void GetJsPaths(nsTArray<nsString>& aPaths) const {
128     aPaths.AppendElements(mJsPaths);
129   }
130 
GetParentObject()131   WebExtensionPolicy* GetParentObject() const { return mExtension; }
132 
133   virtual JSObject* WrapObject(JSContext* aCx,
134                                JS::HandleObject aGivenProto) override;
135 
136  protected:
137   friend class WebExtensionPolicy;
138 
139   virtual ~WebExtensionContentScript() = default;
140 
141   WebExtensionContentScript(WebExtensionPolicy& aExtension,
142                             const ContentScriptInit& aInit, ErrorResult& aRv);
143 
144  private:
145   RefPtr<WebExtensionPolicy> mExtension;
146 
147   bool mHasActiveTabPermission;
148   bool mRestricted;
149 
150   RefPtr<MatchPatternSet> mMatches;
151   RefPtr<MatchPatternSet> mExcludeMatches;
152 
153   Nullable<MatchGlobSet> mIncludeGlobs;
154   Nullable<MatchGlobSet> mExcludeGlobs;
155 
156   nsTArray<nsString> mCssPaths;
157   nsTArray<nsString> mJsPaths;
158 
159   RunAtEnum mRunAt;
160 
161   bool mAllFrames;
162   Nullable<uint64_t> mFrameID;
163   bool mMatchAboutBlank;
164 
165   template <typename T, typename U>
ToNullable(const Nullable<T> & aInput,Nullable<U> & aOutput)166   void ToNullable(const Nullable<T>& aInput, Nullable<U>& aOutput) {
167     if (aInput.IsNull()) {
168       aOutput.SetNull();
169     } else {
170       aOutput.SetValue(aInput.Value());
171     }
172   }
173 };
174 
175 }  // namespace extensions
176 }  // namespace mozilla
177 
178 #endif  // mozilla_extensions_WebExtensionContentScript_h
179