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.
--- 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);