mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 13:51:41 +00:00
Bug 1718924 - part 15: Move TextServicesDocument::mSelStartIndex
and TextServicesDocument::mSelEndIndex
into OffsetEntryArray
r=m_kato
They are indices of `OffsetEntryArray`. Therefore, they should be managed in it. Depends on D119161 Differential Revision: https://phabricator.services.mozilla.com/D119162
This commit is contained in:
parent
987147357a
commit
d3e59b2f42
@ -863,9 +863,10 @@ nsresult TextServicesDocument::DeleteSelection() {
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t i = *mSelStartIndex; i <= *mSelEndIndex; i++) {
|
||||
for (size_t i = mOffsetTable.mSelection.StartIndex();
|
||||
i <= mOffsetTable.mSelection.EndIndex(); i++) {
|
||||
OffsetEntry* entry = mOffsetTable[i].get();
|
||||
if (i == *mSelStartIndex) {
|
||||
if (i == mOffsetTable.mSelection.StartIndex()) {
|
||||
// Calculate the length of the selection. Note that the
|
||||
// selection length can be zero if the start of the selection
|
||||
// is at the very end of a text node entry.
|
||||
@ -894,12 +895,13 @@ nsresult TextServicesDocument::DeleteSelection() {
|
||||
}
|
||||
|
||||
// Adjust selection indexes to account for new entry:
|
||||
++(*mSelStartIndex);
|
||||
++(*mSelEndIndex);
|
||||
mOffsetTable.mSelection.Set(mOffsetTable.mSelection.StartIndex() + 1,
|
||||
mOffsetTable.mSelection.EndIndex() + 1);
|
||||
entry = mOffsetTable[++i].get();
|
||||
}
|
||||
|
||||
if (*mSelStartIndex < *mSelEndIndex) {
|
||||
if (mOffsetTable.mSelection.StartIndex() <
|
||||
mOffsetTable.mSelection.EndIndex()) {
|
||||
// The entire entry is contained in the selection. Mark the
|
||||
// entry invalid.
|
||||
entry->mIsValid = false;
|
||||
@ -907,7 +909,7 @@ nsresult TextServicesDocument::DeleteSelection() {
|
||||
}
|
||||
}
|
||||
|
||||
if (i == *mSelEndIndex) {
|
||||
if (i == mOffsetTable.mSelection.EndIndex()) {
|
||||
if (entry->mIsInsertedText) {
|
||||
// Inserted text offset entries have no width when
|
||||
// talking in terms of string offsets! If the end
|
||||
@ -924,8 +926,8 @@ nsresult TextServicesDocument::DeleteSelection() {
|
||||
if (selLength > 0) {
|
||||
if (*mSelectionEndOffsetInTextInBlock <
|
||||
entry->EndOffsetInTextInBlock()) {
|
||||
// mOffsetInTextInBlock is guaranteed to be inside the
|
||||
// selection, even when *mSelStartIndex == *mSelEndIndex.
|
||||
// mOffsetInTextInBlock is guaranteed to be inside the selection,
|
||||
// even when mOffsetTable.mSelection.IsInSameElement() is true.
|
||||
nsresult rv =
|
||||
mOffsetTable.SplitElementAt(i, entry->mLength - selLength);
|
||||
if (NS_FAILED(rv)) {
|
||||
@ -948,7 +950,8 @@ nsresult TextServicesDocument::DeleteSelection() {
|
||||
}
|
||||
}
|
||||
|
||||
if (i != *mSelStartIndex && i != *mSelEndIndex) {
|
||||
if (i != mOffsetTable.mSelection.StartIndex() &&
|
||||
i != mOffsetTable.mSelection.EndIndex()) {
|
||||
// The entire entry is contained in the selection. Mark the
|
||||
// entry invalid.
|
||||
entry->mIsValid = false;
|
||||
@ -1016,14 +1019,15 @@ nsresult TextServicesDocument::DeleteSelection() {
|
||||
}
|
||||
|
||||
// Move the caret to the end of the first valid entry.
|
||||
// Start with mSelStartIndex since it may still be valid.
|
||||
// Start with mOffsetTable.SelectionStartIndex() since it may still be valid.
|
||||
OffsetEntry* entry = nullptr;
|
||||
for (size_t i = *mSelStartIndex + 1; !entry && i > 0; i--) {
|
||||
for (size_t i = mOffsetTable.mSelection.StartIndex() + 1; !entry && i > 0;
|
||||
i--) {
|
||||
entry = mOffsetTable[i - 1].get();
|
||||
if (!entry->mIsValid) {
|
||||
entry = nullptr;
|
||||
} else {
|
||||
mSelStartIndex = mSelEndIndex = Some(i - 1);
|
||||
mOffsetTable.mSelection.Set(i - 1);
|
||||
mSelectionStartOffsetInTextInBlock = mSelectionEndOffsetInTextInBlock =
|
||||
Some(entry->EndOffsetInTextInBlock());
|
||||
}
|
||||
@ -1031,12 +1035,13 @@ nsresult TextServicesDocument::DeleteSelection() {
|
||||
|
||||
// If we still don't have a valid entry, move the caret
|
||||
// to the next valid entry after the selection:
|
||||
for (size_t i = *mSelEndIndex; !entry && i < mOffsetTable.Length(); i++) {
|
||||
for (size_t i = mOffsetTable.mSelection.EndIndex();
|
||||
!entry && i < mOffsetTable.Length(); i++) {
|
||||
entry = mOffsetTable[i].get();
|
||||
if (!entry->mIsValid) {
|
||||
entry = nullptr;
|
||||
} else {
|
||||
mSelStartIndex = mSelEndIndex = Some(i);
|
||||
mOffsetTable.mSelection.Set(i);
|
||||
mSelectionStartOffsetInTextInBlock = mSelectionEndOffsetInTextInBlock =
|
||||
Some(entry->mOffsetInTextInBlock);
|
||||
}
|
||||
@ -1047,8 +1052,7 @@ nsresult TextServicesDocument::DeleteSelection() {
|
||||
} else {
|
||||
// Uuughh we have no valid offset entry to place our
|
||||
// caret ... just mark the selection invalid.
|
||||
mSelStartIndex.reset();
|
||||
mSelEndIndex.reset();
|
||||
mOffsetTable.mSelection.Reset();
|
||||
mSelectionStartOffsetInTextInBlock.reset();
|
||||
mSelectionEndOffsetInTextInBlock.reset();
|
||||
}
|
||||
@ -1094,7 +1098,8 @@ nsresult TextServicesDocument::InsertText(const nsAString& aText) {
|
||||
|
||||
uint32_t strLength = aText.Length();
|
||||
|
||||
UniquePtr<OffsetEntry>& entry = mOffsetTable[*mSelStartIndex];
|
||||
UniquePtr<OffsetEntry>& entry =
|
||||
mOffsetTable[mOffsetTable.mSelection.StartIndex()];
|
||||
OwningNonNull<Text> const textNodeAtStartEntry = entry->mTextNode;
|
||||
|
||||
NS_ASSERTION((entry->mIsValid), "Invalid insertion point!");
|
||||
@ -1113,7 +1118,7 @@ nsresult TextServicesDocument::InsertText(const nsAString& aText) {
|
||||
newInsertedTextEntry->mOffsetInTextNode = entry->mOffsetInTextNode;
|
||||
// XXX(Bug 1631371) Check if this should use a fallible operation as it
|
||||
// pretended earlier.
|
||||
mOffsetTable.InsertElementAt(*mSelStartIndex,
|
||||
mOffsetTable.InsertElementAt(mOffsetTable.mSelection.StartIndex(),
|
||||
std::move(newInsertedTextEntry));
|
||||
}
|
||||
} else if (entry->EndOffsetInTextInBlock() ==
|
||||
@ -1122,7 +1127,7 @@ nsresult TextServicesDocument::InsertText(const nsAString& aText) {
|
||||
// Look at the next valid entry in the table. If it's an inserted
|
||||
// text entry, add to its length and adjust its node offset. If
|
||||
// it isn't, add a new inserted text entry.
|
||||
uint32_t nextIndex = *mSelStartIndex + 1;
|
||||
uint32_t nextIndex = mOffsetTable.mSelection.StartIndex() + 1;
|
||||
OffsetEntry* insertedTextEntry = nullptr;
|
||||
if (mOffsetTable.Length() > nextIndex) {
|
||||
insertedTextEntry = mOffsetTable[nextIndex].get();
|
||||
@ -1160,7 +1165,7 @@ nsresult TextServicesDocument::InsertText(const nsAString& aText) {
|
||||
|
||||
insertedTextEntry->mLength += strLength;
|
||||
|
||||
mSelStartIndex = mSelEndIndex = Some(nextIndex);
|
||||
mOffsetTable.mSelection.Set(nextIndex);
|
||||
|
||||
RefPtr<Selection> selection =
|
||||
mSelCon->GetSelection(nsISelectionController::SELECTION_NORMAL);
|
||||
@ -1180,7 +1185,7 @@ nsresult TextServicesDocument::InsertText(const nsAString& aText) {
|
||||
// split the current entry into two parts, then insert an inserted text
|
||||
// entry between them!
|
||||
nsresult rv = mOffsetTable.SplitElementAt(
|
||||
*mSelStartIndex,
|
||||
mOffsetTable.mSelection.StartIndex(),
|
||||
entry->EndOffsetInTextInBlock() - *mSelectionStartOffsetInTextInBlock);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING(
|
||||
@ -1193,19 +1198,20 @@ nsresult TextServicesDocument::InsertText(const nsAString& aText) {
|
||||
// XXX(Bug 1631371) Check if this should use a fallible operation as it
|
||||
// pretended earlier.
|
||||
UniquePtr<OffsetEntry>& insertedTextEntry = *mOffsetTable.InsertElementAt(
|
||||
++(*mSelStartIndex),
|
||||
mOffsetTable.mSelection.StartIndex() + 1,
|
||||
MakeUnique<OffsetEntry>(
|
||||
entry->mTextNode, *mSelectionStartOffsetInTextInBlock, strLength));
|
||||
insertedTextEntry->mIsInsertedText = true;
|
||||
insertedTextEntry->mOffsetInTextNode = entry->EndOffsetInTextNode();
|
||||
mSelEndIndex = mSelStartIndex;
|
||||
mOffsetTable.mSelection.Set(mOffsetTable.mSelection.StartIndex() + 1);
|
||||
}
|
||||
|
||||
// We've just finished inserting an inserted text offset entry.
|
||||
// update all entries with the same mTextNode pointer that follow
|
||||
// it in the table!
|
||||
|
||||
for (size_t i = *mSelStartIndex + 1; i < mOffsetTable.Length(); i++) {
|
||||
for (size_t i = mOffsetTable.mSelection.StartIndex() + 1;
|
||||
i < mOffsetTable.Length(); i++) {
|
||||
const UniquePtr<OffsetEntry>& entry = mOffsetTable[i];
|
||||
if (entry->mTextNode != textNodeAtStartEntry) {
|
||||
break;
|
||||
@ -1668,7 +1674,7 @@ nsresult TextServicesDocument::SetSelectionInternal(uint32_t aOffset,
|
||||
}
|
||||
|
||||
if (startTextNode) {
|
||||
mSelStartIndex = Some(i);
|
||||
mOffsetTable.mSelection.Set(i);
|
||||
mSelectionStartOffsetInTextInBlock = Some(aOffset);
|
||||
}
|
||||
}
|
||||
@ -1695,7 +1701,7 @@ nsresult TextServicesDocument::SetSelectionInternal(uint32_t aOffset,
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
mSelEndIndex = mSelStartIndex;
|
||||
mOffsetTable.mSelection.CollapseToStart();
|
||||
mSelectionEndOffsetInTextInBlock = mSelectionStartOffsetInTextInBlock;
|
||||
return NS_OK;
|
||||
}
|
||||
@ -1721,7 +1727,8 @@ nsresult TextServicesDocument::SetSelectionInternal(uint32_t aOffset,
|
||||
}
|
||||
|
||||
if (endTextNode) {
|
||||
mSelEndIndex = Some(i - 1);
|
||||
mOffsetTable.mSelection.Set(mOffsetTable.mSelection.StartIndex(),
|
||||
i - 1);
|
||||
mSelectionEndOffsetInTextInBlock = Some(endOffset);
|
||||
}
|
||||
}
|
||||
@ -2174,13 +2181,13 @@ nsresult TextServicesDocument::GetUncollapsedSelection(
|
||||
}
|
||||
|
||||
bool TextServicesDocument::SelectionIsCollapsed() const {
|
||||
return !SelectionIsValid() || (*mSelStartIndex == *mSelEndIndex &&
|
||||
return !SelectionIsValid() || (mOffsetTable.mSelection.IsInSameElement() &&
|
||||
*mSelectionStartOffsetInTextInBlock ==
|
||||
*mSelectionEndOffsetInTextInBlock);
|
||||
}
|
||||
|
||||
bool TextServicesDocument::SelectionIsValid() const {
|
||||
return mSelStartIndex.isSome() && mSelEndIndex.isSome() &&
|
||||
return mOffsetTable.mSelection.IsSet() &&
|
||||
mSelectionStartOffsetInTextInBlock.isSome() &&
|
||||
mSelectionEndOffsetInTextInBlock.isSome();
|
||||
}
|
||||
@ -2555,13 +2562,15 @@ nsresult TextServicesDocument::RemoveInvalidOffsetEntries() {
|
||||
for (size_t i = 0; i < mOffsetTable.Length();) {
|
||||
if (!mOffsetTable[i]->mIsValid) {
|
||||
mOffsetTable.RemoveElementAt(i);
|
||||
if (mSelStartIndex.isSome() && *mSelStartIndex >= i) {
|
||||
if (mOffsetTable.mSelection.IsSet() &&
|
||||
mOffsetTable.mSelection.StartIndex() >= i) {
|
||||
// We are deleting an entry that comes before
|
||||
// mSelStartIndex, decrement mSelStartIndex so
|
||||
// mOffsetTable.mSelection.StartIndex(), decrement it so
|
||||
// that it points to the correct entry!
|
||||
NS_ASSERTION(i != *mSelStartIndex, "Invalid selection index.");
|
||||
--(*mSelStartIndex);
|
||||
--(*mSelEndIndex);
|
||||
NS_ASSERTION(i != mOffsetTable.mSelection.StartIndex(),
|
||||
"Invalid selection index.");
|
||||
mOffsetTable.mSelection.Set(mOffsetTable.mSelection.StartIndex() - 1,
|
||||
mOffsetTable.mSelection.EndIndex() - 1);
|
||||
}
|
||||
} else {
|
||||
i++;
|
||||
|
@ -88,6 +88,43 @@ class TextServicesDocument final : public nsIEditActionListener {
|
||||
* greater than 0 and less than `mLength`.
|
||||
*/
|
||||
nsresult SplitElementAt(size_t aIndex, uint32_t aOffsetInTextNode);
|
||||
|
||||
class Selection final {
|
||||
public:
|
||||
size_t StartIndex() const {
|
||||
MOZ_ASSERT(IsSet());
|
||||
return *mStartIndex;
|
||||
}
|
||||
size_t EndIndex() const {
|
||||
MOZ_ASSERT(IsSet());
|
||||
return *mEndIndex;
|
||||
}
|
||||
|
||||
bool IsSet() const { return mStartIndex.isSome() && mEndIndex.isSome(); }
|
||||
bool IsInSameElement() const {
|
||||
return IsSet() && StartIndex() == EndIndex();
|
||||
}
|
||||
|
||||
void Reset() {
|
||||
mStartIndex.reset();
|
||||
mEndIndex.reset();
|
||||
}
|
||||
void Set(size_t aIndex) { mEndIndex = mStartIndex = Some(aIndex); }
|
||||
void Set(size_t aStartIndex, size_t aEndIndex) {
|
||||
mStartIndex = Some(aStartIndex);
|
||||
mEndIndex = Some(aEndIndex);
|
||||
}
|
||||
|
||||
void CollapseToStart() {
|
||||
MOZ_ASSERT(mStartIndex.isSome());
|
||||
mEndIndex = mStartIndex;
|
||||
}
|
||||
|
||||
private:
|
||||
Maybe<size_t> mStartIndex;
|
||||
Maybe<size_t> mEndIndex;
|
||||
};
|
||||
Selection mSelection;
|
||||
};
|
||||
|
||||
RefPtr<dom::Document> mDocument;
|
||||
@ -99,11 +136,8 @@ class TextServicesDocument final : public nsIEditActionListener {
|
||||
OffsetEntryArray 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;
|
||||
// Selected start and end offset in all text in a block element.
|
||||
// XXX Should we move them into `OffsetEntryArray::Selection`?
|
||||
Maybe<uint32_t> mSelectionStartOffsetInTextInBlock;
|
||||
Maybe<uint32_t> mSelectionEndOffsetInTextInBlock;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user