Bug 1200980 part.1 Log the behavior of IMEContentObserver for debugging r=smaug

This commit is contained in:
Masayuki Nakano 2015-09-08 12:54:14 +09:00
parent 7fe4357611
commit 4a9e028bdb
2 changed files with 305 additions and 29 deletions

View File

@ -4,6 +4,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/Logging.h"
#include "ContentEventHandler.h"
#include "IMEContentObserver.h"
#include "mozilla/AsyncEventDispatcher.h"
@ -37,6 +39,78 @@ namespace mozilla {
using namespace widget;
PRLogModuleInfo* sIMECOLog = nullptr;
static const char*
ToChar(bool aBool)
{
return aBool ? "true" : "false";
}
class WritingModeToString final : public nsAutoCString
{
public:
explicit WritingModeToString(const WritingMode& aWritingMode)
{
if (!aWritingMode.IsVertical()) {
AssignLiteral("Horizontal");
return;
}
if (aWritingMode.IsVerticalLR()) {
AssignLiteral("Vertical (LR)");
return;
}
AssignLiteral("Vertical (RL)");
}
virtual ~WritingModeToString() {}
};
class SelectionChangeDataToString final : public nsAutoCString
{
public:
explicit SelectionChangeDataToString(
const IMENotification::SelectionChangeDataBase& aData)
{
if (!aData.IsValid()) {
AppendLiteral("{ IsValid()=false }");
return;
}
AppendPrintf("{ mOffset=%u, ", aData.mOffset);
if (aData.mString->Length() > 20) {
AppendPrintf("mString.Length()=%u, ", aData.mString->Length());
} else {
AppendPrintf("mString=\"%s\" (Length()=%u), ",
NS_ConvertUTF16toUTF8(*aData.mString).get(),
aData.mString->Length());
}
AppendPrintf("GetWritingMode()=%s, mReversed=%s, mCausedByComposition=%s, "
"mCausedBySelectionEvent=%s }",
WritingModeToString(aData.GetWritingMode()).get(),
ToChar(aData.mReversed),
ToChar(aData.mCausedByComposition),
ToChar(aData.mCausedBySelectionEvent));
}
virtual ~SelectionChangeDataToString() {}
};
class TextChangeDataToString final : public nsAutoCString
{
public:
explicit TextChangeDataToString(
const IMENotification::TextChangeDataBase& aData)
{
if (!aData.IsValid()) {
AppendLiteral("{ IsValid()=false }");
return;
}
AppendPrintf("{ mStartOffset=%u, mRemovedEndOffset=%u, mAddedEndOffset=%u, "
"mCausedByComposition=%s }", aData.mStartOffset,
aData.mRemovedEndOffset, aData.mAddedEndOffset,
ToChar(aData.mCausedByComposition));
}
virtual ~TextChangeDataToString() {}
};
/******************************************************************************
* mozilla::IMEContentObserver
******************************************************************************/
@ -102,6 +176,9 @@ IMEContentObserver::IMEContentObserver()
#ifdef DEBUG
mTextChangeData.Test();
#endif
if (!sIMECOLog) {
sIMECOLog = PR_NewLogModule("IMEContentObserver");
}
}
void
@ -256,6 +333,12 @@ IMEContentObserver::NotifyIMEOfBlur()
// mWidget must have been non-nullptr if IME has focus.
MOZ_RELEASE_ASSERT(widget);
nsRefPtr<IMEContentObserver> kungFuDeathGrip(this);
MOZ_LOG(sIMECOLog, LogLevel::Info,
("IMECO: 0x%p IMEContentObserver::NotifyIMEOfBlur(), "
"sending NOTIFY_IME_OF_BLUR", this));
// For now, we need to send blur notification in any condition because
// we don't have any simple ways to send blur notification asynchronously.
// After this call, Destroy() or Unlink() will stop observing the content
@ -266,6 +349,10 @@ IMEContentObserver::NotifyIMEOfBlur()
// focus. So, this may not cause any problem.
mIMEHasFocus = false;
IMEStateManager::NotifyIME(IMENotification(NOTIFY_IME_OF_BLUR), widget);
MOZ_LOG(sIMECOLog, LogLevel::Debug,
("IMECO: 0x%p IMEContentObserver::NotifyIMEOfBlur(), "
"sent NOTIFY_IME_OF_BLUR", this));
}
void
@ -786,9 +873,35 @@ IMEContentObserver::AttributeChanged(nsIDocument* aDocument,
MaybeNotifyIMEOfTextChange(data);
}
void
IMEContentObserver::SuppressNotifyingIME()
{
mSuppressNotifications++;
MOZ_LOG(sIMECOLog, LogLevel::Debug,
("IMECO: 0x%p IMEContentObserver::SuppressNotifyingIME(), "
"mSuppressNotifications=%u", this, mSuppressNotifications));
}
void
IMEContentObserver::UnsuppressNotifyingIME()
{
MOZ_LOG(sIMECOLog, LogLevel::Debug,
("IMECO: 0x%p IMEContentObserver::UnsuppressNotifyingIME(), "
"mSuppressNotifications=%u", this, mSuppressNotifications));
if (!mSuppressNotifications || --mSuppressNotifications) {
return;
}
FlushMergeableNotifications();
}
NS_IMETHODIMP
IMEContentObserver::EditAction()
{
MOZ_LOG(sIMECOLog, LogLevel::Debug,
("IMECO: 0x%p IMEContentObserver::EditAction()", this));
mEndOfAddedTextCache.Clear();
mStartOfRemovingTextRangeCache.Clear();
FlushMergeableNotifications();
@ -798,6 +911,9 @@ IMEContentObserver::EditAction()
NS_IMETHODIMP
IMEContentObserver::BeforeEditAction()
{
MOZ_LOG(sIMECOLog, LogLevel::Debug,
("IMECO: 0x%p IMEContentObserver::BeforeEditAction()", this));
mEndOfAddedTextCache.Clear();
mStartOfRemovingTextRangeCache.Clear();
return NS_OK;
@ -806,6 +922,9 @@ IMEContentObserver::BeforeEditAction()
NS_IMETHODIMP
IMEContentObserver::CancelEditAction()
{
MOZ_LOG(sIMECOLog, LogLevel::Debug,
("IMECO: 0x%p IMEContentObserver::CancelEditAction()", this));
mEndOfAddedTextCache.Clear();
mStartOfRemovingTextRangeCache.Clear();
FlushMergeableNotifications();
@ -815,6 +934,9 @@ IMEContentObserver::CancelEditAction()
void
IMEContentObserver::PostFocusSetNotification()
{
MOZ_LOG(sIMECOLog, LogLevel::Debug,
("IMECO: 0x%p IMEContentObserver::PostFocusSetNotification()", this));
mIsFocusEventPending = true;
}
@ -822,9 +944,19 @@ void
IMEContentObserver::PostTextChangeNotification(
const TextChangeDataBase& aTextChangeData)
{
MOZ_LOG(sIMECOLog, LogLevel::Debug,
("IMECO: 0x%p IMEContentObserver::PostTextChangeNotification("
"aTextChangeData=%s)",
this, TextChangeDataToString(aTextChangeData).get()));
mTextChangeData += aTextChangeData;
MOZ_ASSERT(mTextChangeData.IsValid(),
"mTextChangeData must have text change data");
MOZ_LOG(sIMECOLog, LogLevel::Debug,
("IMECO: 0x%p IMEContentObserver::PostTextChangeNotification(), "
"mTextChangeData=%s)",
this, TextChangeDataToString(mTextChangeData).get()));
}
void
@ -832,6 +964,11 @@ IMEContentObserver::PostSelectionChangeNotification(
bool aCausedByComposition,
bool aCausedBySelectionEvent)
{
MOZ_LOG(sIMECOLog, LogLevel::Debug,
("IMECO: 0x%p IMEContentObserver::PostSelectionChangeNotification("
"aCausedByComposition=%s, aCausedBySelectionEvent=%s)",
this, ToChar(aCausedByComposition), ToChar(aCausedBySelectionEvent)));
if (!mIsSelectionChangeEventPending) {
mSelectionChangeCausedOnlyByComposition = aCausedByComposition;
} else {
@ -847,6 +984,53 @@ IMEContentObserver::PostSelectionChangeNotification(
mIsSelectionChangeEventPending = true;
}
void
IMEContentObserver::MaybeNotifyIMEOfFocusSet()
{
MOZ_LOG(sIMECOLog, LogLevel::Debug,
("IMECO: 0x%p IMEContentObserver::MaybeNotifyIMEOfFocusSet()", this));
PostFocusSetNotification();
FlushMergeableNotifications();
}
void
IMEContentObserver::MaybeNotifyIMEOfTextChange(
const TextChangeDataBase& aTextChangeData)
{
MOZ_LOG(sIMECOLog, LogLevel::Debug,
("IMECO: 0x%p IMEContentObserver::MaybeNotifyIMEOfTextChange("
"aTextChangeData=%s)",
this, TextChangeDataToString(aTextChangeData).get()));
PostTextChangeNotification(aTextChangeData);
FlushMergeableNotifications();
}
void
IMEContentObserver::MaybeNotifyIMEOfSelectionChange(
bool aCausedByComposition,
bool aCausedBySelectionEvent)
{
MOZ_LOG(sIMECOLog, LogLevel::Debug,
("IMECO: 0x%p IMEContentObserver::MaybeNotifyIMEOfSelectionChange("
"aCausedByComposition=%s, aCausedBySelectionEvent=%s)",
this, ToChar(aCausedByComposition), ToChar(aCausedBySelectionEvent)));
PostSelectionChangeNotification(aCausedByComposition,
aCausedBySelectionEvent);
FlushMergeableNotifications();
}
void
IMEContentObserver::MaybeNotifyIMEOfPositionChange()
{
MOZ_LOG(sIMECOLog, LogLevel::Debug,
("IMECO: 0x%p IMEContentObserver::MaybeNotifyIMEOfPositionChange()", this));
PostPositionChangeNotification();
FlushMergeableNotifications();
}
bool
IMEContentObserver::UpdateSelectionCache()
{
@ -873,12 +1057,21 @@ IMEContentObserver::UpdateSelectionCache()
mSelectionData.mReversed = selection.mReply.mReversed;
mSelectionData.mCausedByComposition = false;
mSelectionData.mCausedBySelectionEvent = false;
MOZ_LOG(sIMECOLog, LogLevel::Debug,
("IMECO: 0x%p IMEContentObserver::UpdateSelectionCache(), "
"mSelectionData=%s",
this, SelectionChangeDataToString(mSelectionData).get()));
return mSelectionData.IsValid();
}
void
IMEContentObserver::PostPositionChangeNotification()
{
MOZ_LOG(sIMECOLog, LogLevel::Debug,
("IMECO: 0x%p IMEContentObserver::PostPositionChangeNotification()", this));
mIsPositionChangeEventPending = true;
}
@ -938,6 +1131,9 @@ IMEContentObserver::FlushMergeableNotifications()
{
if (!IsSafeToNotifyIME()) {
// So, if this is already called, this should do nothing.
MOZ_LOG(sIMECOLog, LogLevel::Debug,
("IMECO: 0x%p IMEContentObserver::FlushMergeableNotifications(), "
"FAILED, due to unsafe to notify IME", this));
return;
}
@ -948,6 +1144,9 @@ IMEContentObserver::FlushMergeableNotifications()
if (mIsFlushingPendingNotifications) {
// So, if this is already called, this should do nothing.
MOZ_LOG(sIMECOLog, LogLevel::Debug,
("IMECO: 0x%p IMEContentObserver::FlushMergeableNotifications(), "
"FAILED, due to already flushing pending notifications", this));
return;
}
@ -958,6 +1157,9 @@ IMEContentObserver::FlushMergeableNotifications()
// another change.
if (mIsFocusEventPending) {
MOZ_LOG(sIMECOLog, LogLevel::Debug,
("IMECO: 0x%p IMEContentObserver::FlushMergeableNotifications(), "
"creating FocusSetEvent...", this));
mIsFocusEventPending = false;
nsContentUtils::AddScriptRunner(new FocusSetEvent(this));
// This is the first notification to IME. So, we don't need to notify any
@ -967,6 +1169,9 @@ IMEContentObserver::FlushMergeableNotifications()
}
if (mTextChangeData.IsValid()) {
MOZ_LOG(sIMECOLog, LogLevel::Debug,
("IMECO: 0x%p IMEContentObserver::FlushMergeableNotifications(), "
"creating TextChangeEvent...", this));
nsContentUtils::AddScriptRunner(new TextChangeEvent(this, mTextChangeData));
}
@ -974,6 +1179,9 @@ IMEContentObserver::FlushMergeableNotifications()
// notification should not be sent before a text change notification because
// PuppetWidget shouldn't query new text content every selection change.
if (mIsSelectionChangeEventPending) {
MOZ_LOG(sIMECOLog, LogLevel::Debug,
("IMECO: 0x%p IMEContentObserver::FlushMergeableNotifications(), "
"creating SelectionChangeEvent...", this));
mIsSelectionChangeEventPending = false;
nsContentUtils::AddScriptRunner(
new SelectionChangeEvent(this, mSelectionChangeCausedOnlyByComposition,
@ -981,6 +1189,9 @@ IMEContentObserver::FlushMergeableNotifications()
}
if (mIsPositionChangeEventPending) {
MOZ_LOG(sIMECOLog, LogLevel::Debug,
("IMECO: 0x%p IMEContentObserver::FlushMergeableNotifications(), "
"creating PositionChangeEvent...", this));
mIsPositionChangeEventPending = false;
nsContentUtils::AddScriptRunner(new PositionChangeEvent(this));
}
@ -989,10 +1200,17 @@ IMEContentObserver::FlushMergeableNotifications()
if (mTextChangeData.IsValid() ||
mIsSelectionChangeEventPending ||
mIsPositionChangeEventPending) {
MOZ_LOG(sIMECOLog, LogLevel::Debug,
("IMECO: 0x%p IMEContentObserver::FlushMergeableNotifications(), "
"posting AsyncMergeableNotificationsFlusher to current thread", this));
nsRefPtr<AsyncMergeableNotificationsFlusher> asyncFlusher =
new AsyncMergeableNotificationsFlusher(this);
NS_DispatchToCurrentThread(asyncFlusher);
}
MOZ_LOG(sIMECOLog, LogLevel::Debug,
("IMECO: 0x%p IMEContentObserver::FlushMergeableNotifications(), "
"finished", this));
}
/******************************************************************************
@ -1052,11 +1270,17 @@ IMEContentObserver::FocusSetEvent::Run()
if (!CanNotifyIME()) {
// If IMEContentObserver has already gone, we don't need to notify IME of
// focus.
MOZ_LOG(sIMECOLog, LogLevel::Debug,
("IMECO: 0x%p IMEContentObserver::FocusSetEvent::Run(), FAILED, due to "
"impossible to notify IME of focus", this));
mIMEContentObserver->ClearPendingNotifications();
return NS_OK;
}
if (!IsSafeToNotifyIME()) {
MOZ_LOG(sIMECOLog, LogLevel::Debug,
("IMECO: 0x%p IMEContentObserver::FocusSetEvent::Run(), retrying to "
"send NOTIFY_IME_OF_FOCUS...", this));
mIMEContentObserver->PostFocusSetNotification();
return NS_OK;
}
@ -1064,8 +1288,17 @@ IMEContentObserver::FocusSetEvent::Run()
mIMEContentObserver->mIMEHasFocus = true;
// Initialize selection cache with the first selection data.
mIMEContentObserver->UpdateSelectionCache();
MOZ_LOG(sIMECOLog, LogLevel::Info,
("IMECO: 0x%p IMEContentObserver::FocusSetEvent::Run(), "
"sending NOTIFY_IME_OF_FOCUS...", this));
IMEStateManager::NotifyIME(IMENotification(NOTIFY_IME_OF_FOCUS),
mIMEContentObserver->mWidget);
MOZ_LOG(sIMECOLog, LogLevel::Debug,
("IMECO: 0x%p IMEContentObserver::FocusSetEvent::Run(), "
"sent NOTIFY_IME_OF_FOCUS", this));
return NS_OK;
}
@ -1077,10 +1310,16 @@ NS_IMETHODIMP
IMEContentObserver::SelectionChangeEvent::Run()
{
if (!CanNotifyIME()) {
MOZ_LOG(sIMECOLog, LogLevel::Debug,
("IMECO: 0x%p IMEContentObserver::SelectionChangeEvent::Run(), FAILED, "
"due to impossible to notify IME of selection change", this));
return NS_OK;
}
if (!IsSafeToNotifyIME()) {
MOZ_LOG(sIMECOLog, LogLevel::Debug,
("IMECO: 0x%p IMEContentObserver::SelectionChangeEvent::Run(), "
"retrying to send NOTIFY_IME_OF_SELECTION_CHANGE...", this));
mIMEContentObserver->PostSelectionChangeNotification(
mCausedByComposition, mCausedBySelectionEvent);
return NS_OK;
@ -1088,6 +1327,9 @@ IMEContentObserver::SelectionChangeEvent::Run()
SelectionChangeData lastSelChangeData = mIMEContentObserver->mSelectionData;
if (NS_WARN_IF(!mIMEContentObserver->UpdateSelectionCache())) {
MOZ_LOG(sIMECOLog, LogLevel::Error,
("IMECO: 0x%p IMEContentObserver::SelectionChangeEvent::Run(), FAILED, "
"due to UpdateSelectionCache() failure", this));
return NS_OK;
}
@ -1101,6 +1343,9 @@ IMEContentObserver::SelectionChangeEvent::Run()
// The state may be changed since querying content causes flushing layout.
if (!CanNotifyIME()) {
MOZ_LOG(sIMECOLog, LogLevel::Debug,
("IMECO: 0x%p IMEContentObserver::SelectionChangeEvent::Run(), FAILED, "
"due to flushing layout having changed something", this));
return NS_OK;
}
@ -1112,13 +1357,26 @@ IMEContentObserver::SelectionChangeEvent::Run()
lastSelChangeData.String() == newSelChangeData.String() &&
lastSelChangeData.GetWritingMode() == newSelChangeData.GetWritingMode() &&
lastSelChangeData.mReversed == newSelChangeData.mReversed) {
MOZ_LOG(sIMECOLog, LogLevel::Debug,
("IMECO: 0x%p IMEContentObserver::SelectionChangeEvent::Run(), not "
"notifying IME of NOTIFY_IME_OF_SELECTION_CHANGE due to not changed "
"actually", this));
return NS_OK;
}
MOZ_LOG(sIMECOLog, LogLevel::Info,
("IMECO: 0x%p IMEContentObserver::SelectionChangeEvent::Run(), "
"sending NOTIFY_IME_OF_SELECTION_CHANGE... newSelChangeData=%s",
this, SelectionChangeDataToString(newSelChangeData).get()));
IMENotification notification(NOTIFY_IME_OF_SELECTION_CHANGE);
notification.SetData(mIMEContentObserver->mSelectionData,
mCausedByComposition, mCausedBySelectionEvent);
IMEStateManager::NotifyIME(notification, mIMEContentObserver->mWidget);
MOZ_LOG(sIMECOLog, LogLevel::Debug,
("IMECO: 0x%p IMEContentObserver::SelectionChangeEvent::Run(), "
"sent NOTIFY_IME_OF_SELECTION_CHANGE", this));
return NS_OK;
}
@ -1130,17 +1388,32 @@ NS_IMETHODIMP
IMEContentObserver::TextChangeEvent::Run()
{
if (!CanNotifyIME()) {
MOZ_LOG(sIMECOLog, LogLevel::Debug,
("IMECO: 0x%p IMEContentObserver::TextChangeEvent::Run(), FAILED, "
"due to impossible to notify IME of text change", this));
return NS_OK;
}
if (!IsSafeToNotifyIME()) {
MOZ_LOG(sIMECOLog, LogLevel::Debug,
("IMECO: 0x%p IMEContentObserver::TextChangeEvent::Run(), retrying to "
"send NOTIFY_IME_OF_TEXT_CHANGE...", this));
mIMEContentObserver->PostTextChangeNotification(mTextChangeData);
return NS_OK;
}
MOZ_LOG(sIMECOLog, LogLevel::Info,
("IMECO: 0x%p IMEContentObserver::TextChangeEvent::Run(), "
"sending NOTIFY_IME_OF_TEXT_CHANGE... mTextChangeData=%s",
this, TextChangeDataToString(mTextChangeData).get()));
IMENotification notification(NOTIFY_IME_OF_TEXT_CHANGE);
notification.SetData(mTextChangeData);
IMEStateManager::NotifyIME(notification, mIMEContentObserver->mWidget);
MOZ_LOG(sIMECOLog, LogLevel::Debug,
("IMECO: 0x%p IMEContentObserver::TextChangeEvent::Run(), "
"sent NOTIFY_IME_OF_TEXT_CHANGE", this));
return NS_OK;
}
@ -1152,16 +1425,30 @@ NS_IMETHODIMP
IMEContentObserver::PositionChangeEvent::Run()
{
if (!CanNotifyIME()) {
MOZ_LOG(sIMECOLog, LogLevel::Debug,
("IMECO: 0x%p IMEContentObserver::PositionChangeEvent::Run(), FAILED, "
"due to impossible to notify IME of position change", this));
return NS_OK;
}
if (!IsSafeToNotifyIME()) {
MOZ_LOG(sIMECOLog, LogLevel::Debug,
("IMECO: 0x%p IMEContentObserver::PositionChangeEvent::Run(), "
"retrying to send NOTIFY_IME_OF_POSITION_CHANGE...", this));
mIMEContentObserver->PostPositionChangeNotification();
return NS_OK;
}
MOZ_LOG(sIMECOLog, LogLevel::Info,
("IMECO: 0x%p IMEContentObserver::PositionChangeEvent::Run(), "
"sending NOTIFY_IME_OF_POSITION_CHANGE...", this));
IMEStateManager::NotifyIME(IMENotification(NOTIFY_IME_OF_POSITION_CHANGE),
mIMEContentObserver->mWidget);
MOZ_LOG(sIMECOLog, LogLevel::Debug,
("IMECO: 0x%p IMEContentObserver::PositionChangeEvent::Run(), "
"sent NOTIFY_IME_OF_POSITION_CHANGE", this));
return NS_OK;
}
@ -1173,10 +1460,22 @@ NS_IMETHODIMP
IMEContentObserver::AsyncMergeableNotificationsFlusher::Run()
{
if (!CanNotifyIME()) {
MOZ_LOG(sIMECOLog, LogLevel::Debug,
("IMECO: 0x%p IMEContentObserver::AsyncMergeableNotificationsFlusher::"
"Run(), FAILED, due to impossible to flush pending notifications",
this));
return NS_OK;
}
MOZ_LOG(sIMECOLog, LogLevel::Info,
("IMECO: 0x%p IMEContentObserver::AsyncMergeableNotificationsFlusher::"
"Run(), calling FlushMergeableNotifications()...", this));
mIMEContentObserver->FlushMergeableNotifications();
MOZ_LOG(sIMECOLog, LogLevel::Debug,
("IMECO: 0x%p IMEContentObserver::AsyncMergeableNotificationsFlusher::"
"Run(), called FlushMergeableNotifications()", this));
return NS_OK;
}

View File

@ -94,14 +94,8 @@ public:
}
nsIWidget* GetWidget() const { return mWidget; }
nsIEditor* GetEditor() const { return mEditor; }
void SuppressNotifyingIME() { mSuppressNotifications++; }
void UnsuppressNotifyingIME()
{
if (!mSuppressNotifications || --mSuppressNotifications) {
return;
}
FlushMergeableNotifications();
}
void SuppressNotifyingIME();
void UnsuppressNotifyingIME();
nsPresContext* GetPresContext() const;
nsresult GetSelectionAndRoot(nsISelection** aSelection,
nsIContent** aRoot) const;
@ -122,32 +116,15 @@ private:
bool IsSafeToNotifyIME() const;
void PostFocusSetNotification();
void MaybeNotifyIMEOfFocusSet()
{
PostFocusSetNotification();
FlushMergeableNotifications();
}
void MaybeNotifyIMEOfFocusSet();
void PostTextChangeNotification(const TextChangeDataBase& aTextChangeData);
void MaybeNotifyIMEOfTextChange(const TextChangeDataBase& aTextChangeData)
{
PostTextChangeNotification(aTextChangeData);
FlushMergeableNotifications();
}
void MaybeNotifyIMEOfTextChange(const TextChangeDataBase& aTextChangeData);
void PostSelectionChangeNotification(bool aCausedByComposition,
bool aCausedBySelectionEvent);
void MaybeNotifyIMEOfSelectionChange(bool aCausedByComposition,
bool aCausedBySelectionEvent)
{
PostSelectionChangeNotification(aCausedByComposition,
aCausedBySelectionEvent);
FlushMergeableNotifications();
}
bool aCausedBySelectionEvent);
void PostPositionChangeNotification();
void MaybeNotifyIMEOfPositionChange()
{
PostPositionChangeNotification();
FlushMergeableNotifications();
}
void MaybeNotifyIMEOfPositionChange();
void NotifyContentAdded(nsINode* aContainer, int32_t aStart, int32_t aEnd);
void ObserveEditableNode();