author | Masayuki Nakano <masayuki@d-toybox.com> |
Wed, 17 Jun 2015 10:03:57 +0900 | |
changeset 249293 | c215b9a30b7395a9db4c527992c23ab45f5021e9 |
parent 249292 | 9345403c76288e468409cc12411f8ce16ed1a630 |
child 249294 | 83a659053a5239769f32ddaa3ac214b11af2c07c |
push id | 28923 |
push user | ryanvm@gmail.com |
push date | Wed, 17 Jun 2015 18:57:11 +0000 |
treeherder | mozilla-central@099d6cd6725e [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | smaug |
bugs | 1172466 |
milestone | 41.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
dom/events/IMEContentObserver.cpp | file | annotate | diff | comparison | revisions | |
dom/events/IMEContentObserver.h | file | annotate | diff | comparison | revisions |
--- a/dom/events/IMEContentObserver.cpp +++ b/dom/events/IMEContentObserver.cpp @@ -25,24 +25,27 @@ #include "nsIFrame.h" #include "nsINode.h" #include "nsIPresShell.h" #include "nsISelectionController.h" #include "nsISelectionPrivate.h" #include "nsISupports.h" #include "nsIWidget.h" #include "nsPresContext.h" -#include "nsThreadUtils.h" #include "nsWeakReference.h" #include "WritingModes.h" namespace mozilla { using namespace widget; +/****************************************************************************** + * mozilla::IMEContentObserver + ******************************************************************************/ + NS_IMPL_CYCLE_COLLECTION_CLASS(IMEContentObserver) NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(IMEContentObserver) nsAutoScriptBlocker scriptBlocker; tmp->NotifyIMEOfBlur(); tmp->UnregisterObservers(); @@ -379,71 +382,16 @@ IMEContentObserver::GetSelectionAndRoot( } NS_ASSERTION(mSelection && mRootContent, "uninitialized content observer"); NS_ADDREF(*aSelection = mSelection); NS_ADDREF(*aRootContent = mRootContent); return NS_OK; } -// Helper class, used for selection change notification -class SelectionChangeEvent : public nsRunnable -{ -public: - SelectionChangeEvent(IMEContentObserver* aDispatcher, - bool aCausedByComposition) - : mDispatcher(aDispatcher) - , mCausedByComposition(aCausedByComposition) - { - MOZ_ASSERT(mDispatcher); - } - - NS_IMETHOD Run() - { - nsCOMPtr<nsIWidget> widget = mDispatcher->GetWidget(); - nsPresContext* presContext = mDispatcher->GetPresContext(); - if (!widget || !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); - 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 = mDispatcher->GetWidget(); - if (!widget || NS_WARN_IF(widget->Destroyed())) { - return NS_OK; - } - - IMENotification notification(NOTIFY_IME_OF_SELECTION_CHANGE); - notification.mSelectionChangeData.mOffset = - selection.mReply.mOffset; - notification.mSelectionChangeData.mLength = - selection.mReply.mString.Length(); - notification.mSelectionChangeData.SetWritingMode( - selection.GetWritingMode()); - notification.mSelectionChangeData.mReversed = selection.mReply.mReversed; - notification.mSelectionChangeData.mCausedByComposition = - mCausedByComposition; - widget->NotifyIME(notification); - return NS_OK; - } - -private: - nsRefPtr<IMEContentObserver> mDispatcher; - bool mCausedByComposition; -}; - nsresult IMEContentObserver::NotifySelectionChanged(nsIDOMDocument* aDOMDocument, nsISelection* aSelection, int16_t aReason) { bool causedByComposition = IsEditorHandlingEventForComposition(); if (causedByComposition && !mUpdatePreference.WantChangesCausedByComposition()) { @@ -454,39 +402,16 @@ IMEContentObserver::NotifySelectionChang nsresult rv = aSelection->GetRangeCount(&count); NS_ENSURE_SUCCESS(rv, rv); if (count > 0 && mWidget) { MaybeNotifyIMEOfSelectionChange(causedByComposition); } return NS_OK; } -// Helper class, used for position change notification -class PositionChangeEvent final : public nsRunnable -{ -public: - explicit PositionChangeEvent(IMEContentObserver* aDispatcher) - : mDispatcher(aDispatcher) - { - MOZ_ASSERT(mDispatcher); - } - - NS_IMETHOD Run() - { - if (mDispatcher->GetWidget()) { - mDispatcher->GetWidget()->NotifyIME( - IMENotification(NOTIFY_IME_OF_POSITION_CHANGE)); - } - return NS_OK; - } - -private: - nsRefPtr<IMEContentObserver> mDispatcher; -}; - void IMEContentObserver::ScrollPositionChanged() { MaybeNotifyIMEOfPositionChange(); } NS_IMETHODIMP IMEContentObserver::Reflow(DOMHighResTimeStamp aStart, @@ -577,50 +502,16 @@ IMEContentObserver::OnMouseButtonEvent(n return false; } bool consumed = (rv == NS_SUCCESS_EVENT_CONSUMED); aMouseEvent->mFlags.mDefaultPrevented = consumed; return consumed; } -// Helper class, used for text change notification -class TextChangeEvent : public nsRunnable -{ -public: - TextChangeEvent(IMEContentObserver* aDispatcher, - IMEContentObserver::TextChangeData& aData) - : mDispatcher(aDispatcher) - , mData(aData) - { - MOZ_ASSERT(mDispatcher); - MOZ_ASSERT(mData.mStored); - // Reset mStored because this now consumes the data. - aData.mStored = false; - } - - NS_IMETHOD Run() - { - if (mDispatcher->GetWidget()) { - IMENotification notification(NOTIFY_IME_OF_TEXT_CHANGE); - notification.mTextChangeData.mStartOffset = mData.mStartOffset; - notification.mTextChangeData.mOldEndOffset = mData.mRemovedEndOffset; - notification.mTextChangeData.mNewEndOffset = mData.mAddedEndOffset; - notification.mTextChangeData.mCausedByComposition = - mData.mCausedOnlyByComposition; - mDispatcher->GetWidget()->NotifyIME(notification); - } - return NS_OK; - } - -private: - nsRefPtr<IMEContentObserver> mDispatcher; - IMEContentObserver::TextChangeData mData; -}; - void IMEContentObserver::StoreTextChangeData(const TextChangeData& aTextChangeData) { MOZ_ASSERT(aTextChangeData.mStartOffset <= aTextChangeData.mRemovedEndOffset, "end of removed text must be same or larger than start"); MOZ_ASSERT(aTextChangeData.mStartOffset <= aTextChangeData.mAddedEndOffset, "end of added text must be same or larger than start"); @@ -1114,35 +1005,16 @@ IMEContentObserver::MaybeNotifyIMEOfSele void IMEContentObserver::MaybeNotifyIMEOfPositionChange() { mIsPositionChangeEventPending = true; FlushMergeableNotifications(); } -class AsyncMergeableNotificationsFlusher : public nsRunnable -{ -public: - explicit AsyncMergeableNotificationsFlusher(IMEContentObserver* aIMEContentObserver) - : mIMEContentObserver(aIMEContentObserver) - { - MOZ_ASSERT(mIMEContentObserver); - } - - NS_IMETHOD Run() - { - mIMEContentObserver->FlushMergeableNotifications(); - return NS_OK; - } - -private: - nsRefPtr<IMEContentObserver> mIMEContentObserver; -}; - void IMEContentObserver::FlushMergeableNotifications() { // If this is already detached from the widget, this doesn't need to notify // anything. if (!mWidget) { return; } @@ -1649,9 +1521,97 @@ IMEContentObserver::TestMergingTextChang "text"); MOZ_ASSERT(mTextChangeData.mAddedEndOffset == 82, // 70 + (36 - 24) "Test 6-4-3: mAddedEndOffset should be the first end of added text without " "removed text length by the new change"); mTextChangeData.mStored = false; } #endif // #ifdef DEBUG +/****************************************************************************** + * mozilla::IMEContentObserver::SelectionChangeEvent + ******************************************************************************/ + +NS_IMETHODIMP +IMEContentObserver::SelectionChangeEvent::Run() +{ + nsCOMPtr<nsIWidget> widget = mIMEContentObserver->mWidget; + nsPresContext* presContext = mIMEContentObserver->GetPresContext(); + if (!widget || !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); + 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())) { + return NS_OK; + } + + IMENotification notification(NOTIFY_IME_OF_SELECTION_CHANGE); + notification.mSelectionChangeData.mOffset = + selection.mReply.mOffset; + notification.mSelectionChangeData.mLength = + selection.mReply.mString.Length(); + notification.mSelectionChangeData.SetWritingMode( + selection.GetWritingMode()); + notification.mSelectionChangeData.mReversed = selection.mReply.mReversed; + notification.mSelectionChangeData.mCausedByComposition = + mCausedByComposition; + widget->NotifyIME(notification); + return NS_OK; +} + +/****************************************************************************** + * mozilla::IMEContentObserver::TextChangeEvent + ******************************************************************************/ + +NS_IMETHODIMP +IMEContentObserver::TextChangeEvent::Run() +{ + if (!mIMEContentObserver->mWidget) { + return NS_OK; + } + IMENotification notification(NOTIFY_IME_OF_TEXT_CHANGE); + notification.mTextChangeData.mStartOffset = mData.mStartOffset; + notification.mTextChangeData.mOldEndOffset = mData.mRemovedEndOffset; + notification.mTextChangeData.mNewEndOffset = mData.mAddedEndOffset; + notification.mTextChangeData.mCausedByComposition = + mData.mCausedOnlyByComposition; + mIMEContentObserver->mWidget->NotifyIME(notification); + return NS_OK; +} + +/****************************************************************************** + * mozilla::IMEContentObserver::PositionChangeEvent + ******************************************************************************/ + +NS_IMETHODIMP +IMEContentObserver::PositionChangeEvent::Run() +{ + if (mIMEContentObserver->mWidget) { + mIMEContentObserver->mWidget->NotifyIME( + IMENotification(NOTIFY_IME_OF_POSITION_CHANGE)); + } + return NS_OK; +} + +/****************************************************************************** + * mozilla::IMEContentObserver::AsyncMergeableNotificationsFlusher + ******************************************************************************/ + +NS_IMETHODIMP +IMEContentObserver::AsyncMergeableNotificationsFlusher::Run() +{ + mIMEContentObserver->FlushMergeableNotifications(); + return NS_OK; +} + } // namespace mozilla
--- a/dom/events/IMEContentObserver.h +++ b/dom/events/IMEContentObserver.h @@ -13,16 +13,17 @@ #include "nsIDocShell.h" // XXX Why does only this need to be included here? #include "nsIEditor.h" #include "nsIEditorObserver.h" #include "nsIReflowObserver.h" #include "nsISelectionListener.h" #include "nsIScrollObserver.h" #include "nsIWidget.h" // for nsIMEUpdatePreference #include "nsStubMutationObserver.h" +#include "nsThreadUtils.h" #include "nsWeakReference.h" class nsIContent; class nsINode; class nsISelection; class nsPresContext; namespace mozilla { @@ -33,18 +34,16 @@ class EventStateManager; // in the currently focused editor class IMEContentObserver final : public nsISelectionListener , public nsStubMutationObserver , public nsIReflowObserver , public nsIScrollObserver , public nsSupportsWeakReference , public nsIEditorObserver { - friend class AsyncMergeableNotificationsFlusher; - public: IMEContentObserver(); NS_DECL_CYCLE_COLLECTING_ISUPPORTS NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(IMEContentObserver, nsISelectionListener) NS_DECL_NSIEDITOROBSERVER NS_DECL_NSISELECTIONLISTENER @@ -253,13 +252,84 @@ private: uint32_t mSuppressNotifications; int64_t mPreCharacterDataChangeLength; bool mIsObserving; bool mIsSelectionChangeEventPending; bool mSelectionChangeCausedOnlyByComposition; bool mIsPositionChangeEventPending; bool mIsFlushingPendingNotifications; + + + /** + * Helper classes to notify IME. + */ + + class SelectionChangeEvent : public nsRunnable + { + public: + SelectionChangeEvent(IMEContentObserver* aIMEContentObserver, + bool aCausedByComposition) + : mIMEContentObserver(aIMEContentObserver) + , mCausedByComposition(aCausedByComposition) + { + MOZ_ASSERT(mIMEContentObserver); + } + NS_IMETHOD Run() override; + + private: + nsRefPtr<IMEContentObserver> mIMEContentObserver; + bool mCausedByComposition; + }; + + class TextChangeEvent : public nsRunnable + { + public: + TextChangeEvent(IMEContentObserver* aIMEContentObserver, + TextChangeData& aData) + : mIMEContentObserver(aIMEContentObserver) + , mData(aData) + { + MOZ_ASSERT(mIMEContentObserver); + MOZ_ASSERT(mData.mStored); + // Reset mStored because this now consumes the data. + aData.mStored = false; + } + NS_IMETHOD Run() override; + + private: + nsRefPtr<IMEContentObserver> mIMEContentObserver; + TextChangeData mData; + }; + + class PositionChangeEvent final : public nsRunnable + { + public: + explicit PositionChangeEvent(IMEContentObserver* aIMEContentObserver) + : mIMEContentObserver(aIMEContentObserver) + { + MOZ_ASSERT(mIMEContentObserver); + } + NS_IMETHOD Run() override; + + private: + nsRefPtr<IMEContentObserver> mIMEContentObserver; + }; + + class AsyncMergeableNotificationsFlusher : public nsRunnable + { + public: + explicit AsyncMergeableNotificationsFlusher( + IMEContentObserver* aIMEContentObserver) + : mIMEContentObserver(aIMEContentObserver) + { + MOZ_ASSERT(mIMEContentObserver); + } + NS_IMETHOD Run() override; + + private: + nsRefPtr<IMEContentObserver> mIMEContentObserver; + }; }; } // namespace mozilla #endif // mozilla_IMEContentObserver_h_