author | Eitan Isaacson <eitan@monotonous.org> |
Tue, 21 Jul 2020 23:02:57 +0000 | |
changeset 541541 | 5972532c773757211b0d30ed34a3849bae0dc5a9 |
parent 541540 | 1d37ebf3d20ce8071c7482fbf7bcdc37834e950c |
child 541542 | f8de624ccd8a858132ffac2d66d80082acc3ae6a |
push id | 122322 |
push user | eisaacson@mozilla.com |
push date | Tue, 21 Jul 2020 23:11:09 +0000 |
treeherder | autoland@88708e164b1a [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | morgan |
bugs | 1653421 |
milestone | 80.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
accessible/mac/GeckoTextMarker.h | file | annotate | diff | comparison | revisions | |
accessible/mac/GeckoTextMarker.mm | file | annotate | diff | comparison | revisions |
--- a/accessible/mac/GeckoTextMarker.h +++ b/accessible/mac/GeckoTextMarker.h @@ -51,16 +51,18 @@ class GeckoTextMarker final { bool operator<(const GeckoTextMarker& aPoint) const; AccessibleOrProxy mContainer; int32_t mOffset; private: uint32_t CharacterCount(const AccessibleOrProxy& aContainer); + + bool IsEditableRoot(); }; class GeckoTextMarkerRange final { public: GeckoTextMarkerRange(const GeckoTextMarker& aStart, const GeckoTextMarker& aEnd) : mStart(aStart), mEnd(aEnd) {} GeckoTextMarkerRange(AccessibleOrProxy aDoc, AXTextMarkerRangeRef aTextMarkerRange);
--- a/accessible/mac/GeckoTextMarker.mm +++ b/accessible/mac/GeckoTextMarker.mm @@ -95,31 +95,51 @@ bool GeckoTextMarker::operator<(const Ge return child1.IndexInParent() < child2.IndexInParent(); } } MOZ_ASSERT_UNREACHABLE("Broken tree?!"); return false; } +bool GeckoTextMarker::IsEditableRoot() { + uint64_t state = + mContainer.IsProxy() ? mContainer.AsProxy()->State() : mContainer.AsAccessible()->State(); + if ((state & states::EDITABLE) == 0) { + return false; + } + + AccessibleOrProxy parent = mContainer.Parent(); + if (parent.IsNull()) { + // Not sure when this can happen, but it would technically be an editable root. + return true; + } + + state = parent.IsProxy() ? parent.AsProxy()->State() : parent.AsAccessible()->State(); + + return (state & states::EDITABLE) == 0; +} + void GeckoTextMarker::NormalizeNext() { if (AtEnd()) { // If this is the end of the current container, mutate to its parent's // end offset. bool unused; uint32_t endOffset = mContainer.IsProxy() ? mContainer.AsProxy()->EndOffset(&unused) : mContainer.AsAccessible()->EndOffset(); if (endOffset != 0) { - mContainer = mContainer.Parent(); - mOffset = endOffset; + if (!IsEditableRoot()) { + mContainer = mContainer.Parent(); + mOffset = endOffset; - // Call NormalizeNext recursively to get top-most link if at the end of one, - // or innermost link if at the beginning. - NormalizeNext(); + // Call NormalizeNext recursively to get top-most link if at the end of one, + // or innermost link if at the beginning. + NormalizeNext(); + } } } else { AccessibleOrProxy link; if (mContainer.IsProxy()) { ProxyAccessible* proxy = mContainer.AsProxy(); link = proxy->LinkAt(proxy->LinkIndexAtOffset(mOffset)); } else if (HyperTextAccessible* ht = mContainer.AsAccessible()->AsHyperText()) { @@ -141,22 +161,24 @@ void GeckoTextMarker::NormalizeNext() { void GeckoTextMarker::NormalizePrevious() { if (mOffset == 0) { // If we are at the beginning of a container, mutate to its parent's start offset. bool unused; uint32_t startOffset = mContainer.IsProxy() ? mContainer.AsProxy()->StartOffset(&unused) : mContainer.AsAccessible()->StartOffset(); if (startOffset != 0) { - mContainer = mContainer.Parent(); - mOffset = startOffset; + if (!IsEditableRoot()) { + mContainer = mContainer.Parent(); + mOffset = startOffset; - // Call NormalizePrevious recursively to get top-most link if at the start of one, - // or innermost link if at the end. - NormalizePrevious(); + // Call NormalizePrevious recursively to get top-most link if at the start of one, + // or innermost link if at the end. + NormalizePrevious(); + } } } else { AccessibleOrProxy link; if (mContainer.IsProxy()) { ProxyAccessible* proxy = mContainer.AsProxy(); link = proxy->LinkAt(proxy->LinkIndexAtOffset(mOffset - 1)); } else if (HyperTextAccessible* ht = mContainer.AsAccessible()->AsHyperText()) {