Bug 1172466 part.3 Create an abstruct class which is a base class of classes notifying IME r=smaug

This commit is contained in:
Masayuki Nakano 2015-06-17 10:03:57 +09:00
Родитель 031f99fbda
Коммит 81de1dd26c
2 изменённых файлов: 85 добавлений и 56 удалений

Просмотреть файл

@ -1554,6 +1554,36 @@ IMEContentObserver::TestMergingTextChangeData()
}
#endif // #ifdef DEBUG
/******************************************************************************
* mozilla::IMEContentObserver::AChangeEvent
******************************************************************************/
bool
IMEContentObserver::AChangeEvent::CanNotifyIME() const
{
if (NS_WARN_IF(!mIMEContentObserver)) {
return false;
}
State state = mIMEContentObserver->GetState();
// If it's not initialized, we should do nothing.
if (state == eState_NotObserving) {
return false;
}
// If setting focus, just check the state.
if (mChangeEventType == eChangeEventType_Focus) {
return !NS_WARN_IF(mIMEContentObserver->mIMEHasFocus);
}
// If we've not notified IME of focus yet, we shouldn't notify anything.
if (!mIMEContentObserver->mIMEHasFocus) {
return false;
}
// If IME has focus, IMEContentObserver must hold the widget.
MOZ_ASSERT(mIMEContentObserver->mWidget);
return true;
}
/******************************************************************************
* mozilla::IMEContentObserver::FocusSetEvent
******************************************************************************/
@ -1561,12 +1591,7 @@ IMEContentObserver::TestMergingTextChangeData()
NS_IMETHODIMP
IMEContentObserver::FocusSetEvent::Run()
{
if (NS_WARN_IF(mIMEContentObserver->mIMEHasFocus)) {
return NS_OK;
}
nsCOMPtr<nsIWidget> widget = mIMEContentObserver->GetWidget();
if (!widget) {
if (!CanNotifyIME()) {
// If IMEContentObserver has already gone, we don't need to notify IME of
// focus.
mIMEContentObserver->ClearPendingNotifications();
@ -1574,7 +1599,7 @@ IMEContentObserver::FocusSetEvent::Run()
}
mIMEContentObserver->mIMEHasFocus = true;
widget->NotifyIME(IMENotification(NOTIFY_IME_OF_FOCUS));
mIMEContentObserver->mWidget->NotifyIME(IMENotification(NOTIFY_IME_OF_FOCUS));
return NS_OK;
}
@ -1585,31 +1610,27 @@ IMEContentObserver::FocusSetEvent::Run()
NS_IMETHODIMP
IMEContentObserver::SelectionChangeEvent::Run()
{
// If IME has already lost focus, we shouldn't notify any pending
// notifications.
if (!mIMEContentObserver->mIMEHasFocus) {
if (!CanNotifyIME()) {
return NS_OK;
}
nsCOMPtr<nsIWidget> widget = mIMEContentObserver->mWidget;
nsPresContext* presContext = mIMEContentObserver->GetPresContext();
if (!widget || !presContext) {
if (!presContext) {
return NS_OK;
}
// XXX Cannot we cache some information for reducing the cost to compute
// selection offset and writing mode?
WidgetQueryContentEvent selection(true, NS_QUERY_SELECTED_TEXT, widget);
WidgetQueryContentEvent selection(true, NS_QUERY_SELECTED_TEXT,
mIMEContentObserver->mWidget);
ContentEventHandler handler(presContext);
handler.OnQuerySelectedText(&selection);
if (NS_WARN_IF(!selection.mSucceeded)) {
return NS_OK;
}
// The widget might be destroyed during querying the content since it
// causes flushing layout.
widget = mIMEContentObserver->mWidget;
if (!widget || NS_WARN_IF(widget->Destroyed())) {
// The state may be changed since querying content causes flushing layout.
if (!CanNotifyIME()) {
return NS_OK;
}
@ -1623,7 +1644,7 @@ IMEContentObserver::SelectionChangeEvent::Run()
notification.mSelectionChangeData.mReversed = selection.mReply.mReversed;
notification.mSelectionChangeData.mCausedByComposition =
mCausedByComposition;
widget->NotifyIME(notification);
mIMEContentObserver->mWidget->NotifyIME(notification);
return NS_OK;
}
@ -1634,15 +1655,10 @@ IMEContentObserver::SelectionChangeEvent::Run()
NS_IMETHODIMP
IMEContentObserver::TextChangeEvent::Run()
{
// If IME has already lost focus, we shouldn't notify any pending
// notifications.
if (!mIMEContentObserver->mIMEHasFocus) {
if (!CanNotifyIME()) {
return NS_OK;
}
if (!mIMEContentObserver->mWidget) {
return NS_OK;
}
IMENotification notification(NOTIFY_IME_OF_TEXT_CHANGE);
notification.mTextChangeData.mStartOffset = mData.mStartOffset;
notification.mTextChangeData.mOldEndOffset = mData.mRemovedEndOffset;
@ -1660,16 +1676,12 @@ IMEContentObserver::TextChangeEvent::Run()
NS_IMETHODIMP
IMEContentObserver::PositionChangeEvent::Run()
{
// If IME has already lost focus, we shouldn't notify any pending
// notifications.
if (!mIMEContentObserver->mIMEHasFocus) {
if (!CanNotifyIME()) {
return NS_OK;
}
if (mIMEContentObserver->mWidget) {
mIMEContentObserver->mWidget->NotifyIME(
IMENotification(NOTIFY_IME_OF_POSITION_CHANGE));
}
mIMEContentObserver->mWidget->NotifyIME(
IMENotification(NOTIFY_IME_OF_POSITION_CHANGE));
return NS_OK;
}
@ -1680,6 +1692,10 @@ IMEContentObserver::PositionChangeEvent::Run()
NS_IMETHODIMP
IMEContentObserver::AsyncMergeableNotificationsFlusher::Run()
{
if (!CanNotifyIME()) {
return NS_OK;
}
mIMEContentObserver->FlushMergeableNotifications();
return NS_OK;
}

Просмотреть файл

@ -273,46 +273,68 @@ private:
* Helper classes to notify IME.
*/
class FocusSetEvent: public nsRunnable
class AChangeEvent: public nsRunnable
{
public:
explicit FocusSetEvent(IMEContentObserver* aIMEContentObserver)
protected:
enum ChangeEventType
{
eChangeEventType_Focus,
eChangeEventType_Selection,
eChangeEventType_Text,
eChangeEventType_Position,
eChangeEventType_FlushPendingEvents
};
AChangeEvent(ChangeEventType aChangeEventType,
IMEContentObserver* aIMEContentObserver)
: mIMEContentObserver(aIMEContentObserver)
, mChangeEventType(aChangeEventType)
{
MOZ_ASSERT(mIMEContentObserver);
}
NS_IMETHOD Run() override;
private:
nsRefPtr<IMEContentObserver> mIMEContentObserver;
ChangeEventType mChangeEventType;
/**
* CanNotifyIME() checks if mIMEContentObserver can and should notify IME.
*/
bool CanNotifyIME() const;
};
class SelectionChangeEvent : public nsRunnable
class FocusSetEvent: public AChangeEvent
{
public:
explicit FocusSetEvent(IMEContentObserver* aIMEContentObserver)
: AChangeEvent(eChangeEventType_Focus, aIMEContentObserver)
{
}
NS_IMETHOD Run() override;
};
class SelectionChangeEvent : public AChangeEvent
{
public:
SelectionChangeEvent(IMEContentObserver* aIMEContentObserver,
bool aCausedByComposition)
: mIMEContentObserver(aIMEContentObserver)
: AChangeEvent(eChangeEventType_Selection, aIMEContentObserver)
, mCausedByComposition(aCausedByComposition)
{
MOZ_ASSERT(mIMEContentObserver);
}
NS_IMETHOD Run() override;
private:
nsRefPtr<IMEContentObserver> mIMEContentObserver;
bool mCausedByComposition;
};
class TextChangeEvent : public nsRunnable
class TextChangeEvent : public AChangeEvent
{
public:
TextChangeEvent(IMEContentObserver* aIMEContentObserver,
TextChangeData& aData)
: mIMEContentObserver(aIMEContentObserver)
: AChangeEvent(eChangeEventType_Text, aIMEContentObserver)
, mData(aData)
{
MOZ_ASSERT(mIMEContentObserver);
MOZ_ASSERT(mData.mStored);
// Reset mStored because this now consumes the data.
aData.mStored = false;
@ -320,37 +342,28 @@ private:
NS_IMETHOD Run() override;
private:
nsRefPtr<IMEContentObserver> mIMEContentObserver;
TextChangeData mData;
};
class PositionChangeEvent final : public nsRunnable
class PositionChangeEvent final : public AChangeEvent
{
public:
explicit PositionChangeEvent(IMEContentObserver* aIMEContentObserver)
: mIMEContentObserver(aIMEContentObserver)
: AChangeEvent(eChangeEventType_Position, aIMEContentObserver)
{
MOZ_ASSERT(mIMEContentObserver);
}
NS_IMETHOD Run() override;
private:
nsRefPtr<IMEContentObserver> mIMEContentObserver;
};
class AsyncMergeableNotificationsFlusher : public nsRunnable
class AsyncMergeableNotificationsFlusher : public AChangeEvent
{
public:
explicit AsyncMergeableNotificationsFlusher(
IMEContentObserver* aIMEContentObserver)
: mIMEContentObserver(aIMEContentObserver)
: AChangeEvent(eChangeEventType_FlushPendingEvents, aIMEContentObserver)
{
MOZ_ASSERT(mIMEContentObserver);
}
NS_IMETHOD Run() override;
private:
nsRefPtr<IMEContentObserver> mIMEContentObserver;
};
};