Bug 1176950 nsTextStore should keep storing locked content until NOTIFY_IME_OF_COMPOSITION_UPDATE is notified r=emk

This commit is contained in:
Masayuki Nakano 2015-07-12 18:56:23 +09:00
parent c08bf91764
commit f55ec43f29
2 changed files with 34 additions and 10 deletions

View File

@ -1230,6 +1230,7 @@ nsTextStore::nsTextStore()
, mPendingOnSelectionChange(false)
, mPendingOnLayoutChange(false)
, mPendingDestroy(false)
, mPendingClearLockedContent(false)
, mNativeCaretIsCreated(false)
, mDeferNotifyingTSF(false)
{
@ -1604,7 +1605,10 @@ nsTextStore::FlushPendingActions()
return;
}
mLockedContent.Clear();
// If dispatching event causes NOTIFY_IME_OF_COMPOSITION_UPDATE, we should
// wait to abandon mLockedContent until it's notified because the dispatched
// event may be handled asynchronously in e10s mode.
mPendingClearLockedContent = !mPendingActions.Length();
nsRefPtr<nsWindowBase> kungFuDeathGrip(mWidget);
for (uint32_t i = 0; i < mPendingActions.Length(); i++) {
@ -1638,6 +1642,8 @@ nsTextStore::FlushPendingActions()
WidgetCompositionEvent compositionStart(true, NS_COMPOSITION_START,
mWidget);
mWidget->InitEvent(compositionStart);
// NS_COMPOSITION_START always causes NOTIFY_IME_OF_COMPOSITION_UPDATE.
mPendingClearLockedContent = true;
DispatchEvent(compositionStart);
if (!mWidget || mWidget->Destroyed()) {
break;
@ -1701,6 +1707,11 @@ nsTextStore::FlushPendingActions()
action.mRanges->AppendElement(wholeRange);
}
compositionChange.mRanges = action.mRanges;
// When the NS_COMPOSITION_CHANGE causes a DOM text event,
// NOTIFY_IME_OF_COMPOSITION_UPDATE will be notified.
if (compositionChange.CausesDOMTextEvent()) {
mPendingClearLockedContent = true;
}
DispatchEvent(compositionChange);
// Be aware, the mWidget might already have been destroyed.
break;
@ -1721,6 +1732,11 @@ nsTextStore::FlushPendingActions()
mWidget);
mWidget->InitEvent(compositionCommit);
compositionCommit.mData = action.mData;
// When the NS_COMPOSITION_COMMIT causes a DOM text event,
// NOTIFY_IME_OF_COMPOSITION_UPDATE will be notified.
if (compositionCommit.CausesDOMTextEvent()) {
mPendingClearLockedContent = true;
}
DispatchEvent(compositionCommit);
if (!mWidget || mWidget->Destroyed()) {
break;
@ -1783,6 +1799,11 @@ nsTextStore::MaybeFlushPendingNotifications()
return;
}
if (mPendingClearLockedContent) {
mPendingClearLockedContent = false;
mLockedContent.Clear();
}
if (mPendingOnLayoutChange) {
MOZ_LOG(sTextStoreLog, LogLevel::Info,
("TSF: 0x%p nsTextStore::MaybeFlushPendingNotifications(), "
@ -1904,9 +1925,9 @@ nsTextStore::GetSelection(ULONG ulIndex,
nsTextStore::Content&
nsTextStore::LockedContent()
{
MOZ_ASSERT(IsReadLocked(),
"LockedContent must be called only during the document is locked");
if (!IsReadLocked()) {
// This should be called when the document is locked or the content hasn't
// been abandoned yet.
if (NS_WARN_IF(!IsReadLocked() && !mLockedContent.IsInitialized())) {
mLockedContent.Clear();
return mLockedContent;
}
@ -4364,6 +4385,8 @@ nsTextStore::OnTextChangeInternal(const IMENotification& aIMENotification)
void
nsTextStore::NotifyTSFOfTextChange(const TS_TEXTCHANGE& aTextChange)
{
// XXX We need to cache the text change ranges and notify TSF of that
// the document is unlocked.
if (NS_WARN_IF(IsReadLocked())) {
return;
}
@ -4531,9 +4554,7 @@ nsTextStore::OnUpdateCompositionInternal()
"mDeferNotifyingTSF=%s",
this, GetBoolName(mDeferNotifyingTSF)));
if (!mDeferNotifyingTSF) {
return NS_OK;
}
mPendingClearLockedContent = true;
mDeferNotifyingTSF = false;
MaybeFlushPendingNotifications();
return NS_OK;

View File

@ -684,9 +684,9 @@ protected:
bool mInitialized;
};
// mLockedContent caches content of the document ONLY while the document
// is locked. I.e., the content is cleared at unlocking the document since
// we need to reduce the memory usage. This is initialized by
// mLockedContent starts to cache content of the document at first query of
// the content during a document lock. This is abandoned after document is
// unlocked and dispatched events are handled. This is initialized by
// LockedContent() automatically. So, don't access this member directly
// except at calling Clear(), IsInitialized(), IsLayoutChangedAfter() or
// IsLayoutChanged().
@ -779,6 +779,9 @@ protected:
// During the documet is locked, we shouldn't destroy the instance.
// If this is true, the instance will be destroyed after unlocked.
bool mPendingDestroy;
// If this is true, MaybeFlushPendingNotifications() will clear the
// mLockedContent.
bool mPendingClearLockedContent;
// While there is native caret, this is true. Otherwise, false.
bool mNativeCaretIsCreated;
// While the instance is dispatching events, the event may not be handled