From 6440fbddc3cb187cb227396d0b4497a999ead74a Mon Sep 17 00:00:00 2001 From: Masayuki Nakano Date: Thu, 26 May 2022 07:03:20 +0000 Subject: [PATCH] Bug 1770133 - part 4: Make `IMEContentObserver` use `dom::Element` instead of `nsIContent` for root r=m_kato The root is always an element node. So, it should take and store the root node as `dom::Element` rather than `nsIContent`. Differential Revision: https://phabricator.services.mozilla.com/D147135 --- dom/base/nsDOMWindowUtils.cpp | 2 +- dom/events/ContentEventHandler.cpp | 6 +- dom/events/IMEContentObserver.cpp | 160 ++++++++++++++--------------- dom/events/IMEContentObserver.h | 40 ++++---- dom/events/IMEStateManager.cpp | 70 ++++++------- dom/events/IMEStateManager.h | 8 +- dom/events/TextComposition.cpp | 4 +- dom/html/nsGenericHTMLElement.cpp | 30 +++--- 8 files changed, 163 insertions(+), 157 deletions(-) diff --git a/dom/base/nsDOMWindowUtils.cpp b/dom/base/nsDOMWindowUtils.cpp index a078d2973bb5..1b75fca81c09 100644 --- a/dom/base/nsDOMWindowUtils.cpp +++ b/dom/base/nsDOMWindowUtils.cpp @@ -2124,7 +2124,7 @@ nsDOMWindowUtils::GetNodeObservedByIMEContentObserver(nsINode** aNode) { *aNode = nullptr; return NS_OK; } - *aNode = do_AddRef(observer->GetObservingContent()).take(); + *aNode = do_AddRef(observer->GetObservingElement()).take(); return NS_OK; } diff --git a/dom/events/ContentEventHandler.cpp b/dom/events/ContentEventHandler.cpp index 0bc5b66bf315..8a1f54dafc4e 100644 --- a/dom/events/ContentEventHandler.cpp +++ b/dom/events/ContentEventHandler.cpp @@ -3029,9 +3029,11 @@ nsresult ContentEventHandler::OnSelectionEvent(WidgetSelectionEvent* aEvent) { // XXX why do we need to get them from ISM? This method should work fine // without ISM. RefPtr sel; - nsresult rv = IMEStateManager::GetFocusSelectionAndRoot( - getter_AddRefs(sel), getter_AddRefs(mRootContent)); + RefPtr rootElement; + nsresult rv = IMEStateManager::GetFocusSelectionAndRootElement( + getter_AddRefs(sel), getter_AddRefs(rootElement)); mSelection = sel; + mRootContent = rootElement; if (rv != NS_ERROR_NOT_AVAILABLE) { NS_ENSURE_SUCCESS(rv, rv); } else { diff --git a/dom/events/IMEContentObserver.cpp b/dom/events/IMEContentObserver.cpp index f21348f0c4a8..fee6112d1986 100644 --- a/dom/events/IMEContentObserver.cpp +++ b/dom/events/IMEContentObserver.cpp @@ -85,7 +85,7 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(IMEContentObserver) tmp->UnregisterObservers(); NS_IMPL_CYCLE_COLLECTION_UNLINK(mSelection) - NS_IMPL_CYCLE_COLLECTION_UNLINK(mRootContent) + NS_IMPL_CYCLE_COLLECTION_UNLINK(mRootElement) NS_IMPL_CYCLE_COLLECTION_UNLINK(mEditableNode) NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocShell) NS_IMPL_CYCLE_COLLECTION_UNLINK(mEditorBase) @@ -102,7 +102,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(IMEContentObserver) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWidget) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFocusedWidget) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSelection) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mRootContent) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mRootElement) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mEditableNode) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocShell) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mEditorBase) @@ -143,7 +143,7 @@ IMEContentObserver::IMEContentObserver() } void IMEContentObserver::Init(nsIWidget& aWidget, nsPresContext& aPresContext, - nsIContent* aContent, EditorBase& aEditorBase) { + Element* aElement, EditorBase& aEditorBase) { State state = GetState(); if (NS_WARN_IF(state == eState_Observing)) { return; // Nothing to do. @@ -163,7 +163,7 @@ void IMEContentObserver::Init(nsIWidget& aWidget, nsPresContext& aPresContext, mWidget = &aWidget; mIMENotificationRequests = &mWidget->IMENotificationRequestsRef(); - if (!InitWithEditor(aPresContext, aContent, aEditorBase)) { + if (!InitWithEditor(aPresContext, aElement, aEditorBase)) { MOZ_LOG(sIMECOLog, LogLevel::Error, ("0x%p Init() FAILED, due to InitWithEditor() " "failure", @@ -214,10 +214,10 @@ void IMEContentObserver::OnIMEReceivedFocus() { // NOTIFY_IME_OF_FOCUS might cause recreating IMEContentObserver // instance via IMEStateManager::UpdateIMEState(). So, this // instance might already have been destroyed, check it. - if (!mRootContent) { + if (!mRootElement) { MOZ_LOG(sIMECOLog, LogLevel::Warning, ("0x%p OnIMEReceivedFocus(), " - "but mRootContent has already been cleared, so does nothing", + "but mRootElement has already been cleared, so does nothing", this)); return; } @@ -235,9 +235,9 @@ void IMEContentObserver::OnIMEReceivedFocus() { } bool IMEContentObserver::InitWithEditor(nsPresContext& aPresContext, - nsIContent* aContent, + Element* aElement, EditorBase& aEditorBase) { - mEditableNode = IMEStateManager::GetRootEditableNode(&aPresContext, aContent); + mEditableNode = IMEStateManager::GetRootEditableNode(aPresContext, aElement); if (NS_WARN_IF(!mEditableNode)) { return false; } @@ -275,18 +275,20 @@ bool IMEContentObserver::InitWithEditor(nsPresContext& aPresContext, } nsCOMPtr startContainer = selRange->GetStartContainer(); - mRootContent = startContainer->GetSelectionRootContent(presShell); + mRootElement = Element::FromNodeOrNull( + startContainer->GetSelectionRootContent(presShell)); } else { nsCOMPtr editableNode = mEditableNode; - mRootContent = editableNode->GetSelectionRootContent(presShell); + mRootElement = Element::FromNodeOrNull( + editableNode->GetSelectionRootContent(presShell)); } - if (!mRootContent && mEditableNode->IsDocument()) { + if (!mRootElement && mEditableNode->IsDocument()) { // The document node is editable, but there are no contents, this document // is not editable. return false; } - if (NS_WARN_IF(!mRootContent)) { + if (NS_WARN_IF(!mRootElement)) { return false; } @@ -304,7 +306,7 @@ void IMEContentObserver::Clear() { mEditorBase = nullptr; mSelection = nullptr; mEditableNode = nullptr; - mRootContent = nullptr; + mRootElement = nullptr; mDocShell = nullptr; // Should be safe to clear mDocumentObserver here even though it grabs // this instance in most cases because this is called by Init() or Destroy(). @@ -316,7 +318,7 @@ void IMEContentObserver::Clear() { void IMEContentObserver::ObserveEditableNode() { MOZ_RELEASE_ASSERT(mSelection); - MOZ_RELEASE_ASSERT(mRootContent); + MOZ_RELEASE_ASSERT(mRootElement); MOZ_RELEASE_ASSERT(GetState() != eState_Observing); // If this is called before sending NOTIFY_IME_OF_FOCUS (it's possible when @@ -336,10 +338,10 @@ void IMEContentObserver::ObserveEditableNode() { mEditorBase->SetIMEContentObserver(this); } - mRootContent->AddMutationObserver(this); + mRootElement->AddMutationObserver(this); // If it's in a document (should be so), we can use document observer to // reduce redundant computation of text change offsets. - Document* doc = mRootContent->GetComposedDoc(); + Document* doc = mRootElement->GetComposedDoc(); if (doc) { RefPtr documentObserver = mDocumentObserver; documentObserver->Observe(doc); @@ -402,8 +404,8 @@ void IMEContentObserver::UnregisterObservers() { mFocusedWidget = nullptr; } - if (mRootContent) { - mRootContent->RemoveMutationObserver(this); + if (mRootElement) { + mRootElement->RemoveMutationObserver(this); } if (mDocumentObserver) { @@ -446,62 +448,62 @@ void IMEContentObserver::DisconnectFromEventStateManager() { mESM = nullptr; } bool IMEContentObserver::MaybeReinitialize(nsIWidget& aWidget, nsPresContext& aPresContext, - nsIContent* aContent, + Element* aElement, EditorBase& aEditorBase) { - if (!IsObservingContent(&aPresContext, aContent)) { + if (!IsObservingContent(aPresContext, aElement)) { return false; } if (GetState() == eState_StoppedObserving) { - Init(aWidget, aPresContext, aContent, aEditorBase); + Init(aWidget, aPresContext, aElement, aEditorBase); } - return IsManaging(&aPresContext, aContent); + return IsManaging(aPresContext, aElement); } -bool IMEContentObserver::IsManaging(nsPresContext* aPresContext, - nsIContent* aContent) const { +bool IMEContentObserver::IsManaging(const nsPresContext& aPresContext, + const Element* aElement) const { return GetState() == eState_Observing && - IsObservingContent(aPresContext, aContent); + IsObservingContent(aPresContext, aElement); } -bool IMEContentObserver::IsBeingInitializedFor(nsPresContext* aPresContext, - nsIContent* aContent) const { +bool IMEContentObserver::IsBeingInitializedFor( + const nsPresContext& aPresContext, const Element* aElement) const { return GetState() == eState_Initializing && - IsObservingContent(aPresContext, aContent); + IsObservingContent(aPresContext, aElement); } -bool IMEContentObserver::IsManaging(const TextComposition* aComposition) const { +bool IMEContentObserver::IsManaging( + const TextComposition& aTextComposition) const { if (GetState() != eState_Observing) { return false; } - nsPresContext* presContext = aComposition->GetPresContext(); + nsPresContext* const presContext = aTextComposition.GetPresContext(); if (NS_WARN_IF(!presContext)) { return false; } if (presContext != GetPresContext()) { return false; // observing different document } - nsINode* targetNode = aComposition->GetEventTargetNode(); - nsIContent* targetContent = - targetNode && targetNode->IsContent() ? targetNode->AsContent() : nullptr; - return IsObservingContent(presContext, targetContent); + return IsObservingContent( + *presContext, + Element::FromNodeOrNull(aTextComposition.GetEventTargetNode())); } IMEContentObserver::State IMEContentObserver::GetState() const { - if (!mSelection || !mRootContent || !mEditableNode) { + if (!mSelection || !mRootElement || !mEditableNode) { return eState_NotObserving; // failed to initialize or finalized. } - if (!mRootContent->IsInComposedDoc()) { + if (!mRootElement->IsInComposedDoc()) { // the focused editor has already been reframed. return eState_StoppedObserving; } return mIsObserving ? eState_Observing : eState_Initializing; } -bool IMEContentObserver::IsObservingContent(nsPresContext* aPresContext, - nsIContent* aContent) const { +bool IMEContentObserver::IsObservingContent(const nsPresContext& aPresContext, + const Element* aElement) const { return mEditableNode == - IMEStateManager::GetRootEditableNode(aPresContext, aContent); + IMEStateManager::GetRootEditableNode(aPresContext, aElement); } bool IMEContentObserver::IsEditorHandlingEventForComposition() const { @@ -527,15 +529,15 @@ bool IMEContentObserver::IsEditorComposing() const { return mEditorBase->IsIMEComposing(); } -nsresult IMEContentObserver::GetSelectionAndRoot( - Selection** aSelection, nsIContent** aRootContent) const { +nsresult IMEContentObserver::GetSelectionAndRoot(Selection** aSelection, + Element** aRootElement) const { if (!mEditableNode || !mSelection) { return NS_ERROR_NOT_AVAILABLE; } - NS_ASSERTION(mSelection && mRootContent, "uninitialized content observer"); + NS_ASSERTION(mSelection && mRootElement, "uninitialized content observer"); NS_ADDREF(*aSelection = mSelection); - NS_ADDREF(*aRootContent = mRootContent); + NS_ADDREF(*aRootElement = mRootElement); return NS_OK; } @@ -605,7 +607,7 @@ nsresult IMEContentObserver::HandleQueryContentEvent( OffsetAndDataFor::SelectedString); aEvent->mReply->mReversed = mSelectionData.mReversed; } - aEvent->mReply->mContentsRoot = mRootContent; + aEvent->mReply->mContentsRoot = mRootElement; aEvent->mReply->mWritingMode = mSelectionData.GetWritingMode(); // The selection cache in IMEContentObserver must always have been in // an editing host (or an editable annoymous
element). Therefore, @@ -667,25 +669,25 @@ nsresult IMEContentObserver::HandleQueryContentEvent( } if (aEvent->Succeeded() && - NS_WARN_IF(aEvent->mReply->mContentsRoot != mRootContent)) { + NS_WARN_IF(aEvent->mReply->mContentsRoot != mRootElement)) { // Focus has changed unexpectedly, so make the query fail. aEvent->mReply.reset(); } return rv; } -bool IMEContentObserver::OnMouseButtonEvent(nsPresContext* aPresContext, - WidgetMouseEvent* aMouseEvent) { +bool IMEContentObserver::OnMouseButtonEvent(nsPresContext& aPresContext, + WidgetMouseEvent& aMouseEvent) { if (!mIMENotificationRequests || !mIMENotificationRequests->WantMouseButtonEventOnChar()) { return false; } - if (!aMouseEvent->IsTrusted() || aMouseEvent->DefaultPrevented() || - !aMouseEvent->mWidget) { + if (!aMouseEvent.IsTrusted() || aMouseEvent.DefaultPrevented() || + !aMouseEvent.mWidget) { return false; } // Now, we need to notify only mouse down and mouse up event. - switch (aMouseEvent->mMessage) { + switch (aMouseEvent.mMessage) { case eMouseUp: case eMouseDown: break; @@ -696,12 +698,10 @@ bool IMEContentObserver::OnMouseButtonEvent(nsPresContext* aPresContext, return false; } - RefPtr kungFuDeathGrip(this); - WidgetQueryContentEvent queryCharAtPointEvent(true, eQueryCharacterAtPoint, - aMouseEvent->mWidget); - queryCharAtPointEvent.mRefPoint = aMouseEvent->mRefPoint; - ContentEventHandler handler(aPresContext); + aMouseEvent.mWidget); + queryCharAtPointEvent.mRefPoint = aMouseEvent.mRefPoint; + ContentEventHandler handler(&aPresContext); handler.OnQueryCharacterAtPoint(&queryCharAtPointEvent); if (NS_WARN_IF(queryCharAtPointEvent.Failed()) || queryCharAtPointEvent.DidNotFindChar()) { @@ -724,23 +724,23 @@ bool IMEContentObserver::OnMouseButtonEvent(nsPresContext* aPresContext, } // The refPt is relative to its widget. // We should notify it with offset in the widget. - if (aMouseEvent->mWidget != mWidget) { + if (aMouseEvent.mWidget != mWidget) { queryCharAtPointEvent.mRefPoint += - aMouseEvent->mWidget->WidgetToScreenOffset() - + aMouseEvent.mWidget->WidgetToScreenOffset() - mWidget->WidgetToScreenOffset(); } IMENotification notification(NOTIFY_IME_OF_MOUSE_BUTTON_EVENT); - notification.mMouseButtonEventData.mEventMessage = aMouseEvent->mMessage; + notification.mMouseButtonEventData.mEventMessage = aMouseEvent.mMessage; notification.mMouseButtonEventData.mOffset = queryCharAtPointEvent.mReply->StartOffset(); notification.mMouseButtonEventData.mCursorPos = queryCharAtPointEvent.mRefPoint; notification.mMouseButtonEventData.mCharRect = queryCharAtPointEvent.mReply->mRect; - notification.mMouseButtonEventData.mButton = aMouseEvent->mButton; - notification.mMouseButtonEventData.mButtons = aMouseEvent->mButtons; - notification.mMouseButtonEventData.mModifiers = aMouseEvent->mModifiers; + notification.mMouseButtonEventData.mButton = aMouseEvent.mButton; + notification.mMouseButtonEventData.mButtons = aMouseEvent.mButtons; + notification.mMouseButtonEventData.mModifiers = aMouseEvent.mModifiers; nsresult rv = IMEStateManager::NotifyIME(notification, mWidget); if (NS_WARN_IF(NS_FAILED(rv))) { @@ -749,7 +749,7 @@ bool IMEContentObserver::OnMouseButtonEvent(nsPresContext* aPresContext, bool consumed = (rv == NS_SUCCESS_EVENT_CONSUMED); if (consumed) { - aMouseEvent->PreventDefault(); + aMouseEvent.PreventDefault(); } return consumed; } @@ -765,7 +765,7 @@ void IMEContentObserver::CharacterDataWillChange( "mPreCharacterDataChangeLength"); if (!NeedsTextChangeNotification() || - !nsContentUtils::IsInSameAnonymousTree(mRootContent, aContent)) { + !nsContentUtils::IsInSameAnonymousTree(mRootElement, aContent)) { return; } @@ -802,7 +802,7 @@ void IMEContentObserver::CharacterDataChanged( } if (!NeedsTextChangeNotification() || - !nsContentUtils::IsInSameAnonymousTree(mRootContent, aContent)) { + !nsContentUtils::IsInSameAnonymousTree(mRootElement, aContent)) { return; } @@ -822,8 +822,8 @@ void IMEContentObserver::CharacterDataChanged( uint32_t offset = 0; // get offsets of change and fire notification nsresult rv = ContentEventHandler::GetFlatTextLengthInRange( - NodePosition(mRootContent, 0u), - NodePosition(aContent, aInfo.mChangeStart), mRootContent, &offset, + NodePosition(mRootElement, 0u), + NodePosition(aContent, aInfo.mChangeStart), mRootElement, &offset, LINE_BREAK_TYPE_NATIVE); if (NS_WARN_IF(NS_FAILED(rv))) { return; @@ -846,7 +846,7 @@ void IMEContentObserver::NotifyContentAdded(nsINode* aContainer, nsIContent* aFirstContent, nsIContent* aLastContent) { if (!NeedsTextChangeNotification() || - !nsContentUtils::IsInSameAnonymousTree(mRootContent, aFirstContent)) { + !nsContentUtils::IsInSameAnonymousTree(mRootElement, aFirstContent)) { return; } @@ -899,9 +899,9 @@ void IMEContentObserver::NotifyContentAdded(nsINode* aContainer, aFirstContent->GetPreviousSibling())) { mEndOfAddedTextCache.Clear(); rv = ContentEventHandler::GetFlatTextLengthInRange( - NodePosition(mRootContent, 0u), + NodePosition(mRootElement, 0u), NodePositionBefore(aContainer, PointBefore(aContainer, aFirstContent)), - mRootContent, &offset, LINE_BREAK_TYPE_NATIVE); + mRootElement, &offset, LINE_BREAK_TYPE_NATIVE); if (NS_WARN_IF(NS_FAILED((rv)))) { return; } @@ -913,7 +913,7 @@ void IMEContentObserver::NotifyContentAdded(nsINode* aContainer, uint32_t addingLength = 0; rv = ContentEventHandler::GetFlatTextLengthInRange( NodePositionBefore(aContainer, PointBefore(aContainer, aFirstContent)), - NodePosition(aContainer, aLastContent), mRootContent, &addingLength, + NodePosition(aContainer, aLastContent), mRootElement, &addingLength, LINE_BREAK_TYPE_NATIVE); if (NS_WARN_IF(NS_FAILED((rv)))) { mEndOfAddedTextCache.Clear(); @@ -950,7 +950,7 @@ void IMEContentObserver::ContentInserted(nsIContent* aChild) { void IMEContentObserver::ContentRemoved(nsIContent* aChild, nsIContent* aPreviousSibling) { if (!NeedsTextChangeNotification() || - !nsContentUtils::IsInSameAnonymousTree(mRootContent, aChild)) { + !nsContentUtils::IsInSameAnonymousTree(mRootElement, aChild)) { return; } @@ -967,8 +967,8 @@ void IMEContentObserver::ContentRemoved(nsIContent* aChild, // by open tag of aContainer. Be careful when aPreviousSibling is nullptr. rv = ContentEventHandler::GetFlatTextLengthInRange( - NodePosition(mRootContent, 0u), - NodePosition(containerNode, aPreviousSibling), mRootContent, &offset, + NodePosition(mRootElement, 0u), + NodePosition(containerNode, aPreviousSibling), mRootElement, &offset, LINE_BREAK_TYPE_NATIVE); if (NS_WARN_IF(NS_FAILED(rv))) { mStartOfRemovingTextRangeCache.Clear(); @@ -987,7 +987,7 @@ void IMEContentObserver::ContentRemoved(nsIContent* aChild, } else { nsresult rv = ContentEventHandler::GetFlatTextLengthInRange( NodePositionBefore(aChild, 0u), - NodePosition(aChild, aChild->GetChildCount()), mRootContent, + NodePosition(aChild, aChild->GetChildCount()), mRootElement, &textLength, LINE_BREAK_TYPE_NATIVE, true); if (NS_WARN_IF(NS_FAILED(rv))) { mStartOfRemovingTextRangeCache.Clear(); @@ -1018,7 +1018,7 @@ bool IMEContentObserver::IsNextNodeOfLastAddedNode(nsINode* aParent, nsIContent* aChild) const { MOZ_ASSERT(aParent); MOZ_ASSERT(aChild && aChild->GetParentNode() == aParent); - MOZ_ASSERT(mRootContent); + MOZ_ASSERT(mRootElement); MOZ_ASSERT(HasAddedNodesDuringDocumentChange()); // If the parent node isn't changed, we can check that mLastAddedContent has @@ -1047,7 +1047,7 @@ bool IMEContentObserver::IsNextNodeOfLastAddedNode(nsINode* aParent, // Otherwise, we need to check it even with slow path. nsIContent* nextContentOfLastAddedContent = - mLastAddedContent->GetNextNode(mRootContent->GetParentNode()); + mLastAddedContent->GetNextNode(mRootElement->GetParentNode()); if (NS_WARN_IF(!nextContentOfLastAddedContent)) { return false; } @@ -1074,10 +1074,10 @@ void IMEContentObserver::MaybeNotifyIMEOfAddedTextDuringDocumentChange() { // editor. uint32_t offset; nsresult rv = ContentEventHandler::GetFlatTextLengthInRange( - NodePosition(mRootContent, 0u), + NodePosition(mRootElement, 0u), NodePosition(mFirstAddedContainer, PointBefore(mFirstAddedContainer, mFirstAddedContent)), - mRootContent, &offset, LINE_BREAK_TYPE_NATIVE); + mRootElement, &offset, LINE_BREAK_TYPE_NATIVE); if (NS_WARN_IF(NS_FAILED(rv))) { ClearAddedNodesDuringDocumentChange(); return; @@ -1088,7 +1088,7 @@ void IMEContentObserver::MaybeNotifyIMEOfAddedTextDuringDocumentChange() { rv = ContentEventHandler::GetFlatTextLengthInRange( NodePosition(mFirstAddedContainer, PointBefore(mFirstAddedContainer, mFirstAddedContent)), - NodePosition(mLastAddedContainer, mLastAddedContent), mRootContent, + NodePosition(mLastAddedContainer, mLastAddedContent), mRootElement, &length, LINE_BREAK_TYPE_NATIVE); if (NS_WARN_IF(NS_FAILED(rv))) { ClearAddedNodesDuringDocumentChange(); @@ -1289,7 +1289,7 @@ bool IMEContentObserver::UpdateSelectionCache(bool aRequireFlush /* = true */) { handler.OnQuerySelectedText(&querySelectedTextEvent); if (NS_WARN_IF(querySelectedTextEvent.Failed()) || NS_WARN_IF(querySelectedTextEvent.mReply->mContentsRoot != - mRootContent)) { + mRootElement)) { return false; } diff --git a/dom/events/IMEContentObserver.h b/dom/events/IMEContentObserver.h index cd7fd234a3ed..faa4ea9bcf87 100644 --- a/dom/events/IMEContentObserver.h +++ b/dom/events/IMEContentObserver.h @@ -9,6 +9,7 @@ #include "mozilla/Attributes.h" #include "mozilla/EditorBase.h" +#include "mozilla/dom/Element.h" #include "mozilla/dom/Selection.h" #include "nsCOMPtr.h" #include "nsCycleCollectionParticipant.h" @@ -67,8 +68,8 @@ class IMEContentObserver final : public nsStubMutationObserver, */ void OnSelectionChange(dom::Selection& aSelection); - MOZ_CAN_RUN_SCRIPT bool OnMouseButtonEvent(nsPresContext* aPresContext, - WidgetMouseEvent* aMouseEvent); + MOZ_CAN_RUN_SCRIPT bool OnMouseButtonEvent(nsPresContext& aPresContext, + WidgetMouseEvent& aMouseEvent); MOZ_CAN_RUN_SCRIPT nsresult HandleQueryContentEvent(WidgetQueryContentEvent* aEvent); @@ -81,12 +82,12 @@ class IMEContentObserver final : public nsStubMutationObserver, * * @param aWidget The widget which can access native IME. * @param aPresContext The PresContext which has aContent. - * @param aContent An editable element or nullptr if this will observe + * @param aElement An editable element or nullptr if this will observe * design mode document. * @param aEditorBase The editor which is associated with aContent. */ MOZ_CAN_RUN_SCRIPT void Init(nsIWidget& aWidget, nsPresContext& aPresContext, - nsIContent* aContent, EditorBase& aEditorBase); + dom::Element* aElement, EditorBase& aEditorBase); /** * Destroy() finalizes the instance, i.e., stops observing contents and @@ -121,13 +122,14 @@ class IMEContentObserver final : public nsStubMutationObserver, */ MOZ_CAN_RUN_SCRIPT bool MaybeReinitialize(nsIWidget& aWidget, nsPresContext& aPresContext, - nsIContent* aContent, + dom::Element* aElement, EditorBase& aEditorBase); - bool IsManaging(nsPresContext* aPresContext, nsIContent* aContent) const; - bool IsBeingInitializedFor(nsPresContext* aPresContext, - nsIContent* aContent) const; - bool IsManaging(const TextComposition* aTextComposition) const; + bool IsManaging(const nsPresContext& aPresContext, + const dom::Element* aElement) const; + bool IsBeingInitializedFor(const nsPresContext& aPresContext, + const dom::Element* aElement) const; + bool IsManaging(const TextComposition& aTextComposition) const; bool WasInitializedWith(const EditorBase& aEditorBase) const { return mEditorBase == &aEditorBase; } @@ -141,7 +143,7 @@ class IMEContentObserver final : public nsStubMutationObserver, void UnsuppressNotifyingIME(); nsPresContext* GetPresContext() const; nsresult GetSelectionAndRoot(dom::Selection** aSelection, - nsIContent** aRoot) const; + dom::Element** aRootElement) const; /** * TryToFlushPendingNotifications() should be called when pending events @@ -167,8 +169,8 @@ class IMEContentObserver final : public nsStubMutationObserver, void BeforeEditAction(); void CancelEditAction(); - nsIContent* GetObservingContent() const { - return mIsObserving ? mRootContent.get() : nullptr; + dom::Element* GetObservingElement() const { + return mIsObserving ? mRootElement.get() : nullptr; } private: @@ -182,15 +184,15 @@ class IMEContentObserver final : public nsStubMutationObserver, }; State GetState() const; MOZ_CAN_RUN_SCRIPT bool InitWithEditor(nsPresContext& aPresContext, - nsIContent* aContent, + dom::Element* aElement, EditorBase& aEditorBase); void OnIMEReceivedFocus(); void Clear(); - bool IsObservingContent(nsPresContext* aPresContext, - nsIContent* aContent) const; - bool IsReflowLocked() const; - bool IsSafeToNotifyIME() const; - bool IsEditorComposing() const; + [[nodiscard]] bool IsObservingContent(const nsPresContext& aPresContext, + const dom::Element* aElement) const; + [[nodiscard]] bool IsReflowLocked() const; + [[nodiscard]] bool IsSafeToNotifyIME() const; + [[nodiscard]] bool IsEditorComposing() const; // Following methods are called by DocumentObserver when // beginning to update the contents and ending updating the contents. @@ -299,7 +301,7 @@ class IMEContentObserver final : public nsStubMutationObserver, // On the other hand, mWidget is its parent which handles IME. nsCOMPtr mFocusedWidget; RefPtr mSelection; - nsCOMPtr mRootContent; + RefPtr mRootElement; nsCOMPtr mEditableNode; nsCOMPtr mDocShell; RefPtr mEditorBase; diff --git a/dom/events/IMEStateManager.cpp b/dom/events/IMEStateManager.cpp index ffe417ea2ea1..a3d70ae2e5d9 100644 --- a/dom/events/IMEStateManager.cpp +++ b/dom/events/IMEStateManager.cpp @@ -4,9 +4,9 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include "mozilla/Logging.h" +#include "IMEStateManager.h" -#include "mozilla/IMEStateManager.h" +#include "mozilla/Logging.h" #include "mozilla/Attributes.h" #include "mozilla/AutoRestore.h" @@ -550,7 +550,7 @@ nsresult IMEStateManager::OnChangeFocusInternal(nsPresContext* aPresContext, // Otherwise, i.e., new focused content is in this process, let's check // whether the new focused content is already being managed by the // active IME content observer. - else if (!sActiveIMEContentObserver->IsManaging(aPresContext, aElement)) { + else if (!sActiveIMEContentObserver->IsManaging(*aPresContext, aElement)) { DestroyIMEContentObserver(); } } @@ -733,7 +733,7 @@ bool IMEStateManager::OnMouseButtonEventInEditor( return false; } - if (!sActiveIMEContentObserver->IsManaging(&aPresContext, aElement)) { + if (!sActiveIMEContentObserver->IsManaging(aPresContext, aElement)) { MOZ_LOG(sISMLog, LogLevel::Debug, (" OnMouseButtonEventInEditor(), " "the active IMEContentObserver isn't managing the editor")); @@ -741,7 +741,7 @@ bool IMEStateManager::OnMouseButtonEventInEditor( } OwningNonNull observer = *sActiveIMEContentObserver; - bool consumed = observer->OnMouseButtonEvent(&aPresContext, &aMouseEvent); + bool consumed = observer->OnMouseButtonEvent(aPresContext, aMouseEvent); MOZ_LOG(sISMLog, LogLevel::Info, (" OnMouseButtonEventInEditor(), " "mouse event (mMessage=%s, mButton=%d) is %s", @@ -877,7 +877,7 @@ void IMEStateManager::OnFocusInEditor(nsPresContext& aPresContext, // If the IMEContentObserver instance isn't managing the editor actually, // we need to recreate the instance. if (sActiveIMEContentObserver) { - if (sActiveIMEContentObserver->IsManaging(&aPresContext, aElement)) { + if (sActiveIMEContentObserver->IsManaging(aPresContext, aElement)) { MOZ_LOG( sISMLog, LogLevel::Debug, (" OnFocusInEditor(), " @@ -887,7 +887,7 @@ void IMEStateManager::OnFocusInEditor(nsPresContext& aPresContext, // If the IMEContentObserver has not finished initializing itself yet, // we don't need to recreate it because the following // TryToFlushPendingNotifications call must make it initialized. - if (!sActiveIMEContentObserver->IsBeingInitializedFor(&aPresContext, + if (!sActiveIMEContentObserver->IsBeingInitializedFor(aPresContext, aElement)) { DestroyIMEContentObserver(); } @@ -953,7 +953,7 @@ void IMEStateManager::OnReFocus(nsPresContext& aPresContext, } if (!sActiveIMEContentObserver || - !sActiveIMEContentObserver->IsManaging(&aPresContext, &aElement)) { + !sActiveIMEContentObserver->IsManaging(aPresContext, &aElement)) { MOZ_LOG(sISMLog, LogLevel::Debug, (" OnReFocus(), there is no valid IMEContentObserver, so we don't " "manage this. Ignore this")); @@ -1104,7 +1104,7 @@ void IMEStateManager::UpdateIMEState(const IMEState& aNewIMEState, // editor correctly, we should recreate it. const bool createTextStateManager = (!sActiveIMEContentObserver || - !sActiveIMEContentObserver->IsManaging(sFocusedPresContext, aElement)); + !sActiveIMEContentObserver->IsManaging(*sFocusedPresContext, aElement)); const bool updateIMEState = aOptions.contains(UpdateIMEStateOption::ForceUpdate) || @@ -2003,39 +2003,37 @@ bool IMEStateManager::IsEditable(nsINode* node) { } // static -nsINode* IMEStateManager::GetRootEditableNode(const nsPresContext* aPresContext, - const nsIContent* aContent) { - if (aContent) { +nsINode* IMEStateManager::GetRootEditableNode(const nsPresContext& aPresContext, + const Element* aElement) { + if (aElement) { // If the focused content is in design mode, return is composed document - // because aContent may be in UA widget shadow tree. - if (aContent->IsInDesignMode()) { - return aContent->GetComposedDoc(); + // because aElement may be in UA widget shadow tree. + if (aElement->IsInDesignMode()) { + return aElement->GetComposedDoc(); } - nsINode* root = nullptr; - nsINode* node = const_cast(aContent); - while (node && IsEditable(node)) { + nsINode* candidateRootNode = const_cast(aElement); + for (nsINode* node = candidateRootNode; node && IsEditable(node); + node = node->GetParentNode()) { // If the node has independent selection like or - //