1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
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/. */
7 #ifndef mozilla_dom_SharedScriptCache_h
8 #define mozilla_dom_SharedScriptCache_h
10 #include "PLDHashTable.h" // PLDHashEntryHdr
11 #include "js/loader/LoadedScript.h" // JS::loader::LoadedScript
12 #include "js/loader/ScriptKind.h" // JS::loader::ScriptKind
13 #include "js/loader/ScriptLoadRequest.h" // JS::loader::ScriptLoadRequest
14 #include "mozilla/RefPtr.h" // RefPtr
15 #include "mozilla/WeakPtr.h" // SupportsWeakPtr
16 #include "mozilla/CORSMode.h" // mozilla::CORSMode
17 #include "mozilla/MemoryReporting.h" // MallocSizeOf
18 #include "mozilla/SharedSubResourceCache.h" // SharedSubResourceCache, SharedSubResourceCacheLoadingValueBase, SubResourceNetworkMetadataHolder
19 #include "mozilla/dom/CacheExpirationTime.h" // CacheExpirationTime
20 #include "nsIMemoryReporter.h" // nsIMemoryReporter, NS_DECL_NSIMEMORYREPORTER
21 #include "nsIObserver.h" // nsIObserver, NS_DECL_NSIOBSERVER
22 #include "nsIPrincipal.h" // nsIPrincipal
23 #include "nsISupports.h" // nsISupports, NS_DECL_ISUPPORTS
24 #include "nsStringFwd.h" // nsACString
25 #include "mozilla/dom/SRIMetadata.h" // mozilla::dom::SRIMetadata
33 class ScriptHashKey
: public PLDHashEntryHdr
{
35 using KeyType
= const ScriptHashKey
&;
36 using KeyTypePointer
= const ScriptHashKey
*;
38 explicit ScriptHashKey(const ScriptHashKey
& aKey
)
41 mPrincipal(aKey
.mPrincipal
),
42 mLoaderPrincipal(aKey
.mLoaderPrincipal
),
43 mPartitionPrincipal(aKey
.mPartitionPrincipal
),
44 mCORSMode(aKey
.mCORSMode
),
45 mSRIMetadata(aKey
.mSRIMetadata
),
48 mHintCharset(aKey
.mHintCharset
),
49 mIsLinkRelPreload(aKey
.mIsLinkRelPreload
) {
50 MOZ_COUNT_CTOR(ScriptHashKey
);
53 explicit ScriptHashKey(const ScriptHashKey
* aKey
) : ScriptHashKey(*aKey
) {}
55 ScriptHashKey(ScriptHashKey
&& aKey
)
57 mURI(std::move(aKey
.mURI
)),
58 mPrincipal(std::move(aKey
.mPrincipal
)),
59 mLoaderPrincipal(std::move(aKey
.mLoaderPrincipal
)),
60 mPartitionPrincipal(std::move(aKey
.mPartitionPrincipal
)),
61 mCORSMode(std::move(aKey
.mCORSMode
)),
62 mSRIMetadata(std::move(aKey
.mSRIMetadata
)),
63 mKind(std::move(aKey
.mKind
)),
64 mNonce(std::move(aKey
.mNonce
)),
65 mHintCharset(std::move(aKey
.mHintCharset
)),
66 mIsLinkRelPreload(std::move(aKey
.mIsLinkRelPreload
)) {
67 MOZ_COUNT_CTOR(ScriptHashKey
);
70 ScriptHashKey(ScriptLoader
* aLoader
,
71 const JS::loader::ScriptLoadRequest
* aRequest
);
72 explicit ScriptHashKey(const ScriptLoadData
& aLoadData
);
74 MOZ_COUNTED_DTOR(ScriptHashKey
)
76 const ScriptHashKey
& GetKey() const { return *this; }
77 const ScriptHashKey
* GetKeyPointer() const { return this; }
79 bool KeyEquals(const ScriptHashKey
* aKey
) const { return KeyEquals(*aKey
); }
81 bool KeyEquals(const ScriptHashKey
&) const;
83 static const ScriptHashKey
* KeyToPointer(const ScriptHashKey
& aKey
) {
86 static PLDHashNumber
HashKey(const ScriptHashKey
* aKey
) {
87 return nsURIHashKey::HashKey(aKey
->mURI
);
90 nsIPrincipal
* Principal() const { return mPrincipal
; }
91 nsIPrincipal
* LoaderPrincipal() const { return mLoaderPrincipal
; }
92 nsIPrincipal
* PartitionPrincipal() const { return mPartitionPrincipal
; }
94 enum { ALLOW_MEMMOVE
= true };
97 const nsCOMPtr
<nsIURI
> mURI
;
98 const nsCOMPtr
<nsIPrincipal
> mPrincipal
;
99 const nsCOMPtr
<nsIPrincipal
> mLoaderPrincipal
;
100 const nsCOMPtr
<nsIPrincipal
> mPartitionPrincipal
;
101 const CORSMode mCORSMode
;
102 const SRIMetadata mSRIMetadata
;
103 const JS::loader::ScriptKind mKind
;
104 const nsString mNonce
;
106 // charset attribute for classic script.
107 // module always use UTF-8.
108 nsString mHintCharset
;
110 // TODO: Reflect URL classifier data source.
111 // mozilla::dom::ContentType
113 // top-level document's host
114 // maybe part of principal?
115 // what if it's inside frame in different host?
117 const bool mIsLinkRelPreload
;
120 class ScriptLoadData final
121 : public SupportsWeakPtr
,
123 public SharedSubResourceCacheLoadingValueBase
<ScriptLoadData
> {
125 virtual ~ScriptLoadData() {}
128 ScriptLoadData(ScriptLoader
* aLoader
,
129 JS::loader::ScriptLoadRequest
* aRequest
);
133 // Only completed loads are used for the cache.
134 bool IsLoading() const override
{ return false; }
135 bool IsCancelled() const override
{ return false; }
136 bool IsSyncLoad() const override
{ return true; }
138 SubResourceNetworkMetadataHolder
* GetNetworkMetadata() const override
{
139 return mNetworkMetadata
.get();
142 void StartLoading() override
{}
143 void SetLoadCompleted() override
{}
144 void OnCoalescedTo(const ScriptLoadData
& aExistingLoad
) override
{}
145 void Cancel() override
{}
147 void DidCancelLoad() {}
149 bool ShouldDefer() const { return false; }
151 JS::loader::LoadedScript
* ValueForCache() const {
152 return mLoadedScript
.get();
155 const CacheExpirationTime
& ExpirationTime() const { return mExpirationTime
; }
157 ScriptLoader
& Loader() { return *mLoader
; }
159 const ScriptHashKey
& CacheKey() const { return mKey
; }
162 CacheExpirationTime mExpirationTime
= CacheExpirationTime::Never();
163 ScriptLoader
* mLoader
;
165 RefPtr
<JS::loader::LoadedScript
> mLoadedScript
;
166 RefPtr
<SubResourceNetworkMetadataHolder
> mNetworkMetadata
;
169 struct SharedScriptCacheTraits
{
170 using Loader
= ScriptLoader
;
171 using Key
= ScriptHashKey
;
172 using Value
= JS::loader::LoadedScript
;
173 using LoadingValue
= ScriptLoadData
;
175 static ScriptHashKey
KeyFromLoadingValue(const LoadingValue
& aValue
) {
176 return ScriptHashKey(aValue
);
180 class SharedScriptCache final
181 : public SharedSubResourceCache
<SharedScriptCacheTraits
, SharedScriptCache
>,
182 public nsIMemoryReporter
,
186 SharedSubResourceCache
<SharedScriptCacheTraits
, SharedScriptCache
>;
189 NS_DECL_NSIMEMORYREPORTER
195 // This has to be static because it's also called for loaders that don't have
196 // a sheet cache (loaders that are not owned by a document).
197 static void LoadCompleted(SharedScriptCache
*, ScriptLoadData
&);
198 using Base::LoadCompleted
;
199 static void Clear(const Maybe
<nsCOMPtr
<nsIPrincipal
>>& aPrincipal
= Nothing(),
200 const Maybe
<nsCString
>& aSchemelessSite
= Nothing(),
201 const Maybe
<OriginAttributesPattern
>& aPattern
= Nothing());
204 ~SharedScriptCache();
208 } // namespace mozilla
210 #endif // mozilla_dom_SharedScriptCache_h