mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-04 11:26:09 +00:00
Backed out 2 changesets (bug 1709346) for causing XPCConvert crashes. CLOSED TREE
Backed out changeset 7c1e15680741 (bug 1709346) Backed out changeset 34eff3430674 (bug 1709346)
This commit is contained in:
parent
49ef23c2f2
commit
15d4f16e13
@ -779,10 +779,8 @@ void BrowsingContext::Attach(bool aFromIPC, ContentParent* aOriginProcess) {
|
||||
}
|
||||
});
|
||||
|
||||
// We want to create a BrowsingContextWebProgress for all content
|
||||
// BrowsingContexts.
|
||||
if (IsContent() && !Canonical()->mWebProgress) {
|
||||
Canonical()->mWebProgress = new BrowsingContextWebProgress(Canonical());
|
||||
if (IsTopContent() && !Canonical()->GetWebProgress()) {
|
||||
Canonical()->mWebProgress = new BrowsingContextWebProgress();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,44 +3,19 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "BrowsingContextWebProgress.h"
|
||||
#include "mozilla/dom/CanonicalBrowsingContext.h"
|
||||
#include "mozilla/Logging.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIWebProgressListener.h"
|
||||
#include "nsString.h"
|
||||
#include "nsPrintfCString.h"
|
||||
#include "nsIChannel.h"
|
||||
#include "xptinfo.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
static mozilla::LazyLogModule gBCWebProgressLog("BCWebProgress");
|
||||
NS_IMPL_ADDREF(BrowsingContextWebProgress)
|
||||
NS_IMPL_RELEASE(BrowsingContextWebProgress)
|
||||
|
||||
static nsCString DescribeBrowsingContext(CanonicalBrowsingContext* aContext);
|
||||
static nsCString DescribeWebProgress(nsIWebProgress* aWebProgress);
|
||||
static nsCString DescribeRequest(nsIRequest* aRequest);
|
||||
static nsCString DescribeWebProgressFlags(uint32_t aFlags,
|
||||
const nsACString& aPrefix);
|
||||
static nsCString DescribeError(nsresult aError);
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION(BrowsingContextWebProgress, mCurrentBrowsingContext)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(BrowsingContextWebProgress)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(BrowsingContextWebProgress)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(BrowsingContextWebProgress)
|
||||
NS_INTERFACE_MAP_BEGIN(BrowsingContextWebProgress)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIWebProgress)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIWebProgress)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIWebProgressListener)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
BrowsingContextWebProgress::BrowsingContextWebProgress(
|
||||
CanonicalBrowsingContext* aBrowsingContext)
|
||||
: mCurrentBrowsingContext(aBrowsingContext) {}
|
||||
|
||||
BrowsingContextWebProgress::~BrowsingContextWebProgress() = default;
|
||||
|
||||
NS_IMETHODIMP BrowsingContextWebProgress::AddProgressListener(
|
||||
nsIWebProgressListener* aListener, uint32_t aNotifyMask) {
|
||||
nsWeakPtr listener = do_GetWeakReference(aListener);
|
||||
@ -73,18 +48,18 @@ NS_IMETHODIMP BrowsingContextWebProgress::GetDOMWindow(
|
||||
}
|
||||
|
||||
NS_IMETHODIMP BrowsingContextWebProgress::GetIsTopLevel(bool* aIsTopLevel) {
|
||||
*aIsTopLevel = mCurrentBrowsingContext->IsTop();
|
||||
*aIsTopLevel = true;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP BrowsingContextWebProgress::GetIsLoadingDocument(
|
||||
bool* aIsLoadingDocument) {
|
||||
*aIsLoadingDocument = mIsLoadingDocument;
|
||||
*aIsLoadingDocument = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP BrowsingContextWebProgress::GetLoadType(uint32_t* aLoadType) {
|
||||
*aLoadType = mLoadType;
|
||||
*aLoadType = 0;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -119,38 +94,28 @@ void BrowsingContextWebProgress::UpdateAndNotifyListeners(
|
||||
}
|
||||
|
||||
mListenerInfoList.Compact();
|
||||
|
||||
// Notify the parent BrowsingContextWebProgress of the event to continue
|
||||
// propagating.
|
||||
auto* parent = mCurrentBrowsingContext->GetParent();
|
||||
if (parent && parent->GetWebProgress()) {
|
||||
aCallback(parent->GetWebProgress());
|
||||
}
|
||||
}
|
||||
|
||||
void BrowsingContextWebProgress::ContextDiscarded() {
|
||||
if (!mIsLoadingDocument) {
|
||||
if (!mAwaitingStop) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If our BrowsingContext is being discarded while still loading a document,
|
||||
// fire a synthetic `STATE_STOP` to end the ongoing load.
|
||||
MOZ_LOG(gBCWebProgressLog, LogLevel::Info,
|
||||
("Discarded while loading %s",
|
||||
DescribeBrowsingContext(mCurrentBrowsingContext).get()));
|
||||
|
||||
// This matches what nsDocLoader::doStopDocumentLoad does, except we don't
|
||||
// bother notifying for `STATE_STOP | STATE_IS_DOCUMENT`,
|
||||
// nsBrowserStatusFilter would filter it out before it gets to the parent
|
||||
// process.
|
||||
OnStateChange(this, mLoadingDocumentRequest,
|
||||
STATE_STOP | STATE_IS_WINDOW | STATE_IS_NETWORK,
|
||||
NS_ERROR_ABORT);
|
||||
}
|
||||
|
||||
void BrowsingContextWebProgress::ContextReplaced(
|
||||
CanonicalBrowsingContext* aNewContext) {
|
||||
mCurrentBrowsingContext = aNewContext;
|
||||
const int32_t flags = STATE_STOP | STATE_IS_WINDOW | STATE_IS_NETWORK;
|
||||
UpdateAndNotifyListeners(((flags >> 16) & nsIWebProgress::NOTIFY_STATE_ALL),
|
||||
[&](nsIWebProgressListener* listener) {
|
||||
// TODO(emilio): We might want to stash the
|
||||
// request from OnStateChange on a member or
|
||||
// something if having no request causes trouble
|
||||
// here. Ditto for the webprogress instance.
|
||||
listener->OnStateChange(this,
|
||||
/* aRequest = */ nullptr,
|
||||
flags, NS_ERROR_ABORT);
|
||||
});
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -161,62 +126,42 @@ BrowsingContextWebProgress::OnStateChange(nsIWebProgress* aWebProgress,
|
||||
nsIRequest* aRequest,
|
||||
uint32_t aStateFlags,
|
||||
nsresult aStatus) {
|
||||
MOZ_LOG(
|
||||
gBCWebProgressLog, LogLevel::Info,
|
||||
("OnStateChange(%s, %s, %s, %s) on %s",
|
||||
DescribeWebProgress(aWebProgress).get(), DescribeRequest(aRequest).get(),
|
||||
DescribeWebProgressFlags(aStateFlags, "STATE_"_ns).get(),
|
||||
DescribeError(aStatus).get(),
|
||||
DescribeBrowsingContext(mCurrentBrowsingContext).get()));
|
||||
|
||||
bool targetIsThis = aWebProgress == this;
|
||||
|
||||
// We may receive a request from an in-process nsDocShell which doesn't have
|
||||
// `aWebProgress == this` which we should still consider as targeting
|
||||
// ourselves.
|
||||
if (nsCOMPtr<nsIDocShell> docShell = do_QueryInterface(aWebProgress);
|
||||
docShell && docShell->GetBrowsingContext() == mCurrentBrowsingContext) {
|
||||
targetIsThis = true;
|
||||
aWebProgress->GetLoadType(&mLoadType);
|
||||
}
|
||||
|
||||
// Track `mIsLoadingDocument` based on the notifications we've received so far
|
||||
// if the nsIWebProgress being targeted is this one.
|
||||
if (targetIsThis) {
|
||||
constexpr uint32_t startFlags = nsIWebProgressListener::STATE_START |
|
||||
nsIWebProgressListener::STATE_IS_DOCUMENT |
|
||||
nsIWebProgressListener::STATE_IS_REQUEST |
|
||||
nsIWebProgressListener::STATE_IS_WINDOW |
|
||||
nsIWebProgressListener::STATE_IS_NETWORK;
|
||||
constexpr uint32_t stopFlags = nsIWebProgressListener::STATE_STOP |
|
||||
nsIWebProgressListener::STATE_IS_WINDOW;
|
||||
constexpr uint32_t redirectFlags =
|
||||
nsIWebProgressListener::STATE_IS_REDIRECTED_DOCUMENT;
|
||||
if ((aStateFlags & startFlags) == startFlags) {
|
||||
if (mIsLoadingDocument) {
|
||||
// We received a duplicate `STATE_START` notification, silence this
|
||||
// notification until we receive the matching `STATE_STOP` to not fire
|
||||
// duplicate `STATE_START` notifications into frontend on process
|
||||
// switches.
|
||||
return NS_OK;
|
||||
}
|
||||
mIsLoadingDocument = true;
|
||||
|
||||
// Record the request we started the load with, so we can emit a synthetic
|
||||
// `STATE_STOP` notification if the BrowsingContext is discarded before
|
||||
// the notification arrives.
|
||||
mLoadingDocumentRequest = aRequest;
|
||||
} else if ((aStateFlags & stopFlags) == stopFlags) {
|
||||
// We've received a `STATE_STOP` notification targeting this web progress,
|
||||
// clear our loading document flag.
|
||||
mIsLoadingDocument = false;
|
||||
mLoadingDocumentRequest = nullptr;
|
||||
} else if (mIsLoadingDocument &&
|
||||
(aStateFlags & redirectFlags) == redirectFlags) {
|
||||
// If we see a redirected document load, update the loading request which
|
||||
// we'll emit the synthetic STATE_STOP notification with.
|
||||
mLoadingDocumentRequest = aRequest;
|
||||
const uint32_t startDocumentFlags =
|
||||
nsIWebProgressListener::STATE_START |
|
||||
nsIWebProgressListener::STATE_IS_DOCUMENT |
|
||||
nsIWebProgressListener::STATE_IS_REQUEST |
|
||||
nsIWebProgressListener::STATE_IS_WINDOW |
|
||||
nsIWebProgressListener::STATE_IS_NETWORK;
|
||||
bool isTopLevel = false;
|
||||
nsresult rv = aWebProgress->GetIsTopLevel(&isTopLevel);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
bool isTopLevelStartDocumentEvent =
|
||||
(aStateFlags & startDocumentFlags) == startDocumentFlags && isTopLevel;
|
||||
// If we receive a matching STATE_START for a top-level document event,
|
||||
// and we are currently not suspending this event, start suspending all
|
||||
// further matching STATE_START events after this one.
|
||||
if (isTopLevelStartDocumentEvent && !mAwaitingStop) {
|
||||
mAwaitingStop = true;
|
||||
} else if (mAwaitingStop) {
|
||||
// If we are currently suspending matching STATE_START events, check if this
|
||||
// is a corresponding STATE_STOP event.
|
||||
const uint32_t stopWindowFlags = nsIWebProgressListener::STATE_STOP |
|
||||
nsIWebProgressListener::STATE_IS_WINDOW;
|
||||
bool isTopLevelStopWindowEvent =
|
||||
(aStateFlags & stopWindowFlags) == stopWindowFlags && isTopLevel;
|
||||
if (isTopLevelStopWindowEvent) {
|
||||
// If this is a STATE_STOP event corresponding to the initial STATE_START
|
||||
// event, stop suspending matching STATE_START events.
|
||||
mAwaitingStop = false;
|
||||
} else if (isTopLevelStartDocumentEvent) {
|
||||
// We have received a matching STATE_START event at least twice, but
|
||||
// haven't received the corresponding STATE_STOP event for the first one.
|
||||
// Don't let this event through. This is probably a duplicate event from
|
||||
// the new BrowserParent due to a process switch.
|
||||
return NS_OK;
|
||||
}
|
||||
// Allow all other progress events that don't match top-level start document
|
||||
// flags.
|
||||
}
|
||||
|
||||
UpdateAndNotifyListeners(
|
||||
@ -234,12 +179,6 @@ BrowsingContextWebProgress::OnProgressChange(nsIWebProgress* aWebProgress,
|
||||
int32_t aMaxSelfProgress,
|
||||
int32_t aCurTotalProgress,
|
||||
int32_t aMaxTotalProgress) {
|
||||
MOZ_LOG(
|
||||
gBCWebProgressLog, LogLevel::Info,
|
||||
("OnProgressChange(%s, %s, %d, %d, %d, %d) on %s",
|
||||
DescribeWebProgress(aWebProgress).get(), DescribeRequest(aRequest).get(),
|
||||
aCurSelfProgress, aMaxSelfProgress, aCurTotalProgress, aMaxTotalProgress,
|
||||
DescribeBrowsingContext(mCurrentBrowsingContext).get()));
|
||||
UpdateAndNotifyListeners(
|
||||
nsIWebProgress::NOTIFY_PROGRESS, [&](nsIWebProgressListener* listener) {
|
||||
listener->OnProgressChange(aWebProgress, aRequest, aCurSelfProgress,
|
||||
@ -254,13 +193,6 @@ BrowsingContextWebProgress::OnLocationChange(nsIWebProgress* aWebProgress,
|
||||
nsIRequest* aRequest,
|
||||
nsIURI* aLocation,
|
||||
uint32_t aFlags) {
|
||||
MOZ_LOG(
|
||||
gBCWebProgressLog, LogLevel::Info,
|
||||
("OnProgressChange(%s, %s, %s, %s) on %s",
|
||||
DescribeWebProgress(aWebProgress).get(), DescribeRequest(aRequest).get(),
|
||||
aLocation ? aLocation->GetSpecOrDefault().get() : "<null>",
|
||||
DescribeWebProgressFlags(aFlags, "LOCATION_CHANGE_"_ns).get(),
|
||||
DescribeBrowsingContext(mCurrentBrowsingContext).get()));
|
||||
UpdateAndNotifyListeners(
|
||||
nsIWebProgress::NOTIFY_LOCATION, [&](nsIWebProgressListener* listener) {
|
||||
listener->OnLocationChange(aWebProgress, aRequest, aLocation, aFlags);
|
||||
@ -273,12 +205,6 @@ BrowsingContextWebProgress::OnStatusChange(nsIWebProgress* aWebProgress,
|
||||
nsIRequest* aRequest,
|
||||
nsresult aStatus,
|
||||
const char16_t* aMessage) {
|
||||
MOZ_LOG(
|
||||
gBCWebProgressLog, LogLevel::Info,
|
||||
("OnStatusChange(%s, %s, %s, \"%s\") on %s",
|
||||
DescribeWebProgress(aWebProgress).get(), DescribeRequest(aRequest).get(),
|
||||
DescribeError(aStatus).get(), NS_ConvertUTF16toUTF8(aMessage).get(),
|
||||
DescribeBrowsingContext(mCurrentBrowsingContext).get()));
|
||||
UpdateAndNotifyListeners(
|
||||
nsIWebProgress::NOTIFY_STATUS, [&](nsIWebProgressListener* listener) {
|
||||
listener->OnStatusChange(aWebProgress, aRequest, aStatus, aMessage);
|
||||
@ -290,11 +216,6 @@ NS_IMETHODIMP
|
||||
BrowsingContextWebProgress::OnSecurityChange(nsIWebProgress* aWebProgress,
|
||||
nsIRequest* aRequest,
|
||||
uint32_t aState) {
|
||||
MOZ_LOG(
|
||||
gBCWebProgressLog, LogLevel::Info,
|
||||
("OnSecurityChange(%s, %s, %x) on %s",
|
||||
DescribeWebProgress(aWebProgress).get(), DescribeRequest(aRequest).get(),
|
||||
aState, DescribeBrowsingContext(mCurrentBrowsingContext).get()));
|
||||
UpdateAndNotifyListeners(
|
||||
nsIWebProgress::NOTIFY_SECURITY, [&](nsIWebProgressListener* listener) {
|
||||
listener->OnSecurityChange(aWebProgress, aRequest, aState);
|
||||
@ -306,11 +227,6 @@ NS_IMETHODIMP
|
||||
BrowsingContextWebProgress::OnContentBlockingEvent(nsIWebProgress* aWebProgress,
|
||||
nsIRequest* aRequest,
|
||||
uint32_t aEvent) {
|
||||
MOZ_LOG(
|
||||
gBCWebProgressLog, LogLevel::Info,
|
||||
("OnContentBlockingEvent(%s, %s, %x) on %s",
|
||||
DescribeWebProgress(aWebProgress).get(), DescribeRequest(aRequest).get(),
|
||||
aEvent, DescribeBrowsingContext(mCurrentBrowsingContext).get()));
|
||||
UpdateAndNotifyListeners(nsIWebProgress::NOTIFY_CONTENT_BLOCKING,
|
||||
[&](nsIWebProgressListener* listener) {
|
||||
listener->OnContentBlockingEvent(aWebProgress,
|
||||
@ -319,97 +235,5 @@ BrowsingContextWebProgress::OnContentBlockingEvent(nsIWebProgress* aWebProgress,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Helper methods for notification logging
|
||||
|
||||
static nsCString DescribeBrowsingContext(CanonicalBrowsingContext* aContext) {
|
||||
if (!aContext) {
|
||||
return "<null>"_ns;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> currentURI = aContext->GetCurrentURI();
|
||||
return nsPrintfCString(
|
||||
"{top:%d, id:%" PRIx64 ", url:%s}", aContext->IsTop(), aContext->Id(),
|
||||
currentURI ? currentURI->GetSpecOrDefault().get() : "<null>");
|
||||
}
|
||||
|
||||
static nsCString DescribeWebProgress(nsIWebProgress* aWebProgress) {
|
||||
if (!aWebProgress) {
|
||||
return "<null>"_ns;
|
||||
}
|
||||
|
||||
bool isTopLevel = false;
|
||||
aWebProgress->GetIsTopLevel(&isTopLevel);
|
||||
bool isLoadingDocument = false;
|
||||
aWebProgress->GetIsLoadingDocument(&isLoadingDocument);
|
||||
return nsPrintfCString("{isTopLevel:%d, isLoadingDocument:%d}", isTopLevel,
|
||||
isLoadingDocument);
|
||||
}
|
||||
|
||||
static nsCString DescribeRequest(nsIRequest* aRequest) {
|
||||
if (!aRequest) {
|
||||
return "<null>"_ns;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest);
|
||||
if (!channel) {
|
||||
return "<non-channel>"_ns;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> originalURI;
|
||||
channel->GetOriginalURI(getter_AddRefs(originalURI));
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
channel->GetURI(getter_AddRefs(uri));
|
||||
|
||||
return nsPrintfCString(
|
||||
"{URI:%s, originalURI:%s}",
|
||||
uri ? uri->GetSpecOrDefault().get() : "<null>",
|
||||
originalURI ? originalURI->GetSpecOrDefault().get() : "<null>");
|
||||
}
|
||||
|
||||
static nsCString DescribeWebProgressFlags(uint32_t aFlags,
|
||||
const nsACString& aPrefix) {
|
||||
nsCString flags;
|
||||
uint32_t remaining = aFlags;
|
||||
|
||||
// Hackily fetch the names of each constant from the XPT information used for
|
||||
// reflecting it into JS. This doesn't need to be reliable and just exists as
|
||||
// a logging aid.
|
||||
//
|
||||
// If a change to xpt in the future breaks this code, just delete it and
|
||||
// replace it with a normal hex log.
|
||||
if (const auto* ifaceInfo =
|
||||
nsXPTInterfaceInfo::ByIID(NS_GET_IID(nsIWebProgressListener))) {
|
||||
for (uint16_t i = 0; i < ifaceInfo->ConstantCount(); ++i) {
|
||||
const auto& constInfo = ifaceInfo->Constant(i);
|
||||
nsDependentCString name(constInfo.Name());
|
||||
if (!StringBeginsWith(name, aPrefix)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (remaining & constInfo.mValue) {
|
||||
remaining &= ~constInfo.mValue;
|
||||
if (!flags.IsEmpty()) {
|
||||
flags.AppendLiteral("|");
|
||||
}
|
||||
flags.Append(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (remaining != 0 || flags.IsEmpty()) {
|
||||
if (!flags.IsEmpty()) {
|
||||
flags.AppendLiteral("|");
|
||||
}
|
||||
flags.AppendInt(remaining, 16);
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
|
||||
static nsCString DescribeError(nsresult aError) {
|
||||
nsCString name;
|
||||
GetErrorName(aError, name);
|
||||
return name;
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
@ -9,35 +9,18 @@
|
||||
#include "nsIWebProgressListener.h"
|
||||
#include "nsTObserverArray.h"
|
||||
#include "nsWeakReference.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class CanonicalBrowsingContext;
|
||||
|
||||
/// Object acting as the nsIWebProgress instance for a BrowsingContext over its
|
||||
/// lifetime.
|
||||
///
|
||||
/// An active toplevel CanonicalBrowsingContext will always have a
|
||||
/// BrowsingContextWebProgress, which will be moved between contexts as
|
||||
/// BrowsingContextGroup-changing loads are performed.
|
||||
///
|
||||
/// Subframes will only have a `BrowsingContextWebProgress` if they are loaded
|
||||
/// in a content process, and will use the nsDocShell instead if they are loaded
|
||||
/// in the parent process, as parent process documents cannot have or be
|
||||
/// out-of-process iframes.
|
||||
class BrowsingContextWebProgress final : public nsIWebProgress,
|
||||
public nsIWebProgressListener {
|
||||
public:
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(BrowsingContextWebProgress,
|
||||
nsIWebProgress)
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIWEBPROGRESS
|
||||
NS_DECL_NSIWEBPROGRESSLISTENER
|
||||
|
||||
explicit BrowsingContextWebProgress(
|
||||
CanonicalBrowsingContext* aBrowsingContext);
|
||||
BrowsingContextWebProgress() = default;
|
||||
|
||||
struct ListenerInfo {
|
||||
ListenerInfo(nsIWeakReference* aListener, unsigned long aNotifyMask)
|
||||
@ -58,12 +41,9 @@ class BrowsingContextWebProgress final : public nsIWebProgress,
|
||||
};
|
||||
|
||||
void ContextDiscarded();
|
||||
void ContextReplaced(CanonicalBrowsingContext* aNewContext);
|
||||
|
||||
void SetLoadType(uint32_t aLoadType) { mLoadType = aLoadType; }
|
||||
|
||||
private:
|
||||
virtual ~BrowsingContextWebProgress();
|
||||
virtual ~BrowsingContextWebProgress() = default;
|
||||
|
||||
void UpdateAndNotifyListeners(
|
||||
uint32_t aFlag,
|
||||
@ -72,26 +52,16 @@ class BrowsingContextWebProgress final : public nsIWebProgress,
|
||||
using ListenerArray = nsAutoTObserverArray<ListenerInfo, 4>;
|
||||
ListenerArray mListenerInfoList;
|
||||
|
||||
// The current BrowsingContext which owns this BrowsingContextWebProgress.
|
||||
// This context may change during navigations and may not be fully attached at
|
||||
// all times.
|
||||
RefPtr<CanonicalBrowsingContext> mCurrentBrowsingContext;
|
||||
|
||||
// The current request being actively loaded by the BrowsingContext. Only set
|
||||
// while mIsLoadingDocument is true, and is used to fire STATE_STOP
|
||||
// notifications if the BrowsingContext is discarded while the load is
|
||||
// ongoing.
|
||||
nsCOMPtr<nsIRequest> mLoadingDocumentRequest;
|
||||
|
||||
// The most recent load type observed for this BrowsingContextWebProgress.
|
||||
uint32_t mLoadType = 0;
|
||||
|
||||
// Are we currently in the process of loading a document? This is true between
|
||||
// the `STATE_START` notification from content and the `STATE_STOP`
|
||||
// notification being received. Duplicate `STATE_START` events may be
|
||||
// discarded while loading a document to avoid noise caused by process
|
||||
// switches.
|
||||
bool mIsLoadingDocument = false;
|
||||
// This indicates whether we are currently suspending onStateChange top level
|
||||
// STATE_START events for a document. We start suspending whenever we receive
|
||||
// the first STATE_START event with the matching flags (see
|
||||
// ::RecvOnStateChange for details), until we get a corresponding STATE_STOP
|
||||
// event. In the meantime, if there other onStateChange events, this flag does
|
||||
// not affect them. We do this to avoid duplicate onStateChange STATE_START
|
||||
// events that happen during process switch. With this flag, we allow
|
||||
// onStateChange STATE_START event from the old BrowserParent, but not the
|
||||
// same event from the new BrowserParent during a process switch.
|
||||
bool mAwaitingStop = false;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
@ -157,61 +157,16 @@ nsISecureBrowserUI* CanonicalBrowsingContext::GetSecureBrowserUI() {
|
||||
return mSecureBrowserUI;
|
||||
}
|
||||
|
||||
namespace {
|
||||
// The DocShellProgressBridge is attached to a root content docshell loaded in
|
||||
// the parent process. Notifications are paired up with the docshell which they
|
||||
// came from, so that they can be fired to the correct
|
||||
// BrowsingContextWebProgress and bubble through this tree separately.
|
||||
//
|
||||
// Notifications are filtered by a nsBrowserStatusFilter before being received
|
||||
// by the DocShellProgressBridge.
|
||||
class DocShellProgressBridge : public nsIWebProgressListener {
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
// NOTE: This relies in the expansion of `NS_FORWARD_SAFE` and all listener
|
||||
// methods accepting an `aWebProgress` argument. If this changes in the
|
||||
// future, this may need to be written manually.
|
||||
NS_FORWARD_SAFE_NSIWEBPROGRESSLISTENER(GetTargetContext(aWebProgress))
|
||||
|
||||
explicit DocShellProgressBridge(uint64_t aTopContextId)
|
||||
: mTopContextId(aTopContextId) {}
|
||||
|
||||
private:
|
||||
virtual ~DocShellProgressBridge() = default;
|
||||
|
||||
nsIWebProgressListener* GetTargetContext(nsIWebProgress* aWebProgress) {
|
||||
RefPtr<CanonicalBrowsingContext> context;
|
||||
if (nsCOMPtr<nsIDocShell> docShell = do_QueryInterface(aWebProgress)) {
|
||||
context = docShell->GetBrowsingContext()->Canonical();
|
||||
} else {
|
||||
context = CanonicalBrowsingContext::Get(mTopContextId);
|
||||
}
|
||||
return context && !context->IsDiscarded() ? context->GetWebProgress()
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
uint64_t mTopContextId = 0;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS(DocShellProgressBridge, nsIWebProgressListener)
|
||||
} // namespace
|
||||
|
||||
void CanonicalBrowsingContext::MaybeAddAsProgressListener(
|
||||
nsIWebProgress* aWebProgress) {
|
||||
// Only add as a listener if the created docshell is a toplevel content
|
||||
// docshell. We'll get notifications for all of our subframes through a single
|
||||
// listener.
|
||||
if (!IsTopContent()) {
|
||||
if (!GetWebProgress()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mDocShellProgressBridge) {
|
||||
mDocShellProgressBridge = new DocShellProgressBridge(Id());
|
||||
if (!mStatusFilter) {
|
||||
mStatusFilter = new nsBrowserStatusFilter();
|
||||
mStatusFilter->AddProgressListener(mDocShellProgressBridge,
|
||||
mStatusFilter->AddProgressListener(GetWebProgress(),
|
||||
nsIWebProgress::NOTIFY_ALL);
|
||||
}
|
||||
|
||||
aWebProgress->AddProgressListener(mStatusFilter, nsIWebProgress::NOTIFY_ALL);
|
||||
}
|
||||
|
||||
@ -222,10 +177,9 @@ void CanonicalBrowsingContext::ReplacedBy(
|
||||
MOZ_ASSERT(!aNewContext->mSessionHistory);
|
||||
MOZ_ASSERT(IsTop() && aNewContext->IsTop());
|
||||
if (mStatusFilter) {
|
||||
mStatusFilter->RemoveProgressListener(mDocShellProgressBridge);
|
||||
mStatusFilter->RemoveProgressListener(mWebProgress);
|
||||
mStatusFilter = nullptr;
|
||||
}
|
||||
mWebProgress->ContextReplaced(aNewContext);
|
||||
aNewContext->mWebProgress = std::move(mWebProgress);
|
||||
|
||||
// Use the Transaction for the fields which need to be updated whether or not
|
||||
@ -2280,7 +2234,7 @@ bool CanonicalBrowsingContext::AllowedInBFCache(
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_INHERITED(CanonicalBrowsingContext, BrowsingContext,
|
||||
mSessionHistory, mContainerFeaturePolicy,
|
||||
mCurrentBrowserParent, mWebProgress)
|
||||
mCurrentBrowserParent)
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(CanonicalBrowsingContext, BrowsingContext)
|
||||
NS_IMPL_RELEASE_INHERITED(CanonicalBrowsingContext, BrowsingContext)
|
||||
|
@ -449,8 +449,6 @@ class CanonicalBrowsingContext final : public BrowsingContext {
|
||||
|
||||
RefPtr<nsSecureBrowserUI> mSecureBrowserUI;
|
||||
RefPtr<BrowsingContextWebProgress> mWebProgress;
|
||||
|
||||
nsCOMPtr<nsIWebProgressListener> mDocShellProgressBridge;
|
||||
RefPtr<nsBrowserStatusFilter> mStatusFilter;
|
||||
|
||||
RefPtr<FeaturePolicy> mContainerFeaturePolicy;
|
||||
|
@ -3766,7 +3766,10 @@ nsresult BrowserChild::PrepareProgressListenerData(
|
||||
}
|
||||
|
||||
aWebProgressData.browsingContext() = docShell->GetBrowsingContext();
|
||||
nsresult rv = aWebProgress->GetLoadType(&aWebProgressData.loadType());
|
||||
nsresult rv =
|
||||
aWebProgress->GetIsLoadingDocument(&aWebProgressData.isLoadingDocument());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = aWebProgress->GetLoadType(&aWebProgressData.loadType());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return PrepareRequestData(aRequest, aRequestData);
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "mozilla/dom/PointerEventHandler.h"
|
||||
#include "mozilla/dom/BrowserBridgeParent.h"
|
||||
#include "mozilla/dom/RemoteDragStartData.h"
|
||||
#include "mozilla/dom/RemoteWebProgress.h"
|
||||
#include "mozilla/dom/RemoteWebProgressRequest.h"
|
||||
#include "mozilla/dom/SessionHistoryEntry.h"
|
||||
#include "mozilla/dom/SessionStoreUtils.h"
|
||||
@ -2682,17 +2683,14 @@ mozilla::ipc::IPCResult BrowserParent::RecvOnStateChange(
|
||||
const WebProgressData& aWebProgressData, const RequestData& aRequestData,
|
||||
const uint32_t aStateFlags, const nsresult aStatus,
|
||||
const Maybe<WebProgressStateChangeData>& aStateChangeData) {
|
||||
RefPtr<CanonicalBrowsingContext> browsingContext =
|
||||
BrowsingContextForWebProgress(aWebProgressData);
|
||||
if (!browsingContext) {
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIWebProgress> webProgress;
|
||||
nsCOMPtr<nsIRequest> request;
|
||||
if (aRequestData.requestURI()) {
|
||||
request = MakeAndAddRef<RemoteWebProgressRequest>(
|
||||
aRequestData.requestURI(), aRequestData.originalRequestURI(),
|
||||
aRequestData.matchedList());
|
||||
RefPtr<CanonicalBrowsingContext> browsingContext;
|
||||
|
||||
if (!ReconstructWebProgressAndRequest(
|
||||
aWebProgressData, aRequestData, getter_AddRefs(webProgress),
|
||||
getter_AddRefs(request), getter_AddRefs(browsingContext))) {
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
if (aStateChangeData.isSome()) {
|
||||
@ -2714,8 +2712,9 @@ mozilla::ipc::IPCResult BrowserParent::RecvOnStateChange(
|
||||
}
|
||||
}
|
||||
|
||||
if (auto* listener = browsingContext->GetWebProgress()) {
|
||||
listener->OnStateChange(listener, request, aStateFlags, aStatus);
|
||||
if (nsCOMPtr<nsIWebProgressListener> listener =
|
||||
GetBrowsingContext()->Top()->GetWebProgress()) {
|
||||
listener->OnStateChange(webProgress, request, aStateFlags, aStatus);
|
||||
}
|
||||
|
||||
return IPC_OK();
|
||||
@ -2743,17 +2742,14 @@ mozilla::ipc::IPCResult BrowserParent::RecvOnLocationChange(
|
||||
nsIURI* aLocation, const uint32_t aFlags, const bool aCanGoBack,
|
||||
const bool aCanGoForward,
|
||||
const Maybe<WebProgressLocationChangeData>& aLocationChangeData) {
|
||||
RefPtr<CanonicalBrowsingContext> browsingContext =
|
||||
BrowsingContextForWebProgress(aWebProgressData);
|
||||
if (!browsingContext) {
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIWebProgress> webProgress;
|
||||
nsCOMPtr<nsIRequest> request;
|
||||
if (aRequestData.requestURI()) {
|
||||
request = MakeAndAddRef<RemoteWebProgressRequest>(
|
||||
aRequestData.requestURI(), aRequestData.originalRequestURI(),
|
||||
aRequestData.matchedList());
|
||||
RefPtr<CanonicalBrowsingContext> browsingContext;
|
||||
|
||||
if (!ReconstructWebProgressAndRequest(
|
||||
aWebProgressData, aRequestData, getter_AddRefs(webProgress),
|
||||
getter_AddRefs(request), getter_AddRefs(browsingContext))) {
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
browsingContext->SetCurrentRemoteURI(aLocation);
|
||||
@ -2788,8 +2784,9 @@ mozilla::ipc::IPCResult BrowserParent::RecvOnLocationChange(
|
||||
}
|
||||
}
|
||||
|
||||
if (auto* listener = browsingContext->GetWebProgress()) {
|
||||
listener->OnLocationChange(listener, request, aLocation, aFlags);
|
||||
if (nsCOMPtr<nsIWebProgressListener> listener =
|
||||
browsingContext->Top()->GetWebProgress()) {
|
||||
listener->OnLocationChange(webProgress, request, aLocation, aFlags);
|
||||
}
|
||||
|
||||
// Since we've now changed Documents, notify the BrowsingContext that we've
|
||||
@ -2892,13 +2889,20 @@ already_AddRefed<nsIBrowser> BrowserParent::GetBrowser() {
|
||||
return browser.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<CanonicalBrowsingContext>
|
||||
BrowserParent::BrowsingContextForWebProgress(
|
||||
const WebProgressData& aWebProgressData) {
|
||||
bool BrowserParent::ReconstructWebProgressAndRequest(
|
||||
const WebProgressData& aWebProgressData, const RequestData& aRequestData,
|
||||
nsIWebProgress** aOutWebProgress, nsIRequest** aOutRequest,
|
||||
CanonicalBrowsingContext** aOutBrowsingContext) {
|
||||
MOZ_DIAGNOSTIC_ASSERT(aOutWebProgress,
|
||||
"aOutWebProgress should never be null");
|
||||
MOZ_DIAGNOSTIC_ASSERT(aOutRequest, "aOutRequest should never be null");
|
||||
MOZ_DIAGNOSTIC_ASSERT(aOutBrowsingContext,
|
||||
"aOutBrowsingContext should never be null");
|
||||
|
||||
// Look up the BrowsingContext which this notification was fired for.
|
||||
if (aWebProgressData.browsingContext().IsNullOrDiscarded()) {
|
||||
NS_WARNING("WebProgress Ignored: BrowsingContext is null or discarded");
|
||||
return nullptr;
|
||||
return false;
|
||||
}
|
||||
RefPtr<CanonicalBrowsingContext> browsingContext =
|
||||
aWebProgressData.browsingContext().get_canonical();
|
||||
@ -2911,7 +2915,7 @@ BrowserParent::BrowsingContextForWebProgress(
|
||||
WindowGlobalParent* embedder = browsingContext->GetParentWindowContext();
|
||||
if (!embedder || embedder->GetBrowserParent() != this) {
|
||||
NS_WARNING("WebProgress Ignored: wrong embedder process");
|
||||
return nullptr;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2922,15 +2926,26 @@ BrowserParent::BrowsingContextForWebProgress(
|
||||
browsingContext->GetCurrentWindowGlobal();
|
||||
current && current->GetBrowserParent() != this) {
|
||||
NS_WARNING("WebProgress Ignored: no longer current window global");
|
||||
return nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (RefPtr<BrowsingContextWebProgress> progress =
|
||||
browsingContext->GetWebProgress()) {
|
||||
progress->SetLoadType(aWebProgressData.loadType());
|
||||
// Construct a temporary RemoteWebProgress and RemoteWebProgressRequest which
|
||||
// contains relevant state used by our in-parent callbacks.
|
||||
nsCOMPtr<nsIWebProgress> webProgress = MakeAndAddRef<RemoteWebProgress>(
|
||||
aWebProgressData.loadType(), aWebProgressData.isLoadingDocument(),
|
||||
browsingContext->IsTopContent());
|
||||
|
||||
nsCOMPtr<nsIRequest> request;
|
||||
if (aRequestData.requestURI()) {
|
||||
request = MakeAndAddRef<RemoteWebProgressRequest>(
|
||||
aRequestData.requestURI(), aRequestData.originalRequestURI(),
|
||||
aRequestData.matchedList());
|
||||
}
|
||||
|
||||
return browsingContext.forget();
|
||||
webProgress.forget(aOutWebProgress);
|
||||
request.forget(aOutRequest);
|
||||
browsingContext.forget(aOutBrowsingContext);
|
||||
return true;
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult BrowserParent::RecvSessionStoreUpdate(
|
||||
|
@ -307,8 +307,10 @@ class BrowserParent final : public PBrowserParent,
|
||||
|
||||
already_AddRefed<nsIBrowser> GetBrowser();
|
||||
|
||||
already_AddRefed<CanonicalBrowsingContext> BrowsingContextForWebProgress(
|
||||
const WebProgressData& aWebProgressData);
|
||||
bool ReconstructWebProgressAndRequest(
|
||||
const WebProgressData& aWebProgressData, const RequestData& aRequestData,
|
||||
nsIWebProgress** aOutWebProgress, nsIRequest** aOutRequest,
|
||||
CanonicalBrowsingContext** aOutBrowsingContext);
|
||||
|
||||
mozilla::ipc::IPCResult RecvSessionStoreUpdate(
|
||||
const Maybe<nsCString>& aDocShellCaps, const Maybe<bool>& aPrivatedMode,
|
||||
|
@ -116,6 +116,7 @@ namespace dom {
|
||||
struct WebProgressData
|
||||
{
|
||||
MaybeDiscardedBrowsingContext browsingContext;
|
||||
bool isLoadingDocument;
|
||||
uint32_t loadType;
|
||||
};
|
||||
|
||||
|
58
dom/ipc/RemoteWebProgress.cpp
Normal file
58
dom/ipc/RemoteWebProgress.cpp
Normal file
@ -0,0 +1,58 @@
|
||||
/* 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/. */
|
||||
|
||||
#include "RemoteWebProgress.h"
|
||||
|
||||
namespace mozilla::dom {
|
||||
|
||||
NS_IMPL_ADDREF(RemoteWebProgress)
|
||||
NS_IMPL_RELEASE(RemoteWebProgress)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(RemoteWebProgress)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIWebProgress)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
NS_IMETHODIMP RemoteWebProgress::AddProgressListener(
|
||||
nsIWebProgressListener* aListener, uint32_t aNotifyMask) {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP RemoteWebProgress::RemoveProgressListener(
|
||||
nsIWebProgressListener* aListener) {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP RemoteWebProgress::GetDOMWindow(mozIDOMWindowProxy** aDOMWindow) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP RemoteWebProgress::GetIsTopLevel(bool* aIsTopLevel) {
|
||||
NS_ENSURE_ARG_POINTER(aIsTopLevel);
|
||||
*aIsTopLevel = mIsTopLevel;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP RemoteWebProgress::GetIsLoadingDocument(
|
||||
bool* aIsLoadingDocument) {
|
||||
NS_ENSURE_ARG_POINTER(aIsLoadingDocument);
|
||||
*aIsLoadingDocument = mIsLoadingDocument;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP RemoteWebProgress::GetLoadType(uint32_t* aLoadType) {
|
||||
NS_ENSURE_ARG_POINTER(aLoadType);
|
||||
*aLoadType = mLoadType;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP RemoteWebProgress::GetTarget(nsIEventTarget** aTarget) {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP RemoteWebProgress::SetTarget(nsIEventTarget* aTarget) {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
} // namespace mozilla::dom
|
39
dom/ipc/RemoteWebProgress.h
Normal file
39
dom/ipc/RemoteWebProgress.h
Normal file
@ -0,0 +1,39 @@
|
||||
/* 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_RemoteWebProgress_h
|
||||
#define mozilla_dom_RemoteWebProgress_h
|
||||
|
||||
#include "nsIWebProgress.h"
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class RemoteWebProgress final : public nsIWebProgress {
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIWEBPROGRESS
|
||||
|
||||
RemoteWebProgress()
|
||||
: mLoadType(0), mIsLoadingDocument(false), mIsTopLevel(false) {}
|
||||
|
||||
RemoteWebProgress(uint32_t aLoadType, bool aIsLoadingDocument,
|
||||
bool aIsTopLevel)
|
||||
: mLoadType(aLoadType),
|
||||
mIsLoadingDocument(aIsLoadingDocument),
|
||||
mIsTopLevel(aIsTopLevel) {}
|
||||
|
||||
private:
|
||||
virtual ~RemoteWebProgress() = default;
|
||||
|
||||
uint32_t mLoadType;
|
||||
bool mIsLoadingDocument;
|
||||
bool mIsTopLevel;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_RemoteWebProgress_h
|
@ -22,6 +22,7 @@
|
||||
#include "mozilla/dom/BrowserHost.h"
|
||||
#include "mozilla/dom/BrowserParent.h"
|
||||
#include "mozilla/dom/MediaController.h"
|
||||
#include "mozilla/dom/RemoteWebProgress.h"
|
||||
#include "mozilla/dom/WindowGlobalChild.h"
|
||||
#include "mozilla/dom/ChromeUtils.h"
|
||||
#include "mozilla/dom/ipc/IdType.h"
|
||||
@ -524,9 +525,14 @@ void WindowGlobalParent::NotifyContentBlockingEvent(
|
||||
|
||||
// Notify the OnContentBlockingEvent if necessary.
|
||||
if (event) {
|
||||
if (auto* webProgress = GetBrowsingContext()->GetWebProgress()) {
|
||||
webProgress->OnContentBlockingEvent(webProgress, aRequest, event.value());
|
||||
if (!GetBrowsingContext()->GetWebProgress()) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIWebProgress> webProgress =
|
||||
new RemoteWebProgress(0, false, BrowsingContext()->IsTopContent());
|
||||
GetBrowsingContext()->Top()->GetWebProgress()->OnContentBlockingEvent(
|
||||
webProgress, aRequest, event.value());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -62,6 +62,7 @@ EXPORTS.mozilla.dom += [
|
||||
"RefMessageBodyService.h",
|
||||
"RemoteBrowser.h",
|
||||
"RemoteType.h",
|
||||
"RemoteWebProgress.h",
|
||||
"RemoteWebProgressRequest.h",
|
||||
"SharedMessageBody.h",
|
||||
"TabContext.h",
|
||||
@ -113,6 +114,7 @@ UNIFIED_SOURCES += [
|
||||
"ReferrerInfoUtils.cpp",
|
||||
"RefMessageBodyService.cpp",
|
||||
"RemoteBrowser.cpp",
|
||||
"RemoteWebProgress.cpp",
|
||||
"RemoteWebProgressRequest.cpp",
|
||||
"SharedMap.cpp",
|
||||
"SharedMessageBody.cpp",
|
||||
|
@ -139,7 +139,3 @@ support-files =
|
||||
support-files =
|
||||
page_bytecode_cache_asm_js.html
|
||||
page_bytecode_cache_asm_js.js
|
||||
[browser_bug1709346.js]
|
||||
support-files =
|
||||
load_forever.sjs
|
||||
file_empty_cross_site_frame.html
|
||||
|
@ -1,48 +0,0 @@
|
||||
/* 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/. */
|
||||
|
||||
add_task(async function remove_subframe_in_cross_site_frame() {
|
||||
await BrowserTestUtils.withNewTab(
|
||||
"http://mochi.test:8888/browser/dom/tests/browser/file_empty_cross_site_frame.html",
|
||||
async browser => {
|
||||
await TestUtils.waitForCondition(
|
||||
() => !XULBrowserWindow.isBusy,
|
||||
"browser is not busy after the tab finishes loading"
|
||||
);
|
||||
|
||||
// Spawn into the cross-site subframe, and begin loading a slow network
|
||||
// connection. We'll cancel the load before this navigation completes.
|
||||
await SpecialPowers.spawn(
|
||||
browser.browsingContext.children[0],
|
||||
[],
|
||||
async () => {
|
||||
let frame = content.document.createElement("iframe");
|
||||
frame.src = "load_forever.sjs";
|
||||
content.document.body.appendChild(frame);
|
||||
|
||||
frame.addEventListener("load", function() {
|
||||
ok(false, "load should not finish before the frame is removed");
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
is(
|
||||
XULBrowserWindow.isBusy,
|
||||
true,
|
||||
"browser should be busy after the load starts"
|
||||
);
|
||||
|
||||
// Remove the outer iframe, ending the load within this frame's subframe
|
||||
// early.
|
||||
await SpecialPowers.spawn(browser, [], async () => {
|
||||
content.document.querySelector("iframe").remove();
|
||||
});
|
||||
|
||||
await TestUtils.waitForCondition(
|
||||
() => !XULBrowserWindow.isBusy,
|
||||
"Browser should no longer be busy after the frame is removed"
|
||||
);
|
||||
}
|
||||
);
|
||||
});
|
@ -1,2 +0,0 @@
|
||||
<!doctype html>
|
||||
<iframe src="http://example.com/browser/dom/tests/browser/file_empty.html"></iframe>
|
@ -1,15 +0,0 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
let gResponses = [];
|
||||
|
||||
function handleRequest(request, response) {
|
||||
response.seizePower();
|
||||
response.write("HTTP/1.1 200 OK\r\n");
|
||||
response.write("Content-Type: text/plain; charset=utf-8\r\n");
|
||||
response.write("Cache-Control: no-cache, must-revalidate\r\n");
|
||||
response.write("\r\n");
|
||||
|
||||
// Keep the response alive indefinitely.
|
||||
gResponses.push(response);
|
||||
}
|
@ -53,6 +53,7 @@
|
||||
#include "mozilla/dom/BrowserParent.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "mozilla/dom/nsHTTPSOnlyUtils.h"
|
||||
#include "mozilla/dom/RemoteWebProgress.h"
|
||||
#include "mozilla/dom/RemoteWebProgressRequest.h"
|
||||
#include "mozilla/net/UrlClassifierFeatureFactory.h"
|
||||
#include "mozilla/ExtensionPolicyService.h"
|
||||
@ -178,6 +179,13 @@ static auto CreateObjectLoadInfo(nsDocShellLoadState* aLoadState,
|
||||
return loadInfo.forget();
|
||||
}
|
||||
|
||||
static auto WebProgressForBrowsingContext(
|
||||
CanonicalBrowsingContext* aBrowsingContext)
|
||||
-> already_AddRefed<BrowsingContextWebProgress> {
|
||||
return RefPtr<BrowsingContextWebProgress>(aBrowsingContext->GetWebProgress())
|
||||
.forget();
|
||||
}
|
||||
|
||||
/**
|
||||
* An extension to nsDocumentOpenInfo that we run in the parent process, so
|
||||
* that we can make the decision to retarget to content handlers or the external
|
||||
@ -858,15 +866,17 @@ auto DocumentLoadListener::OpenInParent(nsDocShellLoadState* aLoadState,
|
||||
void DocumentLoadListener::FireStateChange(uint32_t aStateFlags,
|
||||
nsresult aStatus) {
|
||||
nsCOMPtr<nsIChannel> request = GetChannel();
|
||||
nsCOMPtr<nsIWebProgress> webProgress =
|
||||
new RemoteWebProgress(GetLoadType(), true, true);
|
||||
|
||||
RefPtr<BrowsingContextWebProgress> webProgress =
|
||||
GetLoadingBrowsingContext()->GetWebProgress();
|
||||
RefPtr<BrowsingContextWebProgress> loadingWebProgress =
|
||||
WebProgressForBrowsingContext(GetLoadingBrowsingContext());
|
||||
|
||||
if (webProgress) {
|
||||
if (loadingWebProgress) {
|
||||
NS_DispatchToMainThread(
|
||||
NS_NewRunnableFunction("DocumentLoadListener::FireStateChange", [=]() {
|
||||
webProgress->OnStateChange(webProgress, request, aStateFlags,
|
||||
aStatus);
|
||||
loadingWebProgress->OnStateChange(webProgress, request, aStateFlags,
|
||||
aStatus);
|
||||
}));
|
||||
}
|
||||
}
|
||||
@ -2615,16 +2625,18 @@ NS_IMETHODIMP DocumentLoadListener::OnStatus(nsIRequest* aRequest,
|
||||
nsresult aStatus,
|
||||
const char16_t* aStatusArg) {
|
||||
nsCOMPtr<nsIChannel> channel = mChannel;
|
||||
nsCOMPtr<nsIWebProgress> webProgress =
|
||||
new RemoteWebProgress(mLoadStateLoadType, true, true);
|
||||
|
||||
RefPtr<BrowsingContextWebProgress> webProgress =
|
||||
GetLoadingBrowsingContext()->GetWebProgress();
|
||||
RefPtr<BrowsingContextWebProgress> topWebProgress =
|
||||
WebProgressForBrowsingContext(GetTopBrowsingContext());
|
||||
const nsString message(aStatusArg);
|
||||
|
||||
if (webProgress) {
|
||||
if (topWebProgress) {
|
||||
NS_DispatchToMainThread(
|
||||
NS_NewRunnableFunction("DocumentLoadListener::OnStatus", [=]() {
|
||||
webProgress->OnStatusChange(webProgress, channel, aStatus,
|
||||
message.get());
|
||||
topWebProgress->OnStatusChange(webProgress, channel, aStatus,
|
||||
message.get());
|
||||
}));
|
||||
}
|
||||
return NS_OK;
|
||||
|
Loading…
Reference in New Issue
Block a user