Bug 974318 part.5 Use WidgetTextEvent::mRanges on Windows r=jimm

This commit is contained in:
Masayuki Nakano 2014-03-04 22:48:27 +09:00
parent c5aac51f12
commit 688be7cbab
4 changed files with 67 additions and 72 deletions

View File

@ -1610,15 +1610,10 @@ nsIMM32Handler::DispatchTextEvent(nsWindow* aWindow,
aWindow->InitEvent(event, &point);
nsAutoTArray<TextRange, 4> textRanges;
if (aCheckAttr) {
SetTextRangeList(textRanges);
event.mRanges = CreateTextRangeArray();
}
event.rangeCount = textRanges.Length();
event.rangeArray = textRanges.Elements();
event.theText = mCompositionString.get();
aWindow->DispatchWindowEvent(&event);
@ -1628,15 +1623,17 @@ nsIMM32Handler::DispatchTextEvent(nsWindow* aWindow,
// it will call SetIMERelatedWindowsPos.
}
void
nsIMM32Handler::SetTextRangeList(nsTArray<TextRange> &aTextRangeList)
already_AddRefed<TextRangeArray>
nsIMM32Handler::CreateTextRangeArray()
{
// Sogou (Simplified Chinese IME) returns contradictory values: The cursor
// position is actual cursor position. However, other values (composition
// string and attributes) are empty. So, if you want to remove following
// assertion, be careful.
NS_ASSERTION(ShouldDrawCompositionStringOurselves(),
"SetTextRangeList is called when we don't need to fire text event");
"CreateTextRangeArray is called when we don't need to fire text event");
nsRefPtr<TextRangeArray> textRangeArray = new TextRangeArray();
TextRange range;
if (mClauseArray.Length() == 0) {
@ -1645,10 +1642,10 @@ nsIMM32Handler::SetTextRangeList(nsTArray<TextRange> &aTextRangeList)
range.mStartOffset = 0;
range.mEndOffset = mCompositionString.Length();
range.mRangeType = NS_TEXTRANGE_RAWINPUT;
aTextRangeList.AppendElement(range);
textRangeArray->AppendElement(range);
PR_LOG(gIMM32Log, PR_LOG_ALWAYS,
("IMM32: SetTextRangeList, mClauseLength=0\n"));
("IMM32: CreateTextRangeArray, mClauseLength=0\n"));
} else {
// iterate over the attributes
uint32_t lastOffset = 0;
@ -1656,7 +1653,8 @@ nsIMM32Handler::SetTextRangeList(nsTArray<TextRange> &aTextRangeList)
uint32_t current = mClauseArray[i + 1];
if (current > mCompositionString.Length()) {
PR_LOG(gIMM32Log, PR_LOG_ALWAYS,
("IMM32: SetTextRangeList, mClauseArray[%ld]=%lu. This is larger than mCompositionString.Length()=%lu\n",
("IMM32: CreateTextRangeArray, mClauseArray[%ld]=%lu. "
"This is larger than mCompositionString.Length()=%lu\n",
i + 1, current, mCompositionString.Length()));
current = int32_t(mCompositionString.Length());
}
@ -1664,12 +1662,12 @@ nsIMM32Handler::SetTextRangeList(nsTArray<TextRange> &aTextRangeList)
range.mRangeType = PlatformToNSAttr(mAttributeArray[lastOffset]);
range.mStartOffset = lastOffset;
range.mEndOffset = current;
aTextRangeList.AppendElement(range);
textRangeArray->AppendElement(range);
lastOffset = current;
PR_LOG(gIMM32Log, PR_LOG_ALWAYS,
("IMM32: SetTextRangeList, index=%ld, rangeType=%s, range=[%lu-%lu]\n",
("IMM32: CreateTextRangeArray, index=%ld, rangeType=%s, range=[%lu-%lu]\n",
i, GetRangeTypeName(range.mRangeType), range.mStartOffset,
range.mEndOffset));
}
@ -1677,25 +1675,28 @@ nsIMM32Handler::SetTextRangeList(nsTArray<TextRange> &aTextRangeList)
if (mCursorPosition == NO_IME_CARET) {
PR_LOG(gIMM32Log, PR_LOG_ALWAYS,
("IMM32: GetTextRangeList, no caret\n"));
return;
("IMM32: CreateTextRangeArray, no caret\n"));
return textRangeArray.forget();
}
int32_t cursor = mCursorPosition;
if (uint32_t(cursor) > mCompositionString.Length()) {
PR_LOG(gIMM32Log, PR_LOG_ALWAYS,
("IMM32: SetTextRangeList, mCursorPosition=%ld. This is larger than mCompositionString.Length()=%lu\n",
("IMM32: CreateTextRangeArray, mCursorPosition=%ld. "
"This is larger than mCompositionString.Length()=%lu\n",
mCursorPosition, mCompositionString.Length()));
cursor = mCompositionString.Length();
}
range.mStartOffset = range.mEndOffset = cursor;
range.mRangeType = NS_TEXTRANGE_CARETPOSITION;
aTextRangeList.AppendElement(range);
textRangeArray->AppendElement(range);
PR_LOG(gIMM32Log, PR_LOG_ALWAYS,
("IMM32: SetTextRangeList, caret position=%ld\n",
("IMM32: CreateTextRangeArray, caret position=%ld\n",
range.mStartOffset));
return textRangeArray.forget();
}
void

View File

@ -8,6 +8,7 @@
#include "nscore.h"
#include <windows.h>
#include "nsCOMPtr.h"
#include "nsString.h"
#include "nsTArray.h"
#include "mozilla/EventForwards.h"
@ -285,7 +286,7 @@ protected:
bool GetTargetClauseRange(uint32_t *aOffset, uint32_t *aLength = nullptr);
void DispatchTextEvent(nsWindow* aWindow, const nsIMEContext &aIMEContext,
bool aCheckAttr = true);
void SetTextRangeList(nsTArray<mozilla::TextRange>& aTextRangeList);
already_AddRefed<mozilla::TextRangeArray> CreateTextRangeArray();
nsresult EnsureClauseArray(int32_t aCount);
nsresult EnsureAttributeArray(int32_t aCount);

View File

@ -1049,41 +1049,38 @@ nsTextStore::FlushPendingActions()
PR_LOG(sTextStoreLog, PR_LOG_DEBUG,
("TSF: 0x%p nsTextStore::FlushPendingActions() "
"flushing COMPOSITION_UPDATE={ mData=\"%s\", "
"mRanges.Length()=%d }",
this, NS_ConvertUTF16toUTF8(action.mData).get(),
action.mRanges.Length()));
"mRanges=0x%p, mRanges->Length()=%d }",
this, NS_ConvertUTF16toUTF8(action.mData).get(), action.mRanges,
action.mRanges ? action.mRanges->Length() : 0));
if (action.mRanges.IsEmpty()) {
TextRange wholeRange;
wholeRange.mStartOffset = 0;
wholeRange.mEndOffset = action.mData.Length();
wholeRange.mRangeType = NS_TEXTRANGE_RAWINPUT;
action.mRanges.AppendElement(wholeRange);
} else {
// Adjust offsets in the ranges for XP linefeed character (only \n).
// XXX Following code is the safest approach. However, it wastes
// a little performance. For ensuring the clauses do not
// overlap each other, we should redesign TextRange later.
for (uint32_t i = 0; i < action.mRanges.Length(); ++i) {
TextRange& range = action.mRanges[i];
TextRange nativeRange = range;
if (nativeRange.mStartOffset > 0) {
nsAutoString preText(
Substring(action.mData, 0, nativeRange.mStartOffset));
preText.ReplaceSubstring(NS_LITERAL_STRING("\r\n"),
NS_LITERAL_STRING("\n"));
range.mStartOffset = preText.Length();
}
if (nativeRange.Length() == 0) {
range.mEndOffset = range.mStartOffset;
} else {
nsAutoString clause(
Substring(action.mData,
nativeRange.mStartOffset, nativeRange.Length()));
clause.ReplaceSubstring(NS_LITERAL_STRING("\r\n"),
NS_LITERAL_STRING("\n"));
range.mEndOffset = range.mStartOffset + clause.Length();
}
if (!action.mRanges) {
NS_WARNING("How does this case occur?");
action.mRanges = new TextRangeArray();
}
// Adjust offsets in the ranges for XP linefeed character (only \n).
// XXX Following code is the safest approach. However, it wastes
// a little performance. For ensuring the clauses do not
// overlap each other, we should redesign TextRange later.
for (uint32_t i = 0; i < action.mRanges->Length(); ++i) {
TextRange& range = action.mRanges->ElementAt(i);
TextRange nativeRange = range;
if (nativeRange.mStartOffset > 0) {
nsAutoString preText(
Substring(action.mData, 0, nativeRange.mStartOffset));
preText.ReplaceSubstring(NS_LITERAL_STRING("\r\n"),
NS_LITERAL_STRING("\n"));
range.mStartOffset = preText.Length();
}
if (nativeRange.Length() == 0) {
range.mEndOffset = range.mStartOffset;
} else {
nsAutoString clause(
Substring(action.mData,
nativeRange.mStartOffset, nativeRange.Length()));
clause.ReplaceSubstring(NS_LITERAL_STRING("\r\n"),
NS_LITERAL_STRING("\n"));
range.mEndOffset = range.mStartOffset + clause.Length();
}
}
@ -1113,15 +1110,14 @@ nsTextStore::FlushPendingActions()
WidgetTextEvent textEvent(true, NS_TEXT_TEXT, mWidget);
mWidget->InitEvent(textEvent);
textEvent.theText = mComposition.mLastData;
if (action.mRanges.IsEmpty()) {
if (action.mRanges->IsEmpty()) {
TextRange wholeRange;
wholeRange.mStartOffset = 0;
wholeRange.mEndOffset = textEvent.theText.Length();
wholeRange.mRangeType = NS_TEXTRANGE_RAWINPUT;
action.mRanges.AppendElement(wholeRange);
action.mRanges->AppendElement(wholeRange);
}
textEvent.rangeArray = action.mRanges.Elements();
textEvent.rangeCount = action.mRanges.Length();
textEvent.mRanges = action.mRanges;
mWidget->DispatchWindowEvent(&textEvent);
// Be aware, the mWidget might already have been destroyed.
break;
@ -1648,11 +1644,10 @@ nsTextStore::RecordCompositionUpdateAction()
PendingAction* action = GetPendingCompositionUpdate();
action->mData = mComposition.mString;
nsTArray<TextRange>& textRanges = action->mRanges;
// The ranges might already have been initialized already, however, if this
// is called again, that means we need to overwrite the ranges with current
// The ranges might already have been initialized, however, if this is
// called again, that means we need to overwrite the ranges with current
// information.
textRanges.Clear();
action->mRanges->Clear();
TextRange newRange;
// No matter if we have display attribute info or not,
@ -1660,7 +1655,7 @@ nsTextStore::RecordCompositionUpdateAction()
newRange.mStartOffset = 0;
newRange.mEndOffset = action->mData.Length();
newRange.mRangeType = NS_TEXTRANGE_RAWINPUT;
textRanges.AppendElement(newRange);
action->mRanges->AppendElement(newRange);
nsRefPtr<ITfRange> range;
while (S_OK == enumRanges->Next(1, getter_AddRefs(range), nullptr) && range) {
@ -1700,14 +1695,14 @@ nsTextStore::RecordCompositionUpdateAction()
}
}
TextRange& lastRange = textRanges[textRanges.Length() - 1];
TextRange& lastRange = action->mRanges->LastElement();
if (lastRange.mStartOffset == newRange.mStartOffset) {
// Replace range if last range is the same as this one
// So that ranges don't overlap and confuse the editor
lastRange = newRange;
} else {
lastRange.mEndOffset = newRange.mStartOffset;
textRanges.AppendElement(newRange);
action->mRanges->AppendElement(newRange);
}
}
@ -1719,8 +1714,8 @@ nsTextStore::RecordCompositionUpdateAction()
// string, however, Gecko doesn't support the wide caret drawing now (Gecko
// doesn't support XOR drawing), unfortunately. For now, we should change
// the range style to undefined.
if (!currentSel.IsCollapsed() && textRanges.Length() == 1) {
TextRange& range = textRanges[0];
if (!currentSel.IsCollapsed() && action->mRanges->Length() == 1) {
TextRange& range = action->mRanges->ElementAt(0);
LONG start = currentSel.MinOffset();
LONG end = currentSel.MaxOffset();
if ((LONG)range.mStartOffset == start - mComposition.mStart &&
@ -1738,7 +1733,7 @@ nsTextStore::RecordCompositionUpdateAction()
TextRange caretRange;
caretRange.mStartOffset = caretRange.mEndOffset = uint32_t(caretPosition);
caretRange.mRangeType = NS_TEXTRANGE_CARETPOSITION;
textRanges.AppendElement(caretRange);
action->mRanges->AppendElement(caretRange);
PR_LOG(sTextStoreLog, PR_LOG_ALWAYS,
("TSF: 0x%p nsTextStore::RecordCompositionUpdateAction() "

View File

@ -501,7 +501,7 @@ protected:
// For compositionupdate and compositionend
nsString mData;
// For compositionupdate
nsTArray<mozilla::TextRange> mRanges;
nsRefPtr<mozilla::TextRangeArray> mRanges;
// For selectionset
bool mSelectionReversed;
};
@ -521,9 +521,7 @@ protected:
}
PendingAction* newAction = mPendingActions.AppendElement();
newAction->mType = PendingAction::COMPOSITION_UPDATE;
// We think that 4 ranges (3 clauses and caret position) are enough for
// most cases.
newAction->mRanges.SetCapacity(4);
newAction->mRanges = new mozilla::TextRangeArray();
return newAction;
}