void TextComposition::NotityUpdateComposition( const WidgetCompositionEvent* aCompositionEvent) { MOZ_RELEASE_ASSERT(!mTabParent); nsEventStatus status; // When compositon start, notify the rect of first offset character. // When not compositon start, notify the rect of selected composition // string if compositionchange event. if (aCompositionEvent->mMessage == eCompositionStart) { nsCOMPtr<nsIWidget> widget = mPresContext->GetRootWidget(); // Update composition start offset WidgetQueryContentEvent selectedTextEvent(true, eQuerySelectedText, widget); widget->DispatchEvent(&selectedTextEvent, status); if (selectedTextEvent.mSucceeded) { mCompositionStartOffset = selectedTextEvent.mReply.mOffset; } else { // Unknown offset NS_WARNING("Cannot get start offset of IME composition"); mCompositionStartOffset = 0; } mCompositionTargetOffset = mCompositionStartOffset; } else if (aCompositionEvent->CausesDOMTextEvent()) { mCompositionTargetOffset = mCompositionStartOffset + aCompositionEvent->TargetClauseOffset(); } else { return; } NotifyIME(NOTIFY_IME_OF_COMPOSITION_UPDATE); }
void TextComposition::NotityUpdateComposition(WidgetGUIEvent* aEvent) { nsEventStatus status; // When compositon start, notify the rect of first offset character. // When not compositon start, notify the rect of selected composition // string if text event. if (aEvent->message == NS_COMPOSITION_START) { nsCOMPtr<nsIWidget> widget = mPresContext->GetRootWidget(); // Update composition start offset WidgetQueryContentEvent selectedTextEvent(true, NS_QUERY_SELECTED_TEXT, widget); widget->DispatchEvent(&selectedTextEvent, status); if (selectedTextEvent.mSucceeded) { mCompositionStartOffset = selectedTextEvent.mReply.mOffset; } else { // Unknown offset NS_WARNING("Cannot get start offset of IME composition"); mCompositionStartOffset = 0; } mCompositionTargetOffset = mCompositionStartOffset; } else if (aEvent->mClass != eTextEventClass) { return; } else { mCompositionTargetOffset = mCompositionStartOffset + aEvent->AsTextEvent()->TargetClauseOffset(); } NotifyIME(NOTIFY_IME_OF_COMPOSITION_UPDATE); }
uint32_t TextComposition::GetSelectionStartOffset() { nsCOMPtr<nsIWidget> widget = mPresContext->GetRootWidget(); WidgetQueryContentEvent selectedTextEvent(true, eQuerySelectedText, widget); // Due to a bug of widget, mRanges may not be nullptr even though composition // string is empty. So, we need to check it here for avoiding to return // odd start offset. if (!mLastData.IsEmpty() && mRanges && mRanges->HasClauses()) { selectedTextEvent.InitForQuerySelectedText( ToSelectionType(mRanges->GetFirstClause()->mRangeType)); } else { NS_WARNING_ASSERTION( !mLastData.IsEmpty() || !mRanges || !mRanges->HasClauses(), "Shouldn't have empty clause info when composition string is empty"); selectedTextEvent.InitForQuerySelectedText(SelectionType::eNormal); } // The editor which has this composition is observed by active // IMEContentObserver, we can use the cache of it. RefPtr<IMEContentObserver> contentObserver = IMEStateManager::GetActiveContentObserver(); bool doQuerySelection = true; if (contentObserver) { if (contentObserver->IsManaging(this)) { doQuerySelection = false; contentObserver->HandleQueryContentEvent(&selectedTextEvent); } // If another editor already has focus, we cannot retrieve selection // in the editor which has this composition... else if (NS_WARN_IF(contentObserver->GetPresContext() == mPresContext)) { return 0; // XXX Is this okay? } } // Otherwise, using slow path (i.e., compute every time with // ContentEventHandler) if (doQuerySelection) { ContentEventHandler handler(mPresContext); handler.HandleQueryContentEvent(&selectedTextEvent); } if (NS_WARN_IF(!selectedTextEvent.mSucceeded)) { return 0; // XXX Is this okay? } return selectedTextEvent.mReply.mOffset; }
void TextComposition::NotityUpdateComposition(WidgetGUIEvent* aEvent) { nsEventStatus status; // When compositon start, notify the rect of first offset character. // When not compositon start, notify the rect of selected composition // string if text event. if (aEvent->message == NS_COMPOSITION_START) { nsCOMPtr<nsIWidget> widget = mPresContext->GetRootWidget(); // Update composition start offset WidgetQueryContentEvent selectedTextEvent(true, NS_QUERY_SELECTED_TEXT, widget); widget->DispatchEvent(&selectedTextEvent, status); if (selectedTextEvent.mSucceeded) { mCompositionStartOffset = selectedTextEvent.mReply.mOffset; } else { // Unknown offset NS_WARNING("Cannot get start offset of IME composition"); mCompositionStartOffset = 0; } mCompositionTargetOffset = mCompositionStartOffset; } else if (aEvent->eventStructType != NS_TEXT_EVENT) { return; } else { WidgetTextEvent* textEvent = aEvent->AsTextEvent(); mCompositionTargetOffset = mCompositionStartOffset; for (uint32_t i = 0; i < textEvent->rangeCount; i++) { TextRange& range = textEvent->rangeArray[i]; if (range.mRangeType == NS_TEXTRANGE_SELECTEDRAWTEXT || range.mRangeType == NS_TEXTRANGE_SELECTEDCONVERTEDTEXT) { mCompositionTargetOffset += range.mStartOffset; break; } } } NotifyIME(widget::NotificationToIME::NOTIFY_IME_OF_COMPOSITION_UPDATE); }