Bug 1333990: Part 2b - Don't enable editor until layout has started. r?ehsan draft
authorKris Maglione <maglione.k@gmail.com>
Tue, 14 Mar 2017 21:22:06 -0700
changeset 499606 9d471599ff42e7fd9a05875912eef65b57405e18
parent 499605 c3fdb20ac0442c327c88d0e61ecf5479adba1a67
child 499607 57dbae3233a179a82b2e0bd0326f8fb149cb6f74
push id49456
push usermaglione.k@gmail.com
push dateThu, 16 Mar 2017 00:44:19 +0000
reviewersehsan
bugs1333990
milestone54.0a1
Bug 1333990: Part 2b - Don't enable editor until layout has started. r?ehsan We need to In order to support asynchronous loading of extension content scripts, we need to be able to exit the HTML parser flush loop immediately after inserting the document element. Normally this doesn't cause problems, but when we enter edit mode with an empty element selected, the editor inserts a <br> node, and a <br> node at the start of the <html> element causes issues. These changes solve that issue by putting off entering editor mode until we begin laying out the document. MozReview-Commit-ID: H2ksNz0jRxs
docshell/test/navigation/test_bug386782.html
dom/base/nsIDocument.h
dom/html/nsHTMLDocument.cpp
dom/html/nsHTMLDocument.h
--- a/docshell/test/navigation/test_bug386782.html
+++ b/docshell/test/navigation/test_bug386782.html
@@ -35,17 +35,17 @@ https://bugzilla.mozilla.org/show_bug.cg
         expectedBodyAfterEdit:  'EDITED <br><p>contentEditable</p>',
         expectedBodyAfterSecondEdit: 'EDITED TWICE <br><p>contentEditable</p>',
       }
     ];
 
     var gTestNum = -1;
     var gTest = null;
 
-    window.onload = goNext();
+    window.onload = goNext;
 
     function goNext() {
       gTestNum++;
       if (gTestNum >= gTests.length) {
         SimpleTest.finish();
         return;
       }
       gTest = gTests[gTestNum];
--- a/dom/base/nsIDocument.h
+++ b/dom/base/nsIDocument.h
@@ -1957,17 +1957,17 @@ public:
     return mLoadedAsInteractiveData;
   }
 
   bool MayStartLayout()
   {
     return mMayStartLayout;
   }
 
-  void SetMayStartLayout(bool aMayStartLayout)
+  virtual void SetMayStartLayout(bool aMayStartLayout)
   {
     mMayStartLayout = aMayStartLayout;
   }
 
   already_AddRefed<nsIDocumentEncoder> GetCachedEncoder();
 
   void SetCachedEncoder(already_AddRefed<nsIDocumentEncoder> aEncoder);
 
--- a/dom/html/nsHTMLDocument.cpp
+++ b/dom/html/nsHTMLDocument.cpp
@@ -2406,17 +2406,17 @@ nsHTMLDocument::GetDesignMode(nsAString&
     aDesignMode.AssignLiteral("off");
   }
   return NS_OK;
 }
 
 void
 nsHTMLDocument::MaybeEditingStateChanged()
 {
-  if (!mPendingMaybeEditingStateChanged &&
+  if (!mPendingMaybeEditingStateChanged && mMayStartLayout &&
       mUpdateNestLevel == 0 && (mContentEditableCount > 0) != IsEditingOn()) {
     if (nsContentUtils::IsSafeToRunScript()) {
       EditingStateChanged();
     } else if (!mInDestructor) {
       nsContentUtils::AddScriptRunner(
         NewRunnableMethod(this, &nsHTMLDocument::MaybeEditingStateChanged));
     }
   }
@@ -2429,16 +2429,25 @@ nsHTMLDocument::EndUpdate(nsUpdateType a
   mPendingMaybeEditingStateChanged = true;
   nsDocument::EndUpdate(aUpdateType);
   if (reset) {
     mPendingMaybeEditingStateChanged = false;
   }
   MaybeEditingStateChanged();
 }
 
+void
+nsHTMLDocument::SetMayStartLayout(bool aMayStartLayout)
+{
+  nsIDocument::SetMayStartLayout(aMayStartLayout);
+
+  MaybeEditingStateChanged();
+}
+
+
 
 // Helper class, used below in ChangeContentEditableCount().
 class DeferredContentEditableCountChangeEvent : public Runnable
 {
 public:
   DeferredContentEditableCountChangeEvent(nsHTMLDocument *aDoc,
                                           nsIContent *aElement)
     : mDoc(aDoc)
--- a/dom/html/nsHTMLDocument.h
+++ b/dom/html/nsHTMLDocument.h
@@ -139,16 +139,18 @@ public:
   private:
     nsHTMLDocument* mDoc;
     EditingState    mSavedState;
   };
   friend class nsAutoEditingState;
 
   void EndUpdate(nsUpdateType aUpdateType) override;
 
+  virtual void SetMayStartLayout(bool aMayStartLayout) override;
+
   virtual nsresult SetEditingState(EditingState aState) override;
 
   virtual nsresult Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult) const override;
 
   virtual void RemovedFromDocShell() override;
 
   virtual mozilla::dom::Element *GetElementById(const nsAString& aElementId) override
   {