Skip to content

Commit

Permalink
Bug 1444491 - Check the number of script blocking style sheets in aut…
Browse files Browse the repository at this point in the history
…ofocus algorithm r=hsivonen

Differential Revision: https://phabricator.services.mozilla.com/D165224
  • Loading branch information
sefeng211 committed Feb 15, 2023
1 parent 6506478 commit af14bb1
Show file tree
Hide file tree
Showing 7 changed files with 47 additions and 5 deletions.
22 changes: 22 additions & 0 deletions dom/base/Document.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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) {
Expand Down
8 changes: 4 additions & 4 deletions dom/base/nsContentSink.h
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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() {
Expand Down
5 changes: 5 additions & 0 deletions dom/html/nsHTMLContentSink.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -924,6 +925,10 @@ void HTMLContentSink::ContinueInterruptedParsingIfEnabled() {
}
}

bool HTMLContentSink::WaitForPendingSheets() {
return nsContentSink::WaitForPendingSheets();
}

void HTMLContentSink::ContinueInterruptedParsingAsync() {
nsCOMPtr<nsIRunnable> ev = NewRunnableMethod(
"HTMLContentSink::ContinueInterruptedParsingIfEnabled", this,
Expand Down
2 changes: 2 additions & 0 deletions parser/html/nsHtml5TreeOpExecutor.h
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,8 @@ class nsHtml5TreeOpExecutor final
*/
void WillResume() override;

virtual nsIContentSink* AsExecutor() override { return this; }

virtual void InitialTranslationCompleted() override;

/**
Expand Down
6 changes: 6 additions & 0 deletions parser/htmlparser/nsIContentSink.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 6 additions & 0 deletions parser/htmlparser/nsIHTMLContentSink.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand Down

0 comments on commit af14bb1

Please sign in to comment.