Bug 1718607 - Make TextServicesDocument use uint32_t for offset in DOM node r=m_kato

Differential Revision: https://phabricator.services.mozilla.com/D118955
This commit is contained in:
Masayuki Nakano 2021-06-30 09:07:35 +00:00
parent 347bc5719a
commit 1fc0882ecc
3 changed files with 297 additions and 422 deletions

File diff suppressed because it is too large Load Diff

View File

@ -6,6 +6,7 @@
#ifndef mozilla_TextServicesDocument_h
#define mozilla_TextServicesDocument_h
#include "mozilla/Maybe.h"
#include "nsCOMPtr.h"
#include "nsCycleCollectionParticipant.h"
#include "nsIEditActionListener.h"
@ -58,13 +59,15 @@ class TextServicesDocument final : public nsIEditActionListener {
nsCOMPtr<nsIContent> mNextTextBlock;
nsTArray<OffsetEntry*> mOffsetTable;
RefPtr<nsRange> mExtent;
// TODO: Making the following members manged in a struct must become the code
// simpler.
Maybe<size_t> mSelStartIndex;
Maybe<size_t> mSelEndIndex;
Maybe<uint32_t> mSelStartOffset;
Maybe<uint32_t> mSelEndOffset;
uint32_t mTxtSvcFilterType;
int32_t mSelStartIndex;
int32_t mSelStartOffset;
int32_t mSelEndIndex;
int32_t mSelEndOffset;
IteratorStatus mIteratorStatus;
protected:
@ -154,7 +157,7 @@ class TextServicesDocument final : public nsIEditActionListener {
*/
MOZ_CAN_RUN_SCRIPT
nsresult LastSelectedBlock(BlockSelectionStatus* aSelStatus,
int32_t* aSelOffset, int32_t* aSelLength);
uint32_t* aSelOffset, uint32_t* aSelLength);
/**
* Tells the document to point to the text block before the current one.
@ -192,8 +195,7 @@ class TextServicesDocument final : public nsIEditActionListener {
* GetCurrentTextBlock().
* @param aLength Number of characters selected.
*/
MOZ_CAN_RUN_SCRIPT
nsresult SetSelection(int32_t aOffset, int32_t aLength);
MOZ_CAN_RUN_SCRIPT nsresult SetSelection(uint32_t aOffset, uint32_t aLength);
/**
* Scrolls the document so that the current selection is visible.
@ -231,15 +233,15 @@ class TextServicesDocument final : public nsIEditActionListener {
void DidDeleteNode(nsINode* aChild);
void DidJoinNodes(nsINode& aLeftNode, nsINode& aRightNode);
private:
// TODO: We should get rid of this method since `aAbstractRange` has
// enough simple API to get them.
static nsresult GetRangeEndPoints(const dom::AbstractRange* aAbstractRange,
nsINode** aStartContainer,
int32_t* aStartOffset,
uint32_t* aStartOffset,
nsINode** aEndContainer,
int32_t* aEndOffset);
uint32_t* aEndOffset);
private:
nsresult CreateFilteredContentIterator(
const dom::AbstractRange* aAbstractRange,
FilteredContentIterator** aFilteredIter);
@ -277,20 +279,20 @@ class TextServicesDocument final : public nsIEditActionListener {
static bool HasSameBlockNodeParent(nsIContent* aContent1,
nsIContent* aContent2);
MOZ_CAN_RUN_SCRIPT
nsresult SetSelectionInternal(int32_t aOffset, int32_t aLength,
bool aDoUpdate);
MOZ_CAN_RUN_SCRIPT
nsresult GetSelection(BlockSelectionStatus* aSelStatus, int32_t* aSelOffset,
int32_t* aSelLength);
MOZ_CAN_RUN_SCRIPT
nsresult GetCollapsedSelection(BlockSelectionStatus* aSelStatus,
int32_t* aSelOffset, int32_t* aSelLength);
MOZ_CAN_RUN_SCRIPT nsresult SetSelectionInternal(uint32_t aOffset,
uint32_t aLength,
bool aDoUpdate);
MOZ_CAN_RUN_SCRIPT nsresult GetSelection(BlockSelectionStatus* aSelStatus,
uint32_t* aSelOffset,
uint32_t* aSelLength);
MOZ_CAN_RUN_SCRIPT nsresult
GetCollapsedSelection(BlockSelectionStatus* aSelStatus, uint32_t* aSelOffset,
uint32_t* aSelLength);
nsresult GetUncollapsedSelection(BlockSelectionStatus* aSelStatus,
int32_t* aSelOffset, int32_t* aSelLength);
uint32_t* aSelOffset, uint32_t* aSelLength);
bool SelectionIsCollapsed();
bool SelectionIsValid();
bool SelectionIsCollapsed() const;
bool SelectionIsValid() const;
static nsresult CreateOffsetTable(nsTArray<OffsetEntry*>* aOffsetTable,
FilteredContentIterator* aFilteredIter,
@ -300,17 +302,17 @@ class TextServicesDocument final : public nsIEditActionListener {
static nsresult NodeHasOffsetEntry(nsTArray<OffsetEntry*>* aOffsetTable,
nsINode* aNode, bool* aHasEntry,
int32_t* aEntryIndex);
size_t* aEntryIndex);
nsresult RemoveInvalidOffsetEntries();
nsresult SplitOffsetEntry(int32_t aTableIndex, int32_t aOffsetIntoEntry);
nsresult SplitOffsetEntry(size_t aTableIndex, uint32_t aOffsetIntoEntry);
static nsresult FindWordBounds(nsTArray<OffsetEntry*>* aOffsetTable,
nsString* aBlockStr, nsINode* aNode,
int32_t aNodeOffset, nsINode** aWordStartNode,
int32_t* aWordStartOffset,
uint32_t aNodeOffset, nsINode** aWordStartNode,
uint32_t* aWordStartOffset,
nsINode** aWordEndNode,
int32_t* aWordEndOffset);
uint32_t* aWordEndOffset);
};
} // namespace mozilla

View File

@ -16,6 +16,7 @@
#include "nsXULAppAPI.h"
#include "RemoteSpellCheckEngineChild.h"
using mozilla::AssertedCast;
using mozilla::GenericPromise;
using mozilla::LogLevel;
using mozilla::PRemoteSpellcheckEngineChild;
@ -104,7 +105,9 @@ nsresult mozSpellChecker::NextMisspelledWord(nsAString& aWord,
}
if (isMisspelled) {
aWord = currWord;
MOZ_KnownLive(mTextServicesDocument)->SetSelection(begin, end - begin);
MOZ_KnownLive(mTextServicesDocument)
->SetSelection(AssertedCast<uint32_t>(begin),
AssertedCast<uint32_t>(end - begin));
// After ScrollSelectionIntoView(), the pending notifications might
// be flushed and PresShell/PresContext/Frames may be dead.
// See bug 418470.
@ -217,7 +220,9 @@ nsresult mozSpellChecker::Replace(const nsAString& aOldWord,
selOffset = begin;
}
}
MOZ_KnownLive(mTextServicesDocument)->SetSelection(begin, end - begin);
MOZ_KnownLive(mTextServicesDocument)
->SetSelection(AssertedCast<uint32_t>(begin),
AssertedCast<uint32_t>(end - begin));
MOZ_KnownLive(mTextServicesDocument)->InsertText(aNewWord);
mTextServicesDocument->GetCurrentTextBlock(str);
end += (aNewWord.Length() -
@ -255,13 +260,15 @@ nsresult mozSpellChecker::Replace(const nsAString& aOldWord,
nsAutoString str;
mTextServicesDocument->GetCurrentTextBlock(str);
if (mConverter->FindNextWord(str, selOffset, &begin, &end)) {
MOZ_KnownLive(mTextServicesDocument)->SetSelection(begin, 0);
MOZ_KnownLive(mTextServicesDocument)
->SetSelection(AssertedCast<uint32_t>(begin), 0);
return NS_OK;
}
mTextServicesDocument->NextBlock();
mTextServicesDocument->GetCurrentTextBlock(str);
if (mConverter->FindNextWord(str, 0, &begin, &end)) {
MOZ_KnownLive(mTextServicesDocument)->SetSelection(begin, 0);
MOZ_KnownLive(mTextServicesDocument)
->SetSelection(AssertedCast<uint32_t>(begin), 0);
}
}
return NS_OK;
@ -434,11 +441,10 @@ nsresult mozSpellChecker::SetupDoc(int32_t* outBlockOffset) {
nsresult rv;
TextServicesDocument::BlockSelectionStatus blockStatus;
int32_t selOffset;
int32_t selLength;
*outBlockOffset = 0;
if (!mFromStart) {
uint32_t selOffset, selLength;
rv = MOZ_KnownLive(mTextServicesDocument)
->LastSelectedBlock(&blockStatus, &selOffset, &selLength);
if (NS_SUCCEEDED(rv) &&
@ -450,7 +456,8 @@ nsresult mozSpellChecker::SetupDoc(int32_t* outBlockOffset) {
// S begins or ends in TB but extends outside of TB.
case TextServicesDocument::BlockSelectionStatus::eBlockPartial:
// the TS doc points to the block we want.
*outBlockOffset = selOffset + selLength;
MOZ_ASSERT(selOffset != UINT32_MAX || selLength != UINT32_MAX);
*outBlockOffset = AssertedCast<int32_t>(selOffset + selLength);
break;
// S extends beyond the start and end of TB.
@ -462,7 +469,8 @@ nsresult mozSpellChecker::SetupDoc(int32_t* outBlockOffset) {
// TB contains entire S.
case TextServicesDocument::BlockSelectionStatus::eBlockContains:
*outBlockOffset = selOffset + selLength;
MOZ_ASSERT(selOffset != UINT32_MAX || selLength != UINT32_MAX);
*outBlockOffset = AssertedCast<int32_t>(selOffset + selLength);
break;
// There is no text block (TB) in or before the selection (S).