Bug 1444491 - Check the number of script blocking style sheets in autofocus algorithm r=hsivonen

Differential Revision: https://phabricator.services.mozilla.com/D165224
This commit is contained in:
Sean Feng 2023-02-15 20:08:38 +00:00
parent 40ee61069d
commit 5630ab554d
7 changed files with 47 additions and 5 deletions

View File

@ -381,6 +381,7 @@
#include "nsIX509Cert.h"
#include "nsIX509CertValidity.h"
#include "nsIXMLContentSink.h"
#include "nsIHTMLContentSink.h"
#include "nsIXULRuntime.h"
#include "nsImageLoadingContent.h"
#include "nsImportModule.h"
@ -12790,6 +12791,27 @@ void Document::FlushAutoFocusCandidates() {
iter.Remove();
continue;
}
nsCOMPtr<nsIContentSink> sink =
do_QueryInterface(autoFocusElementDoc->GetCurrentContentSink());
if (sink) {
nsHtml5TreeOpExecutor* executor =
static_cast<nsHtml5TreeOpExecutor*>(sink->AsExecutor());
if (executor) {
// This is a HTML5 document
MOZ_ASSERT(autoFocusElementDoc->IsHTMLDocument());
// If doc's script-blocking style sheet counter is greater than 0, th
// return.
if (executor->WaitForPendingSheets()) {
// In this case, element is the currently-best candidate, but doc is
// not ready for autofocusing. We'll try again next time flush
// autofocus candidates is called.
ScheduleFlushAutoFocusCandidates();
return;
}
}
}
// The autofocus element could be moved to a different
// top level BC.
if (bc->Top()->GetDocument() != this) {

View File

@ -169,6 +169,10 @@ class nsContentSink : public nsICSSLoaderObserver,
Document* GetDocument() { return mDocument; }
// Later on we might want to make this more involved somehow
// (e.g. stop waiting after some timeout or whatnot).
bool WaitForPendingSheets() { return mPendingSheetCount > 0; }
protected:
inline int32_t GetNotificationInterval() {
if (mDynamicLowerValue) {
@ -180,10 +184,6 @@ class nsContentSink : public nsICSSLoaderObserver,
virtual nsresult FlushTags() = 0;
// Later on we might want to make this more involved somehow
// (e.g. stop waiting after some timeout or whatnot).
bool WaitForPendingSheets() { return mPendingSheetCount > 0; }
void DoProcessLinkHeader();
void StopDeflecting() {

View File

@ -114,6 +114,7 @@ class HTMLContentSink : public nsContentSink, public nsIHTMLContentSink {
virtual void SetDocumentCharset(NotNull<const Encoding*> aEncoding) override;
virtual nsISupports* GetTarget() override;
virtual bool IsScriptExecuting() override;
virtual bool WaitForPendingSheets() override;
virtual void ContinueInterruptedParsingAsync() override;
// nsIHTMLContentSink
@ -924,6 +925,10 @@ void HTMLContentSink::ContinueInterruptedParsingIfEnabled() {
}
}
bool HTMLContentSink::WaitForPendingSheets() {
return nsContentSink::WaitForPendingSheets();
}
void HTMLContentSink::ContinueInterruptedParsingAsync() {
nsCOMPtr<nsIRunnable> ev = NewRunnableMethod(
"HTMLContentSink::ContinueInterruptedParsingIfEnabled", this,

View File

@ -131,6 +131,8 @@ class nsHtml5TreeOpExecutor final
*/
void WillResume() override;
virtual nsIContentSink* AsExecutor() override { return this; }
virtual void InitialTranslationCompleted() override;
/**

View File

@ -89,6 +89,12 @@ class nsIContentSink : public nsISupports {
*/
virtual void WillResume() = 0;
/**
* This method returns nullptr unless `this` can
* be cast as nsHtml5TreeOpExecutor.
*/
virtual nsIContentSink* AsExecutor() { return nullptr; }
/**
* This method gets called by the parser so that the content
* sink can retain a reference to the parser. The expectation

View File

@ -83,6 +83,12 @@ class nsIHTMLContentSink : public nsIContentSink {
* @param aTag - The tag to be closed.
*/
NS_IMETHOD CloseContainer(ElementType aTag) = 0;
/**
* This method returns true if there are more than one
* pending style sheets, false otherwise.
*/
virtual bool WaitForPendingSheets() = 0;
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsIHTMLContentSink, NS_IHTML_CONTENT_SINK_IID)

View File

@ -2,11 +2,12 @@
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/utils.js"></script>
<link rel="stylesheet" href="resources/erase-first.css?pipe=trickle(d1)">
<input id="first" autofocus>
<input id="second" autofocus>
<link rel="stylesheet" href="resources/erase-first.css?pipe=trickle(d1)">
<script>
'use strict';