Bug 808287 - Make sure focus and blur IME notifications always match; r=masayuki

This commit is contained in:
Jim Chen 2012-11-16 11:43:04 -05:00
parent f5eeb4dca0
commit dcfc90091c

View File

@ -51,9 +51,10 @@ class nsTextStateManager MOZ_FINAL : public nsISelectionListener,
public nsStubMutationObserver
{
public:
nsTextStateManager(nsIWidget* aWidget,
nsPresContext* aPresContext,
nsIContent* aContent);
nsTextStateManager()
: mObserving(false)
{
}
NS_DECL_ISUPPORTS
NS_DECL_NSISELECTIONLISTENER
@ -62,6 +63,9 @@ public:
NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED
NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED
void Init(nsIWidget* aWidget,
nsPresContext* aPresContext,
nsIContent* aContent);
void Destroy(void);
bool IsManaging(nsPresContext* aPresContext, nsIContent* aContent);
@ -684,11 +688,12 @@ nsIMEStateManager::NotifyIME(NotificationToIME aNotification,
return NotifyIME(aNotification, widget);
}
nsTextStateManager::nsTextStateManager(nsIWidget* aWidget,
nsPresContext* aPresContext,
nsIContent* aContent) :
mWidget(aWidget), mObserving(false)
void
nsTextStateManager::Init(nsIWidget* aWidget,
nsPresContext* aPresContext,
nsIContent* aContent)
{
mWidget = aWidget;
mEditableNode =
nsIMEStateManager::GetRootEditableNode(aPresContext, aContent);
if (!mEditableNode) {
@ -739,7 +744,14 @@ nsTextStateManager::nsTextStateManager(nsIWidget* aWidget,
false, false))->RunDOMEventWhenSafe();
}
mWidget->OnIMEFocusChange(true);
aWidget->OnIMEFocusChange(true);
// OnIMEFocusChange(true) might cause recreating nsTextStateManager
// instance via nsIMEStateManager::UpdateIMEState(). So, this
// instance might already have been destroyed, check it.
if (!mRootContent) {
return;
}
if (mWidget->GetIMEUpdatePreference().mWantUpdates) {
ObserveEditableNode();
@ -769,12 +781,16 @@ nsTextStateManager::ObserveEditableNode()
void
nsTextStateManager::Destroy(void)
{
if (nsIMEStateManager::sIsTestingIME && mEditableNode) {
nsIDocument* doc = mEditableNode->OwnerDoc();
(new nsAsyncDOMEvent(doc, NS_LITERAL_STRING("MozIMEFocusOut"),
false, false))->RunDOMEventWhenSafe();
// If CreateTextStateManager failed, mRootContent will be null,
// and we should not call OnIMEFocusChange(false)
if (mRootContent) {
if (nsIMEStateManager::sIsTestingIME && mEditableNode) {
nsIDocument* doc = mEditableNode->OwnerDoc();
(new nsAsyncDOMEvent(doc, NS_LITERAL_STRING("MozIMEFocusOut"),
false, false))->RunDOMEventWhenSafe();
}
mWidget->OnIMEFocusChange(false);
}
mWidget->OnIMEFocusChange(false);
// Even if there are some pending notification, it'll never notify the widget.
mWidget = nullptr;
if (mObserving && mSel) {
@ -1047,8 +1063,14 @@ nsIMEStateManager::CreateTextStateManager()
sInitializeIsTestingIME = false;
}
sTextStateObserver = new nsTextStateManager(widget, sPresContext, sContent);
sTextStateObserver = new nsTextStateManager();
NS_ADDREF(sTextStateObserver);
// nsTextStateManager::Init() might create another nsTextStateManager
// instance. So, sTextStateObserver would be replaced with new one.
// We should hold the current instance here.
nsRefPtr<nsTextStateManager> kungFuDeathGrip(sTextStateObserver);
sTextStateObserver->Init(widget, sPresContext, sContent);
}
nsresult