InsertTextTransaction.cpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  2. /* This Source Code Form is subject to the terms of the Mozilla Public
  3. * License, v. 2.0. If a copy of the MPL was not distributed with this
  4. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  5. #include "InsertTextTransaction.h"
  6. #include "mozilla/EditorBase.h" // mEditorBase
  7. #include "mozilla/SelectionState.h" // RangeUpdater
  8. #include "mozilla/dom/Selection.h" // Selection local var
  9. #include "mozilla/dom/Text.h" // mTextNode
  10. #include "nsAString.h" // nsAString parameter
  11. #include "nsDebug.h" // for NS_ASSERTION, etc.
  12. #include "nsError.h" // for NS_OK, etc.
  13. #include "nsQueryObject.h" // for do_QueryObject
  14. namespace mozilla {
  15. using namespace dom;
  16. InsertTextTransaction::InsertTextTransaction(Text& aTextNode,
  17. uint32_t aOffset,
  18. const nsAString& aStringToInsert,
  19. EditorBase& aEditorBase,
  20. RangeUpdater* aRangeUpdater)
  21. : mTextNode(&aTextNode)
  22. , mOffset(aOffset)
  23. , mStringToInsert(aStringToInsert)
  24. , mEditorBase(&aEditorBase)
  25. , mRangeUpdater(aRangeUpdater)
  26. {
  27. }
  28. InsertTextTransaction::~InsertTextTransaction()
  29. {
  30. }
  31. NS_IMPL_CYCLE_COLLECTION_INHERITED(InsertTextTransaction, EditTransactionBase,
  32. mEditorBase,
  33. mTextNode)
  34. NS_IMPL_ADDREF_INHERITED(InsertTextTransaction, EditTransactionBase)
  35. NS_IMPL_RELEASE_INHERITED(InsertTextTransaction, EditTransactionBase)
  36. NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(InsertTextTransaction)
  37. if (aIID.Equals(NS_GET_IID(InsertTextTransaction))) {
  38. foundInterface = static_cast<nsITransaction*>(this);
  39. } else
  40. NS_INTERFACE_MAP_END_INHERITING(EditTransactionBase)
  41. NS_IMETHODIMP
  42. InsertTextTransaction::DoTransaction()
  43. {
  44. if (NS_WARN_IF(!mEditorBase) || NS_WARN_IF(!mTextNode)) {
  45. return NS_ERROR_NOT_AVAILABLE;
  46. }
  47. nsresult rv = mTextNode->InsertData(mOffset, mStringToInsert);
  48. NS_ENSURE_SUCCESS(rv, rv);
  49. // Only set selection to insertion point if editor gives permission
  50. if (mEditorBase->GetShouldTxnSetSelection()) {
  51. RefPtr<Selection> selection = mEditorBase->GetSelection();
  52. NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER);
  53. DebugOnly<nsresult> rv =
  54. selection->Collapse(mTextNode, mOffset + mStringToInsert.Length());
  55. NS_ASSERTION(NS_SUCCEEDED(rv),
  56. "Selection could not be collapsed after insert");
  57. } else {
  58. // Do nothing - DOM Range gravity will adjust selection
  59. }
  60. mRangeUpdater->SelAdjInsertText(*mTextNode, mOffset, mStringToInsert);
  61. return NS_OK;
  62. }
  63. NS_IMETHODIMP
  64. InsertTextTransaction::UndoTransaction()
  65. {
  66. return mTextNode->DeleteData(mOffset, mStringToInsert.Length());
  67. }
  68. NS_IMETHODIMP
  69. InsertTextTransaction::Merge(nsITransaction* aTransaction,
  70. bool* aDidMerge)
  71. {
  72. if (!aTransaction || !aDidMerge) {
  73. return NS_OK;
  74. }
  75. // Set out param default value
  76. *aDidMerge = false;
  77. // If aTransaction is a InsertTextTransaction, and if the selection hasn't
  78. // changed, then absorb it.
  79. RefPtr<InsertTextTransaction> otherTransaction = do_QueryObject(aTransaction);
  80. if (otherTransaction && IsSequentialInsert(*otherTransaction)) {
  81. nsAutoString otherData;
  82. otherTransaction->GetData(otherData);
  83. mStringToInsert += otherData;
  84. *aDidMerge = true;
  85. }
  86. return NS_OK;
  87. }
  88. NS_IMETHODIMP
  89. InsertTextTransaction::GetTxnDescription(nsAString& aString)
  90. {
  91. aString.AssignLiteral("InsertTextTransaction: ");
  92. aString += mStringToInsert;
  93. return NS_OK;
  94. }
  95. /* ============ private methods ================== */
  96. void
  97. InsertTextTransaction::GetData(nsString& aResult)
  98. {
  99. aResult = mStringToInsert;
  100. }
  101. bool
  102. InsertTextTransaction::IsSequentialInsert(
  103. InsertTextTransaction& aOtherTransaction)
  104. {
  105. return aOtherTransaction.mTextNode == mTextNode &&
  106. aOtherTransaction.mOffset == mOffset + mStringToInsert.Length();
  107. }
  108. } // namespace mozilla