Bug 1753508 - Add logger of selection batch r=smaug

This was required for debugging the bug.

Differential Revision: https://phabricator.services.mozilla.com/D139350
This commit is contained in:
Masayuki Nakano 2022-03-11 02:24:24 +00:00
Родитель 5ee6119ad5
Коммит 45ba6f356a
20 изменённых файлов: 351 добавлений и 211 удалений

Просмотреть файл

@ -97,12 +97,12 @@ static constexpr nsLiteralCString kNoDocumentTypeNodeError =
static constexpr nsLiteralCString kNoRangeExistsError =
"No selection range exists"_ns;
namespace mozilla {
/******************************************************************************
* Utility methods defined in nsISelectionController.idl
******************************************************************************/
namespace mozilla {
const char* ToChar(SelectionType aSelectionType) {
switch (aSelectionType) {
case SelectionType::eInvalid:
@ -134,6 +134,48 @@ const char* ToChar(SelectionType aSelectionType) {
}
}
/******************************************************************************
* Utility methods defined in nsISelectionListener.idl
******************************************************************************/
nsCString SelectionChangeReasonsToCString(int16_t aReasons) {
nsCString reasons;
if (!aReasons) {
reasons.AssignLiteral("NO_REASON");
return reasons;
}
auto EnsureSeparator = [](nsCString& aString) -> void {
if (!aString.IsEmpty()) {
aString.AppendLiteral(" | ");
}
};
struct ReasonData {
int16_t mReason;
const char* mReasonStr;
ReasonData(int16_t aReason, const char* aReasonStr)
: mReason(aReason), mReasonStr(aReasonStr) {}
};
for (const ReasonData& reason :
{ReasonData(nsISelectionListener::DRAG_REASON, "DRAG_REASON"),
ReasonData(nsISelectionListener::MOUSEDOWN_REASON, "MOUSEDOWN_REASON"),
ReasonData(nsISelectionListener::MOUSEUP_REASON, "MOUSEUP_REASON"),
ReasonData(nsISelectionListener::KEYPRESS_REASON, "KEYPRESS_REASON"),
ReasonData(nsISelectionListener::SELECTALL_REASON, "SELECTALL_REASON"),
ReasonData(nsISelectionListener::COLLAPSETOSTART_REASON,
"COLLAPSETOSTART_REASON"),
ReasonData(nsISelectionListener::COLLAPSETOEND_REASON,
"COLLAPSETOEND_REASON"),
ReasonData(nsISelectionListener::IME_REASON, "IME_REASON"),
ReasonData(nsISelectionListener::JS_REASON, "JS_REASON")}) {
if (aReasons & reason.mReason) {
EnsureSeparator(reasons);
reasons.Append(reason.mReasonStr);
}
}
return reasons;
}
} // namespace mozilla
//#define DEBUG_SELECTION // uncomment for printf describing every collapse and
@ -3180,17 +3222,17 @@ void Selection::NotifySelectionListeners() {
}
}
void Selection::StartBatchChanges() {
void Selection::StartBatchChanges(const char* aDetails) {
if (mFrameSelection) {
RefPtr<nsFrameSelection> frameSelection = mFrameSelection;
frameSelection->StartBatchChanges();
frameSelection->StartBatchChanges(aDetails);
}
}
void Selection::EndBatchChanges(int16_t aReason) {
void Selection::EndBatchChanges(const char* aDetails, int16_t aReasons) {
if (mFrameSelection) {
RefPtr<nsFrameSelection> frameSelection = mFrameSelection;
frameSelection->EndBatchChanges(aReason);
frameSelection->EndBatchChanges(aDetails, aReasons);
}
}
@ -3403,7 +3445,7 @@ void Selection::SetBaseAndExtentInternal(InLimiter aInLimiter,
// after we set the direction.
// XXX If they are disconnected, shouldn't we return error before allocating
// new nsRange instance?
SelectionBatcher batch(this);
SelectionBatcher batch(this, __FUNCTION__);
const Maybe<int32_t> order =
nsContentUtils::ComparePoints(aAnchorRef, aFocusRef);
if (order && (*order <= 0)) {
@ -3442,7 +3484,7 @@ void Selection::SetStartAndEndInternal(InLimiter aInLimiter,
}
// Don't fire "selectionchange" event until everything done.
SelectionBatcher batch(this);
SelectionBatcher batch(this, __FUNCTION__);
if (aInLimiter == InLimiter::eYes) {
if (!mFrameSelection ||

Просмотреть файл

@ -74,12 +74,25 @@ class Selection final : public nsSupportsWeakReference,
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(Selection)
// match this up with EndbatchChanges. will stop ui updates while multiple
// selection methods are called
void StartBatchChanges();
/**
* Match this up with EndbatchChanges. will stop ui updates while multiple
* selection methods are called
*
* @param aDetails string to explian why this is called. This won't be
* stored nor exposed to selection listeners etc. Just for logging.
*/
void StartBatchChanges(const char* aDetails);
// match this up with StartBatchChanges
void EndBatchChanges(int16_t aReason = nsISelectionListener::NO_REASON);
/**
* Match this up with StartBatchChanges
*
* @param aDetails string to explian why this is called. This won't be
* stored nor exposed to selection listeners etc. Just for logging.
* @param aReasons potentially multiple of the reasons defined in
* nsISelectionListener.idl
*/
void EndBatchChanges(const char* aDetails,
int16_t aReason = nsISelectionListener::NO_REASON);
/**
* NotifyAutoCopy() starts to notify AutoCopyListener of selection changes.
@ -938,24 +951,36 @@ class Selection final : public nsSupportsWeakReference,
// Stack-class to turn on/off selection batching.
class MOZ_STACK_CLASS SelectionBatcher final {
private:
RefPtr<Selection> mSelection;
int16_t mReason;
const RefPtr<Selection> mSelection;
const int16_t mReasons;
const char* const mRequesterFuncName;
public:
explicit SelectionBatcher(Selection& aSelectionRef)
: SelectionBatcher(&aSelectionRef) {}
/**
* @param aRequesterFuncName function name which wants the selection batch.
* This won't be stored nor exposed to selection listeners etc, used only for
* logging. This MUST be living when the destructor runs.
*/
// TODO: Mark these constructors `MOZ_CAN_RUN_SCRIPT` because the destructor
// may run script via nsISelectionListener.
explicit SelectionBatcher(Selection& aSelectionRef,
const char* aRequesterFuncName,
int16_t aReasons = nsISelectionListener::NO_REASON)
: SelectionBatcher(&aSelectionRef, aRequesterFuncName, aReasons) {}
explicit SelectionBatcher(Selection* aSelection,
int16_t aReason = nsISelectionListener::NO_REASON) {
mSelection = aSelection;
mReason = aReason;
const char* aRequesterFuncName,
int16_t aReasons = nsISelectionListener::NO_REASON)
: mSelection(aSelection),
mReasons(aReasons),
mRequesterFuncName(aRequesterFuncName) {
if (mSelection) {
mSelection->StartBatchChanges();
mSelection->StartBatchChanges(mRequesterFuncName);
}
}
~SelectionBatcher() {
if (mSelection) {
mSelection->EndBatchChanges(mReason);
mSelection->EndBatchChanges(mRequesterFuncName, mReasons);
}
}
};

Просмотреть файл

@ -29,4 +29,13 @@ interface nsISelectionListener : nsISupports
in short reason);
};
%{C++
namespace mozilla {
/**
* Returning names of `nsISelectionListener::*_REASON` in aReasons.
*/
nsCString SelectionChangeReasonsToCString(int16_t aReasons);
} // namespace mozilla
%}

Просмотреть файл

@ -2334,7 +2334,8 @@ void TextControlState::SetRangeText(const nsAString& aReplacement,
Selection* selection =
mSelCon ? mSelCon->GetSelection(SelectionType::eNormal) : nullptr;
SelectionBatcher selectionBatcher(
selection, nsISelectionListener::JS_REASON); // no-op if nullptr
selection, __FUNCTION__,
nsISelectionListener::JS_REASON); // no-op if nullptr
MOZ_ASSERT(aStart <= aEnd);
value.Replace(aStart, aEnd - aStart, aReplacement);
@ -2787,7 +2788,7 @@ bool TextControlState::SetValueWithTextEditor(
// FYI: It's safe to use raw pointer for selection here because
// SelectionBatcher will grab it with RefPtr.
Selection* selection = mSelCon->GetSelection(SelectionType::eNormal);
SelectionBatcher selectionBatcher(selection);
SelectionBatcher selectionBatcher(selection, __FUNCTION__);
// get the flags, remove readonly, disabled and max-length,
// set the value, restore flags

Просмотреть файл

@ -288,7 +288,7 @@ nsresult CompositionTransaction::SetIMESelection(
return NS_ERROR_NOT_INITIALIZED;
}
SelectionBatcher selectionBatcher(selection);
SelectionBatcher selectionBatcher(selection, __FUNCTION__);
// First, remove all selections of IME composition.
static const RawSelectionType kIMESelections[] = {

Просмотреть файл

@ -908,7 +908,7 @@ nsresult EditorBase::DoTransactionInternal(nsITransaction* aTransaction) {
// XXX: re-entry during initial reflow. - kin
// get the selection and start a batch change
SelectionBatcher selectionBatcher(SelectionRef());
SelectionBatcher selectionBatcher(SelectionRef(), __FUNCTION__);
if (mTransactionManager) {
RefPtr<TransactionManager> transactionManager(mTransactionManager);
@ -1016,7 +1016,7 @@ nsresult EditorBase::UndoAsAction(uint32_t aCount, nsIPrincipal* aPrincipal) {
return EditorBase::ToGenericNSResult(rv);
}
AutoUpdateViewBatch preventSelectionChangeEvent(*this);
AutoUpdateViewBatch preventSelectionChangeEvent(*this, __FUNCTION__);
NotifyEditorObservers(eNotifyEditorObserversOfBefore);
if (NS_WARN_IF(!CanUndo()) || NS_WARN_IF(Destroyed())) {
@ -1081,7 +1081,7 @@ nsresult EditorBase::RedoAsAction(uint32_t aCount, nsIPrincipal* aPrincipal) {
return EditorBase::ToGenericNSResult(rv);
}
AutoUpdateViewBatch preventSelectionChangeEvent(*this);
AutoUpdateViewBatch preventSelectionChangeEvent(*this, __FUNCTION__);
NotifyEditorObservers(eNotifyEditorObserversOfBefore);
if (NS_WARN_IF(!CanRedo()) || NS_WARN_IF(Destroyed())) {
@ -1124,12 +1124,12 @@ NS_IMETHODIMP EditorBase::BeginTransaction() {
return NS_ERROR_FAILURE;
}
BeginTransactionInternal();
BeginTransactionInternal(__FUNCTION__);
return NS_OK;
}
void EditorBase::BeginTransactionInternal() {
BeginUpdateViewBatch();
void EditorBase::BeginTransactionInternal(const char* aRequesterFuncName) {
BeginUpdateViewBatch(aRequesterFuncName);
if (NS_WARN_IF(!mTransactionManager)) {
return;
@ -1147,11 +1147,11 @@ NS_IMETHODIMP EditorBase::EndTransaction() {
return NS_ERROR_FAILURE;
}
EndTransactionInternal();
EndTransactionInternal(__FUNCTION__);
return NS_OK;
}
void EditorBase::EndTransactionInternal() {
void EditorBase::EndTransactionInternal(const char* aRequesterFuncName) {
if (mTransactionManager) {
RefPtr<TransactionManager> transactionManager(mTransactionManager);
DebugOnly<nsresult> rvIgnored = transactionManager->EndBatch(false);
@ -1159,17 +1159,18 @@ void EditorBase::EndTransactionInternal() {
"TransactionManager::EndBatch() failed, but ignored");
}
EndUpdateViewBatch();
EndUpdateViewBatch(aRequesterFuncName);
}
void EditorBase::BeginPlaceholderTransaction(nsStaticAtom& aTransactionName) {
void EditorBase::BeginPlaceholderTransaction(nsStaticAtom& aTransactionName,
const char* aRequesterFuncName) {
MOZ_ASSERT(IsEditActionDataAvailable());
MOZ_ASSERT(mPlaceholderBatch >= 0, "negative placeholder batch count!");
if (!mPlaceholderBatch) {
NotifyEditorObservers(eNotifyEditorObserversOfBefore);
// time to turn on the batch
BeginUpdateViewBatch();
BeginUpdateViewBatch(aRequesterFuncName);
mPlaceholderTransaction = nullptr;
mPlaceholderName = &aTransactionName;
mSelState.emplace();
@ -1187,7 +1188,8 @@ void EditorBase::BeginPlaceholderTransaction(nsStaticAtom& aTransactionName) {
}
void EditorBase::EndPlaceholderTransaction(
ScrollSelectionIntoView aScrollSelectionIntoView) {
ScrollSelectionIntoView aScrollSelectionIntoView,
const char* aRequesterFuncName) {
MOZ_ASSERT(IsEditActionDataAvailable());
MOZ_ASSERT(mPlaceholderBatch > 0,
"zero or negative placeholder batch count when ending batch!");
@ -1202,7 +1204,7 @@ void EditorBase::EndPlaceholderTransaction(
SelectionRef().SetCanCacheFrameOffset(true);
// time to turn off the batch
EndUpdateViewBatch();
EndUpdateViewBatch(aRequesterFuncName);
// make sure selection is in view
// After ScrollSelectionFocusIntoView(), the pending notifications might be
@ -1678,7 +1680,8 @@ nsresult EditorBase::CutAsAction(nsIPrincipal* aPrincipal) {
// XXX This transaction name is referred by PlaceholderTransaction::Merge()
// so that we need to keep using it here.
AutoPlaceholderBatch treatAsOneTransaction(*this, *nsGkAtoms::DeleteTxnName,
ScrollSelectionIntoView::Yes);
ScrollSelectionIntoView::Yes,
__FUNCTION__);
rv = DeleteSelectionAsSubAction(
eNone, IsTextEditor() ? nsIEditor::eNoStrip : nsIEditor::eStrip);
NS_WARNING_ASSERTION(
@ -2610,8 +2613,8 @@ NS_IMETHODIMP EditorBase::CloneAttributes(Element* aDestElement,
void EditorBase::CloneAttributesWithTransaction(Element& aDestElement,
Element& aSourceElement) {
AutoPlaceholderBatch treatAsOneTransaction(*this,
ScrollSelectionIntoView::Yes);
AutoPlaceholderBatch treatAsOneTransaction(
*this, ScrollSelectionIntoView::Yes, __FUNCTION__);
// Use transaction system for undo only if destination is already in the
// document
@ -2980,11 +2983,11 @@ nsresult EditorBase::InsertTextIntoTextNodeWithTransaction(
// XXX We may not need these view batches anymore. This is handled at a
// higher level now I believe.
BeginUpdateViewBatch();
BeginUpdateViewBatch(__FUNCTION__);
nsresult rv = DoTransactionInternal(transaction);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
"EditorBase::DoTransactionInternal() failed");
EndUpdateViewBatch();
EndUpdateViewBatch(__FUNCTION__);
if (IsHTMLEditor() && pointToInsert.IsSet()) {
auto [begin, end] = ComputeInsertedRange(pointToInsert, aStringToInsert);
@ -3408,23 +3411,23 @@ nsresult EditorBase::EnsurePaddingBRElementInMultilineEditor() {
return NS_OK;
}
void EditorBase::BeginUpdateViewBatch() {
void EditorBase::BeginUpdateViewBatch(const char* aRequesterFuncName) {
MOZ_ASSERT(IsEditActionDataAvailable());
MOZ_ASSERT(mUpdateCount >= 0, "bad state");
if (!mUpdateCount) {
// Turn off selection updates and notifications.
SelectionRef().StartBatchChanges();
SelectionRef().StartBatchChanges(aRequesterFuncName);
}
mUpdateCount++;
}
void EditorBase::EndUpdateViewBatch() {
void EditorBase::EndUpdateViewBatch(const char* aRequesterFuncName) {
MOZ_ASSERT(IsEditActionDataAvailable());
MOZ_ASSERT(mUpdateCount > 0, "bad state");
if (mUpdateCount <= 0) {
if (NS_WARN_IF(mUpdateCount <= 0)) {
mUpdateCount = 0;
return;
}
@ -3434,7 +3437,7 @@ void EditorBase::EndUpdateViewBatch() {
}
// Turn selection updating and notifications back on.
SelectionRef().EndBatchChanges();
SelectionRef().EndBatchChanges(aRequesterFuncName);
}
TextComposition* EditorBase::GetComposition() const { return mComposition; }
@ -3595,7 +3598,8 @@ nsresult EditorBase::OnCompositionChange(
{
AutoPlaceholderBatch treatAsOneTransaction(*this, *nsGkAtoms::IMETxnName,
ScrollSelectionIntoView::Yes);
ScrollSelectionIntoView::Yes,
__FUNCTION__);
MOZ_ASSERT(
mIsInEditSubAction,
@ -4175,7 +4179,8 @@ nsresult EditorBase::DeleteSelectionAsAction(
// delete placeholder txns merge.
AutoPlaceholderBatch treatAsOneTransaction(*this, *nsGkAtoms::DeleteTxnName,
ScrollSelectionIntoView::Yes);
ScrollSelectionIntoView::Yes,
__FUNCTION__);
rv = DeleteSelectionAsSubAction(aDirectionAndAmount, aStripWrappers);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
"EditorBase::DeleteSelectionAsSubAction() failed");
@ -4407,11 +4412,11 @@ nsresult EditorBase::HandleDropEvent(DragEvent* aDropEvent) {
}
// Combine any deletion and drop insertion into one transaction.
AutoPlaceholderBatch treatAsOneTransaction(*this,
ScrollSelectionIntoView::Yes);
AutoPlaceholderBatch treatAsOneTransaction(
*this, ScrollSelectionIntoView::Yes, __FUNCTION__);
// Don't dispatch "selectionchange" event until inserting all contents.
SelectionBatcher selectionBatcher(SelectionRef());
SelectionBatcher selectionBatcher(SelectionRef(), __FUNCTION__);
// Track dropped point with nsRange because we shouldn't insert the
// dropped content into different position even if some event listeners
@ -4561,7 +4566,8 @@ nsresult EditorBase::DeleteSelectionByDragAsAction(bool aDispatchInputEvent) {
// But keep using placeholder transaction for "insertFromDrop" if there is.
Maybe<AutoPlaceholderBatch> treatAsOneTransaction;
if (requestedByAnotherEditor) {
treatAsOneTransaction.emplace(*this, ScrollSelectionIntoView::Yes);
treatAsOneTransaction.emplace(*this, ScrollSelectionIntoView::Yes,
__FUNCTION__);
}
rv = DeleteSelectionAsSubAction(nsIEditor::eNone, IsTextEditor()
@ -4967,7 +4973,8 @@ nsresult EditorBase::OnInputText(const nsAString& aStringToInsert) {
}
AutoPlaceholderBatch treatAsOneTransaction(*this, *nsGkAtoms::TypingTxnName,
ScrollSelectionIntoView::Yes);
ScrollSelectionIntoView::Yes,
__FUNCTION__);
rv = InsertTextAsSubAction(aStringToInsert, SelectionHandling::Delete);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
"EditorBase::InsertTextAsSubAction() failed");
@ -5028,8 +5035,8 @@ nsresult EditorBase::ReplaceTextAsAction(
return EditorBase::ToGenericNSResult(rv);
}
AutoPlaceholderBatch treatAsOneTransaction(*this,
ScrollSelectionIntoView::Yes);
AutoPlaceholderBatch treatAsOneTransaction(
*this, ScrollSelectionIntoView::Yes, __FUNCTION__);
// This should emulates inserting text for better undo/redo behavior.
IgnoredErrorResult ignoredError;
@ -5063,7 +5070,7 @@ nsresult EditorBase::ReplaceTextAsAction(
// Note that do not notify selectionchange caused by selecting all text
// because it's preparation of our delete implementation so web apps
// shouldn't receive such selectionchange before the first mutation.
AutoUpdateViewBatch preventSelectionChangeEvent(*this);
AutoUpdateViewBatch preventSelectionChangeEvent(*this, __FUNCTION__);
// Select the range but as far as possible, we should not create new range
// even if it's part of special Selection.
@ -5928,8 +5935,8 @@ nsresult EditorBase::InsertTextAsAction(const nsAString& aStringToInsert,
if (IsTextEditor()) {
nsContentUtils::PlatformToDOMLineBreaks(stringToInsert);
}
AutoPlaceholderBatch treatAsOneTransaction(*this,
ScrollSelectionIntoView::Yes);
AutoPlaceholderBatch treatAsOneTransaction(
*this, ScrollSelectionIntoView::Yes, __FUNCTION__);
rv = InsertTextAsSubAction(stringToInsert, SelectionHandling::Delete);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
"EditorBase::InsertTextAsSubAction() failed");
@ -6092,7 +6099,7 @@ void EditorBase::AutoEditActionDataSetter::UpdateSelectionCache(
// If the old selection is in batch, we should end the batch which
// `EditorBase::BeginUpdateViewBatch` started.
if (mEditorBase.mUpdateCount && mSelection) {
mSelection->EndBatchChanges();
mSelection->EndBatchChanges(__FUNCTION__);
}
Selection* previousSelection = mSelection;
@ -6117,7 +6124,7 @@ void EditorBase::AutoEditActionDataSetter::UpdateSelectionCache(
// Restart the batching in the new selection.
if (mEditorBase.mUpdateCount) {
aSelection.StartBatchChanges();
aSelection.StartBatchChanges(__FUNCTION__);
}
}

Просмотреть файл

@ -2116,13 +2116,14 @@ class EditorBase : public nsIEditor,
* manager batches.
*/
MOZ_CAN_RUN_SCRIPT_BOUNDARY void BeginPlaceholderTransaction(
nsStaticAtom& aTransactionName);
nsStaticAtom& aTransactionName, const char* aRequesterFuncName);
enum class ScrollSelectionIntoView { No, Yes };
MOZ_CAN_RUN_SCRIPT_BOUNDARY void EndPlaceholderTransaction(
ScrollSelectionIntoView aScrollSelectionIntoView);
ScrollSelectionIntoView aScrollSelectionIntoView,
const char* aRequesterFuncName);
void BeginUpdateViewBatch();
MOZ_CAN_RUN_SCRIPT void EndUpdateViewBatch();
void BeginUpdateViewBatch(const char* aRequesterFuncName);
MOZ_CAN_RUN_SCRIPT void EndUpdateViewBatch(const char* aRequesterFuncName);
/**
* Used by HTMLEditor::AutoTransactionBatch, nsIEditor::BeginTransaction
@ -2132,8 +2133,10 @@ class EditorBase : public nsIEditor,
* XXX What's the difference with PlaceholderTransaction? Should we always
* use it instead?
*/
MOZ_CAN_RUN_SCRIPT void BeginTransactionInternal();
MOZ_CAN_RUN_SCRIPT void EndTransactionInternal();
MOZ_CAN_RUN_SCRIPT void BeginTransactionInternal(
const char* aRequesterFuncName);
MOZ_CAN_RUN_SCRIPT void EndTransactionInternal(
const char* aRequesterFuncName);
protected: // Shouldn't be used by friend classes
/**
@ -2575,28 +2578,41 @@ class EditorBase : public nsIEditor,
*/
class MOZ_RAII AutoPlaceholderBatch final {
public:
/**
* @param aRequesterFuncName function name which wants to end the batch.
* This won't be stored nor exposed to selection listeners etc, used only
* for logging. This MUST be alive when the destructor runs.
*/
AutoPlaceholderBatch(EditorBase& aEditorBase,
ScrollSelectionIntoView aScrollSelectionIntoView)
ScrollSelectionIntoView aScrollSelectionIntoView,
const char* aRequesterFuncName)
: mEditorBase(aEditorBase),
mScrollSelectionIntoView(aScrollSelectionIntoView) {
mEditorBase->BeginPlaceholderTransaction(*nsGkAtoms::_empty);
mScrollSelectionIntoView(aScrollSelectionIntoView),
mRequesterFuncName(aRequesterFuncName) {
mEditorBase->BeginPlaceholderTransaction(*nsGkAtoms::_empty,
mRequesterFuncName);
}
AutoPlaceholderBatch(EditorBase& aEditorBase,
nsStaticAtom& aTransactionName,
ScrollSelectionIntoView aScrollSelectionIntoView)
ScrollSelectionIntoView aScrollSelectionIntoView,
const char* aRequesterFuncName)
: mEditorBase(aEditorBase),
mScrollSelectionIntoView(aScrollSelectionIntoView) {
mEditorBase->BeginPlaceholderTransaction(aTransactionName);
mScrollSelectionIntoView(aScrollSelectionIntoView),
mRequesterFuncName(aRequesterFuncName) {
mEditorBase->BeginPlaceholderTransaction(aTransactionName,
mRequesterFuncName);
}
~AutoPlaceholderBatch() {
mEditorBase->EndPlaceholderTransaction(mScrollSelectionIntoView);
mEditorBase->EndPlaceholderTransaction(mScrollSelectionIntoView,
mRequesterFuncName);
}
protected:
OwningNonNull<EditorBase> mEditorBase;
ScrollSelectionIntoView mScrollSelectionIntoView;
const OwningNonNull<EditorBase> mEditorBase;
const ScrollSelectionIntoView mScrollSelectionIntoView;
const char* const mRequesterFuncName;
};
/**
@ -2663,17 +2679,24 @@ class EditorBase : public nsIEditor,
*/
class MOZ_RAII AutoUpdateViewBatch final {
public:
MOZ_CAN_RUN_SCRIPT explicit AutoUpdateViewBatch(EditorBase& aEditorBase)
: mEditorBase(aEditorBase) {
mEditorBase.BeginUpdateViewBatch();
/**
* @param aRequesterFuncName function name which wants to end the batch.
* This won't be stored nor exposed to selection listeners etc, used only
* for logging. This MUST be alive when the destructor runs.
*/
MOZ_CAN_RUN_SCRIPT explicit AutoUpdateViewBatch(
EditorBase& aEditorBase, const char* aRequesterFuncName)
: mEditorBase(aEditorBase), mRequesterFuncName(aRequesterFuncName) {
mEditorBase.BeginUpdateViewBatch(mRequesterFuncName);
}
MOZ_CAN_RUN_SCRIPT ~AutoUpdateViewBatch() {
MOZ_KnownLive(mEditorBase).EndUpdateViewBatch();
MOZ_KnownLive(mEditorBase).EndUpdateViewBatch(mRequesterFuncName);
}
protected:
EditorBase& mEditorBase;
const char* const mRequesterFuncName;
};
protected:

Просмотреть файл

@ -567,8 +567,8 @@ nsresult HTMLEditor::SetFinalPosition(int32_t aX, int32_t aY) {
y.AppendInt(newY);
// we want one transaction only from a user's point of view
AutoPlaceholderBatch treatAsOneTransaction(*this,
ScrollSelectionIntoView::Yes);
AutoPlaceholderBatch treatAsOneTransaction(
*this, ScrollSelectionIntoView::Yes, __FUNCTION__);
if (NS_WARN_IF(!mAbsolutelyPositionedObject)) {
return NS_ERROR_FAILURE;
@ -647,8 +647,8 @@ nsresult HTMLEditor::SetPositionToAbsoluteOrStatic(Element& aElement,
nsresult HTMLEditor::SetPositionToAbsolute(Element& aElement) {
MOZ_ASSERT(IsEditActionDataAvailable());
AutoPlaceholderBatch treatAsOneTransaction(*this,
ScrollSelectionIntoView::Yes);
AutoPlaceholderBatch treatAsOneTransaction(
*this, ScrollSelectionIntoView::Yes, __FUNCTION__);
int32_t x, y;
DebugOnly<nsresult> rvIgnored = GetElementOrigin(aElement, x, y);
@ -708,8 +708,8 @@ nsresult HTMLEditor::SetPositionToStatic(Element& aElement) {
return NS_ERROR_INVALID_ARG;
}
AutoPlaceholderBatch treatAsOneTransaction(*this,
ScrollSelectionIntoView::Yes);
AutoPlaceholderBatch treatAsOneTransaction(
*this, ScrollSelectionIntoView::Yes, __FUNCTION__);
nsresult rv;
// MOZ_KnownLive(*styledElement): aElement's lifetime must be guarantted
@ -854,8 +854,8 @@ NS_IMETHODIMP HTMLEditor::GetGridSize(uint32_t* aSize) {
nsresult HTMLEditor::SetTopAndLeftWithTransaction(
nsStyledElement& aStyledElement, int32_t aX, int32_t aY) {
AutoPlaceholderBatch treatAsOneTransaction(*this,
ScrollSelectionIntoView::Yes);
AutoPlaceholderBatch treatAsOneTransaction(
*this, ScrollSelectionIntoView::Yes, __FUNCTION__);
nsresult rv;
rv = mCSSEditUtils->SetCSSPropertyPixelsWithTransaction(aStyledElement,
*nsGkAtoms::left, aX);

Просмотреть файл

@ -1392,7 +1392,8 @@ nsresult HTMLEditor::InsertLineBreakAsSubAction() {
// XXX This may be called by execCommand() with "insertLineBreak".
// In such case, naming the transaction "TypingTxnName" is odd.
AutoPlaceholderBatch treatAsOneTransaction(*this, *nsGkAtoms::TypingTxnName,
ScrollSelectionIntoView::Yes);
ScrollSelectionIntoView::Yes,
__FUNCTION__);
// calling it text insertion to trigger moz br treatment by rules
// XXX Why do we use EditSubAction::eInsertText here? Looks like
@ -1519,7 +1520,8 @@ EditActionResult HTMLEditor::InsertParagraphSeparatorAsSubAction() {
// XXX This may be called by execCommand() with "insertParagraph".
// In such case, naming the transaction "TypingTxnName" is odd.
AutoPlaceholderBatch treatAsOneTransaction(*this, *nsGkAtoms::TypingTxnName,
ScrollSelectionIntoView::Yes);
ScrollSelectionIntoView::Yes,
__FUNCTION__);
IgnoredErrorResult ignoredError;
AutoEditSubActionNotifier startToHandleEditSubAction(
@ -2856,8 +2858,8 @@ EditActionResult HTMLEditor::MakeOrChangeListAndListItemAsSubAction(
return EditActionIgnored();
}
AutoPlaceholderBatch treatAsOneTransaction(*this,
ScrollSelectionIntoView::Yes);
AutoPlaceholderBatch treatAsOneTransaction(
*this, ScrollSelectionIntoView::Yes, __FUNCTION__);
// XXX EditSubAction::eCreateOrChangeDefinitionListItem and
// EditSubAction::eCreateOrChangeList are treated differently in
@ -3449,8 +3451,8 @@ nsresult HTMLEditor::RemoveListAtSelectionAsSubAction() {
return result.Rv();
}
AutoPlaceholderBatch treatAsOneTransaction(*this,
ScrollSelectionIntoView::Yes);
AutoPlaceholderBatch treatAsOneTransaction(
*this, ScrollSelectionIntoView::Yes, __FUNCTION__);
IgnoredErrorResult ignoredError;
AutoEditSubActionNotifier startToHandleEditSubAction(
*this, EditSubAction::eRemoveList, nsIEditor::eNext, ignoredError);
@ -3757,8 +3759,8 @@ nsresult HTMLEditor::MaybeInsertPaddingBRElementForEmptyLastLineAtSelection() {
EditActionResult HTMLEditor::IndentAsSubAction() {
MOZ_ASSERT(IsEditActionDataAvailable());
AutoPlaceholderBatch treatAsOneTransaction(*this,
ScrollSelectionIntoView::Yes);
AutoPlaceholderBatch treatAsOneTransaction(
*this, ScrollSelectionIntoView::Yes, __FUNCTION__);
IgnoredErrorResult ignoredError;
AutoEditSubActionNotifier startToHandleEditSubAction(
*this, EditSubAction::eIndent, nsIEditor::eNext, ignoredError);
@ -4425,8 +4427,8 @@ nsresult HTMLEditor::HandleHTMLIndentAtSelectionInternal() {
EditActionResult HTMLEditor::OutdentAsSubAction() {
MOZ_ASSERT(IsEditActionDataAvailable());
AutoPlaceholderBatch treatAsOneTransaction(*this,
ScrollSelectionIntoView::Yes);
AutoPlaceholderBatch treatAsOneTransaction(
*this, ScrollSelectionIntoView::Yes, __FUNCTION__);
IgnoredErrorResult ignoredError;
AutoEditSubActionNotifier startToHandleEditSubAction(
*this, EditSubAction::eOutdent, nsIEditor::eNext, ignoredError);
@ -5191,8 +5193,8 @@ nsresult HTMLEditor::CreateStyleForInsertText(
EditActionResult HTMLEditor::AlignAsSubAction(const nsAString& aAlignType) {
MOZ_ASSERT(IsEditActionDataAvailable());
AutoPlaceholderBatch treatAsOneTransaction(*this,
ScrollSelectionIntoView::Yes);
AutoPlaceholderBatch treatAsOneTransaction(
*this, ScrollSelectionIntoView::Yes, __FUNCTION__);
IgnoredErrorResult ignoredError;
AutoEditSubActionNotifier startToHandleEditSubAction(
*this, EditSubAction::eSetOrClearAlignment, nsIEditor::eNext,
@ -9515,8 +9517,8 @@ nsresult HTMLEditor::ChangeMarginStart(Element& aElement,
EditActionResult HTMLEditor::SetSelectionToAbsoluteAsSubAction() {
MOZ_ASSERT(IsTopLevelEditSubActionDataAvailable());
AutoPlaceholderBatch treatAsOneTransaction(*this,
ScrollSelectionIntoView::Yes);
AutoPlaceholderBatch treatAsOneTransaction(
*this, ScrollSelectionIntoView::Yes, __FUNCTION__);
IgnoredErrorResult ignoredError;
AutoEditSubActionNotifier startToHandleEditSubAction(
*this, EditSubAction::eSetPositionToAbsolute, nsIEditor::eNext,
@ -9920,8 +9922,8 @@ nsresult HTMLEditor::MoveSelectedContentsToDivElementToMakeItAbsolutePosition(
EditActionResult HTMLEditor::SetSelectionToStaticAsSubAction() {
MOZ_ASSERT(IsEditActionDataAvailable());
AutoPlaceholderBatch treatAsOneTransaction(*this,
ScrollSelectionIntoView::Yes);
AutoPlaceholderBatch treatAsOneTransaction(
*this, ScrollSelectionIntoView::Yes, __FUNCTION__);
IgnoredErrorResult ignoredError;
AutoEditSubActionNotifier startToHandleEditSubAction(
*this, EditSubAction::eSetPositionToStatic, nsIEditor::eNext,
@ -9999,8 +10001,8 @@ EditActionResult HTMLEditor::SetSelectionToStaticAsSubAction() {
EditActionResult HTMLEditor::AddZIndexAsSubAction(int32_t aChange) {
MOZ_ASSERT(IsEditActionDataAvailable());
AutoPlaceholderBatch treatAsOneTransaction(*this,
ScrollSelectionIntoView::Yes);
AutoPlaceholderBatch treatAsOneTransaction(
*this, ScrollSelectionIntoView::Yes, __FUNCTION__);
IgnoredErrorResult ignoredError;
AutoEditSubActionNotifier startToHandleEditSubAction(
*this,

Просмотреть файл

@ -1399,8 +1399,8 @@ nsresult HTMLEditor::ReplaceHeadContentsWithSourceWithTransaction(
// Mac linebreaks: Map any remaining CR to LF:
inputString.ReplaceSubstring(u"\r"_ns, u"\n"_ns);
AutoPlaceholderBatch treatAsOneTransaction(*this,
ScrollSelectionIntoView::Yes);
AutoPlaceholderBatch treatAsOneTransaction(
*this, ScrollSelectionIntoView::Yes, __FUNCTION__);
// Get the first range in the selection, for context:
RefPtr<const nsRange> range = SelectionRef().GetRangeAt(0);
@ -1504,8 +1504,8 @@ NS_IMETHODIMP HTMLEditor::RebuildDocumentFromSource(
}
// Time to change the document
AutoPlaceholderBatch treatAsOneTransaction(*this,
ScrollSelectionIntoView::Yes);
AutoPlaceholderBatch treatAsOneTransaction(
*this, ScrollSelectionIntoView::Yes, __FUNCTION__);
nsReadingIterator<char16_t> endtotal;
aSourceString.EndReading(endtotal);
@ -1728,8 +1728,8 @@ nsresult HTMLEditor::InsertElementAtSelectionAsAction(
UndefineCaretBidiLevel();
AutoPlaceholderBatch treatAsOneTransaction(*this,
ScrollSelectionIntoView::Yes);
AutoPlaceholderBatch treatAsOneTransaction(
*this, ScrollSelectionIntoView::Yes, __FUNCTION__);
IgnoredErrorResult ignoredError;
AutoEditSubActionNotifier startToHandleEditSubAction(
*this, EditSubAction::eInsertElement, nsIEditor::eNext, ignoredError);
@ -2497,8 +2497,8 @@ nsresult HTMLEditor::FormatBlockContainerAsSubAction(nsAtom& aTagName) {
MOZ_ASSERT(&aTagName != nsGkAtoms::dd && &aTagName != nsGkAtoms::dt);
AutoPlaceholderBatch treatAsOneTransaction(*this,
ScrollSelectionIntoView::Yes);
AutoPlaceholderBatch treatAsOneTransaction(
*this, ScrollSelectionIntoView::Yes, __FUNCTION__);
IgnoredErrorResult ignoredError;
AutoEditSubActionNotifier startToHandleEditSubAction(
*this, EditSubAction::eCreateOrRemoveBlock, nsIEditor::eNext,
@ -3173,8 +3173,8 @@ nsresult HTMLEditor::InsertLinkAroundSelectionAsAction(
return NS_OK;
}
AutoPlaceholderBatch treatAsOneTransaction(*this,
ScrollSelectionIntoView::Yes);
AutoPlaceholderBatch treatAsOneTransaction(
*this, ScrollSelectionIntoView::Yes, __FUNCTION__);
// Set all attributes found on the supplied anchor element
RefPtr<nsDOMAttributeMap> attributeMap = anchor->Attributes();
@ -5364,8 +5364,8 @@ nsresult HTMLEditor::SetCSSBackgroundColorWithTransaction(
bool selectionIsCollapsed = SelectionRef().IsCollapsed();
AutoPlaceholderBatch treatAsOneTransaction(*this,
ScrollSelectionIntoView::Yes);
AutoPlaceholderBatch treatAsOneTransaction(
*this, ScrollSelectionIntoView::Yes, __FUNCTION__);
IgnoredErrorResult ignoredError;
AutoEditSubActionNotifier startToHandleEditSubAction(
*this, EditSubAction::eInsertElement, nsIEditor::eNext, ignoredError);

Просмотреть файл

@ -4477,18 +4477,25 @@ class HTMLEditor final : public EditorBase,
*/
class MOZ_RAII AutoTransactionBatch final {
public:
MOZ_CAN_RUN_SCRIPT explicit AutoTransactionBatch(HTMLEditor& aHTMLEditor)
: mHTMLEditor(aHTMLEditor) {
MOZ_KnownLive(mHTMLEditor).BeginTransactionInternal();
/**
* @param aRequesterFuncName function name which wants to end the batch.
* This won't be stored nor exposed to selection listeners etc, used only
* for logging. This MUST be alive when the destructor runs.
*/
MOZ_CAN_RUN_SCRIPT explicit AutoTransactionBatch(
HTMLEditor& aHTMLEditor, const char* aRequesterFuncName)
: mHTMLEditor(aHTMLEditor), mRequesterFuncName(aRequesterFuncName) {
MOZ_KnownLive(mHTMLEditor).BeginTransactionInternal(mRequesterFuncName);
}
MOZ_CAN_RUN_SCRIPT ~AutoTransactionBatch() {
MOZ_KnownLive(mHTMLEditor).EndTransactionInternal();
MOZ_KnownLive(mHTMLEditor).EndTransactionInternal(mRequesterFuncName);
}
protected:
// The lifetime must be guaranteed by the creator of this instance.
MOZ_KNOWN_LIVE HTMLEditor& mHTMLEditor;
const char* const mRequesterFuncName;
};
RefPtr<TypeInState> mTypeInState;

Просмотреть файл

@ -147,8 +147,8 @@ nsresult HTMLEditor::LoadHTML(const nsAString& aInputString) {
return NS_ERROR_EDITOR_DESTROYED;
}
AutoPlaceholderBatch treatAsOneTransaction(*this,
ScrollSelectionIntoView::Yes);
AutoPlaceholderBatch treatAsOneTransaction(
*this, ScrollSelectionIntoView::Yes, __FUNCTION__);
IgnoredErrorResult ignoredError;
AutoEditSubActionNotifier startToHandleEditSubAction(
*this, EditSubAction::eInsertHTMLSource, nsIEditor::eNext, ignoredError);
@ -504,8 +504,8 @@ nsresult HTMLEditor::HTMLWithContextInserter::Run(
// force IME commit; set up rules sniffing and batching
mHTMLEditor.CommitComposition();
AutoPlaceholderBatch treatAsOneTransaction(mHTMLEditor,
ScrollSelectionIntoView::Yes);
AutoPlaceholderBatch treatAsOneTransaction(
mHTMLEditor, ScrollSelectionIntoView::Yes, __FUNCTION__);
IgnoredErrorResult ignoredError;
AutoEditSubActionNotifier startToHandleEditSubAction(
MOZ_KnownLive(mHTMLEditor), EditSubAction::ePasteHTMLContent,
@ -1513,8 +1513,8 @@ nsresult HTMLEditor::BlobReader::OnResult(const nsACString& aResult) {
return EditorBase::ToGenericNSResult(rv);
}
AutoPlaceholderBatch treatAsOneTransaction(*mHTMLEditor,
ScrollSelectionIntoView::Yes);
AutoPlaceholderBatch treatAsOneTransaction(
*mHTMLEditor, ScrollSelectionIntoView::Yes, __FUNCTION__);
EditorDOMPoint pointToInsert(mPointToInsert);
rv = MOZ_KnownLive(mHTMLEditor)
->DoInsertHTMLWithContext(stuffToPaste, u""_ns, u""_ns,
@ -1730,8 +1730,8 @@ nsresult HTMLEditor::InsertObject(const nsACString& aType, nsISupports* aObject,
return rv;
}
AutoPlaceholderBatch treatAsOneTransaction(*this,
ScrollSelectionIntoView::Yes);
AutoPlaceholderBatch treatAsOneTransaction(
*this, ScrollSelectionIntoView::Yes, __FUNCTION__);
rv = DoInsertHTMLWithContext(
stuffToPaste, u""_ns, u""_ns, NS_LITERAL_STRING_FROM_CSTRING(kFileMime),
aPointToInsert, aDoDeleteSelection, aIsSafe, false);
@ -1806,7 +1806,7 @@ nsresult HTMLEditor::InsertFromTransferable(nsITransferable* aTransferable,
getter_Copies(cfcontext));
if (NS_SUCCEEDED(rv) && !cffragment.IsEmpty()) {
AutoPlaceholderBatch treatAsOneTransaction(
*this, ScrollSelectionIntoView::Yes);
*this, ScrollSelectionIntoView::Yes, __FUNCTION__);
// If we have our private HTML flavor, we will only use the fragment
// from the CF_HTML. The rest comes from the clipboard.
if (aHavePrivateHTMLFlavor) {
@ -1850,7 +1850,7 @@ nsresult HTMLEditor::InsertFromTransferable(nsITransferable* aTransferable,
if (!stuffToPaste.IsEmpty()) {
AutoPlaceholderBatch treatAsOneTransaction(
*this, ScrollSelectionIntoView::Yes);
*this, ScrollSelectionIntoView::Yes, __FUNCTION__);
if (bestFlavor.EqualsLiteral(kHTMLMime)) {
nsresult rv = DoInsertHTMLWithContext(
stuffToPaste, aContextStr, aInfoStr, flavor, EditorDOMPoint(),
@ -2208,8 +2208,8 @@ nsresult HTMLEditor::PasteTransferableAsAction(nsITransferable* aTransferable,
RefPtr<DataTransfer> dataTransfer = GetInputEventDataTransfer();
if (dataTransfer->HasFile() && dataTransfer->MozItemCount() > 0) {
// Now aTransferable has moved to DataTransfer. Use DataTransfer.
AutoPlaceholderBatch treatAsOneTransaction(*this,
ScrollSelectionIntoView::Yes);
AutoPlaceholderBatch treatAsOneTransaction(
*this, ScrollSelectionIntoView::Yes, __FUNCTION__);
rv = InsertFromDataTransfer(dataTransfer, 0, nullptr, EditorDOMPoint(),
true);
@ -2437,8 +2437,8 @@ nsresult HTMLEditor::PasteAsQuotationAsAction(int32_t aClipboardType,
UndefineCaretBidiLevel();
AutoPlaceholderBatch treatAsOneTransaction(*this,
ScrollSelectionIntoView::Yes);
AutoPlaceholderBatch treatAsOneTransaction(
*this, ScrollSelectionIntoView::Yes, __FUNCTION__);
IgnoredErrorResult ignoredError;
AutoEditSubActionNotifier startToHandleEditSubAction(
*this, EditSubAction::eInsertQuotation, nsIEditor::eNext, ignoredError);
@ -2567,8 +2567,8 @@ nsresult HTMLEditor::PasteAsPlaintextQuotation(int32_t aSelectionType) {
return NS_OK;
}
AutoPlaceholderBatch treatAsOneTransaction(*this,
ScrollSelectionIntoView::Yes);
AutoPlaceholderBatch treatAsOneTransaction(
*this, ScrollSelectionIntoView::Yes, __FUNCTION__);
rv = InsertAsPlaintextQuotation(stuffToPaste, true, 0);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
"HTMLEditor::InsertAsPlaintextQuotation() failed");
@ -2663,9 +2663,9 @@ nsresult HTMLEditor::InsertTextWithQuotations(
// The whole operation should be undoable in one transaction:
// XXX Why isn't enough to use only AutoPlaceholderBatch here?
AutoTransactionBatch bundleAllTransactions(*this);
AutoPlaceholderBatch treatAsOneTransaction(*this,
ScrollSelectionIntoView::Yes);
AutoTransactionBatch bundleAllTransactions(*this, __FUNCTION__);
AutoPlaceholderBatch treatAsOneTransaction(
*this, ScrollSelectionIntoView::Yes, __FUNCTION__);
rv = InsertTextWithQuotationsInternal(aStringToInsert);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
@ -2785,8 +2785,8 @@ nsresult HTMLEditor::InsertAsQuotation(const nsAString& aQuotedText,
"CanHandleAndMaybeDispatchBeforeInputEvent(), failed");
return EditorBase::ToGenericNSResult(rv);
}
AutoPlaceholderBatch treatAsOneTransaction(*this,
ScrollSelectionIntoView::Yes);
AutoPlaceholderBatch treatAsOneTransaction(
*this, ScrollSelectionIntoView::Yes, __FUNCTION__);
rv = InsertAsPlaintextQuotation(aQuotedText, true, aNodeInserted);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
"HTMLEditor::InsertAsPlaintextQuotation() failed");
@ -2802,8 +2802,8 @@ nsresult HTMLEditor::InsertAsQuotation(const nsAString& aQuotedText,
return EditorBase::ToGenericNSResult(rv);
}
AutoPlaceholderBatch treatAsOneTransaction(*this,
ScrollSelectionIntoView::Yes);
AutoPlaceholderBatch treatAsOneTransaction(
*this, ScrollSelectionIntoView::Yes, __FUNCTION__);
nsAutoString citation;
rv = InsertAsCitedQuotationInternal(aQuotedText, citation, false,
aNodeInserted);
@ -3019,9 +3019,9 @@ NS_IMETHODIMP HTMLEditor::Rewrap(bool aRespectNewlines) {
// The whole operation in InsertTextWithQuotationsInternal() should be
// undoable in one transaction.
// XXX Why isn't enough to use only AutoPlaceholderBatch here?
AutoTransactionBatch bundleAllTransactions(*this);
AutoPlaceholderBatch treatAsOneTransaction(*this,
ScrollSelectionIntoView::Yes);
AutoTransactionBatch bundleAllTransactions(*this, __FUNCTION__);
AutoPlaceholderBatch treatAsOneTransaction(
*this, ScrollSelectionIntoView::Yes, __FUNCTION__);
rv = InsertTextWithQuotationsInternal(wrapped);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
"HTMLEditor::InsertTextWithQuotationsInternal() failed");
@ -3049,8 +3049,8 @@ NS_IMETHODIMP HTMLEditor::InsertAsCitedQuotation(const nsAString& aQuotedText,
return EditorBase::ToGenericNSResult(rv);
}
AutoPlaceholderBatch treatAsOneTransaction(*this,
ScrollSelectionIntoView::Yes);
AutoPlaceholderBatch treatAsOneTransaction(
*this, ScrollSelectionIntoView::Yes, __FUNCTION__);
rv = InsertAsPlaintextQuotation(aQuotedText, true, aNodeInserted);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
"HTMLEditor::InsertAsPlaintextQuotation() failed");
@ -3066,8 +3066,8 @@ NS_IMETHODIMP HTMLEditor::InsertAsCitedQuotation(const nsAString& aQuotedText,
return EditorBase::ToGenericNSResult(rv);
}
AutoPlaceholderBatch treatAsOneTransaction(*this,
ScrollSelectionIntoView::Yes);
AutoPlaceholderBatch treatAsOneTransaction(
*this, ScrollSelectionIntoView::Yes, __FUNCTION__);
rv = InsertAsCitedQuotationInternal(aQuotedText, aCitation, aInsertHTML,
aNodeInserted);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),

Просмотреть файл

@ -1260,8 +1260,8 @@ nsresult HTMLEditor::SetFinalSizeWithTransaction(int32_t aX, int32_t aY) {
: 0);
// we want one transaction only from a user's point of view
AutoPlaceholderBatch treatAsOneTransaction(*this,
ScrollSelectionIntoView::Yes);
AutoPlaceholderBatch treatAsOneTransaction(
*this, ScrollSelectionIntoView::Yes, __FUNCTION__);
RefPtr<Element> resizedElement(mResizedObject);
RefPtr<nsStyledElement> resizedStyleElement =
nsStyledElement::FromNodeOrNull(mResizedObject);

Просмотреть файл

@ -85,8 +85,8 @@ nsresult HTMLEditor::SetInlinePropertyAsAction(nsAtom& aProperty,
// XXX Due to bug 1659276 and bug 1659924, we should not scroll selection
// into view after setting the new style.
AutoPlaceholderBatch treatAsOneTransaction(*this,
ScrollSelectionIntoView::No);
AutoPlaceholderBatch treatAsOneTransaction(*this, ScrollSelectionIntoView::No,
__FUNCTION__);
nsAtom* property = &aProperty;
nsAtom* attribute = aAttribute;
@ -229,8 +229,8 @@ nsresult HTMLEditor::SetInlinePropertyInternal(
return result.Rv();
}
AutoPlaceholderBatch treatAsOneTransaction(*this,
ScrollSelectionIntoView::Yes);
AutoPlaceholderBatch treatAsOneTransaction(
*this, ScrollSelectionIntoView::Yes, __FUNCTION__);
IgnoredErrorResult ignoredError;
AutoEditSubActionNotifier startToHandleEditSubAction(
*this, EditSubAction::eInsertElement, nsIEditor::eNext, ignoredError);
@ -1724,8 +1724,8 @@ nsresult HTMLEditor::RemoveAllInlinePropertiesAsAction(
return EditorBase::ToGenericNSResult(rv);
}
AutoPlaceholderBatch treatAsOneTransaction(*this,
ScrollSelectionIntoView::Yes);
AutoPlaceholderBatch treatAsOneTransaction(
*this, ScrollSelectionIntoView::Yes, __FUNCTION__);
IgnoredErrorResult ignoredError;
AutoEditSubActionNotifier startToHandleEditSubAction(
*this, EditSubAction::eRemoveAllTextProperties, nsIEditor::eNext,
@ -1898,8 +1898,8 @@ nsresult HTMLEditor::RemoveInlinePropertyInternal(
return result.Rv();
}
AutoPlaceholderBatch treatAsOneTransaction(*this,
ScrollSelectionIntoView::Yes);
AutoPlaceholderBatch treatAsOneTransaction(
*this, ScrollSelectionIntoView::Yes, __FUNCTION__);
IgnoredErrorResult ignoredError;
AutoEditSubActionNotifier startToHandleEditSubAction(
*this, EditSubAction::eRemoveTextProperty, nsIEditor::eNext,
@ -2260,8 +2260,8 @@ nsresult HTMLEditor::RelativeFontChange(FontSize aDir) {
}
// Wrap with txn batching, rules sniffing, and selection preservation code
AutoPlaceholderBatch treatAsOneTransaction(*this,
ScrollSelectionIntoView::Yes);
AutoPlaceholderBatch treatAsOneTransaction(
*this, ScrollSelectionIntoView::Yes, __FUNCTION__);
IgnoredErrorResult ignoredError;
AutoEditSubActionNotifier startToHandleEditSubAction(
*this, EditSubAction::eSetTextProperty, nsIEditor::eNext, ignoredError);

Просмотреть файл

@ -237,8 +237,8 @@ nsresult HTMLEditor::InsertTableCellsWithTransaction(
MOZ_ASSERT_UNREACHABLE("Invalid InsertPosition");
}
AutoPlaceholderBatch treateAsOneTransaction(*this,
ScrollSelectionIntoView::Yes);
AutoPlaceholderBatch treateAsOneTransaction(
*this, ScrollSelectionIntoView::Yes, __FUNCTION__);
// Prevent auto insertion of BR in new cell until we're done
AutoEditSubActionNotifier startToHandleEditSubAction(
*this, EditSubAction::eInsertNode, nsIEditor::eNext, ignoredError);
@ -485,8 +485,8 @@ nsresult HTMLEditor::InsertTableColumnsWithTransaction(
// Should not be empty since we've already found a cell.
MOZ_ASSERT(!tableSize.IsEmpty());
AutoPlaceholderBatch treateAsOneTransaction(*this,
ScrollSelectionIntoView::Yes);
AutoPlaceholderBatch treateAsOneTransaction(
*this, ScrollSelectionIntoView::Yes, __FUNCTION__);
// Prevent auto insertion of <br> element in new cell until we're done.
AutoEditSubActionNotifier startToHandleEditSubAction(
*this, EditSubAction::eInsertNode, nsIEditor::eNext, ignoredError);
@ -718,8 +718,8 @@ nsresult HTMLEditor::InsertTableRowsWithTransaction(
// Should not be empty since we've already found a cell.
MOZ_ASSERT(!tableSize.IsEmpty());
AutoPlaceholderBatch treateAsOneTransaction(*this,
ScrollSelectionIntoView::Yes);
AutoPlaceholderBatch treateAsOneTransaction(
*this, ScrollSelectionIntoView::Yes, __FUNCTION__);
// Prevent auto insertion of BR in new cell until we're done
AutoEditSubActionNotifier startToHandleEditSubAction(
*this, EditSubAction::eInsertNode, nsIEditor::eNext, ignoredError);
@ -973,8 +973,8 @@ NS_IMETHODIMP HTMLEditor::DeleteTable() {
return NS_ERROR_FAILURE;
}
AutoPlaceholderBatch treateAsOneTransaction(*this,
ScrollSelectionIntoView::Yes);
AutoPlaceholderBatch treateAsOneTransaction(
*this, ScrollSelectionIntoView::Yes, __FUNCTION__);
rv = DeleteTableElementAndChildrenWithTransaction(*table);
NS_WARNING_ASSERTION(
NS_SUCCEEDED(rv),
@ -1024,8 +1024,8 @@ nsresult HTMLEditor::DeleteTableCellWithTransaction(
return NS_ERROR_FAILURE; // XXX Should we just return NS_OK?
}
AutoPlaceholderBatch treateAsOneTransaction(*this,
ScrollSelectionIntoView::Yes);
AutoPlaceholderBatch treateAsOneTransaction(
*this, ScrollSelectionIntoView::Yes, __FUNCTION__);
// Prevent rules testing until we're done
IgnoredErrorResult ignoredError;
AutoEditSubActionNotifier startToHandleEditSubAction(
@ -1317,8 +1317,8 @@ nsresult HTMLEditor::DeleteTableCellContentsWithTransaction() {
return NS_ERROR_FAILURE; // XXX Should we just return NS_OK?
}
AutoPlaceholderBatch treateAsOneTransaction(*this,
ScrollSelectionIntoView::Yes);
AutoPlaceholderBatch treateAsOneTransaction(
*this, ScrollSelectionIntoView::Yes, __FUNCTION__);
// Prevent rules testing until we're done
IgnoredErrorResult ignoredError;
AutoEditSubActionNotifier startToHandleEditSubAction(
@ -1415,8 +1415,8 @@ nsresult HTMLEditor::DeleteSelectedTableColumnsWithTransaction(
return error.StealNSResult();
}
AutoPlaceholderBatch treateAsOneTransaction(*this,
ScrollSelectionIntoView::Yes);
AutoPlaceholderBatch treateAsOneTransaction(
*this, ScrollSelectionIntoView::Yes, __FUNCTION__);
// Prevent rules testing until we're done
IgnoredErrorResult ignoredError;
@ -1671,8 +1671,8 @@ nsresult HTMLEditor::DeleteSelectedTableRowsWithTransaction(
return error.StealNSResult();
}
AutoPlaceholderBatch treateAsOneTransaction(*this,
ScrollSelectionIntoView::Yes);
AutoPlaceholderBatch treateAsOneTransaction(
*this, ScrollSelectionIntoView::Yes, __FUNCTION__);
// Prevent rules testing until we're done
IgnoredErrorResult ignoredError;
@ -2007,7 +2007,7 @@ NS_IMETHODIMP HTMLEditor::SelectAllTableCells() {
// Suppress nsISelectionListener notification
// until all selection changes are finished
SelectionBatcher selectionBatcher(SelectionRef());
SelectionBatcher selectionBatcher(SelectionRef(), __FUNCTION__);
// It is now safe to clear the selection
// BE SURE TO RESET IT BEFORE LEAVING!
@ -2122,7 +2122,7 @@ NS_IMETHODIMP HTMLEditor::SelectTableRow() {
// Suppress nsISelectionListener notification
// until all selection changes are finished
SelectionBatcher selectionBatcher(SelectionRef());
SelectionBatcher selectionBatcher(SelectionRef(), __FUNCTION__);
// It is now safe to clear the selection
// BE SURE TO RESET IT BEFORE LEAVING!
@ -2231,7 +2231,7 @@ NS_IMETHODIMP HTMLEditor::SelectTableColumn() {
// Suppress nsISelectionListener notification
// until all selection changes are finished
SelectionBatcher selectionBatcher(SelectionRef());
SelectionBatcher selectionBatcher(SelectionRef(), __FUNCTION__);
// It is now safe to clear the selection
// BE SURE TO RESET IT BEFORE LEAVING!
@ -2334,8 +2334,8 @@ NS_IMETHODIMP HTMLEditor::SplitTableCell() {
return NS_OK;
}
AutoPlaceholderBatch treateAsOneTransaction(*this,
ScrollSelectionIntoView::Yes);
AutoPlaceholderBatch treateAsOneTransaction(
*this, ScrollSelectionIntoView::Yes, __FUNCTION__);
// Prevent auto insertion of BR in new cell until we're done
IgnoredErrorResult ignoredError;
AutoEditSubActionNotifier startToHandleEditSubAction(
@ -2609,8 +2609,8 @@ NS_IMETHODIMP HTMLEditor::SwitchTableCellHeaderType(Element* aSourceCell,
return EditorBase::ToGenericNSResult(rv);
}
AutoPlaceholderBatch treatAsOneTransaction(*this,
ScrollSelectionIntoView::Yes);
AutoPlaceholderBatch treatAsOneTransaction(
*this, ScrollSelectionIntoView::Yes, __FUNCTION__);
// Prevent auto insertion of BR in new cell created by
// ReplaceContainerAndCloneAttributesWithTransaction().
IgnoredErrorResult ignoredError;
@ -2682,8 +2682,8 @@ NS_IMETHODIMP HTMLEditor::JoinTableCells(bool aMergeNonContiguousContents) {
return NS_ERROR_FAILURE; // XXX Should we just return NS_OK?
}
AutoPlaceholderBatch treateAsOneTransaction(*this,
ScrollSelectionIntoView::Yes);
AutoPlaceholderBatch treateAsOneTransaction(
*this, ScrollSelectionIntoView::Yes, __FUNCTION__);
// Don't let Rules System change the selection
AutoTransactionsConserveSelection dontChangeSelection(*this);
@ -3347,8 +3347,8 @@ nsresult HTMLEditor::NormalizeTableInternal(Element& aTableOrElementInTable) {
// Save current selection
AutoSelectionRestorer restoreSelectionLater(*this);
AutoPlaceholderBatch treateAsOneTransaction(*this,
ScrollSelectionIntoView::Yes);
AutoPlaceholderBatch treateAsOneTransaction(
*this, ScrollSelectionIntoView::Yes, __FUNCTION__);
// Prevent auto insertion of BR in new cell until we're done
IgnoredErrorResult ignoredError;
AutoEditSubActionNotifier startToHandleEditSubAction(

Просмотреть файл

@ -631,7 +631,7 @@ EditActionResult TextEditor::HandleDeleteSelectionInternal(
// want to send a single selectionchange event to the document, so we
// batch the selectionchange events, such that a single event fires after
// the AutoHideSelectionChanges destructor has been run.
SelectionBatcher selectionBatcher(SelectionRef());
SelectionBatcher selectionBatcher(SelectionRef(), __FUNCTION__);
AutoHideSelectionChanges hideSelection(SelectionRef());
nsAutoScriptBlocker scriptBlocker;

Просмотреть файл

@ -282,8 +282,8 @@ NS_IMETHODIMP TextEditor::InsertLineBreak() {
return NS_ERROR_FAILURE;
}
AutoPlaceholderBatch treatAsOneTransaction(*this,
ScrollSelectionIntoView::Yes);
AutoPlaceholderBatch treatAsOneTransaction(
*this, ScrollSelectionIntoView::Yes, __FUNCTION__);
rv = InsertLineBreakAsSubAction();
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
"TextEditor::InsertLineBreakAsSubAction() failed");
@ -307,7 +307,8 @@ nsresult TextEditor::InsertLineBreakAsAction(nsIPrincipal* aPrincipal) {
// XXX This may be called by execCommand() with "insertParagraph".
// In such case, naming the transaction "TypingTxnName" is odd.
AutoPlaceholderBatch treatAsOneTransaction(*this, *nsGkAtoms::TypingTxnName,
ScrollSelectionIntoView::Yes);
ScrollSelectionIntoView::Yes,
__FUNCTION__);
rv = InsertLineBreakAsSubAction();
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
"EditorBase::InsertLineBreakAsSubAction() failed");
@ -332,8 +333,8 @@ nsresult TextEditor::SetTextAsAction(
return EditorBase::ToGenericNSResult(rv);
}
AutoPlaceholderBatch treatAsOneTransaction(*this,
ScrollSelectionIntoView::Yes);
AutoPlaceholderBatch treatAsOneTransaction(
*this, ScrollSelectionIntoView::Yes, __FUNCTION__);
rv = SetTextAsSubAction(aString);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
"TextEditor::SetTextAsSubAction() failed");
@ -372,7 +373,7 @@ nsresult TextEditor::SetTextAsSubAction(const nsAString& aString) {
// Note that do not notify selectionchange caused by selecting all text
// because it's preparation of our delete implementation so web apps
// shouldn't receive such selectionchange before the first mutation.
AutoUpdateViewBatch preventSelectionChangeEvent(*this);
AutoUpdateViewBatch preventSelectionChangeEvent(*this, __FUNCTION__);
// XXX We should make ReplaceSelectionAsSubAction() take range. Then,
// we can saving the expensive cost of modifying `Selection` here.
@ -561,8 +562,8 @@ nsresult TextEditor::PasteAsQuotationAsAction(int32_t aClipboardType,
return EditorBase::ToGenericNSResult(rv);
}
AutoPlaceholderBatch treatAsOneTransaction(*this,
ScrollSelectionIntoView::Yes);
AutoPlaceholderBatch treatAsOneTransaction(
*this, ScrollSelectionIntoView::Yes, __FUNCTION__);
rv = InsertWithQuotationsAsSubAction(stuffToPaste);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
"TextEditor::InsertWithQuotationsAsSubAction() failed");

Просмотреть файл

@ -76,8 +76,8 @@ nsresult TextEditor::InsertTextFromTransferable(
// Sanitize possible carriage returns in the string to be inserted
nsContentUtils::PlatformToDOMLineBreaks(stuffToPaste);
AutoPlaceholderBatch treatAsOneTransaction(*this,
ScrollSelectionIntoView::Yes);
AutoPlaceholderBatch treatAsOneTransaction(
*this, ScrollSelectionIntoView::Yes, __FUNCTION__);
nsresult rv =
InsertTextAsSubAction(stuffToPaste, SelectionHandling::Delete);
if (NS_FAILED(rv)) {

Просмотреть файл

@ -1926,7 +1926,8 @@ nsresult nsFrameSelection::PageMove(bool aForward, bool aExtend,
{
// We don't want any script to run until we check whether selection is
// modified by HandleClick.
SelectionBatcher ensureNoSelectionChangeNotifications(selection);
SelectionBatcher ensureNoSelectionChangeNotifications(selection,
__FUNCTION__);
RangeBoundary oldAnchor = selection->AnchorRef();
RangeBoundary oldFocus = selection->FocusRef();
@ -2148,9 +2149,22 @@ nsFrameSelection::CreateRangeExtendedToSomewhere(
//////////END FRAMESELECTION
void nsFrameSelection::StartBatchChanges() { mBatching.mCounter++; }
LazyLogModule gBatchLog("SelectionBatch");
void nsFrameSelection::EndBatchChanges(int16_t aReasons) {
void nsFrameSelection::StartBatchChanges(const char* aRequesterFuncName) {
MOZ_LOG(gBatchLog, LogLevel::Info,
("%p%snsFrameSelection::StartBatchChanges(%s)", this,
std::string((mBatching.mCounter + 1) * 2, ' ').c_str(),
aRequesterFuncName));
mBatching.mCounter++;
}
void nsFrameSelection::EndBatchChanges(const char* aRequesterFuncName,
int16_t aReasons) {
MOZ_LOG(gBatchLog, LogLevel::Info,
("%p%snsFrameSelection::EndBatchChanges (%s, %s)", this,
std::string(mBatching.mCounter * 2, ' ').c_str(), aRequesterFuncName,
SelectionChangeReasonsToCString(aReasons).get()));
MOZ_ASSERT(mBatching.mCounter > 0, "Bad mBatching.mCounter");
mBatching.mCounter--;
@ -2254,7 +2268,7 @@ nsresult nsFrameSelection::TableSelection::HandleSelection(
// Stack-class to wrap all table selection changes in
// BeginBatchChanges() / EndBatchChanges()
SelectionBatcher selectionBatcher(&aNormalSelection);
SelectionBatcher selectionBatcher(&aNormalSelection, __FUNCTION__);
if (aDragState && mDragSelectingCells) {
return HandleDragSelecting(aTarget, childContent, aMouseEvent,

Просмотреть файл

@ -728,14 +728,23 @@ class nsFrameSelection final {
nsFrameSelection(mozilla::PresShell* aPresShell, nsIContent* aLimiter,
bool aAccessibleCaretEnabled);
void StartBatchChanges();
MOZ_CAN_RUN_SCRIPT_BOUNDARY
/**
* @param aRequesterFuncName function name which wants to start the batch.
* This won't be stored nor exposed to selection listeners etc, used only for
* logging.
*/
void StartBatchChanges(const char* aRequesterFuncName);
/**
* @param aRequesterFuncName function name which wants to end the batch.
* This won't be stored nor exposed to selection listeners etc, used only for
* logging.
* @param aReasons potentially multiple of the reasons defined in
* nsISelectionListener.idl
*/
void EndBatchChanges(int16_t aReasons = nsISelectionListener::NO_REASON);
MOZ_CAN_RUN_SCRIPT_BOUNDARY void EndBatchChanges(
const char* aRequesterFuncName,
int16_t aReasons = nsISelectionListener::NO_REASON);
mozilla::PresShell* GetPresShell() const { return mPresShell; }