Bug 1167022 part.1 Make IMEContentObserver possible to restart to observe editor root node r=smaug

This commit is contained in:
Masayuki Nakano 2015-05-26 16:45:26 +09:00
Родитель 9acae632d9
Коммит 2af6616c71
2 изменённых файлов: 68 добавлений и 39 удалений

Просмотреть файл

@ -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();