Bug 1066594 Restore composition string and selection after restarting composition when a part of composition string is committed r=emk

This commit is contained in:
Masayuki Nakano 2014-09-16 22:46:39 +09:00
parent c5a482b3d8
commit 0753e13806
2 changed files with 80 additions and 20 deletions

View File

@ -2167,7 +2167,7 @@ nsTextStore::RestartComposition(ITfCompositionView* aCompositionView,
// current selection range should be preserved. // current selection range should be preserved.
if (newStart >= mComposition.EndOffset() || newEnd <= mComposition.mStart) { if (newStart >= mComposition.EndOffset() || newEnd <= mComposition.mStart) {
RecordCompositionEndAction(); RecordCompositionEndAction();
RecordCompositionStartAction(aCompositionView, aNewRange, true); RecordCompositionStartAction(aCompositionView, newStart, newLength, true);
return S_OK; return S_OK;
} }
@ -2215,14 +2215,25 @@ nsTextStore::RestartComposition(ITfCompositionView* aCompositionView,
// Record compositionend action. // Record compositionend action.
RecordCompositionEndAction(); RecordCompositionEndAction();
// Record compositionstart action only with the new start since this method
// hasn't restored composing string yet.
RecordCompositionStartAction(aCompositionView, newStart, 0, false);
// Restore the latest text content and selection. // Restore the latest text content and selection.
lockedContent.ReplaceTextWith(oldComposition.mStart, lockedContent.ReplaceSelectedTextWith(
commitString.Length(), nsDependentSubstring(oldComposition.mString,
oldComposition.mString); keepComposingStartOffset - oldComposition.mStart,
keepComposingLength));
currentSelection = oldSelection; currentSelection = oldSelection;
// Record compositionstart action with the new range PR_LOG(sTextStoreLog, PR_LOG_DEBUG,
RecordCompositionStartAction(aCompositionView, aNewRange, true); ("TSF: 0x%p nsTextStore::RestartComposition() succeeded, "
"mComposition={ mStart=%d, mCompositionString.Length()=%d }, "
"currentSelection={ IsDirty()=%s, StartOffset()=%d, Length()=%d }",
this, mComposition.mStart, mComposition.mString.Length(),
GetBoolName(currentSelection.IsDirty()),
currentSelection.StartOffset(), currentSelection.Length()));
return S_OK; return S_OK;
} }
@ -2275,9 +2286,11 @@ nsTextStore::RecordCompositionUpdateAction()
{ {
PR_LOG(sTextStoreLog, PR_LOG_DEBUG, PR_LOG(sTextStoreLog, PR_LOG_DEBUG,
("TSF: 0x%p nsTextStore::RecordCompositionUpdateAction(), " ("TSF: 0x%p nsTextStore::RecordCompositionUpdateAction(), "
"mComposition={ mView=0x%p, mString=\"%s\" }", "mComposition={ mView=0x%p, mStart=%d, mString=\"%s\" "
this, mComposition.mView.get(), "(Length()=%d) }",
NS_ConvertUTF16toUTF8(mComposition.mString).get())); this, mComposition.mView.get(), mComposition.mStart,
NS_ConvertUTF16toUTF8(mComposition.mString).get(),
mComposition.mString.Length()));
if (!mComposition.IsComposing()) { if (!mComposition.IsComposing()) {
PR_LOG(sTextStoreLog, PR_LOG_ERROR, PR_LOG(sTextStoreLog, PR_LOG_ERROR,
@ -2350,9 +2363,35 @@ nsTextStore::RecordCompositionUpdateAction()
nsRefPtr<ITfRange> range; nsRefPtr<ITfRange> range;
while (S_OK == enumRanges->Next(1, getter_AddRefs(range), nullptr) && range) { while (S_OK == enumRanges->Next(1, getter_AddRefs(range), nullptr) && range) {
LONG start = 0, length = 0; LONG rangeStart = 0, rangeLength = 0;
if (FAILED(GetRangeExtent(range, &start, &length))) if (FAILED(GetRangeExtent(range, &rangeStart, &rangeLength))) {
continue; continue;
}
// The range may include out of composition string. We should ignore
// outside of the composition string.
LONG start = std::min(std::max(rangeStart, mComposition.mStart),
mComposition.EndOffset());
LONG end = std::max(std::min(rangeStart + rangeLength,
mComposition.EndOffset()),
mComposition.mStart);
LONG length = end - start;
if (length < 0) {
PR_LOG(sTextStoreLog, PR_LOG_ERROR,
("TSF: 0x%p nsTextStore::RecordCompositionUpdateAction() "
"ignores invalid range (%d-%d)",
this, rangeStart - mComposition.mStart,
rangeStart - mComposition.mStart + rangeLength));
continue;
}
if (!length) {
PR_LOG(sTextStoreLog, PR_LOG_DEBUG,
("TSF: 0x%p nsTextStore::RecordCompositionUpdateAction() "
"ignores a range due to outside of the composition or empty "
"(%d-%d)",
this, rangeStart - mComposition.mStart,
rangeStart - mComposition.mStart + rangeLength));
continue;
}
TextRange newRange; TextRange newRange;
newRange.mStartOffset = uint32_t(start - mComposition.mStart); newRange.mStartOffset = uint32_t(start - mComposition.mStart);
@ -3565,15 +3604,15 @@ nsTextStore::InsertEmbeddedAtSelection(DWORD dwFlags,
} }
HRESULT HRESULT
nsTextStore::RecordCompositionStartAction(ITfCompositionView* pComposition, nsTextStore::RecordCompositionStartAction(ITfCompositionView* aComposition,
ITfRange* aRange, ITfRange* aRange,
bool aPreserveSelection) bool aPreserveSelection)
{ {
PR_LOG(sTextStoreLog, PR_LOG_DEBUG, PR_LOG(sTextStoreLog, PR_LOG_DEBUG,
("TSF: 0x%p nsTextStore::RecordCompositionStartAction(" ("TSF: 0x%p nsTextStore::RecordCompositionStartAction("
"pComposition=0x%p, aRange=0x%p, aPreserveSelection=%s), " "aComposition=0x%p, aRange=0x%p, aPreserveSelection=%s), "
"mComposition.mView=0x%p", "mComposition.mView=0x%p",
this, pComposition, aRange, GetBoolName(aPreserveSelection), this, aComposition, aRange, GetBoolName(aPreserveSelection),
mComposition.mView.get())); mComposition.mView.get()));
LONG start = 0, length = 0; LONG start = 0, length = 0;
@ -3585,6 +3624,23 @@ nsTextStore::RecordCompositionStartAction(ITfCompositionView* pComposition,
return hr; return hr;
} }
return RecordCompositionStartAction(aComposition, start, length,
aPreserveSelection);
}
HRESULT
nsTextStore::RecordCompositionStartAction(ITfCompositionView* aComposition,
LONG aStart,
LONG aLength,
bool aPreserveSelection)
{
PR_LOG(sTextStoreLog, PR_LOG_DEBUG,
("TSF: 0x%p nsTextStore::RecordCompositionStartAction("
"aComposition=0x%p, aStart=%d, aLength=%d, aPreserveSelection=%s), "
"mComposition.mView=0x%p",
this, aComposition, aStart, aLength, GetBoolName(aPreserveSelection),
mComposition.mView.get()));
Content& lockedContent = LockedContent(); Content& lockedContent = LockedContent();
if (!lockedContent.IsInitialized()) { if (!lockedContent.IsInitialized()) {
PR_LOG(sTextStoreLog, PR_LOG_ERROR, PR_LOG(sTextStoreLog, PR_LOG_ERROR,
@ -3596,8 +3652,8 @@ nsTextStore::RecordCompositionStartAction(ITfCompositionView* pComposition,
CompleteLastActionIfStillIncomplete(); CompleteLastActionIfStillIncomplete();
PendingAction* action = mPendingActions.AppendElement(); PendingAction* action = mPendingActions.AppendElement();
action->mType = PendingAction::COMPOSITION_START; action->mType = PendingAction::COMPOSITION_START;
action->mSelectionStart = start; action->mSelectionStart = aStart;
action->mSelectionLength = length; action->mSelectionLength = aLength;
Selection& currentSel = CurrentSelection(); Selection& currentSel = CurrentSelection();
if (currentSel.IsDirty()) { if (currentSel.IsDirty()) {
@ -3605,8 +3661,8 @@ nsTextStore::RecordCompositionStartAction(ITfCompositionView* pComposition,
("TSF: 0x%p nsTextStore::RecordCompositionStartAction() FAILED " ("TSF: 0x%p nsTextStore::RecordCompositionStartAction() FAILED "
"due to CurrentSelection() failure", this)); "due to CurrentSelection() failure", this));
action->mAdjustSelection = true; action->mAdjustSelection = true;
} else if (currentSel.MinOffset() != start || } else if (currentSel.MinOffset() != aStart ||
currentSel.MaxOffset() != start + length) { currentSel.MaxOffset() != aStart + aLength) {
// If new composition range is different from current selection range, // If new composition range is different from current selection range,
// we need to set selection before dispatching compositionstart event. // we need to set selection before dispatching compositionstart event.
action->mAdjustSelection = true; action->mAdjustSelection = true;
@ -3618,7 +3674,7 @@ nsTextStore::RecordCompositionStartAction(ITfCompositionView* pComposition,
action->mAdjustSelection = false; action->mAdjustSelection = false;
} }
lockedContent.StartComposition(pComposition, *action, aPreserveSelection); lockedContent.StartComposition(aComposition, *action, aPreserveSelection);
PR_LOG(sTextStoreLog, PR_LOG_ALWAYS, PR_LOG(sTextStoreLog, PR_LOG_ALWAYS,
("TSF: 0x%p nsTextStore::RecordCompositionStartAction() succeeded: " ("TSF: 0x%p nsTextStore::RecordCompositionStartAction() succeeded: "
@ -3636,7 +3692,7 @@ HRESULT
nsTextStore::RecordCompositionEndAction() nsTextStore::RecordCompositionEndAction()
{ {
PR_LOG(sTextStoreLog, PR_LOG_DEBUG, PR_LOG(sTextStoreLog, PR_LOG_DEBUG,
("TSF: 0x%p nsTextStore::RecordCompositionEndAction(), " ("TSF: 0x%p nsTextStore::RecordCompositionEndAction(), "
"mComposition={ mView=0x%p, mString=\"%s\" }", "mComposition={ mView=0x%p, mString=\"%s\" }",
this, mComposition.mView.get(), this, mComposition.mView.get(),
NS_ConvertUTF16toUTF8(mComposition.mString).get())); NS_ConvertUTF16toUTF8(mComposition.mString).get()));

View File

@ -275,6 +275,10 @@ protected:
HRESULT RecordCompositionStartAction(ITfCompositionView* aCompositionView, HRESULT RecordCompositionStartAction(ITfCompositionView* aCompositionView,
ITfRange* aRange, ITfRange* aRange,
bool aPreserveSelection); bool aPreserveSelection);
HRESULT RecordCompositionStartAction(ITfCompositionView* aComposition,
LONG aStart,
LONG aLength,
bool aPreserveSelection);
HRESULT RecordCompositionUpdateAction(); HRESULT RecordCompositionUpdateAction();
HRESULT RecordCompositionEndAction(); HRESULT RecordCompositionEndAction();