mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-29 20:07:30 +09:00
Merge remote-tracking branch 'origin/master' into custom
This commit is contained in:
commit
b74770e3f1
35 changed files with 953 additions and 661 deletions
|
|
@ -4,6 +4,8 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nspr.h"
|
||||
#include "mozilla/BasicEvents.h"
|
||||
#include "mozilla/EventDispatcher.h"
|
||||
#include "mozilla/Logging.h"
|
||||
|
||||
#include "nsDocLoader.h"
|
||||
|
|
@ -23,6 +25,7 @@
|
|||
#include "nsQueryObject.h"
|
||||
|
||||
#include "nsIDOMWindow.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
|
||||
#include "nsIStringBundle.h"
|
||||
#include "nsIScriptSecurityManager.h"
|
||||
|
|
@ -36,7 +39,10 @@
|
|||
#include "nsIAsyncVerifyRedirectCallback.h"
|
||||
|
||||
using mozilla::DebugOnly;
|
||||
using mozilla::eLoad;
|
||||
using mozilla::EventDispatcher;
|
||||
using mozilla::LogLevel;
|
||||
using mozilla::WidgetEvent;
|
||||
|
||||
static NS_DEFINE_CID(kThisImplCID, NS_THIS_DOCLOADER_IMPL_CID);
|
||||
|
||||
|
|
@ -114,7 +120,8 @@ nsDocLoader::nsDocLoader()
|
|||
mIsLoadingDocument(false),
|
||||
mIsRestoringDocument(false),
|
||||
mDontFlushLayout(false),
|
||||
mIsFlushingLayout(false)
|
||||
mIsFlushingLayout(false),
|
||||
mDocumentOpenedButNotLoaded(false)
|
||||
{
|
||||
ClearInternalProgress();
|
||||
|
||||
|
|
@ -289,7 +296,7 @@ nsDocLoader::IsBusy()
|
|||
}
|
||||
|
||||
/* Is this document loader busy? */
|
||||
if (!mIsLoadingDocument) {
|
||||
if (!IsBlockingLoadEvent()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -414,6 +421,7 @@ nsDocLoader::OnStartRequest(nsIRequest *request, nsISupports *aCtxt)
|
|||
if (!mIsLoadingDocument && (loadFlags & nsIChannel::LOAD_DOCUMENT_URI)) {
|
||||
bJustStartedLoading = true;
|
||||
mIsLoadingDocument = true;
|
||||
mDocumentOpenedButNotLoaded = false;
|
||||
ClearInternalProgress(); // only clear our progress if we are starting a new load....
|
||||
}
|
||||
|
||||
|
|
@ -480,10 +488,11 @@ nsDocLoader::OnStopRequest(nsIRequest *aRequest,
|
|||
mLoadGroup->GetActiveCount(&count);
|
||||
|
||||
MOZ_LOG(gDocLoaderLog, LogLevel::Debug,
|
||||
("DocLoader:%p: OnStopRequest[%p](%s) status=%x mIsLoadingDocument=%s, %u active URLs",
|
||||
("DocLoader:%p: OnStopRequest[%p](%s) status=%x"
|
||||
"mIsLoadingDocument=%s, mDocumentOpenedButNotLoaded=%s, %u active URLs",
|
||||
this, aRequest, name.get(),
|
||||
aStatus, (mIsLoadingDocument ? "true" : "false"),
|
||||
count));
|
||||
(mDocumentOpenedButNotLoaded ? "true" : "false"), count));
|
||||
}
|
||||
|
||||
bool bFireTransferring = false;
|
||||
|
|
@ -598,10 +607,9 @@ nsDocLoader::OnStopRequest(nsIRequest *aRequest,
|
|||
RemoveRequestInfo(aRequest);
|
||||
|
||||
//
|
||||
// Only fire the DocLoaderIsEmpty(...) if the document loader has initiated a
|
||||
// load. This will handle removing the request from our hashtable as needed.
|
||||
// Only fire the DocLoaderIsEmpty(...) if we may need to fire onload.
|
||||
//
|
||||
if (mIsLoadingDocument) {
|
||||
if (IsBlockingLoadEvent()) {
|
||||
nsCOMPtr<nsIDocShell> ds = do_QueryInterface(static_cast<nsIRequestObserver*>(this));
|
||||
bool doNotFlushLayout = false;
|
||||
if (ds) {
|
||||
|
|
@ -647,7 +655,7 @@ NS_IMETHODIMP nsDocLoader::GetDocumentChannel(nsIChannel ** aChannel)
|
|||
|
||||
void nsDocLoader::DocLoaderIsEmpty(bool aFlushLayout)
|
||||
{
|
||||
if (mIsLoadingDocument) {
|
||||
if (IsBlockingLoadEvent()) {
|
||||
/* In the unimagineably rude circumstance that onload event handlers
|
||||
triggered by this function actually kill the window ... ok, it's
|
||||
not unimagineable; it's happened ... this deathgrip keeps this object
|
||||
|
|
@ -660,7 +668,9 @@ void nsDocLoader::DocLoaderIsEmpty(bool aFlushLayout)
|
|||
}
|
||||
|
||||
NS_ASSERTION(!mIsFlushingLayout, "Someone screwed up");
|
||||
NS_ASSERTION(mDocumentRequest, "No Document Request!");
|
||||
// We may not have a document request if we are in a document.open() situation.
|
||||
NS_ASSERTION(mDocumentRequest || mDocumentOpenedButNotLoaded,
|
||||
"No Document Request!");
|
||||
|
||||
// The load group for this DocumentLoader is idle. Flush if we need to.
|
||||
if (aFlushLayout && !mDontFlushLayout) {
|
||||
|
|
@ -687,9 +697,14 @@ void nsDocLoader::DocLoaderIsEmpty(bool aFlushLayout)
|
|||
|
||||
// And now check whether we're really busy; that might have changed with
|
||||
// the layout flush.
|
||||
// Note, mDocumentRequest can be null if the flushing above re-entered this
|
||||
// method.
|
||||
if (!IsBusy() && mDocumentRequest) {
|
||||
//
|
||||
// Note, mDocumentRequest can be null while mDocumentOpenedButNotLoaded is
|
||||
// false if the flushing above re-entered this method. Exit in that case.
|
||||
if (IsBusy() || (!mDocumentRequest && !mDocumentOpenedButNotLoaded)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mDocumentRequest) {
|
||||
// Clear out our request info hash, now that our load really is done and
|
||||
// we don't need it anymore to CalculateMaxProgress().
|
||||
ClearInternalProgress();
|
||||
|
|
@ -715,7 +730,7 @@ void nsDocLoader::DocLoaderIsEmpty(bool aFlushLayout)
|
|||
//
|
||||
mLoadGroup->SetDefaultLoadRequest(nullptr);
|
||||
|
||||
// Take a ref to our parent now so that we can call DocLoaderIsEmpty() on
|
||||
// Take a ref to our parent now so that we can call ChildDoneWithOnload() on
|
||||
// it even if our onload handler removes us from the docloader tree.
|
||||
RefPtr<nsDocLoader> parent = mParent;
|
||||
|
||||
|
|
@ -733,6 +748,67 @@ void nsDocLoader::DocLoaderIsEmpty(bool aFlushLayout)
|
|||
parent->ChildDoneWithOnload(this);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
MOZ_ASSERT(mDocumentOpenedButNotLoaded);
|
||||
mDocumentOpenedButNotLoaded = false;
|
||||
|
||||
// Make sure we do the ChildEnteringOnload/ChildDoneWithOnload even if we
|
||||
// plan to skip firing our own load event, because otherwise we might
|
||||
// never end up firing our parent's load event.
|
||||
RefPtr<nsDocLoader> parent = mParent;
|
||||
if (!parent || parent->ChildEnteringOnload(this)) {
|
||||
nsresult loadGroupStatus = NS_OK;
|
||||
mLoadGroup->GetStatus(&loadGroupStatus);
|
||||
// Make sure we're not canceling the loadgroup. If we are, then we should
|
||||
// not fire a load event just like in the normal navigation case.
|
||||
if (NS_SUCCEEDED(loadGroupStatus) ||
|
||||
loadGroupStatus == NS_ERROR_PARSED_DATA_CACHED) {
|
||||
// Can "doc" or "window" ever come back null here? Our state machine
|
||||
// is complicated enough, so I wouldn't bet against it...
|
||||
nsCOMPtr<nsIDocument> doc = do_GetInterface(GetAsSupports(this));
|
||||
if (doc) {
|
||||
doc->SetReadyStateInternal(nsIDocument::READYSTATE_COMPLETE,
|
||||
/* updateTimingInformation = */ false);
|
||||
|
||||
nsCOMPtr<nsPIDOMWindowOuter> window = doc->GetWindow();
|
||||
if (window && !doc->SkipLoadEventAfterClose()) {
|
||||
MOZ_LOG(gDocLoaderLog, LogLevel::Debug,
|
||||
("DocLoader:%p: Firing load event for document.open\n",
|
||||
this));
|
||||
|
||||
// This is a very cut-down version of
|
||||
// nsDocumentViewer::LoadComplete that doesn't do various things
|
||||
// that are not relevant here because this wasn't an actual
|
||||
// navigation.
|
||||
WidgetEvent event(true, eLoad);
|
||||
event.mFlags.mBubbles = false;
|
||||
event.mFlags.mCancelable = false;
|
||||
// Dispatching to |window|, but using |document| as the target,
|
||||
// per spec.
|
||||
event.mTarget = doc;
|
||||
nsEventStatus unused = nsEventStatus_eIgnore;
|
||||
doc->SetLoadEventFiring(true);
|
||||
EventDispatcher::Dispatch(window, nullptr, &event, nullptr,
|
||||
&unused);
|
||||
doc->SetLoadEventFiring(false);
|
||||
|
||||
// Now unsuppress painting on the presshell, if we
|
||||
// haven't done that yet.
|
||||
nsCOMPtr<nsIPresShell> shell = doc->GetShell();
|
||||
if (shell && !shell->IsDestroying()) {
|
||||
shell->UnsuppressPainting();
|
||||
|
||||
if (!shell->IsDestroying()) {
|
||||
shell->LoadComplete();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (parent) {
|
||||
parent->ChildDoneWithOnload(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -109,6 +109,8 @@ public:
|
|||
unsigned long mNotifyMask;
|
||||
};
|
||||
|
||||
void SetDocumentOpenedButNotLoaded() { mDocumentOpenedButNotLoaded = true; }
|
||||
|
||||
protected:
|
||||
virtual ~nsDocLoader();
|
||||
|
||||
|
|
@ -302,6 +304,15 @@ protected:
|
|||
bool mIsFlushingLayout;
|
||||
|
||||
private:
|
||||
/**
|
||||
* This flag indicates that the loader is waiting for completion of
|
||||
* a document.open-triggered "document load". This is set when
|
||||
* document.open() happens and sets up a new parser and cleared out
|
||||
* when we go to fire our load event or end up with a new document
|
||||
* channel.
|
||||
*/
|
||||
bool mDocumentOpenedButNotLoaded;
|
||||
|
||||
static const PLDHashTableOps sRequestInfoHashOps;
|
||||
|
||||
// A list of kids that are in the middle of their onload calls and will let
|
||||
|
|
@ -324,10 +335,20 @@ private:
|
|||
nsRequestInfo *GetRequestInfo(nsIRequest* aRequest);
|
||||
void ClearRequestInfoHash();
|
||||
int64_t CalculateMaxProgress();
|
||||
/// void DumpChannelInfo(void);
|
||||
/// void DumpChannelInfo(void);
|
||||
|
||||
// used to clear our internal progress state between loads...
|
||||
void ClearInternalProgress();
|
||||
|
||||
/**
|
||||
* Used to test whether we might need to fire a load event. This
|
||||
* can happen when we have a document load going on, or when we've
|
||||
* had document.open() called and haven't fired the corresponding
|
||||
* load event yet.
|
||||
*/
|
||||
bool IsBlockingLoadEvent() const {
|
||||
return mIsLoadingDocument || mDocumentOpenedButNotLoaded;
|
||||
}
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsDocLoader, NS_THIS_DOCLOADER_IMPL_CID)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue