212 lines
7 KiB
C++
212 lines
7 KiB
C++
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
|
/* 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_SharedScriptCache_h
|
|
#define mozilla_dom_SharedScriptCache_h
|
|
|
|
#include "PLDHashTable.h" // PLDHashEntryHdr
|
|
#include "js/loader/LoadedScript.h" // JS::loader::LoadedScript
|
|
#include "js/loader/ScriptKind.h" // JS::loader::ScriptKind
|
|
#include "js/loader/ScriptLoadRequest.h" // JS::loader::ScriptLoadRequest
|
|
#include "mozilla/RefPtr.h" // RefPtr
|
|
#include "mozilla/WeakPtr.h" // SupportsWeakPtr
|
|
#include "mozilla/CORSMode.h" // mozilla::CORSMode
|
|
#include "mozilla/MemoryReporting.h" // MallocSizeOf
|
|
#include "mozilla/SharedSubResourceCache.h" // SharedSubResourceCache, SharedSubResourceCacheLoadingValueBase, SubResourceNetworkMetadataHolder
|
|
#include "mozilla/dom/CacheExpirationTime.h" // CacheExpirationTime
|
|
#include "nsIMemoryReporter.h" // nsIMemoryReporter, NS_DECL_NSIMEMORYREPORTER
|
|
#include "nsIObserver.h" // nsIObserver, NS_DECL_NSIOBSERVER
|
|
#include "nsIPrincipal.h" // nsIPrincipal
|
|
#include "nsISupports.h" // nsISupports, NS_DECL_ISUPPORTS
|
|
#include "nsStringFwd.h" // nsACString
|
|
#include "mozilla/dom/SRIMetadata.h" // mozilla::dom::SRIMetadata
|
|
|
|
namespace mozilla {
|
|
namespace dom {
|
|
|
|
class ScriptLoader;
|
|
class ScriptLoadData;
|
|
|
|
class ScriptHashKey : public PLDHashEntryHdr {
|
|
public:
|
|
using KeyType = const ScriptHashKey&;
|
|
using KeyTypePointer = const ScriptHashKey*;
|
|
|
|
explicit ScriptHashKey(const ScriptHashKey& aKey)
|
|
: PLDHashEntryHdr(),
|
|
mURI(aKey.mURI),
|
|
mLoaderPrincipal(aKey.mLoaderPrincipal),
|
|
mPartitionPrincipal(aKey.mPartitionPrincipal),
|
|
mCORSMode(aKey.mCORSMode),
|
|
mSRIMetadata(aKey.mSRIMetadata),
|
|
mKind(aKey.mKind),
|
|
mNonce(aKey.mNonce),
|
|
mHintCharset(aKey.mHintCharset),
|
|
mIsLinkRelPreload(aKey.mIsLinkRelPreload) {
|
|
MOZ_COUNT_CTOR(ScriptHashKey);
|
|
}
|
|
|
|
explicit ScriptHashKey(const ScriptHashKey* aKey) : ScriptHashKey(*aKey) {}
|
|
|
|
ScriptHashKey(ScriptHashKey&& aKey)
|
|
: PLDHashEntryHdr(),
|
|
mURI(std::move(aKey.mURI)),
|
|
mLoaderPrincipal(std::move(aKey.mLoaderPrincipal)),
|
|
mPartitionPrincipal(std::move(aKey.mPartitionPrincipal)),
|
|
mCORSMode(std::move(aKey.mCORSMode)),
|
|
mSRIMetadata(std::move(aKey.mSRIMetadata)),
|
|
mKind(std::move(aKey.mKind)),
|
|
mNonce(std::move(aKey.mNonce)),
|
|
mHintCharset(std::move(aKey.mHintCharset)),
|
|
mIsLinkRelPreload(std::move(aKey.mIsLinkRelPreload)) {
|
|
MOZ_COUNT_CTOR(ScriptHashKey);
|
|
}
|
|
|
|
ScriptHashKey(ScriptLoader* aLoader,
|
|
const JS::loader::ScriptLoadRequest* aRequest);
|
|
explicit ScriptHashKey(const ScriptLoadData& aLoadData);
|
|
|
|
MOZ_COUNTED_DTOR(ScriptHashKey)
|
|
|
|
const ScriptHashKey& GetKey() const { return *this; }
|
|
const ScriptHashKey* GetKeyPointer() const { return this; }
|
|
|
|
bool KeyEquals(const ScriptHashKey* aKey) const { return KeyEquals(*aKey); }
|
|
|
|
bool KeyEquals(const ScriptHashKey&) const;
|
|
|
|
static const ScriptHashKey* KeyToPointer(const ScriptHashKey& aKey) {
|
|
return &aKey;
|
|
}
|
|
static PLDHashNumber HashKey(const ScriptHashKey* aKey) {
|
|
return nsURIHashKey::HashKey(aKey->mURI);
|
|
}
|
|
|
|
nsIPrincipal* LoaderPrincipal() const { return mLoaderPrincipal; }
|
|
nsIPrincipal* PartitionPrincipal() const { return mPartitionPrincipal; }
|
|
|
|
nsIURI* URI() const { return mURI; }
|
|
|
|
enum { ALLOW_MEMMOVE = true };
|
|
|
|
protected:
|
|
const nsCOMPtr<nsIURI> mURI;
|
|
const nsCOMPtr<nsIPrincipal> mLoaderPrincipal;
|
|
const nsCOMPtr<nsIPrincipal> mPartitionPrincipal;
|
|
const CORSMode mCORSMode;
|
|
const SRIMetadata mSRIMetadata;
|
|
const JS::loader::ScriptKind mKind;
|
|
const nsString mNonce;
|
|
|
|
// charset attribute for classic script.
|
|
// module always use UTF-8.
|
|
nsString mHintCharset;
|
|
|
|
// TODO: Reflect URL classifier data source.
|
|
// mozilla::dom::ContentType
|
|
// maybe implicit
|
|
// top-level document's host
|
|
// maybe part of principal?
|
|
// what if it's inside frame in different host?
|
|
|
|
const bool mIsLinkRelPreload;
|
|
};
|
|
|
|
class ScriptLoadData final
|
|
: public SupportsWeakPtr,
|
|
public nsISupports,
|
|
public SharedSubResourceCacheLoadingValueBase<ScriptLoadData> {
|
|
protected:
|
|
~ScriptLoadData() {}
|
|
|
|
public:
|
|
ScriptLoadData(ScriptLoader* aLoader,
|
|
JS::loader::ScriptLoadRequest* aRequest);
|
|
|
|
NS_DECL_ISUPPORTS
|
|
|
|
// Only completed loads are used for the cache.
|
|
bool IsLoading() const override { return false; }
|
|
bool IsCancelled() const override { return false; }
|
|
bool IsSyncLoad() const override { return true; }
|
|
|
|
SubResourceNetworkMetadataHolder* GetNetworkMetadata() const override {
|
|
return mNetworkMetadata.get();
|
|
}
|
|
|
|
void StartLoading() override {}
|
|
void SetLoadCompleted() override {}
|
|
void OnCoalescedTo(const ScriptLoadData& aExistingLoad) override {}
|
|
void Cancel() override {}
|
|
|
|
void DidCancelLoad() {}
|
|
|
|
bool ShouldDefer() const { return false; }
|
|
|
|
JS::loader::LoadedScript* ValueForCache() const {
|
|
return mLoadedScript.get();
|
|
}
|
|
|
|
const CacheExpirationTime& ExpirationTime() const { return mExpirationTime; }
|
|
|
|
ScriptLoader& Loader() { return *mLoader; }
|
|
|
|
const ScriptHashKey& CacheKey() const { return mKey; }
|
|
|
|
private:
|
|
CacheExpirationTime mExpirationTime = CacheExpirationTime::Never();
|
|
ScriptLoader* mLoader;
|
|
ScriptHashKey mKey;
|
|
RefPtr<JS::loader::LoadedScript> mLoadedScript;
|
|
RefPtr<SubResourceNetworkMetadataHolder> mNetworkMetadata;
|
|
};
|
|
|
|
struct SharedScriptCacheTraits {
|
|
using Loader = ScriptLoader;
|
|
using Key = ScriptHashKey;
|
|
using Value = JS::loader::LoadedScript;
|
|
using LoadingValue = ScriptLoadData;
|
|
|
|
static ScriptHashKey KeyFromLoadingValue(const LoadingValue& aValue) {
|
|
return ScriptHashKey(aValue);
|
|
}
|
|
};
|
|
|
|
class SharedScriptCache final
|
|
: public SharedSubResourceCache<SharedScriptCacheTraits, SharedScriptCache>,
|
|
public nsIMemoryReporter,
|
|
public nsIObserver {
|
|
public:
|
|
using Base =
|
|
SharedSubResourceCache<SharedScriptCacheTraits, SharedScriptCache>;
|
|
|
|
NS_DECL_ISUPPORTS
|
|
NS_DECL_NSIMEMORYREPORTER
|
|
NS_DECL_NSIOBSERVER
|
|
|
|
SharedScriptCache();
|
|
void Init();
|
|
|
|
// This has to be static because it's also called for loaders that don't have
|
|
// a sheet cache (loaders that are not owned by a document).
|
|
static void LoadCompleted(SharedScriptCache*, ScriptLoadData&);
|
|
using Base::LoadCompleted;
|
|
static void Clear(const Maybe<bool>& aChrome = Nothing(),
|
|
const Maybe<nsCOMPtr<nsIPrincipal>>& aPrincipal = Nothing(),
|
|
const Maybe<nsCString>& aSchemelessSite = Nothing(),
|
|
const Maybe<OriginAttributesPattern>& aPattern = Nothing(),
|
|
const Maybe<nsCString>& aURL = Nothing());
|
|
|
|
static void PrepareForLastCC();
|
|
|
|
protected:
|
|
~SharedScriptCache();
|
|
};
|
|
|
|
} // namespace dom
|
|
} // namespace mozilla
|
|
|
|
#endif // mozilla_dom_SharedScriptCache_h
|