зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1167022 part.1 Make IMEContentObserver possible to restart to observe editor root node r=smaug
This commit is contained in:
Родитель
9acae632d9
Коммит
2af6616c71
|
@ -43,7 +43,8 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(IMEContentObserver)
|
|||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(IMEContentObserver)
|
||||
nsAutoScriptBlocker scriptBlocker;
|
||||
|
||||
tmp->UnregisterObservers(true);
|
||||
tmp->NotifyIMEOfBlur(true);
|
||||
tmp->UnregisterObservers();
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mWidget)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mSelection)
|
||||
|
@ -104,11 +105,26 @@ IMEContentObserver::Init(nsIWidget* aWidget,
|
|||
{
|
||||
MOZ_ASSERT(aEditor, "aEditor must not be null");
|
||||
|
||||
bool firstInitialization =
|
||||
!(mRootContent && !mRootContent->IsInComposedDoc());
|
||||
if (!firstInitialization) {
|
||||
// If this is now trying to initialize with new contents, all observers
|
||||
// should be registered again for simpler implementation.
|
||||
UnregisterObservers();
|
||||
// Clear members which may not be initialized again.
|
||||
mRootContent = nullptr;
|
||||
mEditor = nullptr;
|
||||
mSelection = nullptr;
|
||||
mDocShell = nullptr;
|
||||
}
|
||||
|
||||
mESM = aPresContext->EventStateManager();
|
||||
mESM->OnStartToObserveContent(this);
|
||||
|
||||
mWidget = aWidget;
|
||||
mEditableNode = IMEStateManager::GetRootEditableNode(aPresContext, aContent);
|
||||
|
||||
mEditableNode =
|
||||
IMEStateManager::GetRootEditableNode(aPresContext, aContent);
|
||||
if (!mEditableNode) {
|
||||
return;
|
||||
}
|
||||
|
@ -154,19 +170,21 @@ IMEContentObserver::Init(nsIWidget* aWidget,
|
|||
}
|
||||
NS_ENSURE_TRUE_VOID(mRootContent);
|
||||
|
||||
if (IMEStateManager::IsTestingIME()) {
|
||||
nsIDocument* doc = aPresContext->Document();
|
||||
(new AsyncEventDispatcher(doc, NS_LITERAL_STRING("MozIMEFocusIn"),
|
||||
false, false))->RunDOMEventWhenSafe();
|
||||
}
|
||||
if (firstInitialization) {
|
||||
if (IMEStateManager::IsTestingIME()) {
|
||||
nsIDocument* doc = aPresContext->Document();
|
||||
(new AsyncEventDispatcher(doc, NS_LITERAL_STRING("MozIMEFocusIn"),
|
||||
false, false))->RunDOMEventWhenSafe();
|
||||
}
|
||||
|
||||
aWidget->NotifyIME(IMENotification(NOTIFY_IME_OF_FOCUS));
|
||||
aWidget->NotifyIME(IMENotification(NOTIFY_IME_OF_FOCUS));
|
||||
|
||||
// NOTIFY_IME_OF_FOCUS might cause recreating IMEContentObserver
|
||||
// instance via IMEStateManager::UpdateIMEState(). So, this
|
||||
// instance might already have been destroyed, check it.
|
||||
if (!mRootContent) {
|
||||
return;
|
||||
// NOTIFY_IME_OF_FOCUS might cause recreating IMEContentObserver
|
||||
// instance via IMEStateManager::UpdateIMEState(). So, this
|
||||
// instance might already have been destroyed, check it.
|
||||
if (!mRootContent) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
mDocShell = aPresContext->GetDocShell();
|
||||
|
@ -203,34 +221,40 @@ IMEContentObserver::ObserveEditableNode()
|
|||
}
|
||||
|
||||
void
|
||||
IMEContentObserver::UnregisterObservers(bool aPostEvent)
|
||||
IMEContentObserver::NotifyIMEOfBlur(bool aPostEvent)
|
||||
{
|
||||
// If this failed to initialize, mRootContent may be null, then, we
|
||||
// should not call NotifyIME(IMENotification(NOTIFY_IME_OF_BLUR))
|
||||
if (!mRootContent || !mWidget) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (IMEStateManager::IsTestingIME() && mEditableNode) {
|
||||
nsIDocument* doc = mEditableNode->OwnerDoc();
|
||||
if (doc) {
|
||||
nsRefPtr<AsyncEventDispatcher> dispatcher =
|
||||
new AsyncEventDispatcher(doc, NS_LITERAL_STRING("MozIMEFocusOut"),
|
||||
false, false);
|
||||
if (aPostEvent) {
|
||||
dispatcher->PostDOMEvent();
|
||||
} else {
|
||||
dispatcher->RunDOMEventWhenSafe();
|
||||
}
|
||||
}
|
||||
}
|
||||
// A test event handler might destroy the widget.
|
||||
if (mWidget) {
|
||||
mWidget->NotifyIME(IMENotification(NOTIFY_IME_OF_BLUR));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
IMEContentObserver::UnregisterObservers()
|
||||
{
|
||||
if (mEditor) {
|
||||
mEditor->RemoveEditorObserver(this);
|
||||
}
|
||||
|
||||
// If CreateTextStateManager failed, mRootContent will be null, then, we
|
||||
// should not call NotifyIME(IMENotification(NOTIFY_IME_OF_BLUR))
|
||||
if (mRootContent && mWidget) {
|
||||
if (IMEStateManager::IsTestingIME() && mEditableNode) {
|
||||
nsIDocument* doc = mEditableNode->OwnerDoc();
|
||||
if (doc) {
|
||||
nsRefPtr<AsyncEventDispatcher> dispatcher =
|
||||
new AsyncEventDispatcher(doc, NS_LITERAL_STRING("MozIMEFocusOut"),
|
||||
false, false);
|
||||
if (aPostEvent) {
|
||||
dispatcher->PostDOMEvent();
|
||||
} else {
|
||||
dispatcher->RunDOMEventWhenSafe();
|
||||
}
|
||||
}
|
||||
}
|
||||
// A test event handler might destroy the widget.
|
||||
if (mWidget) {
|
||||
mWidget->NotifyIME(IMENotification(NOTIFY_IME_OF_BLUR));
|
||||
}
|
||||
}
|
||||
|
||||
if (mUpdatePreference.WantSelectionChange() && mSelection) {
|
||||
nsCOMPtr<nsISelectionPrivate> selPrivate(do_QueryInterface(mSelection));
|
||||
if (selPrivate) {
|
||||
|
@ -259,7 +283,8 @@ IMEContentObserver::Destroy()
|
|||
{
|
||||
// WARNING: When you change this method, you have to check Unlink() too.
|
||||
|
||||
UnregisterObservers(false);
|
||||
NotifyIMEOfBlur(false);
|
||||
UnregisterObservers();
|
||||
|
||||
mEditor = nullptr;
|
||||
// Even if there are some pending notification, it'll never notify the widget.
|
||||
|
|
|
@ -140,11 +140,15 @@ private:
|
|||
void NotifyContentAdded(nsINode* aContainer, int32_t aStart, int32_t aEnd);
|
||||
void ObserveEditableNode();
|
||||
/**
|
||||
* UnregisterObservers() unresiters all listeners and observers.
|
||||
* NotifyIMEOfBlur() notifies IME of blur.
|
||||
* @param aPostEvent When true, DOM event will be posted to the thread.
|
||||
* Otherwise, dispatched when safe.
|
||||
*/
|
||||
void UnregisterObservers(bool aPostEvent);
|
||||
void NotifyIMEOfBlur(bool aPostEvent);
|
||||
/**
|
||||
* UnregisterObservers() unregisters all listeners and observers.
|
||||
*/
|
||||
void UnregisterObservers();
|
||||
void StoreTextChangeData(const TextChangeData& aTextChangeData);
|
||||
void FlushMergeableNotifications();
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче