Bug 1161389 - Skip AccessibleCaret frame if nsDisplayListBuilder doesn't build caret. r=roc
authorTing-Yu Lin <tlin@mozilla.com>
Wed, 27 May 2015 16:37:44 +0800
changeset 268033 ad884eef34812182585545cf9f6d50778348d2cd
parent 268032 cc1287e6504e54070cbf10cafead3eda2ed515d2
child 268034 cc31aa2410bda44068db780df10bedbb02236233
push id2294
push userbsmedberg@mozilla.com
push dateWed, 27 May 2015 15:05:10 +0000
reviewersroc
bugs1161389
milestone41.0a1
Bug 1161389 - Skip AccessibleCaret frame if nsDisplayListBuilder doesn't build caret. r=roc When nsDisplayListBuilder doesn't build caret, we need to skip building AccessibleCaret frames. We check that the content of the frame has "moz-accessiblecaret" class.
layout/base/nsCSSFrameConstructor.cpp
layout/base/nsDisplayList.cpp
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -2642,17 +2642,17 @@ nsCSSFrameConstructor::ConstructDocEleme
     contentFrame->SetInitialChildList(kPrincipalList, childItems);
   }
 
   // set the primary frame
   aDocElement->SetPrimaryFrame(contentFrame);
 
   SetInitialSingleChild(mDocElementContainingBlock, newFrame);
 
-  // Create touch caret frame if there is a canvas frame
+  // Create frames for anonymous contents if there is a canvas frame.
   if (mDocElementContainingBlock->GetType() == nsGkAtoms::canvasFrame) {
     ConstructAnonymousContentForCanvas(state, mDocElementContainingBlock,
                                        aDocElement);
   }
 
   return newFrame;
 }
 
@@ -2910,17 +2910,16 @@ nsCSSFrameConstructor::ConstructAnonymou
                                                           nsIFrame* aFrame,
                                                           nsIContent* aDocElement)
 {
   NS_ASSERTION(aFrame->GetType() == nsGkAtoms::canvasFrame, "aFrame should be canvas frame!");
 
   nsAutoTArray<nsIAnonymousContentCreator::ContentInfo, 4> anonymousItems;
   GetAnonymousContent(aDocElement, aFrame, anonymousItems);
   if (anonymousItems.IsEmpty()) {
-    // Touch caret is not enabled.
     return;
   }
 
   FrameConstructionItemList itemsToConstruct;
   nsContainerFrame* frameAsContainer = do_QueryFrame(aFrame);
   AddFCItemsForAnonymousContent(aState, frameAsContainer, anonymousItems, itemsToConstruct);
 
   nsFrameItems frameItems;
--- a/layout/base/nsDisplayList.cpp
+++ b/layout/base/nsDisplayList.cpp
@@ -64,16 +64,17 @@
 #include "nsPrintfCString.h"
 #include "UnitTransforms.h"
 #include "LayersLogging.h"
 #include "FrameLayerBuilder.h"
 #include "mozilla/EventStateManager.h"
 #include "RestyleManager.h"
 #include "nsCaret.h"
 #include "nsISelection.h"
+#include "nsDOMTokenList.h"
 
 // GetCurrentTime is defined in winbase.h as zero argument macro forwarding to
 // GetTickCount().
 #ifdef GetCurrentTime
 #undef GetCurrentTime
 #endif
 
 using namespace mozilla;
@@ -892,19 +893,30 @@ nsDisplayListBuilder::ResetMarkedFramesF
   mFramesMarkedForDisplay.SetLength(firstFrameForShell);
 }
 
 void
 nsDisplayListBuilder::MarkFramesForDisplayList(nsIFrame* aDirtyFrame,
                                                const nsFrameList& aFrames,
                                                const nsRect& aDirtyRect) {
   mFramesMarkedForDisplay.SetCapacity(mFramesMarkedForDisplay.Length() + aFrames.GetLength());
-  for (nsFrameList::Enumerator e(aFrames); !e.AtEnd(); e.Next()) {
-    mFramesMarkedForDisplay.AppendElement(e.get());
-    MarkOutOfFlowFrameForDisplay(aDirtyFrame, e.get(), aDirtyRect);
+  for (nsIFrame* e : aFrames) {
+    // Skip the AccessibleCaret frame when building no caret.
+    if (!IsBuildingCaret()) {
+      nsIContent* content = e->GetContent();
+      if (content && content->IsInNativeAnonymousSubtree() && content->IsElement()) {
+        ErrorResult rv;
+        auto classList = content->AsElement()->ClassList();
+        if (classList->Contains(NS_LITERAL_STRING("moz-accessiblecaret"), rv)) {
+          continue;
+        }
+      }
+    }
+    mFramesMarkedForDisplay.AppendElement(e);
+    MarkOutOfFlowFrameForDisplay(aDirtyFrame, e, aDirtyRect);
   }
 }
 
 void
 nsDisplayListBuilder::MarkPreserve3DFramesForDisplayList(nsIFrame* aDirtyFrame, const nsRect& aDirtyRect)
 {
   nsAutoTArray<nsIFrame::ChildList,4> childListArray;
   aDirtyFrame->GetChildLists(&childListArray);