зеркало из https://github.com/mozilla/gecko-dev.git
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
This commit is contained in:
Родитель
f93d054430
Коммит
6440fbddc3
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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<Selection> sel;
|
||||
nsresult rv = IMEStateManager::GetFocusSelectionAndRoot(
|
||||
getter_AddRefs(sel), getter_AddRefs(mRootContent));
|
||||
RefPtr<Element> 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 {
|
||||
|
|
|
@ -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<nsINode> startContainer = selRange->GetStartContainer();
|
||||
mRootContent = startContainer->GetSelectionRootContent(presShell);
|
||||
mRootElement = Element::FromNodeOrNull(
|
||||
startContainer->GetSelectionRootContent(presShell));
|
||||
} else {
|
||||
nsCOMPtr<nsINode> 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> 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 <div> 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<IMEContentObserver> 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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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<nsIWidget> mFocusedWidget;
|
||||
RefPtr<dom::Selection> mSelection;
|
||||
nsCOMPtr<nsIContent> mRootContent;
|
||||
RefPtr<dom::Element> mRootElement;
|
||||
nsCOMPtr<nsINode> mEditableNode;
|
||||
nsCOMPtr<nsIDocShell> mDocShell;
|
||||
RefPtr<EditorBase> mEditorBase;
|
||||
|
|
|
@ -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<IMEContentObserver> 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<nsIContent*>(aContent);
|
||||
while (node && IsEditable(node)) {
|
||||
nsINode* candidateRootNode = const_cast<Element*>(aElement);
|
||||
for (nsINode* node = candidateRootNode; node && IsEditable(node);
|
||||
node = node->GetParentNode()) {
|
||||
// If the node has independent selection like <input type="text"> or
|
||||
// <textarea>, the node should be the root editable node for aContent.
|
||||
// <textarea>, the node should be the root editable node for aElement.
|
||||
// FYI: <select> element also has independent selection but IsEditable()
|
||||
// returns false.
|
||||
// XXX: If somebody adds new editable element which has independent
|
||||
// selection but doesn't own editor, we'll need more checks here.
|
||||
// XXX: If aContent is not in native anonymous subtree, checking
|
||||
// XXX: If aElement is not in native anonymous subtree, checking
|
||||
// independent selection must be wrong, see bug 1731005.
|
||||
if (node->IsContent() && node->AsContent()->HasIndependentSelection()) {
|
||||
return node;
|
||||
}
|
||||
root = node;
|
||||
node = node->GetParentNode();
|
||||
candidateRootNode = node;
|
||||
}
|
||||
return root;
|
||||
return candidateRootNode;
|
||||
}
|
||||
if (aPresContext && aPresContext->Document() &&
|
||||
aPresContext->Document()->IsInDesignMode()) {
|
||||
return aPresContext->Document();
|
||||
}
|
||||
return nullptr;
|
||||
|
||||
return aPresContext.Document() && aPresContext.Document()->IsInDesignMode()
|
||||
? aPresContext.Document()
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
// static
|
||||
|
@ -2078,16 +2076,16 @@ void IMEStateManager::CreateIMEContentObserver(EditorBase& aEditorBase,
|
|||
GetBoolName(sTextInputHandlingWidget &&
|
||||
!sTextInputHandlingWidget->Destroyed()),
|
||||
sActiveIMEContentObserver.get(),
|
||||
GetBoolName(sActiveIMEContentObserver
|
||||
? sActiveIMEContentObserver->IsManaging(
|
||||
sFocusedPresContext, sFocusedElement)
|
||||
: false)));
|
||||
GetBoolName(sActiveIMEContentObserver && sFocusedPresContext &&
|
||||
sActiveIMEContentObserver->IsManaging(
|
||||
*sFocusedPresContext, sFocusedElement))));
|
||||
|
||||
if (NS_WARN_IF(sActiveIMEContentObserver)) {
|
||||
MOZ_LOG(sISMLog, LogLevel::Error,
|
||||
(" CreateIMEContentObserver(), FAILED due to "
|
||||
"there is already an active IMEContentObserver"));
|
||||
MOZ_ASSERT(sActiveIMEContentObserver->IsManaging(sFocusedPresContext,
|
||||
MOZ_ASSERT(sFocusedPresContext);
|
||||
MOZ_ASSERT(sActiveIMEContentObserver->IsManaging(*sFocusedPresContext,
|
||||
sFocusedElement));
|
||||
return;
|
||||
}
|
||||
|
@ -2151,13 +2149,13 @@ void IMEStateManager::CreateIMEContentObserver(EditorBase& aEditorBase,
|
|||
}
|
||||
|
||||
// static
|
||||
nsresult IMEStateManager::GetFocusSelectionAndRoot(Selection** aSelection,
|
||||
nsIContent** aRootContent) {
|
||||
nsresult IMEStateManager::GetFocusSelectionAndRootElement(
|
||||
Selection** aSelection, Element** aRootElement) {
|
||||
if (!sActiveIMEContentObserver) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
return sActiveIMEContentObserver->GetSelectionAndRoot(aSelection,
|
||||
aRootContent);
|
||||
aRootElement);
|
||||
}
|
||||
|
||||
// static
|
||||
|
|
|
@ -182,8 +182,8 @@ class IMEStateManager {
|
|||
// control compared to having the two methods incorporated into OnChangeFocus
|
||||
|
||||
// Get the focused editor's selection and root
|
||||
static nsresult GetFocusSelectionAndRoot(dom::Selection** aSel,
|
||||
nsIContent** aRoot);
|
||||
static nsresult GetFocusSelectionAndRootElement(dom::Selection** aSel,
|
||||
dom::Element** aRootElement);
|
||||
// This method updates the current IME state. However, if the enabled state
|
||||
// isn't changed by the new state, this method does nothing.
|
||||
// Note that this method changes the IME state of the active element in the
|
||||
|
@ -296,8 +296,8 @@ class IMEStateManager {
|
|||
static nsresult NotifyIME(IMEMessage aMessage, nsPresContext* aPresContext,
|
||||
BrowserParent* aBrowserParent = nullptr);
|
||||
|
||||
static nsINode* GetRootEditableNode(const nsPresContext* aPresContext,
|
||||
const nsIContent* aContent);
|
||||
static nsINode* GetRootEditableNode(const nsPresContext& aPresContext,
|
||||
const dom::Element* aElement);
|
||||
|
||||
/**
|
||||
* Returns active IMEContentObserver but may be nullptr if focused content
|
||||
|
|
|
@ -545,7 +545,7 @@ uint32_t TextComposition::GetSelectionStartOffset() {
|
|||
IMEStateManager::GetActiveContentObserver();
|
||||
bool doQuerySelection = true;
|
||||
if (contentObserver) {
|
||||
if (contentObserver->IsManaging(this)) {
|
||||
if (contentObserver->IsManaging(*this)) {
|
||||
doQuerySelection = false;
|
||||
contentObserver->HandleQueryContentEvent(&querySelectedTextEvent);
|
||||
}
|
||||
|
@ -621,7 +621,7 @@ void TextComposition::MaybeNotifyIMEOfCompositionEventHandled(
|
|||
// event handled. Although, this is a bug but it should be okay since
|
||||
// destroying IMEContentObserver notifies IME of blur. So, native IME
|
||||
// handler can treat it as this notification too.
|
||||
if (contentObserver && contentObserver->IsManaging(this)) {
|
||||
if (contentObserver && contentObserver->IsManaging(*this)) {
|
||||
contentObserver->MaybeNotifyCompositionEventHandled();
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -739,19 +739,23 @@ nsresult nsGenericHTMLElement::AfterSetAttr(
|
|||
StaticPrefs::dom_forms_enterkeyhint())) {
|
||||
nsPIDOMWindowOuter* window = OwnerDoc()->GetWindow();
|
||||
if (window && window->GetFocusedElement() == this) {
|
||||
IMEContentObserver* observer =
|
||||
IMEStateManager::GetActiveContentObserver();
|
||||
nsPresContext* presContext = GetPresContext(eForComposedDoc);
|
||||
if (observer && observer->IsManaging(presContext, this)) {
|
||||
if (RefPtr<EditorBase> editor =
|
||||
nsContentUtils::GetActiveEditor(window)) {
|
||||
IMEState newState;
|
||||
editor->GetPreferredIMEState(&newState);
|
||||
OwningNonNull<nsGenericHTMLElement> kungFuDeathGrip(*this);
|
||||
IMEStateManager::UpdateIMEState(
|
||||
newState, kungFuDeathGrip, *editor,
|
||||
{IMEStateManager::UpdateIMEStateOption::ForceUpdate,
|
||||
IMEStateManager::UpdateIMEStateOption::DontCommitComposition});
|
||||
if (IMEContentObserver* observer =
|
||||
IMEStateManager::GetActiveContentObserver()) {
|
||||
if (const nsPresContext* presContext =
|
||||
GetPresContext(eForComposedDoc)) {
|
||||
if (observer->IsManaging(*presContext, this)) {
|
||||
if (RefPtr<EditorBase> editor =
|
||||
nsContentUtils::GetActiveEditor(window)) {
|
||||
IMEState newState;
|
||||
editor->GetPreferredIMEState(&newState);
|
||||
OwningNonNull<nsGenericHTMLElement> kungFuDeathGrip(*this);
|
||||
IMEStateManager::UpdateIMEState(
|
||||
newState, kungFuDeathGrip, *editor,
|
||||
{IMEStateManager::UpdateIMEStateOption::ForceUpdate,
|
||||
IMEStateManager::UpdateIMEStateOption::
|
||||
DontCommitComposition});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче