зеркало из https://github.com/mozilla/gecko-dev.git
Part 7: Bug 1700623 - Make session storage session store work with Fission. r=nika
Use the newly added session storage data getter to access the session storage in the parent and store it in session store without a round trip to content processes. Depends on D111433 Differential Revision: https://phabricator.services.mozilla.com/D111434
This commit is contained in:
Родитель
d1e7d2a409
Коммит
dc6296a1ba
|
@ -3025,6 +3025,14 @@ void BrowsingContext::DidSet(FieldIndex<IDX_CurrentInnerWindowId>) {
|
|||
prevWindowContext->Canonical()->DidBecomeCurrentWindowGlobal(false);
|
||||
}
|
||||
if (mCurrentWindowContext) {
|
||||
// We set a timer when we set the current inner window. This
|
||||
// will then flush the session storage to session store to
|
||||
// make sure that we don't miss to store session storage to
|
||||
// session store that is a result of navigation. This is due
|
||||
// to Bug 1700623. We wish to fix this in Bug 1711886, where
|
||||
// making sure to store everything would make this timer
|
||||
// unnecessary.
|
||||
Canonical()->MaybeScheduleSessionStoreUpdate();
|
||||
mCurrentWindowContext->Canonical()->DidBecomeCurrentWindowGlobal(true);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "mozilla/dom/BrowsingContextGroup.h"
|
||||
#include "mozilla/dom/ContentParent.h"
|
||||
#include "mozilla/dom/EventTarget.h"
|
||||
#include "mozilla/dom/PBackgroundSessionStorageCache.h"
|
||||
#include "mozilla/dom/PWindowGlobalParent.h"
|
||||
#include "mozilla/dom/WindowGlobalParent.h"
|
||||
#include "mozilla/dom/ContentProcessManager.h"
|
||||
|
@ -42,6 +43,9 @@
|
|||
#include "nsBrowserStatusFilter.h"
|
||||
#include "nsIBrowser.h"
|
||||
#include "nsTHashSet.h"
|
||||
#include "SessionStoreFunctions.h"
|
||||
#include "nsIXPConnect.h"
|
||||
#include "nsImportModule.h"
|
||||
|
||||
#ifdef NS_PRINTING
|
||||
# include "mozilla/embedding/printingui/PrintingParent.h"
|
||||
|
@ -1022,6 +1026,8 @@ void CanonicalBrowsingContext::CanonicalDiscard() {
|
|||
if (IsTop()) {
|
||||
BackgroundSessionStorageManager::RemoveManager(Id());
|
||||
}
|
||||
|
||||
CancelSessionStoreUpdate();
|
||||
}
|
||||
|
||||
void CanonicalBrowsingContext::NotifyStartDelayedAutoplayMedia() {
|
||||
|
@ -2026,6 +2032,119 @@ void CanonicalBrowsingContext::RestoreState::Resolve() {
|
|||
mPromise = nullptr;
|
||||
}
|
||||
|
||||
nsresult CanonicalBrowsingContext::WriteSessionStorageToSessionStore(
|
||||
const nsTArray<SSCacheCopy>& aSesssionStorage, uint32_t aEpoch) {
|
||||
RefPtr<WindowGlobalParent> windowParent = GetCurrentWindowGlobal();
|
||||
|
||||
if (!windowParent) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
Element* frameElement = windowParent->GetRootOwnerElement();
|
||||
if (!frameElement) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISessionStoreFunctions> funcs =
|
||||
do_ImportModule("resource://gre/modules/SessionStoreFunctions.jsm");
|
||||
if (!funcs) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIXPConnectWrappedJS> wrapped = do_QueryInterface(funcs);
|
||||
AutoJSAPI jsapi;
|
||||
if (!jsapi.Init(wrapped->GetJSObjectGlobal())) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
Record<nsCString, Record<nsString, nsString>> storage;
|
||||
JS::RootedValue update(jsapi.cx());
|
||||
|
||||
if (!aSesssionStorage.IsEmpty()) {
|
||||
SessionStoreUtils::ConstructSessionStorageValues(this, aSesssionStorage,
|
||||
storage);
|
||||
if (!ToJSValue(jsapi.cx(), storage, &update)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
} else {
|
||||
update.setNull();
|
||||
}
|
||||
|
||||
return funcs->UpdateSessionStoreForStorage(frameElement, this, aEpoch,
|
||||
update);
|
||||
}
|
||||
|
||||
void CanonicalBrowsingContext::UpdateSessionStoreSessionStorage(
|
||||
const std::function<void()>& aDone) {
|
||||
using DataPromise = BackgroundSessionStorageManager::DataPromise;
|
||||
BackgroundSessionStorageManager::GetData(
|
||||
this, StaticPrefs::browser_sessionstore_dom_storage_limit(),
|
||||
/* aCancelSessionStoreTiemr = */ true)
|
||||
->Then(GetCurrentSerialEventTarget(), __func__,
|
||||
[self = RefPtr{this}, aDone, epoch = GetSessionStoreEpoch()](
|
||||
const DataPromise::ResolveOrRejectValue& valueList) {
|
||||
if (valueList.IsResolve()) {
|
||||
self->WriteSessionStorageToSessionStore(
|
||||
valueList.ResolveValue(), epoch);
|
||||
}
|
||||
aDone();
|
||||
});
|
||||
}
|
||||
|
||||
/* static */
|
||||
void CanonicalBrowsingContext::UpdateSessionStoreForStorage(
|
||||
uint64_t aBrowsingContextId) {
|
||||
RefPtr<CanonicalBrowsingContext> browsingContext = Get(aBrowsingContextId);
|
||||
|
||||
if (!browsingContext) {
|
||||
return;
|
||||
}
|
||||
|
||||
browsingContext->UpdateSessionStoreSessionStorage([]() {});
|
||||
}
|
||||
|
||||
void CanonicalBrowsingContext::MaybeScheduleSessionStoreUpdate() {
|
||||
if (!IsTop()) {
|
||||
Top()->MaybeScheduleSessionStoreUpdate();
|
||||
return;
|
||||
}
|
||||
|
||||
if (IsInBFCache()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mSessionStoreSessionStorageUpdateTimer) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (StaticPrefs::browser_sessionstore_debug_no_auto_updates()) {
|
||||
UpdateSessionStoreSessionStorage([]() {});
|
||||
return;
|
||||
}
|
||||
|
||||
auto result = NS_NewTimerWithFuncCallback(
|
||||
[](nsITimer*, void* aClosure) {
|
||||
auto* context = static_cast<CanonicalBrowsingContext*>(aClosure);
|
||||
context->UpdateSessionStoreSessionStorage([]() {});
|
||||
},
|
||||
this, StaticPrefs::browser_sessionstore_interval(),
|
||||
nsITimer::TYPE_ONE_SHOT,
|
||||
"CanonicalBrowsingContext::MaybeScheduleSessionStoreUpdate");
|
||||
|
||||
if (result.isErr()) {
|
||||
return;
|
||||
}
|
||||
|
||||
mSessionStoreSessionStorageUpdateTimer = result.unwrap();
|
||||
}
|
||||
|
||||
void CanonicalBrowsingContext::CancelSessionStoreUpdate() {
|
||||
if (mSessionStoreSessionStorageUpdateTimer) {
|
||||
mSessionStoreSessionStorageUpdateTimer->Cancel();
|
||||
mSessionStoreSessionStorageUpdateTimer = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void CanonicalBrowsingContext::SetContainerFeaturePolicy(
|
||||
FeaturePolicy* aContainerFeaturePolicy) {
|
||||
mContainerFeaturePolicy = aContainerFeaturePolicy;
|
||||
|
@ -2231,7 +2350,8 @@ bool CanonicalBrowsingContext::AllowedInBFCache(
|
|||
|
||||
NS_IMPL_CYCLE_COLLECTION_INHERITED(CanonicalBrowsingContext, BrowsingContext,
|
||||
mSessionHistory, mContainerFeaturePolicy,
|
||||
mCurrentBrowserParent)
|
||||
mCurrentBrowserParent,
|
||||
mSessionStoreSessionStorageUpdateTimer)
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(CanonicalBrowsingContext, BrowsingContext)
|
||||
NS_IMPL_RELEASE_INHERITED(CanonicalBrowsingContext, BrowsingContext)
|
||||
|
|
|
@ -30,6 +30,7 @@ class nsSHistory;
|
|||
class nsBrowserStatusFilter;
|
||||
class nsSecureBrowserUI;
|
||||
class CallerWillNotifyHistoryIndexAndLengthChanges;
|
||||
class nsITimer;
|
||||
|
||||
namespace mozilla {
|
||||
enum class CallState;
|
||||
|
@ -47,6 +48,7 @@ struct LoadURIOptions;
|
|||
class MediaController;
|
||||
struct LoadingSessionHistoryInfo;
|
||||
class SessionHistoryEntry;
|
||||
class SSCacheCopy;
|
||||
class WindowGlobalParent;
|
||||
|
||||
// RemotenessChangeOptions is passed through the methods to store the state
|
||||
|
@ -292,6 +294,11 @@ class CanonicalBrowsingContext final : public BrowsingContext {
|
|||
void RequestRestoreTabContent(WindowGlobalParent* aWindow);
|
||||
already_AddRefed<Promise> GetRestorePromise();
|
||||
|
||||
nsresult WriteSessionStorageToSessionStore(
|
||||
const nsTArray<SSCacheCopy>& aSesssionStorage, uint32_t aEpoch);
|
||||
|
||||
void UpdateSessionStoreSessionStorage(const std::function<void()>& aDone);
|
||||
|
||||
// Called when a BrowserParent for this BrowsingContext has been fully
|
||||
// destroyed (i.e. `ActorDestroy` was called).
|
||||
void BrowserParentDestroyed(BrowserParent* aBrowserParent,
|
||||
|
@ -405,6 +412,10 @@ class CanonicalBrowsingContext final : public BrowsingContext {
|
|||
// has become unloaded for one reason or another.
|
||||
void ShowSubframeCrashedUI(BrowserBridgeParent* aBridge);
|
||||
|
||||
void MaybeScheduleSessionStoreUpdate();
|
||||
|
||||
void CancelSessionStoreUpdate();
|
||||
|
||||
// XXX(farre): Store a ContentParent pointer here rather than mProcessId?
|
||||
// Indicates which process owns the docshell.
|
||||
uint64_t mProcessId;
|
||||
|
@ -458,6 +469,8 @@ class CanonicalBrowsingContext final : public BrowsingContext {
|
|||
// If this is a top level context, this is true if our browser ID is marked as
|
||||
// active in the process priority manager.
|
||||
bool mPriorityActive = false;
|
||||
|
||||
nsCOMPtr<nsITimer> mSessionStoreSessionStorageUpdateTimer;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
|
|
@ -117,6 +117,12 @@
|
|||
#include "mozilla/dom/BrowserBridgeHost.h"
|
||||
#include "mozilla/dom/BrowsingContextGroup.h"
|
||||
|
||||
#include "mozilla/dom/SessionStorageManager.h"
|
||||
#include "mozilla/ipc/BackgroundChild.h"
|
||||
#include "mozilla/ipc/PBackgroundChild.h"
|
||||
#include "mozilla/dom/PBackgroundSessionStorageCache.h"
|
||||
#include "mozilla/ipc/BackgroundUtils.h"
|
||||
|
||||
#include "mozilla/dom/HTMLBodyElement.h"
|
||||
|
||||
#include "mozilla/ContentPrincipal.h"
|
||||
|
@ -134,6 +140,7 @@ using namespace mozilla;
|
|||
using namespace mozilla::hal;
|
||||
using namespace mozilla::dom;
|
||||
using namespace mozilla::dom::ipc;
|
||||
using namespace mozilla::ipc;
|
||||
using namespace mozilla::layers;
|
||||
using namespace mozilla::layout;
|
||||
typedef ScrollableLayerGuid::ViewID ViewID;
|
||||
|
@ -3189,42 +3196,28 @@ already_AddRefed<Promise> nsFrameLoader::RequestTabStateFlush(
|
|||
if (mSessionStoreListener) {
|
||||
context->FlushSessionStore();
|
||||
mSessionStoreListener->ForceFlushFromParent(false);
|
||||
context->Canonical()->UpdateSessionStoreSessionStorage(
|
||||
[promise]() { promise->MaybeResolveWithUndefined(); });
|
||||
|
||||
// No async ipc call is involved in parent only case
|
||||
promise->MaybeResolveWithUndefined();
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
// XXX(farre): We hack around not having fully implemented session
|
||||
// store session storage collection in the parent. What we need to
|
||||
// do is to make sure that we always flush the toplevel context
|
||||
// first. And also to wait for that flush to resolve. This will be
|
||||
// fixed by moving session storage collection to the parent, which
|
||||
// will happen in Bug 1700623.
|
||||
RefPtr<ContentParent> contentParent =
|
||||
context->Canonical()->GetContentParent();
|
||||
using FlushPromise = ContentParent::FlushTabStatePromise;
|
||||
contentParent->SendFlushTabState(context)->Then(
|
||||
GetCurrentSerialEventTarget(), __func__,
|
||||
[promise, context,
|
||||
contentParent](const FlushPromise::ResolveOrRejectValue&) {
|
||||
nsTArray<RefPtr<FlushPromise>> flushPromises;
|
||||
context->Group()->EachOtherParent(
|
||||
contentParent, [&](ContentParent* aParent) {
|
||||
if (aParent->CanSend()) {
|
||||
flushPromises.AppendElement(
|
||||
aParent->SendFlushTabState(context));
|
||||
}
|
||||
});
|
||||
nsTArray<RefPtr<FlushPromise>> flushPromises;
|
||||
context->Group()->EachParent([&](ContentParent* aParent) {
|
||||
if (aParent->CanSend()) {
|
||||
flushPromises.AppendElement(aParent->SendFlushTabState(context));
|
||||
}
|
||||
});
|
||||
|
||||
FlushPromise::All(GetCurrentSerialEventTarget(), flushPromises)
|
||||
->Then(
|
||||
GetCurrentSerialEventTarget(), __func__,
|
||||
[promise](
|
||||
const FlushPromise::AllPromiseType::ResolveOrRejectValue&) {
|
||||
promise->MaybeResolveWithUndefined();
|
||||
});
|
||||
});
|
||||
RefPtr<FlushPromise::AllPromiseType> flushPromise =
|
||||
FlushPromise::All(GetCurrentSerialEventTarget(), flushPromises);
|
||||
|
||||
context->Canonical()->UpdateSessionStoreSessionStorage([flushPromise,
|
||||
promise]() {
|
||||
flushPromise->Then(GetCurrentSerialEventTarget(), __func__,
|
||||
[promise]() { promise->MaybeResolveWithUndefined(); });
|
||||
});
|
||||
|
||||
return promise.forget();
|
||||
}
|
||||
|
@ -3241,7 +3234,6 @@ void nsFrameLoader::RequestTabStateFlush() {
|
|||
// No async ipc call is involved in parent only case
|
||||
return;
|
||||
}
|
||||
|
||||
context->Group()->EachParent([&](ContentParent* aParent) {
|
||||
if (aParent->CanSend()) {
|
||||
aParent->SendFlushTabState(
|
||||
|
|
|
@ -180,11 +180,6 @@ dictionary InputElementData {
|
|||
dictionary UpdateSessionStoreData {
|
||||
ByteString docShellCaps;
|
||||
boolean isPrivate;
|
||||
// for sessionStorage
|
||||
sequence<ByteString> storageOrigins;
|
||||
sequence<DOMString> storageKeys;
|
||||
sequence<DOMString> storageValues;
|
||||
boolean isFullStorage;
|
||||
};
|
||||
|
||||
[GenerateConversionToJS]
|
||||
|
|
|
@ -3791,15 +3791,7 @@ bool BrowserChild::UpdateSessionStore(bool aIsFinal) {
|
|||
privatedMode.emplace(store->GetPrivateModeEnabled());
|
||||
}
|
||||
|
||||
nsTArray<nsCString> origins;
|
||||
nsTArray<nsString> keys, values;
|
||||
bool isFullStorage = false;
|
||||
if (store->IsStorageUpdated()) {
|
||||
isFullStorage = store->GetAndClearStorageChanges(origins, keys, values);
|
||||
}
|
||||
|
||||
Unused << SendSessionStoreUpdate(docShellCaps, privatedMode, origins, keys,
|
||||
values, isFullStorage,
|
||||
Unused << SendSessionStoreUpdate(docShellCaps, privatedMode,
|
||||
store->GetAndClearSHistoryChanged(),
|
||||
aIsFinal, mSessionStoreListener->GetEpoch());
|
||||
return true;
|
||||
|
|
|
@ -2951,8 +2951,6 @@ bool BrowserParent::ReconstructWebProgressAndRequest(
|
|||
|
||||
mozilla::ipc::IPCResult BrowserParent::RecvSessionStoreUpdate(
|
||||
const Maybe<nsCString>& aDocShellCaps, const Maybe<bool>& aPrivatedMode,
|
||||
nsTArray<nsCString>&& aOrigins, nsTArray<nsString>&& aKeys,
|
||||
nsTArray<nsString>&& aValues, const bool aIsFullStorage,
|
||||
const bool aNeedCollectSHistory, const bool& aIsFinal,
|
||||
const uint32_t& aEpoch) {
|
||||
UpdateSessionStoreData data;
|
||||
|
@ -2962,16 +2960,6 @@ mozilla::ipc::IPCResult BrowserParent::RecvSessionStoreUpdate(
|
|||
if (aPrivatedMode.isSome()) {
|
||||
data.mIsPrivate.Construct() = aPrivatedMode.value();
|
||||
}
|
||||
// In normal case, we only update the storage when needed.
|
||||
// However, we need to reset the session storage(aOrigins.Length() will be 0)
|
||||
// if the usage is over the "browser_sessionstore_dom_storage_limit".
|
||||
// In this case, aIsFullStorage is true.
|
||||
if (aOrigins.Length() != 0 || aIsFullStorage) {
|
||||
data.mStorageOrigins.Construct(std::move(aOrigins));
|
||||
data.mStorageKeys.Construct(std::move(aKeys));
|
||||
data.mStorageValues.Construct(std::move(aValues));
|
||||
data.mIsFullStorage.Construct() = aIsFullStorage;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISessionStoreFunctions> funcs =
|
||||
do_ImportModule("resource://gre/modules/SessionStoreFunctions.jsm");
|
||||
|
|
|
@ -314,8 +314,6 @@ class BrowserParent final : public PBrowserParent,
|
|||
|
||||
mozilla::ipc::IPCResult RecvSessionStoreUpdate(
|
||||
const Maybe<nsCString>& aDocShellCaps, const Maybe<bool>& aPrivatedMode,
|
||||
nsTArray<nsCString>&& aOrigins, nsTArray<nsString>&& aKeys,
|
||||
nsTArray<nsString>&& aValues, const bool aIsFullStorage,
|
||||
const bool aNeedCollectSHistory, const bool& aIsFinal,
|
||||
const uint32_t& aEpoch);
|
||||
|
||||
|
|
|
@ -563,8 +563,6 @@ parent:
|
|||
async NavigationFinished();
|
||||
|
||||
async SessionStoreUpdate(nsCString? aDocShellCaps, bool? aPrivatedMode,
|
||||
nsCString[] aOrigins, nsString[] aKeys,
|
||||
nsString[] aValues, bool aIsFullStorage,
|
||||
bool aNeedCollectSHistory,
|
||||
bool aIsFinal, uint32_t aEpoch);
|
||||
|
||||
|
|
|
@ -67,6 +67,8 @@
|
|||
#include "nsIXPConnect.h"
|
||||
#include "nsImportModule.h"
|
||||
|
||||
#include "mozilla/dom/PBackgroundSessionStorageCache.h"
|
||||
|
||||
using namespace mozilla::ipc;
|
||||
using namespace mozilla::dom::ipc;
|
||||
|
||||
|
@ -1244,7 +1246,7 @@ Element* WindowGlobalParent::GetRootOwnerElement() {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
nsresult WindowGlobalParent::UpdateSessionStore(
|
||||
nsresult WindowGlobalParent::WriteFormDataAndScrollToSessionStore(
|
||||
const Maybe<FormData>& aFormData, const Maybe<nsPoint>& aScrollPosition,
|
||||
uint32_t aEpoch) {
|
||||
if (!aFormData && !aScrollPosition) {
|
||||
|
@ -1342,7 +1344,8 @@ nsresult WindowGlobalParent::ResetSessionStore(uint32_t aEpoch) {
|
|||
mozilla::ipc::IPCResult WindowGlobalParent::RecvUpdateSessionStore(
|
||||
const Maybe<FormData>& aFormData, const Maybe<nsPoint>& aScrollPosition,
|
||||
uint32_t aEpoch) {
|
||||
if (NS_FAILED(UpdateSessionStore(aFormData, aScrollPosition, aEpoch))) {
|
||||
if (NS_FAILED(WriteFormDataAndScrollToSessionStore(aFormData, aScrollPosition,
|
||||
aEpoch))) {
|
||||
MOZ_LOG(BrowsingContext::GetLog(), LogLevel::Debug,
|
||||
("ParentIPC: Failed to update session store entry."));
|
||||
}
|
||||
|
|
|
@ -46,6 +46,7 @@ class JSActorMessageMeta;
|
|||
struct PageUseCounters;
|
||||
class WindowSessionStoreState;
|
||||
struct WindowSessionStoreUpdate;
|
||||
class SSCacheQueryResult;
|
||||
|
||||
/**
|
||||
* A handle in the parent process to a specific nsGlobalWindowInner object.
|
||||
|
@ -213,9 +214,9 @@ class WindowGlobalParent final : public WindowContext,
|
|||
|
||||
const nsACString& GetRemoteType() override;
|
||||
|
||||
nsresult UpdateSessionStore(const Maybe<FormData>& aFormData,
|
||||
const Maybe<nsPoint>& aScrollPosition,
|
||||
uint32_t aEpoch);
|
||||
nsresult WriteFormDataAndScrollToSessionStore(
|
||||
const Maybe<FormData>& aFormData, const Maybe<nsPoint>& aScrollPosition,
|
||||
uint32_t aEpoch);
|
||||
|
||||
Maybe<uint64_t> GetSingleChannelId() { return mSingleChannelId; }
|
||||
|
||||
|
|
|
@ -145,7 +145,8 @@ void SessionStoreDataCollector::Collect() {
|
|||
|
||||
if (RefPtr<WindowGlobalParent> windowParent =
|
||||
mWindowChild->GetParentActor()) {
|
||||
windowParent->UpdateSessionStore(maybeFormData, maybeScroll, mEpoch);
|
||||
windowParent->WriteFormDataAndScrollToSessionStore(maybeFormData,
|
||||
maybeScroll, mEpoch);
|
||||
} else {
|
||||
mWindowChild->SendUpdateSessionStore(maybeFormData, maybeScroll, mEpoch);
|
||||
}
|
||||
|
|
|
@ -20,4 +20,8 @@ interface nsISessionStoreFunctions : nsISupports {
|
|||
void UpdateSessionStoreForWindow(
|
||||
in Element aBrowser, in BrowsingContext aBrowsingContext,
|
||||
in uint32_t aEpoch, in jsval aData);
|
||||
|
||||
void UpdateSessionStoreForStorage(
|
||||
in Element aBrowser, in BrowsingContext aBrowsingContext,
|
||||
in uint32_t aEpoch, in jsval aData);
|
||||
};
|
||||
|
|
|
@ -40,37 +40,27 @@ function UpdateSessionStoreForWindow(
|
|||
);
|
||||
}
|
||||
|
||||
var EXPORTED_SYMBOLS = ["UpdateSessionStore", "UpdateSessionStoreForWindow"];
|
||||
function UpdateSessionStoreForStorage(
|
||||
aBrowser,
|
||||
aBrowsingContext,
|
||||
aEpoch,
|
||||
aData
|
||||
) {
|
||||
return SessionStoreFuncInternal.updateSessionStoreForStorage(
|
||||
aBrowser,
|
||||
aBrowsingContext,
|
||||
aEpoch,
|
||||
aData
|
||||
);
|
||||
}
|
||||
|
||||
var EXPORTED_SYMBOLS = [
|
||||
"UpdateSessionStore",
|
||||
"UpdateSessionStoreForWindow",
|
||||
"UpdateSessionStoreForStorage",
|
||||
];
|
||||
|
||||
var SessionStoreFuncInternal = {
|
||||
updateStorage: function SSF_updateStorage(aOrigins, aKeys, aValues) {
|
||||
let data = {};
|
||||
for (let i = 0; i < aOrigins.length; i++) {
|
||||
// If the key isn't defined, then .clear() was called, and we send
|
||||
// up null for this domain to indicate that storage has been cleared
|
||||
// for it.
|
||||
if (aKeys[i] == "") {
|
||||
while (aOrigins[i + 1] == aOrigins[i]) {
|
||||
i++;
|
||||
}
|
||||
data[aOrigins[i]] = null;
|
||||
} else {
|
||||
let hostData = {};
|
||||
hostData[aKeys[i]] = aValues[i];
|
||||
while (aOrigins[i + 1] == aOrigins[i]) {
|
||||
i++;
|
||||
hostData[aKeys[i]] = aValues[i];
|
||||
}
|
||||
data[aOrigins[i]] = hostData;
|
||||
}
|
||||
}
|
||||
if (aOrigins.length) {
|
||||
return data;
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
|
||||
updateSessionStore: function SSF_updateSessionStore(
|
||||
aBrowser,
|
||||
aBrowsingContext,
|
||||
|
@ -86,25 +76,13 @@ var SessionStoreFuncInternal = {
|
|||
currentData.isPrivate = aData.isPrivate;
|
||||
}
|
||||
|
||||
if (aData.isFullStorage != undefined) {
|
||||
let storage = this.updateStorage(
|
||||
aData.storageOrigins,
|
||||
aData.storageKeys,
|
||||
aData.storageValues
|
||||
);
|
||||
if (aData.isFullStorage) {
|
||||
currentData.storage = storage;
|
||||
} else {
|
||||
currentData.storagechange = storage;
|
||||
}
|
||||
}
|
||||
|
||||
SessionStore.updateSessionStoreFromTablistener(aBrowser, aBrowsingContext, {
|
||||
data: currentData,
|
||||
epoch: aEpoch,
|
||||
sHistoryNeeded: aCollectSHistory,
|
||||
});
|
||||
},
|
||||
|
||||
updateSessionStoreForWindow: function SSF_updateSessionStoreForWindow(
|
||||
aBrowser,
|
||||
aBrowsingContext,
|
||||
|
@ -118,4 +96,16 @@ var SessionStoreFuncInternal = {
|
|||
epoch: aEpoch,
|
||||
});
|
||||
},
|
||||
|
||||
updateSessionStoreForStorage: function SSF_updateSessionStoreForWindow(
|
||||
aBrowser,
|
||||
aBrowsingContext,
|
||||
aEpoch,
|
||||
aData
|
||||
) {
|
||||
SessionStore.updateSessionStoreFromTablistener(aBrowser, aBrowsingContext, {
|
||||
data: { storage: aData },
|
||||
epoch: aEpoch,
|
||||
});
|
||||
},
|
||||
};
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
#include "mozilla/dom/SessionStoreListener.h"
|
||||
#include "mozilla/dom/SessionStoreUtils.h"
|
||||
#include "mozilla/dom/SessionStoreUtilsBinding.h"
|
||||
#include "mozilla/dom/StorageEvent.h"
|
||||
#include "mozilla/dom/BrowserChild.h"
|
||||
#include "mozilla/StaticPrefs_browser.h"
|
||||
#include "nsGenericHTMLElement.h"
|
||||
|
@ -44,7 +43,6 @@ ContentSessionStore::ContentSessionStore(nsIDocShell* aDocShell)
|
|||
: mDocShell(aDocShell),
|
||||
mPrivateChanged(false),
|
||||
mIsPrivate(false),
|
||||
mStorageStatus(NO_STORAGE),
|
||||
mDocCapChanged(false),
|
||||
mSHistoryChanged(false),
|
||||
mSHistoryChangedFromParent(false) {
|
||||
|
@ -104,18 +102,6 @@ bool ContentSessionStore::GetPrivateModeEnabled() {
|
|||
return mIsPrivate;
|
||||
}
|
||||
|
||||
void ContentSessionStore::SetFullStorageNeeded() {
|
||||
// We need the entire session storage, reset the pending individual change
|
||||
ResetStorageChanges();
|
||||
mStorageStatus = FULLSTORAGE;
|
||||
}
|
||||
|
||||
void ContentSessionStore::ResetStorageChanges() {
|
||||
mOrigins.Clear();
|
||||
mKeys.Clear();
|
||||
mValues.Clear();
|
||||
}
|
||||
|
||||
void ContentSessionStore::SetSHistoryChanged() {
|
||||
mSHistoryChanged = mozilla::SessionHistoryInParent();
|
||||
}
|
||||
|
@ -132,15 +118,12 @@ void ContentSessionStore::OnDocumentStart() {
|
|||
mDocCapChanged = true;
|
||||
}
|
||||
|
||||
SetFullStorageNeeded();
|
||||
|
||||
if (mozilla::SessionHistoryInParent()) {
|
||||
mSHistoryChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
void ContentSessionStore::OnDocumentEnd() {
|
||||
SetFullStorageNeeded();
|
||||
if (mozilla::SessionHistoryInParent()) {
|
||||
mSHistoryChanged = true;
|
||||
}
|
||||
|
@ -167,8 +150,6 @@ TabListener::TabListener(nsIDocShell* aDocShell, Element* aElement)
|
|||
mProgressListenerRegistered(false),
|
||||
mEventListenerRegistered(false),
|
||||
mPrefObserverRegistered(false),
|
||||
mStorageObserverRegistered(false),
|
||||
mStorageChangeListenerRegistered(false),
|
||||
mUpdatedTimer(nullptr),
|
||||
mTimeoutDisabled(false),
|
||||
mUpdateInterval(15000),
|
||||
|
@ -208,13 +189,6 @@ nsresult TabListener::Init() {
|
|||
mPrefObserverRegistered = true;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
|
||||
NS_WARNING_ASSERTION(obs, "no observer service");
|
||||
if (obs) {
|
||||
obs->AddObserver(this, "browser:purge-sessionStorage", true);
|
||||
mStorageObserverRegistered = true;
|
||||
}
|
||||
|
||||
AddEventListeners();
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -225,10 +199,6 @@ void TabListener::AddEventListeners() {
|
|||
eventTarget->AddSystemEventListener(u"DOMTitleChanged"_ns, this, false);
|
||||
}
|
||||
mEventListenerRegistered = true;
|
||||
|
||||
eventTarget->AddSystemEventListener(u"MozSessionStorageChanged"_ns, this,
|
||||
false);
|
||||
mStorageChangeListenerRegistered = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -241,11 +211,6 @@ void TabListener::RemoveEventListeners() {
|
|||
}
|
||||
mEventListenerRegistered = false;
|
||||
}
|
||||
if (mStorageChangeListenerRegistered) {
|
||||
eventTarget->RemoveSystemEventListener(u"MozSessionStorageChanged"_ns,
|
||||
this, false);
|
||||
mStorageChangeListenerRegistered = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -324,7 +289,6 @@ NS_IMETHODIMP TabListener::OnStateChange(nsIWebProgress* aWebProgress,
|
|||
|
||||
if (aStateFlags & (nsIWebProgressListener::STATE_START)) {
|
||||
mSessionStore->OnDocumentStart();
|
||||
ResetStorageChangeListener();
|
||||
} else if (aStateFlags & (nsIWebProgressListener::STATE_STOP)) {
|
||||
mSessionStore->OnDocumentEnd();
|
||||
}
|
||||
|
@ -351,24 +315,7 @@ TabListener::HandleEvent(Event* aEvent) {
|
|||
|
||||
nsAutoString eventType;
|
||||
aEvent->GetType(eventType);
|
||||
if (eventType.EqualsLiteral("MozSessionStorageChanged")) {
|
||||
auto event = static_cast<StorageEvent*>(aEvent);
|
||||
RefPtr<Storage> changingStorage = event->GetStorageArea();
|
||||
if (!changingStorage) {
|
||||
return NS_OK;
|
||||
}
|
||||
// How much data does DOMSessionStorage contain?
|
||||
int64_t storageUsage = changingStorage->GetOriginQuotaUsage();
|
||||
if (storageUsage > StaticPrefs::browser_sessionstore_dom_storage_limit()) {
|
||||
RemoveStorageChangeListener();
|
||||
mSessionStore->ResetStorageChanges();
|
||||
mSessionStore->ResetStorage();
|
||||
return NS_OK;
|
||||
}
|
||||
if (mSessionStore->AppendSessionStorageChange(event)) {
|
||||
AddTimerForUpdate();
|
||||
}
|
||||
} else if (eventType.EqualsLiteral("DOMTitleChanged")) {
|
||||
if (eventType.EqualsLiteral("DOMTitleChanged")) {
|
||||
mSessionStore->SetSHistoryChanged();
|
||||
AddTimerForUpdate();
|
||||
}
|
||||
|
@ -411,12 +358,6 @@ NS_IMETHODIMP TabListener::OnContentBlockingEvent(nsIWebProgress* aWebProgress,
|
|||
|
||||
nsresult TabListener::Observe(nsISupports* aSubject, const char* aTopic,
|
||||
const char16_t* aData) {
|
||||
if (!strcmp(aTopic, "browser:purge-sessionStorage")) {
|
||||
mSessionStore->SetFullStorageNeeded();
|
||||
AddTimerForUpdate();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (!strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID)) {
|
||||
nsCOMPtr<nsIPrefBranch> prefBranch = do_QueryInterface(aSubject);
|
||||
|
||||
|
@ -496,61 +437,6 @@ int CollectPositions(BrowsingContext* aBrowsingContext,
|
|||
return aPositionDescendants[currentIdx] + 1;
|
||||
}
|
||||
|
||||
bool ContentSessionStore::AppendSessionStorageChange(StorageEvent* aEvent) {
|
||||
// We will collect the full SessionStore if mStorageStatus is FULLSTORAGE.
|
||||
// These partial changes can be skipped in this case.
|
||||
if (mStorageStatus == FULLSTORAGE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
RefPtr<Storage> changingStorage = aEvent->GetStorageArea();
|
||||
if (!changingStorage) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPrincipal> storagePrincipal = changingStorage->StoragePrincipal();
|
||||
if (!storagePrincipal) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsAutoCString origin;
|
||||
nsresult rv = storagePrincipal->GetOrigin(origin);
|
||||
if (NS_FAILED(rv)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mOrigins.AppendElement(origin);
|
||||
aEvent->GetKey(*mKeys.AppendElement());
|
||||
aEvent->GetNewValue(*mValues.AppendElement());
|
||||
mStorageStatus = STORAGECHANGE;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ContentSessionStore::GetAndClearStorageChanges(
|
||||
nsTArray<nsCString>& aOrigins, nsTArray<nsString>& aKeys,
|
||||
nsTArray<nsString>& aValues) {
|
||||
MOZ_ASSERT(IsStorageUpdated());
|
||||
bool isFullStorage = false;
|
||||
|
||||
if (mStorageStatus == RESET) {
|
||||
isFullStorage = true;
|
||||
} else if (mStorageStatus == FULLSTORAGE) {
|
||||
MOZ_ASSERT(mDocShell);
|
||||
SessionStoreUtils::CollectedSessionStorage(
|
||||
nsDocShell::Cast(mDocShell)->GetBrowsingContext(), aOrigins, aKeys,
|
||||
aValues);
|
||||
isFullStorage = true;
|
||||
} else if (mStorageStatus == STORAGECHANGE) {
|
||||
aOrigins.SwapElements(mOrigins);
|
||||
aKeys.SwapElements(mKeys);
|
||||
aValues.SwapElements(mValues);
|
||||
}
|
||||
|
||||
ResetStorageChanges();
|
||||
mStorageStatus = NO_STORAGE;
|
||||
return isFullStorage;
|
||||
}
|
||||
|
||||
bool TabListener::ForceFlushFromParent(bool aIsFinal) {
|
||||
if (!XRE_IsParentProcess()) {
|
||||
return false;
|
||||
|
@ -610,15 +496,6 @@ bool TabListener::UpdateSessionStore(bool aIsFlush, bool aIsFinal) {
|
|||
if (mSessionStore->IsPrivateChanged()) {
|
||||
data.mIsPrivate.Construct() = mSessionStore->GetPrivateModeEnabled();
|
||||
}
|
||||
if (mSessionStore->IsStorageUpdated()) {
|
||||
nsTArray<nsCString> origins;
|
||||
nsTArray<nsString> keys, values;
|
||||
data.mIsFullStorage.Construct() =
|
||||
mSessionStore->GetAndClearStorageChanges(origins, keys, values);
|
||||
data.mStorageOrigins.Construct(std::move(origins));
|
||||
data.mStorageKeys.Construct(std::move(keys));
|
||||
data.mStorageValues.Construct(std::move(values));
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISessionStoreFunctions> funcs =
|
||||
do_ImportModule("resource://gre/modules/SessionStoreFunctions.jsm");
|
||||
|
@ -638,33 +515,6 @@ bool TabListener::UpdateSessionStore(bool aIsFlush, bool aIsFinal) {
|
|||
return true;
|
||||
}
|
||||
|
||||
void TabListener::ResetStorageChangeListener() {
|
||||
if (mStorageChangeListenerRegistered) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<EventTarget> eventTarget = GetEventTarget();
|
||||
if (!eventTarget) {
|
||||
return;
|
||||
}
|
||||
eventTarget->AddSystemEventListener(u"MozSessionStorageChanged"_ns, this,
|
||||
false);
|
||||
mStorageChangeListenerRegistered = true;
|
||||
}
|
||||
|
||||
void TabListener::RemoveStorageChangeListener() {
|
||||
if (!mStorageChangeListenerRegistered) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<EventTarget> eventTarget = GetEventTarget();
|
||||
if (eventTarget) {
|
||||
eventTarget->RemoveSystemEventListener(u"MozSessionStorageChanged"_ns, this,
|
||||
false);
|
||||
mStorageChangeListenerRegistered = false;
|
||||
}
|
||||
}
|
||||
|
||||
void TabListener::RemoveListeners() {
|
||||
if (mProgressListenerRegistered) {
|
||||
nsCOMPtr<nsIWebProgress> webProgress = do_QueryInterface(mDocShell);
|
||||
|
@ -676,7 +526,7 @@ void TabListener::RemoveListeners() {
|
|||
|
||||
RemoveEventListeners();
|
||||
|
||||
if (mPrefObserverRegistered || mStorageObserverRegistered) {
|
||||
if (mPrefObserverRegistered) {
|
||||
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
|
||||
if (!obs) {
|
||||
return;
|
||||
|
@ -686,10 +536,6 @@ void TabListener::RemoveListeners() {
|
|||
obs->RemoveObserver(this, kPrefInterval);
|
||||
mPrefObserverRegistered = false;
|
||||
}
|
||||
if (mStorageObserverRegistered) {
|
||||
obs->RemoveObserver(this, "browser:purge-sessionStorage");
|
||||
mStorageObserverRegistered = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -19,8 +19,6 @@ class nsITimer;
|
|||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class StorageEvent;
|
||||
|
||||
class ContentSessionStore {
|
||||
public:
|
||||
explicit ContentSessionStore(nsIDocShell* aDocShell);
|
||||
|
@ -33,31 +31,6 @@ class ContentSessionStore {
|
|||
bool IsPrivateChanged() { return mPrivateChanged; }
|
||||
bool GetPrivateModeEnabled();
|
||||
|
||||
// Use "mStorageStatus" to manage the status of storageChanges
|
||||
bool IsStorageUpdated() { return mStorageStatus != NO_STORAGE; }
|
||||
void ResetStorage() { mStorageStatus = RESET; }
|
||||
/*
|
||||
There are three situations we need entire session storage:
|
||||
1. OnDocumentStart: PageLoad started
|
||||
2. OnDocumentEnd: PageLoad completed
|
||||
3. receive "browser:purge-sessionStorage" event
|
||||
Use SetFullStorageNeeded() to set correct "mStorageStatus" and
|
||||
reset the pending individual change.
|
||||
*/
|
||||
void SetFullStorageNeeded();
|
||||
void ResetStorageChanges();
|
||||
// GetAndClearStorageChanges() is used for getting storageChanges.
|
||||
// It clears the stored storage changes before returning.
|
||||
// It will return true if it is a entire session storage.
|
||||
// Otherwise, it will return false.
|
||||
bool GetAndClearStorageChanges(nsTArray<nsCString>& aOrigins,
|
||||
nsTArray<nsString>& aKeys,
|
||||
nsTArray<nsString>& aValues);
|
||||
// Using AppendSessionStorageChange() to append session storage change when
|
||||
// receiving "MozSessionStorageChanged".
|
||||
// Return true if there is a new storage change which is appended.
|
||||
bool AppendSessionStorageChange(StorageEvent* aEvent);
|
||||
|
||||
void SetSHistoryChanged();
|
||||
// request "collect sessionHistory" which is happened in the parent process
|
||||
void SetSHistoryFromParentChanged();
|
||||
|
@ -71,8 +44,8 @@ class ContentSessionStore {
|
|||
void OnDocumentStart();
|
||||
void OnDocumentEnd();
|
||||
bool UpdateNeeded() {
|
||||
return mPrivateChanged || mDocCapChanged || IsStorageUpdated() ||
|
||||
mSHistoryChanged || mSHistoryChangedFromParent;
|
||||
return mPrivateChanged || mDocCapChanged || mSHistoryChanged ||
|
||||
mSHistoryChangedFromParent;
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -82,18 +55,8 @@ class ContentSessionStore {
|
|||
nsCOMPtr<nsIDocShell> mDocShell;
|
||||
bool mPrivateChanged;
|
||||
bool mIsPrivate;
|
||||
enum {
|
||||
NO_STORAGE,
|
||||
RESET,
|
||||
FULLSTORAGE,
|
||||
STORAGECHANGE,
|
||||
} mStorageStatus;
|
||||
bool mDocCapChanged;
|
||||
nsCString mDocCaps;
|
||||
// mOrigins, mKeys, mValues are for sessionStorage partial changes
|
||||
nsTArray<nsCString> mOrigins;
|
||||
nsTArray<nsString> mKeys;
|
||||
nsTArray<nsString> mValues;
|
||||
// mSHistoryChanged means there are history changes which are found
|
||||
// in the child process. The flag is set when
|
||||
// 1. webProgress changes to STATE_START
|
||||
|
@ -138,8 +101,6 @@ class TabListener : public nsIDOMEventListener,
|
|||
void AddEventListeners();
|
||||
void RemoveEventListeners();
|
||||
bool UpdateSessionStore(bool aIsFlush = false, bool aIsFinal = false);
|
||||
void ResetStorageChangeListener();
|
||||
void RemoveStorageChangeListener();
|
||||
virtual ~TabListener();
|
||||
|
||||
nsCOMPtr<nsIDocShell> mDocShell;
|
||||
|
@ -148,8 +109,6 @@ class TabListener : public nsIDOMEventListener,
|
|||
bool mProgressListenerRegistered;
|
||||
bool mEventListenerRegistered;
|
||||
bool mPrefObserverRegistered;
|
||||
bool mStorageObserverRegistered;
|
||||
bool mStorageChangeListenerRegistered;
|
||||
// Timer used to update data
|
||||
nsCOMPtr<nsITimer> mUpdatedTimer;
|
||||
bool mTimeoutDisabled;
|
||||
|
|
|
@ -24,6 +24,8 @@
|
|||
#include "mozilla/dom/XPathResult.h"
|
||||
#include "mozilla/dom/XPathEvaluator.h"
|
||||
#include "mozilla/dom/XPathExpression.h"
|
||||
#include "mozilla/dom/PBackgroundSessionStorageCache.h"
|
||||
#include "mozilla/ipc/BackgroundUtils.h"
|
||||
#include "mozilla/ReverseIterator.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "nsCharSeparatedTokenizer.h"
|
||||
|
@ -1262,105 +1264,6 @@ void SessionStoreUtils::RestoreFormData(
|
|||
}
|
||||
}
|
||||
|
||||
/* Read entries in the session storage data contained in a tab's history. */
|
||||
static void ReadAllEntriesFromStorage(nsPIDOMWindowOuter* aWindow,
|
||||
nsTArray<nsCString>& aOrigins,
|
||||
nsTArray<nsString>& aKeys,
|
||||
nsTArray<nsString>& aValues) {
|
||||
BrowsingContext* const browsingContext = aWindow->GetBrowsingContext();
|
||||
if (!browsingContext) {
|
||||
return;
|
||||
}
|
||||
|
||||
Document* doc = aWindow->GetDoc();
|
||||
if (!doc) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPrincipal> principal = doc->NodePrincipal();
|
||||
if (!principal) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPrincipal> storagePrincipal = doc->EffectiveStoragePrincipal();
|
||||
if (!storagePrincipal) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsAutoCString origin;
|
||||
nsresult rv = storagePrincipal->GetOrigin(origin);
|
||||
if (NS_FAILED(rv) || aOrigins.Contains(origin)) {
|
||||
// Don't read a host twice.
|
||||
return;
|
||||
}
|
||||
|
||||
/* Completed checking for recursion and is about to read storage*/
|
||||
const RefPtr<SessionStorageManager> storageManager =
|
||||
browsingContext->GetSessionStorageManager();
|
||||
if (!storageManager) {
|
||||
return;
|
||||
}
|
||||
RefPtr<Storage> storage;
|
||||
storageManager->GetStorage(aWindow->GetCurrentInnerWindow(), principal,
|
||||
storagePrincipal, false, getter_AddRefs(storage));
|
||||
if (!storage) {
|
||||
return;
|
||||
}
|
||||
mozilla::IgnoredErrorResult result;
|
||||
uint32_t len = storage->GetLength(*principal, result);
|
||||
if (result.Failed() || len == 0) {
|
||||
return;
|
||||
}
|
||||
int64_t storageUsage = storage->GetOriginQuotaUsage();
|
||||
if (storageUsage > StaticPrefs::browser_sessionstore_dom_storage_limit()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < len; i++) {
|
||||
nsString key, value;
|
||||
mozilla::IgnoredErrorResult res;
|
||||
storage->Key(i, key, *principal, res);
|
||||
if (res.Failed()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
storage->GetItem(key, value, *principal, res);
|
||||
if (res.Failed()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
aKeys.AppendElement(key);
|
||||
aValues.AppendElement(value);
|
||||
aOrigins.AppendElement(origin);
|
||||
}
|
||||
}
|
||||
|
||||
/* Collect Collect session storage from current frame and all child frame */
|
||||
/* static */
|
||||
void SessionStoreUtils::CollectedSessionStorage(
|
||||
BrowsingContext* aBrowsingContext, nsTArray<nsCString>& aOrigins,
|
||||
nsTArray<nsString>& aKeys, nsTArray<nsString>& aValues) {
|
||||
/* Collect session store from current frame */
|
||||
nsPIDOMWindowOuter* window = aBrowsingContext->GetDOMWindow();
|
||||
if (!window) {
|
||||
return;
|
||||
}
|
||||
ReadAllEntriesFromStorage(window, aOrigins, aKeys, aValues);
|
||||
|
||||
/* Collect session storage from all child frame */
|
||||
if (!window->GetDocShell()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// This is not going to work for fission. Bug 1572084 for tracking it.
|
||||
for (BrowsingContext* child : aBrowsingContext->Children()) {
|
||||
if (!child->CreatedDynamically()) {
|
||||
SessionStoreUtils::CollectedSessionStorage(child, aOrigins, aKeys,
|
||||
aValues);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* static */
|
||||
void SessionStoreUtils::RestoreSessionStorage(
|
||||
const GlobalObject& aGlobal, nsIDocShell* aDocShell,
|
||||
|
@ -1804,6 +1707,83 @@ nsresult SessionStoreUtils::ConstructFormDataValues(
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
static nsresult ConstructSessionStorageValue(
|
||||
const nsTArray<SSSetItemInfo>& aValues,
|
||||
Record<nsString, nsString>& aRecord) {
|
||||
auto& entries = aRecord.Entries();
|
||||
for (const auto& value : aValues) {
|
||||
auto entry = entries.AppendElement();
|
||||
entry->mKey = value.key();
|
||||
entry->mValue = value.value();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* static */
|
||||
nsresult SessionStoreUtils::ConstructSessionStorageValues(
|
||||
CanonicalBrowsingContext* aBrowsingContext,
|
||||
const nsTArray<SSCacheCopy>& aValues,
|
||||
Record<nsCString, Record<nsString, nsString>>& aRecord) {
|
||||
if (!aRecord.Entries().SetCapacity(aValues.Length(), fallible)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// We wish to remove this step of mapping originAttributes+originKey
|
||||
// to a storage principal in Bug 1711886 by consolidating the
|
||||
// storage format in SessionStorageManagerBase and Session Store.
|
||||
nsTHashMap<nsCStringHashKey, nsIPrincipal*> storagePrincipalList;
|
||||
aBrowsingContext->PreOrderWalk([&storagePrincipalList](
|
||||
BrowsingContext* aContext) {
|
||||
WindowGlobalParent* windowParent =
|
||||
aContext->Canonical()->GetCurrentWindowGlobal();
|
||||
if (!windowParent) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsIPrincipal* storagePrincipal = windowParent->DocumentStoragePrincipal();
|
||||
if (!storagePrincipal) {
|
||||
return;
|
||||
}
|
||||
|
||||
const OriginAttributes& originAttributes =
|
||||
storagePrincipal->OriginAttributesRef();
|
||||
nsAutoCString originAttributesSuffix;
|
||||
originAttributes.CreateSuffix(originAttributesSuffix);
|
||||
|
||||
nsAutoCString originKey;
|
||||
storagePrincipal->GetStorageOriginKey(originKey);
|
||||
|
||||
storagePrincipalList.InsertOrUpdate(originAttributesSuffix + originKey,
|
||||
storagePrincipal);
|
||||
});
|
||||
|
||||
for (const auto& value : aValues) {
|
||||
nsIPrincipal* storagePrincipal =
|
||||
storagePrincipalList.Get(value.originAttributes() + value.originKey());
|
||||
if (!storagePrincipal) {
|
||||
continue;
|
||||
}
|
||||
|
||||
auto entry = aRecord.Entries().AppendElement();
|
||||
|
||||
if (!entry->mValue.Entries().SetCapacity(
|
||||
value.defaultData().Length() + value.sessionData().Length(),
|
||||
fallible)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (NS_FAILED(storagePrincipal->GetOrigin(entry->mKey))) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
ConstructSessionStorageValue(value.defaultData(), entry->mValue);
|
||||
ConstructSessionStorageValue(value.sessionData(), entry->mValue);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* static */ void SessionStoreUtils::ResetSessionStore(
|
||||
BrowsingContext* aContext) {
|
||||
MOZ_RELEASE_ASSERT(NATIVE_LISTENER);
|
||||
|
|
|
@ -25,6 +25,8 @@ namespace dom {
|
|||
class CanonicalBrowsingContext;
|
||||
class GlobalObject;
|
||||
struct SSScrollPositionDict;
|
||||
class SSCacheCopy;
|
||||
class SSSetItemInfo;
|
||||
|
||||
namespace sessionstore {
|
||||
class DocShellRestoreState;
|
||||
|
@ -104,11 +106,6 @@ class SessionStoreUtils {
|
|||
Document& aDocument, const nsString& aInnerHTML,
|
||||
const nsTArray<SessionStoreRestoreData::Entry>& aEntries);
|
||||
|
||||
static void CollectedSessionStorage(BrowsingContext* aBrowsingContext,
|
||||
nsTArray<nsCString>& aOrigins,
|
||||
nsTArray<nsString>& aKeys,
|
||||
nsTArray<nsString>& aValues);
|
||||
|
||||
static void RestoreSessionStorage(
|
||||
const GlobalObject& aGlobal, nsIDocShell* aDocShell,
|
||||
const Record<nsString, Record<nsString, nsString>>& aData);
|
||||
|
@ -138,6 +135,11 @@ class SessionStoreUtils {
|
|||
aEntries,
|
||||
bool aParseSessionData = false);
|
||||
|
||||
static nsresult ConstructSessionStorageValues(
|
||||
CanonicalBrowsingContext* aBrowsingContext,
|
||||
const nsTArray<SSCacheCopy>& aValues,
|
||||
Record<nsCString, Record<nsString, nsString>>& aStorage);
|
||||
|
||||
static void ResetSessionStore(BrowsingContext* aContext);
|
||||
|
||||
#if defined(MOZ_WIDGET_ANDROID) || defined(MOZ_THUNDERBIRD) || \
|
||||
|
|
Загрузка…
Ссылка в новой задаче