mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-25 20:01:50 +00:00
Bug 1737919 part 4: Update cached spelling errors when a spelling error is added without the text changing. r=morgan,smaug
We already have an nsISelectionListener, but that only tells us that a change happened somewhere in the selection, not which range changed. We don't want to push a cache update for all ranges when only one changed. Therefore, this patch adds an accessibility notification in mozInlineSpellChecker::AddRange. We don't need this for removed ranges because the text will change for any spelling error corrections and text updates trigger spelling error cache updates. Differential Revision: https://phabricator.services.mozilla.com/D147244
This commit is contained in:
parent
3daa72eb49
commit
7564ed957c
@ -13,11 +13,13 @@
|
||||
#include "nsCoreUtils.h"
|
||||
#include "nsEventShell.h"
|
||||
#include "nsFrameSelection.h"
|
||||
#include "TextLeafRange.h"
|
||||
|
||||
#include "mozilla/PresShell.h"
|
||||
#include "mozilla/dom/Document.h"
|
||||
#include "mozilla/dom/Selection.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "mozilla/StaticPrefs_accessibility.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::a11y;
|
||||
@ -226,4 +228,14 @@ void SelectionManager::ProcessSelectionChanged(SelData* aSelData) {
|
||||
}
|
||||
}
|
||||
|
||||
void SelectionManager::SpellCheckRangeAdded(const nsRange& aRange) {
|
||||
// Events are fired in SelectionManager::NotifySelectionChanged. This is only
|
||||
// used to push cache updates.
|
||||
if (StaticPrefs::accessibility_cache_enabled_AtStartup()) {
|
||||
dom::Document* doc = aRange.GetStartContainer()->OwnerDoc();
|
||||
MOZ_ASSERT(doc);
|
||||
TextLeafPoint::UpdateCachedSpellingError(doc, aRange);
|
||||
}
|
||||
}
|
||||
|
||||
SelectionManager::~SelectionManager() = default;
|
||||
|
@ -9,6 +9,8 @@
|
||||
#include "nsISelectionListener.h"
|
||||
#include "mozilla/WeakPtr.h"
|
||||
|
||||
class nsRange;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class PresShell;
|
||||
@ -106,6 +108,18 @@ class SelectionManager : public nsISelectionListener {
|
||||
mAccWithCaret = nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by mozInlineSpellChecker when a spell check range is added.
|
||||
* nsISelectionListener isn't sufficient for spelling errors, since it only
|
||||
* tells us that there was a change, not which range changed. We don't want
|
||||
* to unnecessarily push a cache update for all Accessibles in the entire
|
||||
* selection.
|
||||
* We don't need an equivalent notification for removals because a spelling
|
||||
* error correction is triggered by a text change and text changes trigger a
|
||||
* cache update already.
|
||||
*/
|
||||
void SpellCheckRangeAdded(const nsRange& aRange);
|
||||
|
||||
~SelectionManager();
|
||||
|
||||
protected:
|
||||
|
@ -8,15 +8,18 @@
|
||||
|
||||
#include "HyperTextAccessible-inl.h"
|
||||
#include "mozilla/a11y/Accessible.h"
|
||||
#include "mozilla/a11y/CacheConstants.h"
|
||||
#include "mozilla/a11y/DocAccessible.h"
|
||||
#include "mozilla/a11y/DocAccessibleParent.h"
|
||||
#include "mozilla/a11y/LocalAccessible.h"
|
||||
#include "mozilla/BinarySearch.h"
|
||||
#include "mozilla/Casting.h"
|
||||
#include "mozilla/dom/CharacterData.h"
|
||||
#include "mozilla/dom/Document.h"
|
||||
#include "mozilla/intl/Segmenter.h"
|
||||
#include "mozilla/intl/WordBreaker.h"
|
||||
#include "mozilla/StaticPrefs_layout.h"
|
||||
#include "nsAccessibilityService.h"
|
||||
#include "nsAccUtils.h"
|
||||
#include "nsBlockFrame.h"
|
||||
#include "nsContentUtils.h"
|
||||
@ -24,6 +27,7 @@
|
||||
#include "nsIAccessiblePivot.h"
|
||||
#include "nsILineIterator.h"
|
||||
#include "nsINode.h"
|
||||
#include "nsRange.h"
|
||||
#include "nsStyleStructInlines.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsTextFrame.h"
|
||||
@ -1236,6 +1240,32 @@ nsTArray<int32_t> TextLeafPoint::GetSpellingErrorOffsets(
|
||||
return offsets;
|
||||
}
|
||||
|
||||
/* static */
|
||||
void TextLeafPoint::UpdateCachedSpellingError(dom::Document* aDocument,
|
||||
const nsRange& aRange) {
|
||||
DocAccessible* docAcc = GetExistingDocAccessible(aDocument);
|
||||
if (!docAcc) {
|
||||
return;
|
||||
}
|
||||
LocalAccessible* startAcc = docAcc->GetAccessible(aRange.GetStartContainer());
|
||||
LocalAccessible* endAcc = docAcc->GetAccessible(aRange.GetEndContainer());
|
||||
if (!startAcc || !endAcc) {
|
||||
return;
|
||||
}
|
||||
for (Accessible* acc = startAcc; acc; acc = NextLeaf(acc)) {
|
||||
if (acc->IsTextLeaf()) {
|
||||
docAcc->QueueCacheUpdate(acc->AsLocal(), CacheDomain::Spelling);
|
||||
}
|
||||
if (acc == endAcc) {
|
||||
// Subtle: We check this here rather than in the loop condition because
|
||||
// we want to include endAcc but stop once we reach it. Putting it in the
|
||||
// loop condition would mean we stop at endAcc, but we would also exclude
|
||||
// it; i.e. we wouldn't push the cache for it.
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
already_AddRefed<AccAttributes> TextLeafPoint::GetTextAttributesLocalAcc(
|
||||
bool aIncludeDefaults) const {
|
||||
LocalAccessible* acc = mAcc->AsLocal();
|
||||
|
@ -13,7 +13,14 @@
|
||||
#include "nsDirection.h"
|
||||
#include "nsIAccessibleText.h"
|
||||
|
||||
namespace mozilla::a11y {
|
||||
class nsRange;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
class Document;
|
||||
}
|
||||
|
||||
namespace a11y {
|
||||
class Accessible;
|
||||
class LocalAccessible;
|
||||
|
||||
@ -136,6 +143,12 @@ class TextLeafPoint final {
|
||||
*/
|
||||
static nsTArray<int32_t> GetSpellingErrorOffsets(LocalAccessible* aAcc);
|
||||
|
||||
/**
|
||||
* Queue a cache update for a spelling error in a given DOM range.
|
||||
*/
|
||||
static void UpdateCachedSpellingError(dom::Document* aDocument,
|
||||
const nsRange& aRange);
|
||||
|
||||
/**
|
||||
* Find the start of a run of text attributes in a specific direction.
|
||||
* A text attributes run is a span of text where the attributes are the same.
|
||||
@ -212,6 +225,7 @@ class TextLeafRange final {
|
||||
TextLeafPoint mEnd;
|
||||
};
|
||||
|
||||
} // namespace mozilla::a11y
|
||||
} // namespace a11y
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
||||
|
@ -53,6 +53,9 @@
|
||||
#include "mozilla/dom/MouseEvent.h"
|
||||
#include "mozilla/dom/Selection.h"
|
||||
#include "mozInlineSpellWordUtil.h"
|
||||
#ifdef ACCESSIBILITY
|
||||
# include "nsAccessibilityService.h"
|
||||
#endif
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsCRT.h"
|
||||
#include "nsGenericHTMLElement.h"
|
||||
@ -1879,6 +1882,11 @@ nsresult mozInlineSpellChecker::AddRange(Selection* aSpellCheckSelection,
|
||||
rv = err.StealNSResult();
|
||||
} else {
|
||||
mNumWordsInSpellSelection++;
|
||||
#ifdef ACCESSIBILITY
|
||||
if (nsAccessibilityService* accService = GetAccService()) {
|
||||
accService->SpellCheckRangeAdded(*aRange);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user