зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1384606 - part 4: Make `nsIFrame::GetFrameFromDirection` allow to return content in different native anonymous subtree if the caller wants r=emilio
The a11y module wants to traverse frames in native anonymous subtrees. Therefore, this patch adds new option for allowing it, makes `nsIFrame::GetFrameFromDirection` check it before comparing native anonymous subtree root nodes, and makes `HyperTextAccessible::FindOffset` use the option. Differential Revision: https://phabricator.services.mozilla.com/D172759
This commit is contained in:
Родитель
9cf5036656
Коммит
25e942f2a0
|
@ -534,7 +534,8 @@ uint32_t HyperTextAccessible::FindOffset(uint32_t aOffset,
|
|||
PeekOffsetStruct pos(
|
||||
aAmount, aDirection, innerContentOffset, nsPoint(0, 0),
|
||||
{PeekOffsetOption::JumpLines, PeekOffsetOption::IsKeyboardSelect,
|
||||
PeekOffsetOption::PreserveSpaces},
|
||||
PeekOffsetOption::PreserveSpaces,
|
||||
PeekOffsetOption::AllowContentInDifferentNativeAnonymousSubtreeRoot},
|
||||
aWordMovementType);
|
||||
nsresult rv = frameAtOffset->PeekOffset(&pos);
|
||||
|
||||
|
|
|
@ -977,10 +977,12 @@ nsPrevNextBidiLevels nsFrameSelection::GetPrevNextBidiLevels(
|
|||
return levels;
|
||||
}
|
||||
|
||||
PeekOffsetOptions peekOffsetOptions{PeekOffsetOption::ScrollViewStop};
|
||||
if (aJumpLines) {
|
||||
peekOffsetOptions += PeekOffsetOption::JumpLines;
|
||||
}
|
||||
nsIFrame* newFrame =
|
||||
currentFrame
|
||||
->GetFrameFromDirection(direction, false, aJumpLines, true, false)
|
||||
.mFrame;
|
||||
currentFrame->GetFrameFromDirection(direction, peekOffsetOptions).mFrame;
|
||||
|
||||
FrameBidiData currentBidi = currentFrame->GetBidiData();
|
||||
mozilla::intl::BidiEmbeddingLevel currentLevel = currentBidi.embeddingLevel;
|
||||
|
|
|
@ -101,6 +101,10 @@ enum class PeekOffsetOption : uint8_t {
|
|||
// If true, the offset has to end up in an editable node, otherwise we'll keep
|
||||
// searching.
|
||||
ForceEditableRegion,
|
||||
|
||||
// If set, the result's native anonymous subtree root may be different from
|
||||
// the scan start content's root.
|
||||
AllowContentInDifferentNativeAnonymousSubtreeRoot,
|
||||
};
|
||||
|
||||
using PeekOffsetOptions = EnumSet<PeekOffsetOption>;
|
||||
|
|
|
@ -9523,19 +9523,19 @@ Result<bool, nsresult> nsIFrame::IsLogicallyAtLineEdge(
|
|||
}
|
||||
|
||||
nsIFrame::SelectablePeekReport nsIFrame::GetFrameFromDirection(
|
||||
nsDirection aDirection, bool aVisual, bool aJumpLines, bool aScrollViewStop,
|
||||
bool aForceEditableRegion) {
|
||||
nsDirection aDirection, const PeekOffsetOptions& aOptions) {
|
||||
SelectablePeekReport result;
|
||||
|
||||
nsPresContext* presContext = PresContext();
|
||||
bool needsVisualTraversal = aVisual && presContext->BidiEnabled();
|
||||
const bool needsVisualTraversal =
|
||||
aOptions.contains(PeekOffsetOption::Visual) && presContext->BidiEnabled();
|
||||
nsCOMPtr<nsIFrameEnumerator> frameTraversal;
|
||||
MOZ_TRY(NS_NewFrameTraversal(getter_AddRefs(frameTraversal), presContext,
|
||||
this, eLeaf, needsVisualTraversal,
|
||||
aScrollViewStop,
|
||||
true, // aFollowOOFs
|
||||
false // aSkipPopupChecks
|
||||
));
|
||||
MOZ_TRY(NS_NewFrameTraversal(
|
||||
getter_AddRefs(frameTraversal), presContext, this, eLeaf,
|
||||
needsVisualTraversal, aOptions.contains(PeekOffsetOption::ScrollViewStop),
|
||||
true, // aFollowOOFs
|
||||
false // aSkipPopupChecks
|
||||
));
|
||||
|
||||
// Find the prev/next selectable frame
|
||||
bool selectable = false;
|
||||
|
@ -9544,8 +9544,8 @@ nsIFrame::SelectablePeekReport nsIFrame::GetFrameFromDirection(
|
|||
const nsIContent* const nativeAnonymousSubtreeContent =
|
||||
GetClosestNativeAnonymousSubtreeRoot();
|
||||
while (!selectable) {
|
||||
auto [blockFrame, lineFrame] =
|
||||
traversedFrame->GetContainingBlockForLine(aScrollViewStop);
|
||||
auto [blockFrame, lineFrame] = traversedFrame->GetContainingBlockForLine(
|
||||
aOptions.contains(PeekOffsetOption::ScrollViewStop));
|
||||
if (!blockFrame) {
|
||||
return result;
|
||||
}
|
||||
|
@ -9564,7 +9564,7 @@ nsIFrame::SelectablePeekReport nsIFrame::GetFrameFromDirection(
|
|||
: traversedFrame->IsLogicallyAtLineEdge(it, thisLine, aDirection));
|
||||
if (atLineEdge) {
|
||||
result.mJumpedLine = true;
|
||||
if (!aJumpLines) {
|
||||
if (!aOptions.contains(PeekOffsetOption::JumpLines)) {
|
||||
return result; // we are done. cannot jump lines
|
||||
}
|
||||
int32_t lineToCheckWrap =
|
||||
|
@ -9580,19 +9580,24 @@ nsIFrame::SelectablePeekReport nsIFrame::GetFrameFromDirection(
|
|||
return result;
|
||||
}
|
||||
|
||||
auto IsSelectable = [aForceEditableRegion, nativeAnonymousSubtreeContent](
|
||||
const nsIFrame* aFrame) {
|
||||
if (!aFrame->IsSelectable(nullptr)) {
|
||||
return false;
|
||||
}
|
||||
// If the new frame is in a native anonymous subtree, we should treat it
|
||||
// as not selectable unless the frame and found frame are in same subtree.
|
||||
if (aFrame->GetClosestNativeAnonymousSubtreeRoot() !=
|
||||
nativeAnonymousSubtreeContent) {
|
||||
return false;
|
||||
}
|
||||
return !aForceEditableRegion || aFrame->GetContent()->IsEditable();
|
||||
};
|
||||
auto IsSelectable =
|
||||
[aOptions, nativeAnonymousSubtreeContent](const nsIFrame* aFrame) {
|
||||
if (!aFrame->IsSelectable(nullptr)) {
|
||||
return false;
|
||||
}
|
||||
// If the new frame is in a native anonymous subtree, we should treat
|
||||
// it as not selectable unless the frame and found frame are in same
|
||||
// subtree.
|
||||
if (!aOptions.contains(
|
||||
PeekOffsetOption::
|
||||
AllowContentInDifferentNativeAnonymousSubtreeRoot) &&
|
||||
aFrame->GetClosestNativeAnonymousSubtreeRoot() !=
|
||||
nativeAnonymousSubtreeContent) {
|
||||
return false;
|
||||
}
|
||||
return !aOptions.contains(PeekOffsetOption::ForceEditableRegion) ||
|
||||
aFrame->GetContent()->IsEditable();
|
||||
};
|
||||
|
||||
// Skip br frames, but only if we can select something before hitting the
|
||||
// end of the line or a non-selectable region.
|
||||
|
@ -9623,7 +9628,8 @@ nsIFrame::SelectablePeekReport nsIFrame::GetFrameFromDirection(
|
|||
|
||||
result.mOffset = (aDirection == eDirNext) ? 0 : -1;
|
||||
|
||||
if (aVisual && nsBidiPresUtils::IsReversedDirectionFrame(traversedFrame)) {
|
||||
if (aOptions.contains(PeekOffsetOption::Visual) &&
|
||||
nsBidiPresUtils::IsReversedDirectionFrame(traversedFrame)) {
|
||||
// The new frame is reverse-direction, go to the other end
|
||||
result.mOffset = -1 - result.mOffset;
|
||||
}
|
||||
|
@ -9633,11 +9639,7 @@ nsIFrame::SelectablePeekReport nsIFrame::GetFrameFromDirection(
|
|||
|
||||
nsIFrame::SelectablePeekReport nsIFrame::GetFrameFromDirection(
|
||||
const PeekOffsetStruct& aPos) {
|
||||
return GetFrameFromDirection(
|
||||
aPos.mDirection, aPos.mOptions.contains(PeekOffsetOption::Visual),
|
||||
aPos.mOptions.contains(PeekOffsetOption::JumpLines),
|
||||
aPos.mOptions.contains(PeekOffsetOption::ScrollViewStop),
|
||||
aPos.mOptions.contains(PeekOffsetOption::ForceEditableRegion));
|
||||
return GetFrameFromDirection(aPos.mDirection, aPos.mOptions);
|
||||
}
|
||||
|
||||
nsView* nsIFrame::GetClosestView(nsPoint* aOffset) const {
|
||||
|
|
|
@ -55,6 +55,7 @@
|
|||
#include "mozilla/AspectRatio.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/Baseline.h"
|
||||
#include "mozilla/EnumSet.h"
|
||||
#include "mozilla/EventForwards.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "mozilla/RelativeTo.h"
|
||||
|
@ -129,6 +130,7 @@ struct CharacterDataChangeInfo;
|
|||
|
||||
namespace mozilla {
|
||||
|
||||
enum class PeekOffsetOption : uint8_t;
|
||||
enum class PseudoStyleType : uint8_t;
|
||||
enum class TableSelectionMode : uint32_t;
|
||||
|
||||
|
@ -3877,17 +3879,14 @@ class nsIFrame : public nsQueryFrame {
|
|||
* Called to find the previous/next non-anonymous selectable leaf frame.
|
||||
*
|
||||
* @param aDirection the direction to move in (eDirPrevious or eDirNext)
|
||||
* @param aVisual whether bidi caret behavior is visual (true) or logical
|
||||
* (false)
|
||||
* @param aJumpLines whether to allow jumping across line boundaries
|
||||
* @param aScrollViewStop whether to stop when reaching a scroll frame
|
||||
* boundary
|
||||
* @param aOptions the other options which is same as
|
||||
* PeekOffsetStruct::mOptions.
|
||||
* FIXME: Due to the include hell, we cannot use the alias, PeekOffsetOptions
|
||||
* is not available in this header file.
|
||||
*/
|
||||
SelectablePeekReport GetFrameFromDirection(nsDirection aDirection,
|
||||
bool aVisual, bool aJumpLines,
|
||||
bool aScrollViewStop,
|
||||
bool aForceEditableRegion);
|
||||
|
||||
SelectablePeekReport GetFrameFromDirection(
|
||||
nsDirection aDirection,
|
||||
const mozilla::EnumSet<mozilla::PeekOffsetOption>& aOptions);
|
||||
SelectablePeekReport GetFrameFromDirection(
|
||||
const mozilla::PeekOffsetStruct& aPos);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче