Bug 1372829 - part1: Make mozilla::PlaceholderTransaction inherit mozilla::SupportsWeakPtr instead of nsSupportsWeakReference r=m_kato

EditorBase stores PlaceholderTransaction with nsWeakPtr.  However, retrieving its pointer requires a QI.  So, for reducing the QI cost, EditorBase should use WeakPtr instead and PlaceholderTransaction needs to inherit SupportsWeakPtr instead of nsSupportsWeakReference.

MozReview-Commit-ID: IYwSTbJebMk

--HG--
extra : rebase_source : fa728b09afa826506befbeb46aba54075ecf4787
This commit is contained in:
Masayuki Nakano 2017-06-14 19:05:48 +09:00
parent 074fbc5557
commit 46f0810215
6 changed files with 53 additions and 43 deletions

View File

@ -126,12 +126,12 @@ using namespace widget;
*****************************************************************************/ *****************************************************************************/
EditorBase::EditorBase() EditorBase::EditorBase()
: mPlaceHolderName(nullptr) : mPlaceholderName(nullptr)
, mSelState(nullptr) , mSelState(nullptr)
, mModCount(0) , mModCount(0)
, mFlags(0) , mFlags(0)
, mUpdateCount(0) , mUpdateCount(0)
, mPlaceHolderBatch(0) , mPlaceholderBatch(0)
, mAction(EditAction::none) , mAction(EditAction::none)
, mIMETextOffset(0) , mIMETextOffset(0)
, mIMETextLength(0) , mIMETextLength(0)
@ -680,29 +680,29 @@ EditorBase::GetSelection(SelectionType aSelectionType)
NS_IMETHODIMP NS_IMETHODIMP
EditorBase::DoTransaction(nsITransaction* aTxn) EditorBase::DoTransaction(nsITransaction* aTxn)
{ {
if (mPlaceHolderBatch && !mPlaceHolderTxn) { if (mPlaceholderBatch && !mPlaceholderTransactionWeak) {
nsCOMPtr<nsIAbsorbingTransaction> placeholderTransaction = RefPtr<PlaceholderTransaction> placeholderTransaction =
new PlaceholderTransaction(*this, mPlaceHolderName, Move(mSelState)); new PlaceholderTransaction(*this, mPlaceholderName, Move(mSelState));
// Save off weak reference to placeholder transaction // Save off weak reference to placeholder transaction
mPlaceHolderTxn = do_GetWeakReference(placeholderTransaction); mPlaceholderTransactionWeak = placeholderTransaction;
// QI to an nsITransaction since that's what DoTransaction() expects
nsCOMPtr<nsITransaction> transaction =
do_QueryInterface(placeholderTransaction);
// We will recurse, but will not hit this case in the nested call // We will recurse, but will not hit this case in the nested call
DoTransaction(transaction); DoTransaction(placeholderTransaction);
if (mTxnMgr) { if (mTxnMgr) {
nsCOMPtr<nsITransaction> topTxn = mTxnMgr->PeekUndoStack(); nsCOMPtr<nsITransaction> topTransaction = mTxnMgr->PeekUndoStack();
if (topTxn) { nsCOMPtr<nsIAbsorbingTransaction> topAbsorbingTransaction =
placeholderTransaction = do_QueryInterface(topTxn); do_QueryInterface(topTransaction);
if (placeholderTransaction) { if (topAbsorbingTransaction) {
RefPtr<PlaceholderTransaction> topPlaceholderTransaction =
topAbsorbingTransaction->AsPlaceholderTransaction();
if (topPlaceholderTransaction) {
// there is a placeholder transaction on top of the undo stack. It // there is a placeholder transaction on top of the undo stack. It
// is either the one we just created, or an earlier one that we are // is either the one we just created, or an earlier one that we are
// now merging into. From here on out remember this placeholder // now merging into. From here on out remember this placeholder
// instead of the one we just created. // instead of the one we just created.
mPlaceHolderTxn = do_GetWeakReference(placeholderTransaction); mPlaceholderTransactionWeak = topPlaceholderTransaction;
} }
} }
} }
@ -916,13 +916,13 @@ EditorBase::EndTransaction()
NS_IMETHODIMP NS_IMETHODIMP
EditorBase::BeginPlaceHolderTransaction(nsIAtom* aName) EditorBase::BeginPlaceHolderTransaction(nsIAtom* aName)
{ {
NS_PRECONDITION(mPlaceHolderBatch >= 0, "negative placeholder batch count!"); MOZ_ASSERT(mPlaceholderBatch >= 0, "negative placeholder batch count!");
if (!mPlaceHolderBatch) { if (!mPlaceholderBatch) {
NotifyEditorObservers(eNotifyEditorObserversOfBefore); NotifyEditorObservers(eNotifyEditorObserversOfBefore);
// time to turn on the batch // time to turn on the batch
BeginUpdateViewBatch(); BeginUpdateViewBatch();
mPlaceHolderTxn = nullptr; mPlaceholderTransactionWeak = nullptr;
mPlaceHolderName = aName; mPlaceholderName = aName;
RefPtr<Selection> selection = GetSelection(); RefPtr<Selection> selection = GetSelection();
if (selection) { if (selection) {
mSelState = MakeUnique<SelectionState>(); mSelState = MakeUnique<SelectionState>();
@ -932,12 +932,12 @@ EditorBase::BeginPlaceHolderTransaction(nsIAtom* aName)
// So if current selection is into IME text node, it might be failed // So if current selection is into IME text node, it might be failed
// to restore selection by UndoTransaction. // to restore selection by UndoTransaction.
// So we need update selection by range updater. // So we need update selection by range updater.
if (mPlaceHolderName == nsGkAtoms::IMETxnName) { if (mPlaceholderName == nsGkAtoms::IMETxnName) {
mRangeUpdater.RegisterSelectionState(*mSelState); mRangeUpdater.RegisterSelectionState(*mSelState);
} }
} }
} }
mPlaceHolderBatch++; mPlaceholderBatch++;
return NS_OK; return NS_OK;
} }
@ -945,8 +945,9 @@ EditorBase::BeginPlaceHolderTransaction(nsIAtom* aName)
NS_IMETHODIMP NS_IMETHODIMP
EditorBase::EndPlaceHolderTransaction() EditorBase::EndPlaceHolderTransaction()
{ {
NS_PRECONDITION(mPlaceHolderBatch > 0, "zero or negative placeholder batch count when ending batch!"); MOZ_ASSERT(mPlaceholderBatch > 0,
if (mPlaceHolderBatch == 1) { "zero or negative placeholder batch count when ending batch!");
if (mPlaceholderBatch == 1) {
RefPtr<Selection> selection = GetSelection(); RefPtr<Selection> selection = GetSelection();
// By making the assumption that no reflow happens during the calls // By making the assumption that no reflow happens during the calls
@ -986,21 +987,16 @@ EditorBase::EndPlaceHolderTransaction()
if (mSelState) { if (mSelState) {
// we saved the selection state, but never got to hand it to placeholder // we saved the selection state, but never got to hand it to placeholder
// (else we ould have nulled out this pointer), so destroy it to prevent leaks. // (else we ould have nulled out this pointer), so destroy it to prevent leaks.
if (mPlaceHolderName == nsGkAtoms::IMETxnName) { if (mPlaceholderName == nsGkAtoms::IMETxnName) {
mRangeUpdater.DropSelectionState(*mSelState); mRangeUpdater.DropSelectionState(*mSelState);
} }
mSelState = nullptr; mSelState = nullptr;
} }
// We might have never made a placeholder if no action took place. // We might have never made a placeholder if no action took place.
if (mPlaceHolderTxn) { if (mPlaceholderTransactionWeak) {
nsCOMPtr<nsIAbsorbingTransaction> plcTxn = do_QueryReferent(mPlaceHolderTxn); RefPtr<PlaceholderTransaction> placeholderTransaction =
if (plcTxn) { mPlaceholderTransactionWeak.get();
plcTxn->EndPlaceHolderBatch(); placeholderTransaction->EndPlaceHolderBatch();
} else {
// in the future we will check to make sure undo is off here,
// since that is the only known case where the placeholdertxn would disappear on us.
// For now just removing the assert.
}
// notify editor observers of action but if composing, it's done by // notify editor observers of action but if composing, it's done by
// compositionchange event handler. // compositionchange event handler.
if (!mComposition) { if (!mComposition) {
@ -1010,7 +1006,7 @@ EditorBase::EndPlaceHolderTransaction()
NotifyEditorObservers(eNotifyEditorObserversOfCancel); NotifyEditorObservers(eNotifyEditorObserversOfCancel);
} }
} }
mPlaceHolderBatch--; mPlaceholderBatch--;
return NS_OK; return NS_OK;
} }

View File

@ -9,8 +9,9 @@
#include "mozilla/Assertions.h" // for MOZ_ASSERT, etc. #include "mozilla/Assertions.h" // for MOZ_ASSERT, etc.
#include "mozilla/OwningNonNull.h" // for OwningNonNull #include "mozilla/OwningNonNull.h" // for OwningNonNull
#include "mozilla/SelectionState.h" // for RangeUpdater, etc. #include "mozilla/SelectionState.h" // for RangeUpdater, etc.
#include "mozilla/StyleSheet.h" // for StyleSheet #include "mozilla/StyleSheet.h" // for StyleSheet
#include "mozilla/UniquePtr.h" #include "mozilla/UniquePtr.h"
#include "mozilla/WeakPtr.h" // for WeakPtr
#include "mozilla/dom/Text.h" #include "mozilla/dom/Text.h"
#include "nsCOMPtr.h" // for already_AddRefed, nsCOMPtr #include "nsCOMPtr.h" // for already_AddRefed, nsCOMPtr
#include "nsCycleCollectionParticipant.h" #include "nsCycleCollectionParticipant.h"
@ -116,6 +117,7 @@ class HTMLEditor;
class InsertNodeTransaction; class InsertNodeTransaction;
class InsertTextTransaction; class InsertTextTransaction;
class JoinNodeTransaction; class JoinNodeTransaction;
class PlaceholderTransaction;
class RemoveStyleSheetTransaction; class RemoveStyleSheetTransaction;
class SetTextTransaction; class SetTextTransaction;
class SplitNodeTransaction; class SplitNodeTransaction;
@ -1008,11 +1010,11 @@ protected:
// Weak reference to the nsISelectionController. // Weak reference to the nsISelectionController.
nsWeakPtr mSelConWeak; nsWeakPtr mSelConWeak;
// Weak reference to placeholder for begin/end batch purposes. // Weak reference to placeholder for begin/end batch purposes.
nsWeakPtr mPlaceHolderTxn; WeakPtr<PlaceholderTransaction> mPlaceholderTransactionWeak;
// Weak reference to the nsIDOMDocument. // Weak reference to the nsIDOMDocument.
nsWeakPtr mDocWeak; nsWeakPtr mDocWeak;
// Name of placeholder transaction. // Name of placeholder transaction.
nsIAtom* mPlaceHolderName; nsIAtom* mPlaceholderName;
// Saved selection state for placeholder transaction batching. // Saved selection state for placeholder transaction batching.
mozilla::UniquePtr<SelectionState> mSelState; mozilla::UniquePtr<SelectionState> mSelState;
// IME composition this is not null between compositionstart and // IME composition this is not null between compositionstart and
@ -1045,7 +1047,7 @@ protected:
int32_t mUpdateCount; int32_t mUpdateCount;
// Nesting count for batching. // Nesting count for batching.
int32_t mPlaceHolderBatch; int32_t mPlaceholderBatch;
// The current editor action. // The current editor action.
EditAction mAction; EditAction mAction;

View File

@ -56,7 +56,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(PlaceholderTransaction) NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(PlaceholderTransaction)
NS_INTERFACE_MAP_ENTRY(nsIAbsorbingTransaction) NS_INTERFACE_MAP_ENTRY(nsIAbsorbingTransaction)
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
NS_INTERFACE_MAP_END_INHERITING(EditAggregateTransaction) NS_INTERFACE_MAP_END_INHERITING(EditAggregateTransaction)
NS_IMPL_ADDREF_INHERITED(PlaceholderTransaction, EditAggregateTransaction) NS_IMPL_ADDREF_INHERITED(PlaceholderTransaction, EditAggregateTransaction)

View File

@ -9,6 +9,7 @@
#include "EditAggregateTransaction.h" #include "EditAggregateTransaction.h"
#include "mozilla/EditorUtils.h" #include "mozilla/EditorUtils.h"
#include "mozilla/UniquePtr.h" #include "mozilla/UniquePtr.h"
#include "mozilla/WeakPtr.h"
#include "nsIAbsorbingTransaction.h" #include "nsIAbsorbingTransaction.h"
#include "nsIDOMNode.h" #include "nsIDOMNode.h"
#include "nsCOMPtr.h" #include "nsCOMPtr.h"
@ -26,11 +27,14 @@ class CompositionTransaction;
* transactions it has absorbed. * transactions it has absorbed.
*/ */
class PlaceholderTransaction final : public EditAggregateTransaction, class PlaceholderTransaction final
public nsIAbsorbingTransaction, : public EditAggregateTransaction
public nsSupportsWeakReference , public nsIAbsorbingTransaction
, public SupportsWeakPtr<PlaceholderTransaction>
{ {
public: public:
MOZ_DECLARE_WEAKREFERENCE_TYPENAME(PlaceholderTransaction)
NS_DECL_ISUPPORTS_INHERITED NS_DECL_ISUPPORTS_INHERITED
PlaceholderTransaction(EditorBase& aEditorBase, nsIAtom* aName, PlaceholderTransaction(EditorBase& aEditorBase, nsIAtom* aName,
@ -59,6 +63,11 @@ public:
NS_IMETHOD Commit() override; NS_IMETHOD Commit() override;
NS_IMETHOD_(PlaceholderTransaction*) AsPlaceholderTransaction() override
{
return this;
}
nsresult RememberEndingSelection(); nsresult RememberEndingSelection();
protected: protected:

View File

@ -872,7 +872,7 @@ TextEditor::UpdateIMEComposition(WidgetCompositionEvent* aCompsitionChangeEvent)
// of NotifiyEditorObservers(eNotifyEditorObserversOfEnd) or // of NotifiyEditorObservers(eNotifyEditorObserversOfEnd) or
// NotifiyEditorObservers(eNotifyEditorObserversOfCancel) which notifies // NotifiyEditorObservers(eNotifyEditorObserversOfCancel) which notifies
// TextComposition of a selection change. // TextComposition of a selection change.
MOZ_ASSERT(!mPlaceHolderBatch, MOZ_ASSERT(!mPlaceholderBatch,
"UpdateIMEComposition() must be called without place holder batch"); "UpdateIMEComposition() must be called without place holder batch");
TextComposition::CompositionChangeEventHandlingMarker TextComposition::CompositionChangeEventHandlingMarker
compositionChangeEventHandlingMarker(mComposition, aCompsitionChangeEvent); compositionChangeEventHandlingMarker(mComposition, aCompsitionChangeEvent);

View File

@ -23,6 +23,7 @@ class nsIAtom;
namespace mozilla { namespace mozilla {
class EditorBase; class EditorBase;
class PlaceholderTransaction;
class SelectionState; class SelectionState;
} // namespace mozilla } // namespace mozilla
@ -45,6 +46,9 @@ public:
NS_IMETHOD ForwardEndBatchTo(nsIAbsorbingTransaction *aForwardingAddress)=0; NS_IMETHOD ForwardEndBatchTo(nsIAbsorbingTransaction *aForwardingAddress)=0;
NS_IMETHOD Commit()=0; NS_IMETHOD Commit()=0;
NS_IMETHOD_(mozilla::PlaceholderTransaction*)
AsPlaceholderTransaction() = 0;
}; };
NS_DEFINE_STATIC_IID_ACCESSOR(nsIAbsorbingTransaction, NS_DEFINE_STATIC_IID_ACCESSOR(nsIAbsorbingTransaction,