зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1526268 Part 2 - Fix the logic to detect whether AccessibleCaret's position is changed. r=mats
This is the main patch to fix bug 1526268. It is wrong to use the cached rects relative to the root frame (ViewportFrame) to detect whether AccessibleCaret's position is changed or not, because it doesn't account the root scroll frame's scroll offset. The effect is that we always produce "PositionChangedResult::Changed" when scrolling on position:static elements, but "PositionChangedResult::NotChanged" on position:fixed elements. This patch fixes this by using the rect relative to custom content container, which is the actually rect to set caret's position, to check whether the position is changed or not. Note that even with this patch, the caret on "position:fixed" element is still jumpy during scrolling due to APZ. Part 3 will fixed this. Differential Revision: https://phabricator.services.mozilla.com/D51350 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
22b2870b5a
Коммит
742cd4bddc
|
@ -102,8 +102,7 @@ void AccessibleCaret::SetAppearance(Appearance aAppearance) {
|
|||
|
||||
// Need to reset rect since the cached rect will be compared in SetPosition.
|
||||
if (mAppearance == Appearance::None) {
|
||||
mImaginaryCaretRect = nsRect();
|
||||
mZoomLevel = 0.0f;
|
||||
ClearCachedData();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -231,6 +230,12 @@ void AccessibleCaret::RemoveCaretElement(Document* aDocument) {
|
|||
aDocument->RemoveAnonymousContent(*mCaretElementHolder, IgnoreErrors());
|
||||
}
|
||||
|
||||
void AccessibleCaret::ClearCachedData() {
|
||||
mImaginaryCaretRect = nsRect();
|
||||
mImaginaryCaretRectInContainerFrame = nsRect();
|
||||
mZoomLevel = 0.0f;
|
||||
}
|
||||
|
||||
AccessibleCaret::PositionChangedResult AccessibleCaret::SetPosition(
|
||||
nsIFrame* aFrame, int32_t aOffset) {
|
||||
if (!CustomContentContainerFrame()) {
|
||||
|
@ -245,27 +250,31 @@ AccessibleCaret::PositionChangedResult AccessibleCaret::SetPosition(
|
|||
|
||||
if (imaginaryCaretRectInFrame.IsEmpty()) {
|
||||
// Don't bother to set the caret position since it's invisible.
|
||||
mImaginaryCaretRect = nsRect();
|
||||
mZoomLevel = 0.0f;
|
||||
ClearCachedData();
|
||||
return PositionChangedResult::Invisible;
|
||||
}
|
||||
|
||||
nsRect imaginaryCaretRect = imaginaryCaretRectInFrame;
|
||||
nsLayoutUtils::TransformRect(aFrame, RootFrame(), imaginaryCaretRect);
|
||||
float zoomLevel = GetZoomLevel();
|
||||
// SetCaretElementStyle() requires the input rect relative to the custom
|
||||
// content container frame.
|
||||
nsRect imaginaryCaretRectInContainerFrame = imaginaryCaretRectInFrame;
|
||||
nsLayoutUtils::TransformRect(aFrame, CustomContentContainerFrame(),
|
||||
imaginaryCaretRectInContainerFrame);
|
||||
const float zoomLevel = GetZoomLevel();
|
||||
|
||||
if (imaginaryCaretRect.IsEqualEdges(mImaginaryCaretRect) &&
|
||||
if (imaginaryCaretRectInContainerFrame.IsEqualEdges(
|
||||
mImaginaryCaretRectInContainerFrame) &&
|
||||
FuzzyEqualsMultiplicative(zoomLevel, mZoomLevel)) {
|
||||
return PositionChangedResult::NotChanged;
|
||||
}
|
||||
|
||||
nsRect imaginaryCaretRect = imaginaryCaretRectInFrame;
|
||||
nsLayoutUtils::TransformRect(aFrame, RootFrame(), imaginaryCaretRect);
|
||||
|
||||
// Cache mImaginaryCaretRect, which is relative to the root frame.
|
||||
mImaginaryCaretRect = imaginaryCaretRect;
|
||||
mImaginaryCaretRectInContainerFrame = imaginaryCaretRectInContainerFrame;
|
||||
mZoomLevel = zoomLevel;
|
||||
|
||||
// SetCaretElementStyle() requires the input rect relative to container frame.
|
||||
nsRect imaginaryCaretRectInContainerFrame = imaginaryCaretRectInFrame;
|
||||
nsLayoutUtils::TransformRect(aFrame, CustomContentContainerFrame(),
|
||||
imaginaryCaretRectInContainerFrame);
|
||||
SetCaretElementStyle(imaginaryCaretRectInContainerFrame, mZoomLevel);
|
||||
|
||||
return PositionChangedResult::Changed;
|
||||
|
|
|
@ -168,6 +168,9 @@ class AccessibleCaret {
|
|||
// Remove caret element from custom content container.
|
||||
void RemoveCaretElement(dom::Document*);
|
||||
|
||||
// Clear the cached rects and zoom level.
|
||||
void ClearCachedData();
|
||||
|
||||
// The top-center of the imaginary caret to which this AccessibleCaret is
|
||||
// attached.
|
||||
static nsPoint CaretElementPosition(const nsRect& aRect) {
|
||||
|
@ -199,6 +202,10 @@ class AccessibleCaret {
|
|||
// mImaginaryCaretRect is relative to root frame.
|
||||
nsRect mImaginaryCaretRect;
|
||||
|
||||
// Cached mImaginaryCaretRect relative to the custom content container. This
|
||||
// is used in SetPosition() to check whether the caret position has changed.
|
||||
nsRect mImaginaryCaretRectInContainerFrame;
|
||||
|
||||
// Cache current zoom level to determine whether position is changed.
|
||||
float mZoomLevel = 0.0f;
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче