Bug 1377447 - Add a new flush type between Frames and InterruptibleLayout to initialize layout if needed and use it from CheckIfFocusable. r=smaug, a=jcristau
authorEhsan Akhgari <ehsan@mozilla.com>
Tue, 18 Jul 2017 10:17:00 -0400
changeset 414352 33b0931bbfc03c110d37ea360beec1e1d33db958
parent 414351 7bb0d5ad88b30422b030cbd1c3e0973a30df660c
child 414353 17955eae8f847e1fd55696182d8f6db81f5c2dae
push id1490
push usermtabara@mozilla.com
push dateMon, 31 Jul 2017 14:08:16 +0000
treeherdermozilla-release@70e32e6bf15e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug, jcristau
bugs1377447
milestone55.0
Bug 1377447 - Add a new flush type between Frames and InterruptibleLayout to initialize layout if needed and use it from CheckIfFocusable. r=smaug, a=jcristau
dom/base/FlushType.h
dom/base/nsFocusManager.cpp
dom/html/nsHTMLContentSink.cpp
dom/xml/nsXMLContentSink.cpp
layout/base/PresShell.cpp
layout/reftests/bugs/1377447-1-ref.html
layout/reftests/bugs/1377447-1.html
layout/reftests/bugs/1377447-2.html
layout/reftests/bugs/reftest.list
parser/html/nsHtml5TreeOpExecutor.cpp
--- a/dom/base/FlushType.h
+++ b/dom/base/FlushType.h
@@ -22,22 +22,23 @@ namespace mozilla {
 enum class FlushType : uint8_t {
   None             = 0, /* Actually don't flush anything */
   Content          = 1, /* flush the content model construction */
   ContentAndNotify = 2, /* As above, plus flush the frame model
                            construction and other nsIMutationObserver
                            notifications. */
   Style            = 3, /* As above, plus flush style reresolution */
   Frames           = Style,
-  InterruptibleLayout = 4, /* As above, plus flush reflow,
+  EnsurePresShellInitAndFrames = 4, /* As above, plus ensure the pres shell is alive */
+  InterruptibleLayout = 5, /* As above, plus flush reflow,
                               but allow it to be interrupted (so
                               an incomplete layout may result) */
-  Layout           = 5, /* As above, but layout must run to
+  Layout           = 6, /* As above, but layout must run to
                            completion */
-  Display          = 6, /* As above, plus flush painting */
+  Display          = 7, /* As above, plus flush painting */
 
   Count
 };
 
 struct ChangesToFlush {
   ChangesToFlush(FlushType aFlushType, bool aFlushAnimations)
     : mFlushType(aFlushType)
     , mFlushAnimations(aFlushAnimations)
--- a/dom/base/nsFocusManager.cpp
+++ b/dom/base/nsFocusManager.cpp
@@ -1562,19 +1562,20 @@ nsFocusManager::CheckIfFocusable(nsICont
 
   nsCOMPtr<nsIDocument> doc = aContent->GetComposedDoc();
   // can't focus elements that are not in documents
   if (!doc) {
     LOGCONTENT("Cannot focus %s because content not in document", aContent)
     return nullptr;
   }
 
-  // Make sure that our frames are up to date
+  // Make sure that our frames are up to date while ensuring the presshell is
+  // also initialized in case we come from an autofocus event.
   mEventHandlingNeedsFlush = false;
-  doc->FlushPendingNotifications(FlushType::Frames);
+  doc->FlushPendingNotifications(FlushType::EnsurePresShellInitAndFrames);
 
   nsIPresShell *shell = doc->GetShell();
   if (!shell)
     return nullptr;
 
   // the root content can always be focused,
   // except in userfocusignored context.
   if (aContent == doc->GetRootElement())
--- a/dom/html/nsHTMLContentSink.cpp
+++ b/dom/html/nsHTMLContentSink.cpp
@@ -1063,17 +1063,17 @@ HTMLContentSink::FlushPendingNotificatio
   if (!mInNotification) {
     // Only flush if we're still a document observer (so that our child counts
     // should be correct).
     if (mIsDocumentObserver) {
       if (aType >= FlushType::ContentAndNotify) {
         FlushTags();
       }
     }
-    if (aType >= FlushType::InterruptibleLayout) {
+    if (aType >= FlushType::EnsurePresShellInitAndFrames) {
       // Make sure that layout has started so that the reflow flush
       // will actually happen.
       StartLayout(true);
     }
   }
 }
 
 nsresult
--- a/dom/xml/nsXMLContentSink.cpp
+++ b/dom/xml/nsXMLContentSink.cpp
@@ -1463,17 +1463,17 @@ nsXMLContentSink::FlushPendingNotificati
       // counts should be correct).
       if (aType >= FlushType::ContentAndNotify) {
         FlushTags();
       }
       else {
         FlushText(false);
       }
     }
-    if (aType >= FlushType::InterruptibleLayout) {
+    if (aType >= FlushType::EnsurePresShellInitAndFrames) {
       // Make sure that layout has started so that the reflow flush
       // will actually happen.
       MaybeStartLayout(true);
     }
   }
 }
 
 /**
--- a/layout/base/PresShell.cpp
+++ b/layout/base/PresShell.cpp
@@ -4069,16 +4069,19 @@ PresShell::DoFlushPendingNotifications(m
 
 #ifdef MOZ_GECKO_PROFILER
   static const EnumeratedArray<FlushType,
                                FlushType::Count,
                                const char*> flushTypeNames = {
     "",
     "Content",
     "ContentAndNotify",
+    // As far as the profiler is concerned, EnsurePresShellInitAndFrames and
+    // Frames are the same
+    "Style",
     "Style",
     "InterruptibleLayout",
     "Layout",
     "Display"
   };
 
   PROFILER_LABEL_DYNAMIC("PresShell", "Flush",
     js::ProfileEntry::Category::GRAPHICS,
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/1377447-1-ref.html
@@ -0,0 +1,3 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<input type="text" autofocus="" onfocus="document.documentElement.removeAttribute('class')">
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/1377447-1.html
@@ -0,0 +1,4 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<link rel="stylesheet" href="nothing">
+<input type="text" autofocus="" onfocus="document.documentElement.removeAttribute('class')">
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/1377447-2.html
@@ -0,0 +1,3 @@
+<!DOCTYPE html>
+<html>
+<input type="text">
--- a/layout/reftests/bugs/reftest.list
+++ b/layout/reftests/bugs/reftest.list
@@ -2008,8 +2008,10 @@ fails-if(styloVsGecko) == 1322512-1.html
 fails-if(!stylo||styloVsGecko) == 1365162-1.html 1365162-1-ref.html
 == 1366144.html 1366144-ref.html
 == 1367592-1.html 1367592-1-ref.html
 == 1368113-1.html 1368113-1-ref.html
 == 1369584-1a.html 1369584-1-ref.html
 == 1369584-1b.html 1369584-1-ref.html
 == 1369954-1.xhtml 1369954-1-ref.xhtml
 == 1369985-1.html 1369985-1-ref.html
+needs-focus == 1377447-1.html 1377447-1-ref.html
+needs-focus != 1377447-1.html 1377447-2.html
--- a/parser/html/nsHtml5TreeOpExecutor.cpp
+++ b/parser/html/nsHtml5TreeOpExecutor.cpp
@@ -210,17 +210,17 @@ nsHtml5TreeOpExecutor::SetParser(nsParse
 {
   mParser = aParser;
   return NS_OK;
 }
 
 void
 nsHtml5TreeOpExecutor::FlushPendingNotifications(FlushType aType)
 {
-  if (aType >= FlushType::InterruptibleLayout) {
+  if (aType >= FlushType::EnsurePresShellInitAndFrames) {
     // Bug 577508 / 253951
     nsContentSink::StartLayout(true);
   }
 }
 
 nsISupports*
 nsHtml5TreeOpExecutor::GetTarget()
 {