Bug 960866 part.1 nsEditor should store a pointer of TextComposition while composition r=ehsan

This commit is contained in:
Masayuki Nakano 2014-02-12 22:02:55 +09:00
parent 034d4328f4
commit 1b410997b5
7 changed files with 85 additions and 35 deletions

View File

@ -1126,9 +1126,23 @@ nsIMEStateManager::GetFocusSelectionAndRoot(nsISelection** aSel,
return NS_OK;
}
TextComposition*
// static
already_AddRefed<TextComposition>
nsIMEStateManager::GetTextCompositionFor(nsIWidget* aWidget)
{
return sTextCompositions ?
sTextCompositions->GetCompositionFor(aWidget) : nullptr;
if (!sTextCompositions) {
return nullptr;
}
nsRefPtr<TextComposition> textComposition =
sTextCompositions->GetCompositionFor(aWidget);
return textComposition.forget();
}
// static
already_AddRefed<TextComposition>
nsIMEStateManager::GetTextCompositionFor(WidgetGUIEvent* aEvent)
{
MOZ_ASSERT(aEvent->AsCompositionEvent() || aEvent->AsTextEvent(),
"aEvent has to be WidgetCompositionEvent or WidgetTextEvent");
return GetTextCompositionFor(aEvent->widget);
}

View File

@ -98,7 +98,17 @@ public:
/**
* Get TextComposition from widget.
*/
static mozilla::TextComposition* GetTextCompositionFor(nsIWidget* aWidget);
static already_AddRefed<mozilla::TextComposition>
GetTextCompositionFor(nsIWidget* aWidget);
/**
* Returns TextComposition instance for the event.
*
* @param aEvent Should be a composition event or a text event which is
* being dispatched.
*/
static already_AddRefed<mozilla::TextComposition>
GetTextCompositionFor(mozilla::WidgetGUIEvent* aEvent);
/**
* Send a notification to IME. It depends on the IME or platform spec what

View File

@ -21,6 +21,7 @@
#include "JoinElementTxn.h" // for JoinElementTxn
#include "PlaceholderTxn.h" // for PlaceholderTxn
#include "SplitElementTxn.h" // for SplitElementTxn
#include "TextComposition.h" // for TextComposition
#include "mozFlushType.h" // for mozFlushType::Flush_Frames
#include "mozISpellCheckingEngine.h"
#include "mozInlineSpellChecker.h" // for mozInlineSpellChecker
@ -2010,10 +2011,25 @@ nsEditor::StopPreservingSelection()
mSavedSel.MakeEmpty();
}
void
nsEditor::EnsureComposition(mozilla::WidgetGUIEvent* aEvent)
{
if (mComposition) {
return;
}
// The compositionstart event must cause creating new TextComposition
// instance at being dispatched by nsIMEStateManager.
mComposition = nsIMEStateManager::GetTextCompositionFor(aEvent);
if (!mComposition) {
MOZ_CRASH("nsIMEStateManager doesn't return proper composition");
}
}
nsresult
nsEditor::BeginIMEComposition()
nsEditor::BeginIMEComposition(WidgetCompositionEvent* aCompositionEvent)
{
MOZ_ASSERT(!mComposition, "There is composition already");
EnsureComposition(aCompositionEvent);
mInIMEMode = true;
if (mPhonetic) {
mPhonetic->Truncate(0);
@ -2044,6 +2060,7 @@ nsEditor::EndIMEComposition()
mIMEBufferLength = 0;
mInIMEMode = false;
mIsIMEComposing = false;
mComposition = nullptr;
// notify editor observers of action
NotifyEditorObservers();

View File

@ -69,6 +69,7 @@ class nsTransactionManager;
namespace mozilla {
class Selection;
class TextComposition;
namespace dom {
class Element;
@ -242,9 +243,8 @@ public:
mozilla::dom::Element** aContent);
// IME event handlers
virtual nsresult BeginIMEComposition();
virtual nsresult UpdateIMEComposition(const nsAString &aCompositionString,
nsIPrivateTextRangeList *aTextRange)=0;
virtual nsresult BeginIMEComposition(mozilla::WidgetCompositionEvent* aEvent);
virtual nsresult UpdateIMEComposition(nsIDOMEvent* aDOMTextEvent) = 0;
void EndIMEComposition();
void SwitchTextDirectionTo(uint32_t aDirection);
@ -413,6 +413,13 @@ protected:
return !IsPasswordEditor() && !IsReadonly() && !IsDisabled() && !ShouldSkipSpellCheck();
}
/**
* EnsureComposition() should be composition event handlers or text event
* handler. This tries to get the composition for the event and set it to
* mComposition.
*/
void EnsureComposition(mozilla::WidgetGUIEvent* aEvent);
public:
/** All editor operations which alter the doc should be prefaced
@ -830,6 +837,9 @@ protected:
nsIAtom *mPlaceHolderName; // name of placeholder transaction
nsSelectionState *mSelState; // saved selection state for placeholder txn batching
nsString *mPhonetic;
// IME composition this is not null between compositionstart and
// compositionend.
nsRefPtr<mozilla::TextComposition> mComposition;
// various listeners
nsCOMArray<nsIEditActionListener> mActionListeners; // listens to all low level actions on the doc

View File

@ -5,6 +5,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/Assertions.h" // for MOZ_ASSERT, etc
#include "mozilla/Preferences.h" // for Preferences
#include "mozilla/TextEvents.h" // for WidgetCompositionEvent
#include "mozilla/dom/Element.h" // for Element
#include "mozilla/dom/EventTarget.h" // for EventTarget
#include "nsAString.h"
@ -42,8 +43,6 @@
#include "nsINode.h" // for nsINode, ::NODE_IS_EDITABLE, etc
#include "nsIPlaintextEditor.h" // for nsIPlaintextEditor, etc
#include "nsIPresShell.h" // for nsIPresShell
#include "nsIPrivateTextEvent.h" // for nsIPrivateTextEvent
#include "nsIPrivateTextRange.h" // for nsIPrivateTextRangeList
#include "nsISelection.h" // for nsISelection
#include "nsISelectionController.h" // for nsISelectionController, etc
#include "nsISelectionPrivate.h" // for nsISelectionPrivate
@ -661,24 +660,12 @@ nsEditorEventListener::HandleText(nsIDOMEvent* aTextEvent)
return NS_OK;
}
nsCOMPtr<nsIPrivateTextEvent> textEvent = do_QueryInterface(aTextEvent);
if (!textEvent) {
//non-ui event passed in. bad things.
return NS_OK;
}
nsAutoString composedText;
nsCOMPtr<nsIPrivateTextRangeList> textRangeList;
textEvent->GetText(composedText);
textRangeList = textEvent->GetInputRange();
// if we are readonly or disabled, then do nothing.
if (mEditor->IsReadonly() || mEditor->IsDisabled()) {
return NS_OK;
}
return mEditor->UpdateIMEComposition(composedText, textRangeList);
return mEditor->UpdateIMEComposition(aTextEvent);
}
/**
@ -905,7 +892,9 @@ nsEditorEventListener::HandleStartComposition(nsIDOMEvent* aCompositionEvent)
if (!mEditor->IsAcceptableInputEvent(aCompositionEvent)) {
return NS_OK;
}
return mEditor->BeginIMEComposition();
WidgetCompositionEvent* compositionStart =
aCompositionEvent->GetInternalNSEvent()->AsCompositionEvent();
return mEditor->BeginIMEComposition(compositionStart);
}
void

View File

@ -39,6 +39,7 @@
#include "nsINameSpaceManager.h"
#include "nsINode.h"
#include "nsIPresShell.h"
#include "nsIPrivateTextEvent.h"
#include "nsIPrivateTextRange.h"
#include "nsISelection.h"
#include "nsISelectionController.h"
@ -811,7 +812,7 @@ NS_IMETHODIMP nsPlaintextEditor::InsertLineBreak()
}
nsresult
nsPlaintextEditor::BeginIMEComposition()
nsPlaintextEditor::BeginIMEComposition(WidgetCompositionEvent* aEvent)
{
NS_ENSURE_TRUE(!mInIMEMode, NS_OK);
@ -825,14 +826,20 @@ nsPlaintextEditor::BeginIMEComposition()
textEditRules->ResetIMETextPWBuf();
}
return nsEditor::BeginIMEComposition();
return nsEditor::BeginIMEComposition(aEvent);
}
nsresult
nsPlaintextEditor::UpdateIMEComposition(const nsAString& aCompositionString,
nsIPrivateTextRangeList* aTextRangeList)
nsPlaintextEditor::UpdateIMEComposition(nsIDOMEvent* aDOMTextEvent)
{
NS_ABORT_IF_FALSE(aTextRangeList, "aTextRangeList must not be nullptr");
NS_ABORT_IF_FALSE(aDOMTextEvent, "aDOMTextEvent must not be nullptr");
WidgetTextEvent* widgetTextEvent =
aDOMTextEvent->GetInternalNSEvent()->AsTextEvent();
NS_ENSURE_TRUE(widgetTextEvent, NS_ERROR_INVALID_ARG);
EnsureComposition(widgetTextEvent);
mInIMEMode = true;
nsCOMPtr<nsIPresShell> ps = GetPresShell();
NS_ENSURE_TRUE(ps, NS_ERROR_NOT_INITIALIZED);
@ -845,7 +852,11 @@ nsPlaintextEditor::UpdateIMEComposition(const nsAString& aCompositionString,
// Update information of clauses in the new composition string.
// This will be refered by followed methods.
mIMETextRangeList = aTextRangeList;
nsCOMPtr<nsIPrivateTextEvent> privateTextEvent =
do_QueryInterface(aDOMTextEvent);
NS_ENSURE_TRUE(privateTextEvent, NS_ERROR_INVALID_ARG);
mIMETextRangeList = privateTextEvent->GetInputRange();
NS_ABORT_IF_FALSE(mIMETextRangeList, "mIMETextRangeList must not be nullptr");
// We set mIsIMEComposing properly.
SetIsIMEComposing();
@ -853,9 +864,9 @@ nsPlaintextEditor::UpdateIMEComposition(const nsAString& aCompositionString,
{
nsAutoPlaceHolderBatch batch(this, nsGkAtoms::IMETxnName);
rv = InsertText(aCompositionString);
rv = InsertText(widgetTextEvent->theText);
mIMEBufferLength = aCompositionString.Length();
mIMEBufferLength = widgetTextEvent->theText.Length();
if (caretP) {
caretP->SetCaretDOMSelection(selection);

View File

@ -122,9 +122,8 @@ public:
virtual already_AddRefed<mozilla::dom::EventTarget> GetDOMEventTarget();
virtual nsresult BeginIMEComposition();
virtual nsresult UpdateIMEComposition(const nsAString &aCompositionString,
nsIPrivateTextRangeList *aTextRange);
virtual nsresult BeginIMEComposition(mozilla::WidgetCompositionEvent* aEvent);
virtual nsresult UpdateIMEComposition(nsIDOMEvent* aTextEvent) MOZ_OVERRIDE;
virtual already_AddRefed<nsIContent> GetInputEventTargetContent();