Bug 775467 - Make readyState progress through all states without duplicate transitions. r=bzbarsky.

This commit is contained in:
Henri Sivonen 2012-07-27 16:35:09 +03:00
parent 0593b6bc8d
commit ee51a2e035
10 changed files with 66 additions and 7 deletions

View File

@ -1455,7 +1455,7 @@ nsContentSink::EndUpdate(nsIDocument *aDocument, nsUpdateType aUpdateType)
void
nsContentSink::DidBuildModelImpl(bool aTerminated)
{
if (mDocument && !aTerminated) {
if (mDocument) {
MOZ_ASSERT(mDocument->GetReadyStateEnum() ==
nsIDocument::READYSTATE_LOADING, "Bad readyState");
mDocument->SetReadyStateInternal(nsIDocument::READYSTATE_INTERACTIVE);

View File

@ -347,10 +347,12 @@ ImageDocument::SetScriptGlobalObject(nsIScriptGlobalObject* aScriptGlobalObject)
target->AddEventListener(NS_LITERAL_STRING("resize"), this, false);
target->AddEventListener(NS_LITERAL_STRING("keypress"), this, false);
if (!nsContentUtils::IsChildOfSameType(this)) {
if (!nsContentUtils::IsChildOfSameType(this) &&
GetReadyStateEnum() != nsIDocument::READYSTATE_COMPLETE) {
LinkStylesheet(NS_LITERAL_STRING("resource://gre/res/TopLevelImageDocument.css"));
LinkStylesheet(NS_LITERAL_STRING("chrome://global/skin/TopLevelImageDocument.css"));
}
BecomeInteractive();
}
}

View File

@ -194,6 +194,26 @@ MediaDocument::StartDocumentLoad(const char* aCommand,
return NS_OK;
}
void
MediaDocument::BecomeInteractive()
{
// In principle, if we knew the readyState code to work, we could infer
// restoration from GetReadyStateEnum() == nsIDocument::READYSTATE_COMPLETE.
bool restoring = false;
nsPIDOMWindow* window = GetWindow();
if (window) {
nsIDocShell* docShell = window->GetDocShell();
if (docShell) {
docShell->GetRestoringDocument(&restoring);
}
}
if (!restoring) {
MOZ_ASSERT(GetReadyStateEnum() == nsIDocument::READYSTATE_LOADING,
"Bad readyState");
SetReadyStateInternal(nsIDocument::READYSTATE_INTERACTIVE);
}
}
nsresult
MediaDocument::CreateSyntheticDocument()
{

View File

@ -35,6 +35,8 @@ public:
virtual void SetScriptGlobalObject(nsIScriptGlobalObject* aGlobalObject);
protected:
void BecomeInteractive();
virtual nsresult CreateSyntheticDocument();
friend class MediaDocumentStreamListener;

View File

@ -179,6 +179,7 @@ PluginDocument::SetScriptGlobalObject(nsIScriptGlobalObject* aScriptGlobalObject
CreateSyntheticPluginDocument();
NS_ASSERTION(NS_SUCCEEDED(rv), "failed to create synthetic document");
}
BecomeInteractive();
} else {
mStreamListener = nsnull;
}

View File

@ -70,9 +70,13 @@ VideoDocument::SetScriptGlobalObject(nsIScriptGlobalObject* aScriptGlobalObject)
// anything that might require it....
MediaDocument::SetScriptGlobalObject(aScriptGlobalObject);
if (aScriptGlobalObject && !nsContentUtils::IsChildOfSameType(this)) {
LinkStylesheet(NS_LITERAL_STRING("resource://gre/res/TopLevelVideoDocument.css"));
LinkStylesheet(NS_LITERAL_STRING("chrome://global/skin/TopLevelVideoDocument.css"));
if (aScriptGlobalObject) {
if (!nsContentUtils::IsChildOfSameType(this) &&
GetReadyStateEnum() != nsIDocument::READYSTATE_COMPLETE) {
LinkStylesheet(NS_LITERAL_STRING("resource://gre/res/TopLevelVideoDocument.css"));
LinkStylesheet(NS_LITERAL_STRING("chrome://global/skin/TopLevelVideoDocument.css"));
}
BecomeInteractive();
}
}

View File

@ -262,6 +262,15 @@ CheckXSLTParamPI(nsIDOMProcessingInstruction* aPi,
NS_IMETHODIMP
nsXMLContentSink::DidBuildModel(bool aTerminated)
{
if (!mParser) {
// If mParser is null, this parse has already been terminated and must
// not been terminated again. However, nsDocument may still think that
// the parse has not been terminated and call back into here in the case
// where the XML parser has finished but the XSLT transform associated
// with the document has not.
return NS_OK;
}
DidBuildModelImpl(aTerminated);
if (mXSLTProcessor) {

View File

@ -1095,6 +1095,11 @@ txMozillaXSLTProcessor::notifyError()
}
URIUtils::ResetWithSource(document, mSource);
MOZ_ASSERT(document->GetReadyStateEnum() ==
nsIDocument::READYSTATE_UNINITIALIZED,
"Bad readyState.");
document->SetReadyStateInternal(nsIDocument::READYSTATE_LOADING);
NS_NAMED_LITERAL_STRING(ns, "http://www.mozilla.org/newlayout/xml/parsererror.xml");
nsCOMPtr<nsIDOMElement> element;
@ -1146,6 +1151,11 @@ txMozillaXSLTProcessor::notifyError()
}
}
MOZ_ASSERT(document->GetReadyStateEnum() ==
nsIDocument::READYSTATE_LOADING,
"Bad readyState.");
document->SetReadyStateInternal(nsIDocument::READYSTATE_INTERACTIVE);
mObserver->OnTransformDone(mTransformResult, document);
}

View File

@ -7253,7 +7253,9 @@ nsDocShell::RestoreFromHistory()
mLSHE->GetRefreshURIList(getter_AddRefs(refreshURIList));
// Reattach to the window object.
mIsRestoringDocument = true; // for MediaDocument::BecomeInteractive
rv = mContentViewer->Open(windowState, mLSHE);
mIsRestoringDocument = false;
// Hack to keep nsDocShellEditorData alive across the
// SetContentViewer(nsnull) call below.

View File

@ -991,8 +991,6 @@ DocumentViewerImpl::LoadComplete(nsresult aStatus)
// will depend on whether it's cached!
if(window &&
(NS_SUCCEEDED(aStatus) || aStatus == NS_ERROR_PARSED_DATA_CACHED)) {
if (mDocument)
mDocument->SetReadyStateInternal(nsIDocument::READYSTATE_COMPLETE);
nsEventStatus status = nsEventStatus_eIgnore;
nsEvent event(true, NS_LOAD);
event.flags |= NS_EVENT_FLAG_CANT_BUBBLE;
@ -1008,6 +1006,17 @@ DocumentViewerImpl::LoadComplete(nsresult aStatus)
docShell->GetRestoringDocument(&restoring);
if (!restoring) {
MOZ_ASSERT(mDocument->IsXUL() || // readyState for XUL is bogus
mDocument->GetReadyStateEnum() ==
nsIDocument::READYSTATE_INTERACTIVE ||
// test_stricttransportsecurity.html has old-style
// docshell-generated about:blank docs reach this code!
(mDocument->GetReadyStateEnum() ==
nsIDocument::READYSTATE_UNINITIALIZED &&
NS_IsAboutBlank(mDocument->GetDocumentURI())),
"Bad readystate");
mDocument->SetReadyStateInternal(nsIDocument::READYSTATE_COMPLETE);
nsRefPtr<nsDOMNavigationTiming> timing(mDocument->GetNavigationTiming());
if (timing) {
timing->NotifyLoadEventStart();