Bug 1206545 - Initialize AccessibleCaretEventHub in nsCanvasFrame. r=roc draft
authorTing-Yu Lin <tlin@mozilla.com>
Mon, 16 Nov 2015 18:10:16 +0800
changeset 308985 489b687d8e53ef2cdf2deba4fc9ea59dad323388
parent 308984 a7516c4ae07e3f5013d21a7d72d331b724c6ee43
child 308986 b51717ab90725599d7875c90ccaa93c00cacbb71
push id7547
push usertlin@mozilla.com
push dateMon, 16 Nov 2015 10:11:56 +0000
reviewersroc
bugs1206545
milestone45.0a1
Bug 1206545 - Initialize AccessibleCaretEventHub in nsCanvasFrame. r=roc To properly initialize AccessibleCaretEventHub, both canvas frame and its anonymous mCustomContentContainer are required to successfully insert anonymous caret elements. However, if <html> has "display: none", nsCSSFrameConstructor::ConstructDocElementFrame() will return early in [1] without constructing mCustomContentContainer. Thus, AccessibleCaretEventHub will fail to initialize in [2] due to null mCustomContentContainer. By moving AccessibleCaretEventHub::Init() to nsCanvasFrame::CreateAnonymousContent(), we can guarantee that mCustomContentContainer is constructed before initializing AccessibleCaretEventHub. [1] https://dxr.mozilla.org/mozilla-central/rev/7cd2d806bd069c0260ff73f023ac85f892b863bf/layout/base/nsCSSFrameConstructor.cpp#2413-2416 [2] https://dxr.mozilla.org/mozilla-central/rev/7cd2d806bd069c0260ff73f023ac85f892b863bf/layout/base/nsPresShell.cpp#1682
layout/base/nsPresShell.cpp
layout/generic/nsCanvasFrame.cpp
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -1672,21 +1672,16 @@ PresShell::Initialize(nscoord aWidth, ns
 
       // Something in mFrameConstructor->ContentInserted may have caused
       // Destroy() to get called, bug 337586.
       NS_ENSURE_STATE(!mHaveShutDown);
 
       mFrameConstructor->EndUpdate();
     }
 
-    // Initialize after nsCanvasFrame is created.
-    if (mAccessibleCaretEventHub) {
-      mAccessibleCaretEventHub->Init();
-    }
-
     // nsAutoScriptBlocker going out of scope may have killed us too
     NS_ENSURE_STATE(!mHaveShutDown);
 
     // Run the XBL binding constructors for any new frames we've constructed
     mDocument->BindingManager()->ProcessAttachedQueue();
 
     // Constructors may have killed us too
     NS_ENSURE_STATE(!mHaveShutDown);
--- a/layout/generic/nsCanvasFrame.cpp
+++ b/layout/generic/nsCanvasFrame.cpp
@@ -2,16 +2,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* rendering object that goes directly inside the document's scrollbars */
 
 #include "nsCanvasFrame.h"
 
+#include "AccessibleCaretEventHub.h"
 #include "gfxUtils.h"
 #include "nsContainerFrame.h"
 #include "nsCSSRendering.h"
 #include "nsPresContext.h"
 #include "nsStyleContext.h"
 #include "nsRenderingContext.h"
 #include "nsGkAtoms.h"
 #include "nsPresShell.h"
@@ -169,16 +170,23 @@ nsCanvasFrame::CreateAnonymousContent(ns
     mCustomContentContainer->AppendChildTo(node->AsContent(), true);
   }
 
   // Only create a frame for mCustomContentContainer if it has some children.
   if (len == 0) {
     HideCustomContentContainer();
   }
 
+  RefPtr<AccessibleCaretEventHub> eventHub =
+    PresContext()->GetPresShell()->GetAccessibleCaretEventHub();
+  if (eventHub) {
+    // AccessibleCaret will insert anonymous caret elements.
+    eventHub->Init();
+  }
+
   return NS_OK;
 }
 
 void
 nsCanvasFrame::AppendAnonymousContentTo(nsTArray<nsIContent*>& aElements, uint32_t aFilter)
 {
   if (mTouchCaretElement) {
     aElements.AppendElement(mTouchCaretElement);