diff --git a/dom/events/IMEContentObserver.cpp b/dom/events/IMEContentObserver.cpp index ec5d2f3b197..ef8dd49b017 100644 --- a/dom/events/IMEContentObserver.cpp +++ b/dom/events/IMEContentObserver.cpp @@ -852,6 +852,35 @@ IMEContentObserver::PostSelectionChangeNotification( mIsSelectionChangeEventPending = true; } +bool +IMEContentObserver::UpdateSelectionCache() +{ + MOZ_ASSERT(IsSafeToNotifyIME()); + + if (!mUpdatePreference.WantSelectionChange()) { + return false; + } + + mSelectionData.Clear(); + + // XXX Cannot we cache some information for reducing the cost to compute + // selection offset and writing mode? + WidgetQueryContentEvent selection(true, NS_QUERY_SELECTED_TEXT, mWidget); + ContentEventHandler handler(GetPresContext()); + handler.OnQuerySelectedText(&selection); + if (NS_WARN_IF(!selection.mSucceeded)) { + return false; + } + + mSelectionData.mOffset = selection.mReply.mOffset; + *mSelectionData.mString = selection.mReply.mString; + mSelectionData.SetWritingMode(selection.GetWritingMode()); + mSelectionData.mReversed = selection.mReply.mReversed; + mSelectionData.mCausedByComposition = false; + mSelectionData.mCausedBySelectionEvent = false; + return mSelectionData.IsValid(); +} + void IMEContentObserver::PostPositionChangeNotification() { @@ -1060,13 +1089,7 @@ IMEContentObserver::SelectionChangeEvent::Run() 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, - mIMEContentObserver->mWidget); - ContentEventHandler handler(mIMEContentObserver->GetPresContext()); - handler.OnQuerySelectedText(&selection); - if (NS_WARN_IF(!selection.mSucceeded)) { + if (NS_WARN_IF(!mIMEContentObserver->UpdateSelectionCache())) { return NS_OK; } @@ -1076,15 +1099,8 @@ IMEContentObserver::SelectionChangeEvent::Run() } IMENotification notification(NOTIFY_IME_OF_SELECTION_CHANGE); - notification.mSelectionChangeData.mOffset = selection.mReply.mOffset; - *notification.mSelectionChangeData.mString = selection.mReply.mString; - notification.mSelectionChangeData.SetWritingMode( - selection.GetWritingMode()); - notification.mSelectionChangeData.mReversed = selection.mReply.mReversed; - notification.mSelectionChangeData.mCausedByComposition = - mCausedByComposition; - notification.mSelectionChangeData.mCausedBySelectionEvent = - mCausedBySelectionEvent; + notification.SetData(mIMEContentObserver->mSelectionData, + mCausedByComposition, mCausedBySelectionEvent); IMEStateManager::NotifyIME(notification, mIMEContentObserver->mWidget); return NS_OK; } @@ -1106,7 +1122,7 @@ IMEContentObserver::TextChangeEvent::Run() } IMENotification notification(NOTIFY_IME_OF_TEXT_CHANGE); - notification.mTextChangeData = mTextChangeData; + notification.SetData(mTextChangeData); IMEStateManager::NotifyIME(notification, mIMEContentObserver->mWidget); return NS_OK; } diff --git a/dom/events/IMEContentObserver.h b/dom/events/IMEContentObserver.h index 77e09f8408a..b22c6d7e88a 100644 --- a/dom/events/IMEContentObserver.h +++ b/dom/events/IMEContentObserver.h @@ -40,6 +40,7 @@ class IMEContentObserver final : public nsISelectionListener , public nsIEditorObserver { public: + typedef widget::IMENotification::SelectionChangeData SelectionChangeData; typedef widget::IMENotification::TextChangeData TextChangeData; typedef widget::IMENotification::TextChangeDataBase TextChangeDataBase; @@ -167,6 +168,15 @@ private: mTextChangeData.Clear(); } + /** + * UpdateSelectionCache() updates mSelectionData with the latest selection. + * This should be called only when IsSafeToNotifyIME() returns true. + * + * Note that this does nothing if mUpdatePreference.WantSelectionChange() + * returns false. + */ + bool UpdateSelectionCache(); + nsCOMPtr mWidget; nsCOMPtr mSelection; nsCOMPtr mRootContent; @@ -230,6 +240,11 @@ private: TextChangeData mTextChangeData; + // mSelectionData is the last selection data which was notified. This is + // modified by UpdateSelectionCache(). Note that mCausedBy* are always + // false. Do NOT refer them. + SelectionChangeData mSelectionData; + EventStateManager* mESM; nsIMEUpdatePreference mUpdatePreference; diff --git a/widget/IMEData.h b/widget/IMEData.h index efa798c2687..c0b0ba84127 100644 --- a/widget/IMEData.h +++ b/widget/IMEData.h @@ -757,6 +757,27 @@ struct IMENotification final MouseButtonEventData mMouseButtonEventData; }; + void SetData(const SelectionChangeDataBase& aSelectionChangeData) + { + MOZ_RELEASE_ASSERT(mMessage == NOTIFY_IME_OF_SELECTION_CHANGE); + mSelectionChangeData.Assign(aSelectionChangeData); + } + void SetData(const SelectionChangeDataBase& aSelectionChangeData, + bool aCausedByComposition, + bool aCausedBySelectionEvent) + { + MOZ_RELEASE_ASSERT(mMessage == NOTIFY_IME_OF_SELECTION_CHANGE); + mSelectionChangeData.Assign(aSelectionChangeData); + mSelectionChangeData.mCausedByComposition = aCausedByComposition; + mSelectionChangeData.mCausedBySelectionEvent = aCausedBySelectionEvent; + } + + void SetData(const TextChangeDataBase& aTextChangeData) + { + MOZ_RELEASE_ASSERT(mMessage == NOTIFY_IME_OF_TEXT_CHANGE); + mTextChangeData = aTextChangeData; + } + bool IsCausedByComposition() const { switch (mMessage) {