mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-30 00:01:50 +00:00
Bug 1275914 part.2 Modify TextComposition::mCompositionStartOffset after every composition event dispatch r=smaug
When composition string hasn't been non-empty, insertion point of the composition string can be changed by a DOM event handler. E.g., compositionstart, first compositionupdate and first text. Therefore, TextComposition should update the composition start offset cache after every event dispatch. MozReview-Commit-ID: FOPewPTRuCn --HG-- extra : rebase_source : 95fbba8130a1d21e957cee305b3b2a433bfae56a
This commit is contained in:
parent
7716923106
commit
b44f10c1f3
@ -69,6 +69,7 @@ TextComposition::TextComposition(nsPresContext* aPresContext,
|
||||
, mAllowControlCharacters(
|
||||
Preferences::GetBool("dom.compositionevent.allow_control_characters",
|
||||
false))
|
||||
, mWasCompositionStringEmpty(true)
|
||||
{
|
||||
MOZ_ASSERT(aCompositionEvent->mNativeIMEContext.IsValid());
|
||||
}
|
||||
@ -152,6 +153,8 @@ TextComposition::DispatchEvent(WidgetCompositionEvent* aDispatchEvent,
|
||||
|
||||
EventDispatcher::Dispatch(mNode, mPresContext,
|
||||
aDispatchEvent, nullptr, aStatus, aCallBack);
|
||||
|
||||
OnCompositionEventDispatched(aDispatchEvent);
|
||||
}
|
||||
|
||||
void
|
||||
@ -241,6 +244,8 @@ TextComposition::DispatchCompositionEvent(
|
||||
EventDispatchingCallback* aCallBack,
|
||||
bool aIsSynthesized)
|
||||
{
|
||||
mWasCompositionStringEmpty = mString.IsEmpty();
|
||||
|
||||
// If the content is a container of TabParent, composition should be in the
|
||||
// remote process.
|
||||
if (mTabParent) {
|
||||
@ -402,7 +407,7 @@ TextComposition::DispatchCompositionEvent(
|
||||
MOZ_ASSERT(!HasEditor(), "Why does the editor still keep to hold this?");
|
||||
}
|
||||
|
||||
OnCompositionEventHandled(aCompositionEvent);
|
||||
MaybeNotifyIMEOfCompositionEventHandled(aCompositionEvent);
|
||||
}
|
||||
|
||||
// static
|
||||
@ -430,32 +435,57 @@ TextComposition::HandleSelectionEvent(nsPresContext* aPresContext,
|
||||
}
|
||||
|
||||
void
|
||||
TextComposition::OnCompositionEventHandled(
|
||||
TextComposition::OnCompositionEventDispatched(
|
||||
const WidgetCompositionEvent* aCompositionEvent)
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(!mTabParent);
|
||||
|
||||
nsEventStatus status;
|
||||
if (!IsValidStateForComposition(aCompositionEvent->mWidget)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// When compositon start, notify the rect of first offset character.
|
||||
// When not compositon start, notify the rect of selected composition
|
||||
// string if compositionchange event.
|
||||
if (aCompositionEvent->mMessage == eCompositionStart) {
|
||||
// Every composition event may cause changing composition start offset,
|
||||
// especially when there is no composition string. Therefore, we need to
|
||||
// update mCompositionStartOffset with the latest offset.
|
||||
|
||||
MOZ_ASSERT(aCompositionEvent->mMessage != eCompositionStart ||
|
||||
mWasCompositionStringEmpty,
|
||||
"mWasCompositionStringEmpty should be true if the dispatched "
|
||||
"event is eCompositionStart");
|
||||
|
||||
if (mWasCompositionStringEmpty &&
|
||||
!aCompositionEvent->CausesDOMCompositionEndEvent()) {
|
||||
// If there was no composition string, current selection start may be the
|
||||
// offset for inserting composition string.
|
||||
nsCOMPtr<nsIWidget> widget = mPresContext->GetRootWidget();
|
||||
// Update composition start offset
|
||||
WidgetQueryContentEvent selectedTextEvent(true, eQuerySelectedText, widget);
|
||||
widget->DispatchEvent(&selectedTextEvent, status);
|
||||
if (selectedTextEvent.mSucceeded) {
|
||||
mCompositionStartOffset = selectedTextEvent.mReply.mOffset;
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
if (mString.IsEmpty()) {
|
||||
widget->DispatchEvent(&selectedTextEvent, status);
|
||||
} else {
|
||||
// Unknown offset
|
||||
NS_WARNING("Cannot get start offset of IME composition");
|
||||
MOZ_ASSERT(aCompositionEvent->mMessage == eCompositionChange);
|
||||
// TODO: Update mCompositionStartOffset with first IME selection
|
||||
}
|
||||
if (NS_WARN_IF(!selectedTextEvent.mSucceeded)) {
|
||||
// XXX Is this okay?
|
||||
mCompositionStartOffset = 0;
|
||||
} else {
|
||||
mCompositionStartOffset = selectedTextEvent.mReply.mOffset;
|
||||
}
|
||||
mTargetClauseOffsetInComposition = 0;
|
||||
} else if (aCompositionEvent->CausesDOMTextEvent()) {
|
||||
}
|
||||
|
||||
if (aCompositionEvent->CausesDOMTextEvent()) {
|
||||
mTargetClauseOffsetInComposition = aCompositionEvent->TargetClauseOffset();
|
||||
} else {
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TextComposition::MaybeNotifyIMEOfCompositionEventHandled(
|
||||
const WidgetCompositionEvent* aCompositionEvent)
|
||||
{
|
||||
if (aCompositionEvent->mMessage != eCompositionStart &&
|
||||
!aCompositionEvent->CausesDOMTextEvent()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -258,6 +258,10 @@ private:
|
||||
// and compositionend events.
|
||||
bool mAllowControlCharacters;
|
||||
|
||||
// mWasCompositionStringEmpty is true if the composition string was empty
|
||||
// when DispatchCompositionEvent() is called.
|
||||
bool mWasCompositionStringEmpty;
|
||||
|
||||
// Hide the default constructor and copy constructor.
|
||||
TextComposition()
|
||||
: mPresContext(nullptr)
|
||||
@ -272,6 +276,7 @@ private:
|
||||
, mRequestedToCommitOrCancel(false)
|
||||
, mWasNativeCompositionEndEventDiscarded(false)
|
||||
, mAllowControlCharacters(false)
|
||||
, mWasCompositionStringEmpty(true)
|
||||
{}
|
||||
TextComposition(const TextComposition& aOther);
|
||||
|
||||
@ -375,9 +380,18 @@ private:
|
||||
void OnCompositionEventDiscarded(WidgetCompositionEvent* aCompositionEvent);
|
||||
|
||||
/**
|
||||
* Calculate composition offset then notify composition update to widget
|
||||
* OnCompositionEventDispatched() is called after a composition event is
|
||||
* dispatched.
|
||||
*/
|
||||
void OnCompositionEventHandled(
|
||||
void OnCompositionEventDispatched(
|
||||
const WidgetCompositionEvent* aDispatchEvent);
|
||||
|
||||
/**
|
||||
* MaybeNotifyIMEOfCompositionEventHandled() notifies IME of composition
|
||||
* event handled. This should be called after dispatching a composition
|
||||
* event which came from widget.
|
||||
*/
|
||||
void MaybeNotifyIMEOfCompositionEventHandled(
|
||||
const WidgetCompositionEvent* aCompositionEvent);
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user