Bug 1077345 part.1 Add TextComposition::IsValidStateForComposition() for checking if it's safe to dispatch an event to the DOM tree r=smaug

This commit is contained in:
Masayuki Nakano 2014-11-25 14:02:29 +09:00
parent ac20ce0143
commit a58378d200
2 changed files with 24 additions and 13 deletions

View File

@ -61,11 +61,19 @@ TextComposition::MatchesNativeContext(nsIWidget* aWidget) const
return mNativeContext == aWidget->GetInputContext().mNativeIMEContext;
}
bool
TextComposition::IsValidStateForComposition(nsIWidget* aWidget) const
{
return !Destroyed() && aWidget && !aWidget->Destroyed() &&
mPresContext->GetPresShell() &&
!mPresContext->GetPresShell()->IsDestroying();
}
bool
TextComposition::MaybeDispatchCompositionUpdate(
const WidgetCompositionEvent* aCompositionEvent)
{
if (Destroyed()) {
if (!IsValidStateForComposition(aCompositionEvent->widget)) {
return false;
}
@ -86,7 +94,7 @@ TextComposition::MaybeDispatchCompositionUpdate(
mLastData = compositionUpdate.mData;
EventDispatcher::Dispatch(mNode, mPresContext,
&compositionUpdate, nullptr, &status, nullptr);
return !Destroyed();
return IsValidStateForComposition(aCompositionEvent->widget);
}
void
@ -117,7 +125,7 @@ TextComposition::DispatchCompositionEvent(
EventDispatchingCallback* aCallBack,
bool aIsSynthesized)
{
if (Destroyed()) {
if (!IsValidStateForComposition(aCompositionEvent->widget)) {
*aStatus = nsEventStatus_eConsumeNoDefault;
return;
}
@ -175,7 +183,7 @@ TextComposition::DispatchCompositionEvent(
EventDispatcher::Dispatch(mNode, mPresContext,
aCompositionEvent, nullptr, aStatus, aCallBack);
if (NS_WARN_IF(Destroyed())) {
if (!IsValidStateForComposition(aCompositionEvent->widget)) {
return;
}
@ -295,13 +303,13 @@ TextComposition::RequestToCommit(nsIWidget* aWidget, bool aDiscard)
// If changing the data or committing string isn't empty, we need to
// dispatch compositionchange event for setting the composition string
// without IME selection.
if (!Destroyed() && !widget->Destroyed() &&
if (IsValidStateForComposition(widget) &&
(changingData || !commitData.IsEmpty())) {
nsEventStatus status = nsEventStatus_eIgnore;
widget->DispatchEvent(&changeEvent, status);
}
if (!Destroyed() && !widget->Destroyed()) {
if (IsValidStateForComposition(widget)) {
nsEventStatus status = nsEventStatus_eIgnore;
WidgetCompositionEvent endEvent(true, NS_COMPOSITION_END, widget);
endEvent.mData = commitData;
@ -411,22 +419,17 @@ TextComposition::CompositionEventDispatcher::CompositionEventDispatcher(
NS_IMETHODIMP
TextComposition::CompositionEventDispatcher::Run()
{
nsRefPtr<nsPresContext> presContext = mTextComposition->mPresContext;
if (!presContext || !presContext->GetPresShell() ||
presContext->GetPresShell()->IsDestroying()) {
return NS_OK; // cannot dispatch any events anymore
}
// The widget can be different from the widget which has dispatched
// composition events because GetWidget() returns a widget which is proper
// for calling NotifyIME(). However, this must no be problem since both
// widget should share native IME context. Therefore, even if an event
// handler uses the widget for requesting IME to commit or cancel, it works.
nsCOMPtr<nsIWidget> widget(mTextComposition->GetWidget());
if (NS_WARN_IF(!widget)) {
if (!mTextComposition->IsValidStateForComposition(widget)) {
return NS_OK; // cannot dispatch any events anymore
}
nsRefPtr<nsPresContext> presContext = mTextComposition->mPresContext;
nsEventStatus status = nsEventStatus_eIgnore;
switch (mEventMessage) {
case NS_COMPOSITION_START: {

View File

@ -249,6 +249,14 @@ private:
*/
void EditorDidHandleCompositionChangeEvent();
/**
* IsValidStateForComposition() returns true if it's safe to dispatch an event
* to the DOM tree. Otherwise, false.
* WARNING: This doesn't check script blocker state. It should be checked
* before dispatching the first event.
*/
bool IsValidStateForComposition(nsIWidget* aWidget) const;
/**
* DispatchCompositionEvent() dispatches the aCompositionEvent to the mContent
* synchronously. The caller must ensure that it's safe to dispatch the event.