зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1156659 - Added set offline per tab to BrowsingContext. r=valentin,nika,necko-reviewers,kershaw
Differential Revision: https://phabricator.services.mozilla.com/D187704
This commit is contained in:
Родитель
7c10529183
Коммит
3b39108bc7
|
@ -3529,6 +3529,11 @@ bool BrowsingContext::CanSet(FieldIndex<IDX_IsUnderHiddenEmbedderElement>,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool BrowsingContext::CanSet(FieldIndex<IDX_ForceOffline>, bool aNewValue,
|
||||||
|
ContentParent* aSource) {
|
||||||
|
return XRE_IsParentProcess() && !aSource;
|
||||||
|
}
|
||||||
|
|
||||||
void BrowsingContext::DidSet(FieldIndex<IDX_IsUnderHiddenEmbedderElement>,
|
void BrowsingContext::DidSet(FieldIndex<IDX_IsUnderHiddenEmbedderElement>,
|
||||||
bool aOldValue) {
|
bool aOldValue) {
|
||||||
nsIDocShell* shell = GetDocShell();
|
nsIDocShell* shell = GetDocShell();
|
||||||
|
|
|
@ -267,7 +267,9 @@ struct EmbedderColorSchemes {
|
||||||
* a content process. */ \
|
* a content process. */ \
|
||||||
FIELD(EmbeddedInContentDocument, bool) \
|
FIELD(EmbeddedInContentDocument, bool) \
|
||||||
/* If true, this browsing context is within a hidden embedded document. */ \
|
/* If true, this browsing context is within a hidden embedded document. */ \
|
||||||
FIELD(IsUnderHiddenEmbedderElement, bool)
|
FIELD(IsUnderHiddenEmbedderElement, bool) \
|
||||||
|
/* If true, this browsing context is offline */ \
|
||||||
|
FIELD(ForceOffline, bool)
|
||||||
|
|
||||||
// BrowsingContext, in this context, is the cross process replicated
|
// BrowsingContext, in this context, is the cross process replicated
|
||||||
// environment in which information about documents is stored. In
|
// environment in which information about documents is stored. In
|
||||||
|
@ -611,6 +613,8 @@ class BrowsingContext : public nsILoadContext, public nsWrapperCache {
|
||||||
aRv);
|
aRv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ForceOffline() const { return GetForceOffline(); }
|
||||||
|
|
||||||
bool ForceDesktopViewport() const { return GetForceDesktopViewport(); }
|
bool ForceDesktopViewport() const { return GetForceDesktopViewport(); }
|
||||||
|
|
||||||
bool AuthorStyleDisabledDefault() const {
|
bool AuthorStyleDisabledDefault() const {
|
||||||
|
@ -1229,6 +1233,9 @@ class BrowsingContext : public nsILoadContext, public nsWrapperCache {
|
||||||
const bool& aIsUnderHiddenEmbedderElement,
|
const bool& aIsUnderHiddenEmbedderElement,
|
||||||
ContentParent* aSource);
|
ContentParent* aSource);
|
||||||
|
|
||||||
|
bool CanSet(FieldIndex<IDX_ForceOffline>, bool aNewValue,
|
||||||
|
ContentParent* aSource);
|
||||||
|
|
||||||
bool CanSet(FieldIndex<IDX_EmbeddedInContentDocument>, bool,
|
bool CanSet(FieldIndex<IDX_EmbeddedInContentDocument>, bool,
|
||||||
ContentParent* aSource) {
|
ContentParent* aSource) {
|
||||||
return CheckOnlyEmbedderCanSet(aSource);
|
return CheckOnlyEmbedderCanSet(aSource);
|
||||||
|
|
|
@ -320,6 +320,7 @@ void CanonicalBrowsingContext::ReplacedBy(
|
||||||
txn.SetEmbedderColorSchemes(GetEmbedderColorSchemes());
|
txn.SetEmbedderColorSchemes(GetEmbedderColorSchemes());
|
||||||
txn.SetHasRestoreData(GetHasRestoreData());
|
txn.SetHasRestoreData(GetHasRestoreData());
|
||||||
txn.SetShouldDelayMediaFromStart(GetShouldDelayMediaFromStart());
|
txn.SetShouldDelayMediaFromStart(GetShouldDelayMediaFromStart());
|
||||||
|
txn.SetForceOffline(GetForceOffline());
|
||||||
|
|
||||||
// Propagate some settings on BrowsingContext replacement so they're not lost
|
// Propagate some settings on BrowsingContext replacement so they're not lost
|
||||||
// on bfcached navigations. These are important for GeckoView (see bug
|
// on bfcached navigations. These are important for GeckoView (see bug
|
||||||
|
|
|
@ -561,7 +561,17 @@ bool Navigator::CookieEnabled() {
|
||||||
return granted;
|
return granted;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Navigator::OnLine() { return !NS_IsOffline(); }
|
bool Navigator::OnLine() {
|
||||||
|
if (mWindow) {
|
||||||
|
// Check if this tab is set to be offline.
|
||||||
|
BrowsingContext* bc = mWindow->GetBrowsingContext();
|
||||||
|
if (bc && bc->Top()->GetForceOffline()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Return the default browser value
|
||||||
|
return !NS_IsOffline();
|
||||||
|
}
|
||||||
|
|
||||||
void Navigator::GetBuildID(nsAString& aBuildID, CallerType aCallerType,
|
void Navigator::GetBuildID(nsAString& aBuildID, CallerType aCallerType,
|
||||||
ErrorResult& aRv) const {
|
ErrorResult& aRv) const {
|
||||||
|
|
|
@ -129,6 +129,12 @@ interface BrowsingContext {
|
||||||
|
|
||||||
[SetterThrows] attribute boolean isActive;
|
[SetterThrows] attribute boolean isActive;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When set to true all channels in this browsing context or its children will report navigator.onLine = false,
|
||||||
|
* and HTTP requests created from these browsing context will fail with NS_ERROR_OFFLINE.
|
||||||
|
*/
|
||||||
|
[SetterThrows] attribute boolean forceOffline;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets whether this is an app tab. Non-same-origin link navigations from app
|
* Sets whether this is an app tab. Non-same-origin link navigations from app
|
||||||
* tabs may be forced to open in new contexts, rather than in the same context.
|
* tabs may be forced to open in new contexts, rather than in the same context.
|
||||||
|
|
|
@ -560,6 +560,12 @@ nsresult nsHttpChannel::OnBeforeConnect() {
|
||||||
// Save that on the loadInfo so it can later be consumed by SecurityInfo.jsm
|
// Save that on the loadInfo so it can later be consumed by SecurityInfo.jsm
|
||||||
mLoadInfo->SetHstsStatus(isSecureURI);
|
mLoadInfo->SetHstsStatus(isSecureURI);
|
||||||
|
|
||||||
|
RefPtr<mozilla::dom::BrowsingContext> bc;
|
||||||
|
mLoadInfo->GetBrowsingContext(getter_AddRefs(bc));
|
||||||
|
if (bc && bc->Top()->GetForceOffline()) {
|
||||||
|
return NS_ERROR_OFFLINE;
|
||||||
|
}
|
||||||
|
|
||||||
// At this point it is no longer possible to call
|
// At this point it is no longer possible to call
|
||||||
// HttpBaseChannel::UpgradeToSecure.
|
// HttpBaseChannel::UpgradeToSecure.
|
||||||
StoreUpgradableToSecure(false);
|
StoreUpgradableToSecure(false);
|
||||||
|
@ -1031,8 +1037,12 @@ void nsHttpChannel::SpeculativeConnect() {
|
||||||
// don't speculate if we are offline, when doing http upgrade (i.e.
|
// don't speculate if we are offline, when doing http upgrade (i.e.
|
||||||
// websockets bootstrap), or if we can't do keep-alive (because then we
|
// websockets bootstrap), or if we can't do keep-alive (because then we
|
||||||
// couldn't reuse the speculative connection anyhow).
|
// couldn't reuse the speculative connection anyhow).
|
||||||
|
RefPtr<mozilla::dom::BrowsingContext> bc;
|
||||||
|
mLoadInfo->GetBrowsingContext(getter_AddRefs(bc));
|
||||||
|
|
||||||
if (gIOService->IsOffline() || mUpgradeProtocolCallback ||
|
if (gIOService->IsOffline() || mUpgradeProtocolCallback ||
|
||||||
!(mCaps & NS_HTTP_ALLOW_KEEPALIVE)) {
|
!(mCaps & NS_HTTP_ALLOW_KEEPALIVE) ||
|
||||||
|
(bc && bc->Top()->GetForceOffline())) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3672,6 +3682,9 @@ nsresult nsHttpChannel::OpenCacheEntryInternal(bool isHttps) {
|
||||||
uint32_t cacheEntryOpenFlags;
|
uint32_t cacheEntryOpenFlags;
|
||||||
bool offline = gIOService->IsOffline();
|
bool offline = gIOService->IsOffline();
|
||||||
|
|
||||||
|
RefPtr<mozilla::dom::BrowsingContext> bc;
|
||||||
|
mLoadInfo->GetBrowsingContext(getter_AddRefs(bc));
|
||||||
|
|
||||||
bool maybeRCWN = false;
|
bool maybeRCWN = false;
|
||||||
|
|
||||||
nsAutoCString cacheControlRequestHeader;
|
nsAutoCString cacheControlRequestHeader;
|
||||||
|
@ -3682,7 +3695,8 @@ nsresult nsHttpChannel::OpenCacheEntryInternal(bool isHttps) {
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (offline || (mLoadFlags & INHIBIT_CACHING)) {
|
if (offline || (mLoadFlags & INHIBIT_CACHING) ||
|
||||||
|
(bc && bc->Top()->GetForceOffline())) {
|
||||||
if (BYPASS_LOCAL_CACHE(mLoadFlags, LoadPreferCacheLoadOverBypass()) &&
|
if (BYPASS_LOCAL_CACHE(mLoadFlags, LoadPreferCacheLoadOverBypass()) &&
|
||||||
!offline) {
|
!offline) {
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|
|
@ -145,3 +145,4 @@ support-files =
|
||||||
[browser_103_private_window.js]
|
[browser_103_private_window.js]
|
||||||
[browser_speculative_connection_link_header.js]
|
[browser_speculative_connection_link_header.js]
|
||||||
[browser_103_assets_extension.js]
|
[browser_103_assets_extension.js]
|
||||||
|
[browser_test_offline_tab.js]
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
add_task(async function test_set_tab_offline() {
|
||||||
|
await BrowserTestUtils.withNewTab("https://example.com", async browser => {
|
||||||
|
// Set the tab to offline
|
||||||
|
gBrowser.selectedBrowser.browsingContext.forceOffline = true;
|
||||||
|
|
||||||
|
await SpecialPowers.spawn(browser, [], async () => {
|
||||||
|
try {
|
||||||
|
await content.fetch("https://example.com/empty.html");
|
||||||
|
ok(false, "Should not load since tab is offline");
|
||||||
|
} catch (err) {
|
||||||
|
is(err.name, "TypeError", "Should fail since tab is offline");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
add_task(async function test_set_tab_online() {
|
||||||
|
await BrowserTestUtils.withNewTab("https://example.com", async browser => {
|
||||||
|
// Set the tab to online
|
||||||
|
gBrowser.selectedBrowser.browsingContext.forceOffline = false;
|
||||||
|
|
||||||
|
await SpecialPowers.spawn(browser, [], async () => {
|
||||||
|
try {
|
||||||
|
await content.fetch("https://example.com/empty.html");
|
||||||
|
ok(true, "Should load since tab is online");
|
||||||
|
} catch (err) {
|
||||||
|
ok(false, "Should not fail since tab is online");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
Загрузка…
Ссылка в новой задаче