mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 13:21:05 +00:00
Bug 962005 Make mozilla::TextComposition ref-countable class r=smaug
This commit is contained in:
parent
d46a808c6c
commit
95852769e5
@ -31,17 +31,6 @@ TextComposition::TextComposition(nsPresContext* aPresContext,
|
||||
{
|
||||
}
|
||||
|
||||
TextComposition::TextComposition(const TextComposition& aOther)
|
||||
{
|
||||
mNativeContext = aOther.mNativeContext;
|
||||
mPresContext = aOther.mPresContext;
|
||||
mNode = aOther.mNode;
|
||||
mLastData = aOther.mLastData;
|
||||
mCompositionStartOffset = aOther.mCompositionStartOffset;
|
||||
mCompositionTargetOffset = aOther.mCompositionTargetOffset;
|
||||
mIsSynthesizedForTests = aOther.mIsSynthesizedForTests;
|
||||
}
|
||||
|
||||
bool
|
||||
TextComposition::MatchesNativeContext(nsIWidget* aWidget) const
|
||||
{
|
||||
@ -118,15 +107,13 @@ TextComposition::DispatchCompsotionEventRunnable(uint32_t aEventMessage,
|
||||
void
|
||||
TextComposition::SynthesizeCommit(bool aDiscard)
|
||||
{
|
||||
// backup this instance and use it since this instance might be destroyed
|
||||
// by nsIMEStateManager if this is managed by it.
|
||||
TextComposition composition = *this;
|
||||
nsAutoString data(aDiscard ? EmptyString() : composition.mLastData);
|
||||
if (composition.mLastData != data) {
|
||||
composition.DispatchCompsotionEventRunnable(NS_COMPOSITION_UPDATE, data);
|
||||
composition.DispatchCompsotionEventRunnable(NS_TEXT_TEXT, data);
|
||||
nsRefPtr<TextComposition> kungFuDeathGrip(this);
|
||||
nsAutoString data(aDiscard ? EmptyString() : mLastData);
|
||||
if (mLastData != data) {
|
||||
DispatchCompsotionEventRunnable(NS_COMPOSITION_UPDATE, data);
|
||||
DispatchCompsotionEventRunnable(NS_TEXT_TEXT, data);
|
||||
}
|
||||
composition.DispatchCompsotionEventRunnable(NS_COMPOSITION_END, data);
|
||||
DispatchCompsotionEventRunnable(NS_COMPOSITION_END, data);
|
||||
}
|
||||
|
||||
nsresult
|
||||
@ -202,7 +189,7 @@ TextCompositionArray::index_type
|
||||
TextCompositionArray::IndexOf(nsIWidget* aWidget)
|
||||
{
|
||||
for (index_type i = Length(); i > 0; --i) {
|
||||
if (ElementAt(i - 1).MatchesNativeContext(aWidget)) {
|
||||
if (ElementAt(i - 1)->MatchesNativeContext(aWidget)) {
|
||||
return i - 1;
|
||||
}
|
||||
}
|
||||
@ -213,7 +200,7 @@ TextCompositionArray::index_type
|
||||
TextCompositionArray::IndexOf(nsPresContext* aPresContext)
|
||||
{
|
||||
for (index_type i = Length(); i > 0; --i) {
|
||||
if (ElementAt(i - 1).GetPresContext() == aPresContext) {
|
||||
if (ElementAt(i - 1)->GetPresContext() == aPresContext) {
|
||||
return i - 1;
|
||||
}
|
||||
}
|
||||
@ -228,7 +215,7 @@ TextCompositionArray::IndexOf(nsPresContext* aPresContext,
|
||||
if (index == NoIndex) {
|
||||
return NoIndex;
|
||||
}
|
||||
nsINode* node = ElementAt(index).GetEventTargetNode();
|
||||
nsINode* node = ElementAt(index)->GetEventTargetNode();
|
||||
return node == aNode ? index : NoIndex;
|
||||
}
|
||||
|
||||
@ -236,7 +223,7 @@ TextComposition*
|
||||
TextCompositionArray::GetCompositionFor(nsIWidget* aWidget)
|
||||
{
|
||||
index_type i = IndexOf(aWidget);
|
||||
return i != NoIndex ? &ElementAt(i) : nullptr;
|
||||
return i != NoIndex ? ElementAt(i) : nullptr;
|
||||
}
|
||||
|
||||
TextComposition*
|
||||
@ -244,7 +231,7 @@ TextCompositionArray::GetCompositionFor(nsPresContext* aPresContext,
|
||||
nsINode* aNode)
|
||||
{
|
||||
index_type i = IndexOf(aPresContext, aNode);
|
||||
return i != NoIndex ? &ElementAt(i) : nullptr;
|
||||
return i != NoIndex ? ElementAt(i) : nullptr;
|
||||
}
|
||||
|
||||
TextComposition*
|
||||
@ -253,9 +240,9 @@ TextCompositionArray::GetCompositionInContent(nsPresContext* aPresContext,
|
||||
{
|
||||
// There should be only one composition per content object.
|
||||
for (index_type i = Length(); i > 0; --i) {
|
||||
nsINode* node = ElementAt(i - 1).GetEventTargetNode();
|
||||
nsINode* node = ElementAt(i - 1)->GetEventTargetNode();
|
||||
if (node && nsContentUtils::ContentIsDescendantOf(node, aContent)) {
|
||||
return &ElementAt(i - 1);
|
||||
return ElementAt(i - 1);
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
|
@ -31,13 +31,14 @@ namespace mozilla {
|
||||
class TextComposition MOZ_FINAL
|
||||
{
|
||||
friend class ::nsIMEStateManager;
|
||||
|
||||
NS_INLINE_DECL_REFCOUNTING(TextComposition)
|
||||
|
||||
public:
|
||||
TextComposition(nsPresContext* aPresContext,
|
||||
nsINode* aNode,
|
||||
WidgetGUIEvent* aEvent);
|
||||
|
||||
TextComposition(const TextComposition& aOther);
|
||||
|
||||
~TextComposition()
|
||||
{
|
||||
// WARNING: mPresContext may be destroying, so, be careful if you touch it.
|
||||
@ -97,8 +98,10 @@ private:
|
||||
// See the comment for IsSynthesizedForTests().
|
||||
bool mIsSynthesizedForTests;
|
||||
|
||||
// Hide the default constructor
|
||||
// Hide the default constructor and copy constructor.
|
||||
TextComposition() {}
|
||||
TextComposition(const TextComposition& aOther);
|
||||
|
||||
|
||||
/**
|
||||
* DispatchEvent() dispatches the aEvent to the mContent synchronously.
|
||||
@ -163,7 +166,8 @@ private:
|
||||
* in the array can be destroyed by calling some methods of itself.
|
||||
*/
|
||||
|
||||
class TextCompositionArray MOZ_FINAL : public nsAutoTArray<TextComposition, 2>
|
||||
class TextCompositionArray MOZ_FINAL :
|
||||
public nsAutoTArray<nsRefPtr<TextComposition>, 2>
|
||||
{
|
||||
public:
|
||||
index_type IndexOf(nsIWidget* aWidget);
|
||||
|
@ -148,12 +148,10 @@ nsIMEStateManager::OnRemoveContent(nsPresContext* aPresContext,
|
||||
|
||||
// First, if there is a composition in the aContent, clean up it.
|
||||
if (sTextCompositions) {
|
||||
TextComposition* compositionInContent =
|
||||
nsRefPtr<TextComposition> compositionInContent =
|
||||
sTextCompositions->GetCompositionInContent(aPresContext, aContent);
|
||||
|
||||
if (compositionInContent) {
|
||||
// Store the composition before accessing the native IME.
|
||||
TextComposition storedComposition = *compositionInContent;
|
||||
// Try resetting the native IME state. Be aware, typically, this method
|
||||
// is called during the content being removed. Then, the native
|
||||
// composition events which are caused by following APIs are ignored due
|
||||
@ -161,15 +159,15 @@ nsIMEStateManager::OnRemoveContent(nsPresContext* aPresContext,
|
||||
nsCOMPtr<nsIWidget> widget = aPresContext->GetRootWidget();
|
||||
if (widget) {
|
||||
nsresult rv =
|
||||
storedComposition.NotifyIME(REQUEST_TO_CANCEL_COMPOSITION);
|
||||
compositionInContent->NotifyIME(REQUEST_TO_CANCEL_COMPOSITION);
|
||||
if (NS_FAILED(rv)) {
|
||||
storedComposition.NotifyIME(REQUEST_TO_COMMIT_COMPOSITION);
|
||||
compositionInContent->NotifyIME(REQUEST_TO_COMMIT_COMPOSITION);
|
||||
}
|
||||
// By calling the APIs, the composition may have been finished normally.
|
||||
compositionInContent =
|
||||
sTextCompositions->GetCompositionFor(
|
||||
storedComposition.GetPresContext(),
|
||||
storedComposition.GetEventTargetNode());
|
||||
compositionInContent->GetPresContext(),
|
||||
compositionInContent->GetEventTargetNode());
|
||||
}
|
||||
}
|
||||
|
||||
@ -558,12 +556,12 @@ nsIMEStateManager::DispatchCompositionEvent(nsINode* aEventTargetNode,
|
||||
|
||||
WidgetGUIEvent* GUIEvent = aEvent->AsGUIEvent();
|
||||
|
||||
TextComposition* composition =
|
||||
nsRefPtr<TextComposition> composition =
|
||||
sTextCompositions->GetCompositionFor(GUIEvent->widget);
|
||||
if (!composition) {
|
||||
MOZ_ASSERT(GUIEvent->message == NS_COMPOSITION_START);
|
||||
TextComposition newComposition(aPresContext, aEventTargetNode, GUIEvent);
|
||||
composition = sTextCompositions->AppendElement(newComposition);
|
||||
composition = new TextComposition(aPresContext, aEventTargetNode, GUIEvent);
|
||||
sTextCompositions->AppendElement(composition);
|
||||
}
|
||||
#ifdef DEBUG
|
||||
else {
|
||||
@ -593,7 +591,7 @@ nsIMEStateManager::NotifyIME(NotificationToIME aNotification,
|
||||
{
|
||||
NS_ENSURE_TRUE(aWidget, NS_ERROR_INVALID_ARG);
|
||||
|
||||
TextComposition* composition = nullptr;
|
||||
nsRefPtr<TextComposition> composition;
|
||||
if (sTextCompositions) {
|
||||
composition = sTextCompositions->GetCompositionFor(aWidget);
|
||||
}
|
||||
@ -618,12 +616,10 @@ nsIMEStateManager::NotifyIME(NotificationToIME aNotification,
|
||||
switch (aNotification) {
|
||||
case REQUEST_TO_COMMIT_COMPOSITION: {
|
||||
nsCOMPtr<nsIWidget> widget(aWidget);
|
||||
TextComposition backup = *composition;
|
||||
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
if (!backup.GetLastData().IsEmpty()) {
|
||||
if (!composition->GetLastData().IsEmpty()) {
|
||||
WidgetTextEvent textEvent(true, NS_TEXT_TEXT, widget);
|
||||
textEvent.theText = backup.GetLastData();
|
||||
textEvent.theText = composition->GetLastData();
|
||||
textEvent.mFlags.mIsSynthesizedForTests = true;
|
||||
widget->DispatchEvent(&textEvent, status);
|
||||
if (widget->Destroyed()) {
|
||||
@ -633,7 +629,7 @@ nsIMEStateManager::NotifyIME(NotificationToIME aNotification,
|
||||
|
||||
status = nsEventStatus_eIgnore;
|
||||
WidgetCompositionEvent endEvent(true, NS_COMPOSITION_END, widget);
|
||||
endEvent.data = backup.GetLastData();
|
||||
endEvent.data = composition->GetLastData();
|
||||
endEvent.mFlags.mIsSynthesizedForTests = true;
|
||||
widget->DispatchEvent(&endEvent, status);
|
||||
|
||||
@ -641,12 +637,10 @@ nsIMEStateManager::NotifyIME(NotificationToIME aNotification,
|
||||
}
|
||||
case REQUEST_TO_CANCEL_COMPOSITION: {
|
||||
nsCOMPtr<nsIWidget> widget(aWidget);
|
||||
TextComposition backup = *composition;
|
||||
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
if (!backup.GetLastData().IsEmpty()) {
|
||||
if (!composition->GetLastData().IsEmpty()) {
|
||||
WidgetCompositionEvent updateEvent(true, NS_COMPOSITION_UPDATE, widget);
|
||||
updateEvent.data = backup.GetLastData();
|
||||
updateEvent.data = composition->GetLastData();
|
||||
updateEvent.mFlags.mIsSynthesizedForTests = true;
|
||||
widget->DispatchEvent(&updateEvent, status);
|
||||
if (widget->Destroyed()) {
|
||||
@ -655,7 +649,7 @@ nsIMEStateManager::NotifyIME(NotificationToIME aNotification,
|
||||
|
||||
status = nsEventStatus_eIgnore;
|
||||
WidgetTextEvent textEvent(true, NS_TEXT_TEXT, widget);
|
||||
textEvent.theText = backup.GetLastData();
|
||||
textEvent.theText = composition->GetLastData();
|
||||
textEvent.mFlags.mIsSynthesizedForTests = true;
|
||||
widget->DispatchEvent(&textEvent, status);
|
||||
if (widget->Destroyed()) {
|
||||
@ -665,7 +659,7 @@ nsIMEStateManager::NotifyIME(NotificationToIME aNotification,
|
||||
|
||||
status = nsEventStatus_eIgnore;
|
||||
WidgetCompositionEvent endEvent(true, NS_COMPOSITION_END, widget);
|
||||
endEvent.data = backup.GetLastData();
|
||||
endEvent.data = composition->GetLastData();
|
||||
endEvent.mFlags.mIsSynthesizedForTests = true;
|
||||
widget->DispatchEvent(&endEvent, status);
|
||||
|
||||
@ -1133,7 +1127,8 @@ nsIMEStateManager::GetFocusSelectionAndRoot(nsISelection** aSel,
|
||||
}
|
||||
|
||||
TextComposition*
|
||||
nsIMEStateManager::GetTextComposition(nsIWidget* aWidget)
|
||||
nsIMEStateManager::GetTextCompositionFor(nsIWidget* aWidget)
|
||||
{
|
||||
return sTextCompositions->GetCompositionFor(aWidget);
|
||||
return sTextCompositions ?
|
||||
sTextCompositions->GetCompositionFor(aWidget) : nullptr;
|
||||
}
|
||||
|
@ -98,7 +98,7 @@ public:
|
||||
/**
|
||||
* Get TextComposition from widget.
|
||||
*/
|
||||
static mozilla::TextComposition* GetTextComposition(nsIWidget* aWidget);
|
||||
static mozilla::TextComposition* GetTextCompositionFor(nsIWidget* aWidget);
|
||||
|
||||
/**
|
||||
* Send a notification to IME. It depends on the IME or platform spec what
|
||||
|
@ -490,8 +490,8 @@ PuppetWidget::NotifyIMEOfUpdateComposition()
|
||||
|
||||
NS_ENSURE_TRUE(mTabChild, NS_ERROR_FAILURE);
|
||||
|
||||
mozilla::TextComposition* textComposition =
|
||||
nsIMEStateManager::GetTextComposition(this);
|
||||
nsRefPtr<TextComposition> textComposition =
|
||||
nsIMEStateManager::GetTextCompositionFor(this);
|
||||
NS_ENSURE_TRUE(textComposition, NS_ERROR_FAILURE);
|
||||
|
||||
nsEventStatus status;
|
||||
|
Loading…
Reference in New Issue
Block a user