Bug 1047588 IMEContentObserver::Init() should take nsIEditor because nsDocShell sometimes hasn't been initialized and nsContentEditor::GetHTMLEditor() fails r=smaug

This commit is contained in:
Masayuki Nakano 2014-11-05 10:36:37 +09:00
parent 6246edc88e
commit 2e0a02aec5
6 changed files with 34 additions and 43 deletions

View File

@ -28,7 +28,6 @@
#include "nsISelectionController.h" #include "nsISelectionController.h"
#include "nsISelectionPrivate.h" #include "nsISelectionPrivate.h"
#include "nsISupports.h" #include "nsISupports.h"
#include "nsITextControlElement.h"
#include "nsIWidget.h" #include "nsIWidget.h"
#include "nsPresContext.h" #include "nsPresContext.h"
#include "nsThreadUtils.h" #include "nsThreadUtils.h"
@ -99,8 +98,11 @@ IMEContentObserver::IMEContentObserver()
void void
IMEContentObserver::Init(nsIWidget* aWidget, IMEContentObserver::Init(nsIWidget* aWidget,
nsPresContext* aPresContext, nsPresContext* aPresContext,
nsIContent* aContent) nsIContent* aContent,
nsIEditor* aEditor)
{ {
MOZ_ASSERT(aEditor, "aEditor must not be null");
mESM = aPresContext->EventStateManager(); mESM = aPresContext->EventStateManager();
mESM->OnStartToObserveContent(this); mESM->OnStartToObserveContent(this);
@ -110,27 +112,8 @@ IMEContentObserver::Init(nsIWidget* aWidget,
return; return;
} }
nsCOMPtr<nsITextControlElement> textControlElement = mEditor = aEditor;
do_QueryInterface(mEditableNode); mEditor->AddEditorObserver(this);
if (textControlElement) {
// This may fail. For example, <input type="button" contenteditable>
mEditor = textControlElement->GetTextEditor();
if (!mEditor && mEditableNode->IsContent()) {
// The element must be an editing host.
nsIContent* editingHost = mEditableNode->AsContent()->GetEditingHost();
MOZ_ASSERT(editingHost == mEditableNode,
"found editing host should be mEditableNode");
if (editingHost == mEditableNode) {
mEditor = nsContentUtils::GetHTMLEditor(aPresContext);
}
}
} else {
mEditor = nsContentUtils::GetHTMLEditor(aPresContext);
}
MOZ_ASSERT(mEditor, "Failed to get editor");
if (mEditor) {
mEditor->AddEditorObserver(this);
}
nsIPresShell* presShell = aPresContext->PresShell(); nsIPresShell* presShell = aPresContext->PresShell();

View File

@ -64,7 +64,7 @@ public:
WidgetMouseEvent* aMouseEvent); WidgetMouseEvent* aMouseEvent);
void Init(nsIWidget* aWidget, nsPresContext* aPresContext, void Init(nsIWidget* aWidget, nsPresContext* aPresContext,
nsIContent* aContent); nsIContent* aContent, nsIEditor* aEditor);
void Destroy(); void Destroy();
/** /**
* IMEContentObserver is stored by EventStateManager during observing. * IMEContentObserver is stored by EventStateManager during observing.

View File

@ -25,6 +25,7 @@
#include "nsIContent.h" #include "nsIContent.h"
#include "nsIDocument.h" #include "nsIDocument.h"
#include "nsIDOMMouseEvent.h" #include "nsIDOMMouseEvent.h"
#include "nsIEditor.h"
#include "nsIForm.h" #include "nsIForm.h"
#include "nsIFormControl.h" #include "nsIFormControl.h"
#include "nsINode.h" #include "nsINode.h"
@ -559,12 +560,14 @@ IMEStateManager::OnClickInEditor(nsPresContext* aPresContext,
// static // static
void void
IMEStateManager::OnFocusInEditor(nsPresContext* aPresContext, IMEStateManager::OnFocusInEditor(nsPresContext* aPresContext,
nsIContent* aContent) nsIContent* aContent,
nsIEditor* aEditor)
{ {
PR_LOG(sISMLog, PR_LOG_ALWAYS, PR_LOG(sISMLog, PR_LOG_ALWAYS,
("ISM: IMEStateManager::OnFocusInEditor(aPresContext=0x%p, aContent=0x%p), " ("ISM: IMEStateManager::OnFocusInEditor(aPresContext=0x%p, aContent=0x%p, "
"sPresContext=0x%p, sContent=0x%p, sActiveIMEContentObserver=0x%p", "aEditor=0x%p), sPresContext=0x%p, sContent=0x%p, "
aPresContext, aContent, sPresContext, sContent, "sActiveIMEContentObserver=0x%p",
aPresContext, aContent, aEditor, sPresContext, sContent,
sActiveIMEContentObserver)); sActiveIMEContentObserver));
if (sPresContext != aPresContext || sContent != aContent) { if (sPresContext != aPresContext || sContent != aContent) {
@ -586,21 +589,22 @@ IMEStateManager::OnFocusInEditor(nsPresContext* aPresContext,
DestroyIMEContentObserver(); DestroyIMEContentObserver();
} }
CreateIMEContentObserver(); CreateIMEContentObserver(aEditor);
} }
// static // static
void void
IMEStateManager::UpdateIMEState(const IMEState& aNewIMEState, IMEStateManager::UpdateIMEState(const IMEState& aNewIMEState,
nsIContent* aContent) nsIContent* aContent,
nsIEditor* aEditor)
{ {
PR_LOG(sISMLog, PR_LOG_ALWAYS, PR_LOG(sISMLog, PR_LOG_ALWAYS,
("ISM: IMEStateManager::UpdateIMEState(aNewIMEState={ mEnabled=%s, " ("ISM: IMEStateManager::UpdateIMEState(aNewIMEState={ mEnabled=%s, "
"mOpen=%s }, aContent=0x%p), " "mOpen=%s }, aContent=0x%p, aEditor=0x%p), "
"sPresContext=0x%p, sContent=0x%p, sActiveIMEContentObserver=0x%p, " "sPresContext=0x%p, sContent=0x%p, sActiveIMEContentObserver=0x%p, "
"sIsGettingNewIMEState=%s", "sIsGettingNewIMEState=%s",
GetIMEStateEnabledName(aNewIMEState.mEnabled), GetIMEStateEnabledName(aNewIMEState.mEnabled),
GetIMEStateSetOpenName(aNewIMEState.mOpen), aContent, GetIMEStateSetOpenName(aNewIMEState.mOpen), aContent, aEditor,
sPresContext, sContent, sActiveIMEContentObserver, sPresContext, sContent, sActiveIMEContentObserver,
GetBoolName(sIsGettingNewIMEState))); GetBoolName(sIsGettingNewIMEState)));
@ -651,7 +655,7 @@ IMEStateManager::UpdateIMEState(const IMEState& aNewIMEState,
} }
if (createTextStateManager) { if (createTextStateManager) {
CreateIMEContentObserver(); CreateIMEContentObserver(aEditor);
} }
} }
@ -1145,13 +1149,13 @@ IMEStateManager::DestroyIMEContentObserver()
// static // static
void void
IMEStateManager::CreateIMEContentObserver() IMEStateManager::CreateIMEContentObserver(nsIEditor* aEditor)
{ {
PR_LOG(sISMLog, PR_LOG_ALWAYS, PR_LOG(sISMLog, PR_LOG_ALWAYS,
("ISM: IMEStateManager::CreateIMEContentObserver(), " ("ISM: IMEStateManager::CreateIMEContentObserver(aEditor=0x%p), "
"sPresContext=0x%p, sContent=0x%p, sActiveIMEContentObserver=0x%p, " "sPresContext=0x%p, sContent=0x%p, sActiveIMEContentObserver=0x%p, "
"sActiveIMEContentObserver->IsManaging(sPresContext, sContent)=%s", "sActiveIMEContentObserver->IsManaging(sPresContext, sContent)=%s",
sPresContext, sContent, sActiveIMEContentObserver, aEditor, sPresContext, sContent, sActiveIMEContentObserver,
GetBoolName(sActiveIMEContentObserver ? GetBoolName(sActiveIMEContentObserver ?
sActiveIMEContentObserver->IsManaging(sPresContext, sContent) : false))); sActiveIMEContentObserver->IsManaging(sPresContext, sContent) : false)));
@ -1195,7 +1199,7 @@ IMEStateManager::CreateIMEContentObserver()
// instance. So, sActiveIMEContentObserver would be replaced with new one. // instance. So, sActiveIMEContentObserver would be replaced with new one.
// We should hold the current instance here. // We should hold the current instance here.
nsRefPtr<IMEContentObserver> kungFuDeathGrip(sActiveIMEContentObserver); nsRefPtr<IMEContentObserver> kungFuDeathGrip(sActiveIMEContentObserver);
sActiveIMEContentObserver->Init(widget, sPresContext, sContent); sActiveIMEContentObserver->Init(widget, sPresContext, sContent, aEditor);
} }
// static // static

View File

@ -11,6 +11,7 @@
class nsIContent; class nsIContent;
class nsIDOMMouseEvent; class nsIDOMMouseEvent;
class nsIEditor;
class nsINode; class nsINode;
class nsPIDOMWindow; class nsPIDOMWindow;
class nsPresContext; class nsPresContext;
@ -65,7 +66,8 @@ public:
// Note that this method changes the IME state of the active element in the // Note that this method changes the IME state of the active element in the
// widget. So, the caller must have focus. // widget. So, the caller must have focus.
static void UpdateIMEState(const IMEState &aNewIMEState, static void UpdateIMEState(const IMEState &aNewIMEState,
nsIContent* aContent); nsIContent* aContent,
nsIEditor* aEditor);
// This method is called when user operates mouse button in focused editor // This method is called when user operates mouse button in focused editor
// and before the editor handles it. // and before the editor handles it.
@ -89,7 +91,8 @@ public:
// If the editor is for contenteditable, the active editinghost. // If the editor is for contenteditable, the active editinghost.
// If the editor is for designMode, nullptr. // If the editor is for designMode, nullptr.
static void OnFocusInEditor(nsPresContext* aPresContext, static void OnFocusInEditor(nsPresContext* aPresContext,
nsIContent* aContent); nsIContent* aContent,
nsIEditor* aEditor);
/** /**
* All composition events must be dispatched via DispatchCompositionEvent() * All composition events must be dispatched via DispatchCompositionEvent()
@ -149,7 +152,7 @@ protected:
nsIContent* aContent); nsIContent* aContent);
static void EnsureTextCompositionArray(); static void EnsureTextCompositionArray();
static void CreateIMEContentObserver(); static void CreateIMEContentObserver(nsIEditor* aEditor);
static void DestroyIMEContentObserver(); static void DestroyIMEContentObserver();
static bool IsEditable(nsINode* node); static bool IsEditable(nsINode* node);

View File

@ -315,7 +315,7 @@ nsEditor::PostCreate()
rv = GetPreferredIMEState(&newState); rv = GetPreferredIMEState(&newState);
NS_ENSURE_SUCCESS(rv, NS_OK); NS_ENSURE_SUCCESS(rv, NS_OK);
nsCOMPtr<nsIContent> content = GetFocusedContentForIME(); nsCOMPtr<nsIContent> content = GetFocusedContentForIME();
IMEStateManager::UpdateIMEState(newState, content); IMEStateManager::UpdateIMEState(newState, content, this);
} }
return NS_OK; return NS_OK;
} }
@ -496,7 +496,7 @@ nsEditor::SetFlags(uint32_t aFlags)
// NOTE: When the enabled state isn't going to be modified, this method // NOTE: When the enabled state isn't going to be modified, this method
// is going to do nothing. // is going to do nothing.
nsCOMPtr<nsIContent> content = GetFocusedContentForIME(); nsCOMPtr<nsIContent> content = GetFocusedContentForIME();
IMEStateManager::UpdateIMEState(newState, content); IMEStateManager::UpdateIMEState(newState, content, this);
} }
} }

View File

@ -1097,7 +1097,8 @@ nsEditorEventListener::Focus(nsIDOMEvent* aEvent)
nsCOMPtr<nsIPresShell> ps = GetPresShell(); nsCOMPtr<nsIPresShell> ps = GetPresShell();
NS_ENSURE_TRUE(ps, NS_OK); NS_ENSURE_TRUE(ps, NS_OK);
nsCOMPtr<nsIContent> focusedContent = mEditor->GetFocusedContentForIME(); nsCOMPtr<nsIContent> focusedContent = mEditor->GetFocusedContentForIME();
IMEStateManager::OnFocusInEditor(ps->GetPresContext(), focusedContent); IMEStateManager::OnFocusInEditor(ps->GetPresContext(), focusedContent,
mEditor);
return NS_OK; return NS_OK;
} }