tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

ChangeAttributeTransaction.cpp (7423B)


      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 
      6 #include "ChangeAttributeTransaction.h"
      7 
      8 #include "EditorDOMAPIWrapper.h"
      9 
     10 #include "mozilla/Logging.h"
     11 #include "mozilla/ToString.h"
     12 #include "mozilla/dom/Element.h"  // for Element
     13 
     14 #include "nsAString.h"
     15 #include "nsError.h"  // for NS_ERROR_NOT_INITIALIZED, etc.
     16 
     17 namespace mozilla {
     18 
     19 using namespace dom;
     20 
     21 // static
     22 already_AddRefed<ChangeAttributeTransaction> ChangeAttributeTransaction::Create(
     23    EditorBase& aEditorBase, Element& aElement, nsAtom& aAttribute,
     24    const nsAString& aValue) {
     25  RefPtr<ChangeAttributeTransaction> transaction =
     26      new ChangeAttributeTransaction(aEditorBase, aElement, aAttribute,
     27                                     &aValue);
     28  return transaction.forget();
     29 }
     30 
     31 // static
     32 already_AddRefed<ChangeAttributeTransaction>
     33 ChangeAttributeTransaction::CreateToRemove(EditorBase& aEditorBase,
     34                                           Element& aElement,
     35                                           nsAtom& aAttribute) {
     36  RefPtr<ChangeAttributeTransaction> transaction =
     37      new ChangeAttributeTransaction(aEditorBase, aElement, aAttribute,
     38                                     nullptr);
     39  return transaction.forget();
     40 }
     41 
     42 ChangeAttributeTransaction::ChangeAttributeTransaction(EditorBase& aEditorBase,
     43                                                       Element& aElement,
     44                                                       nsAtom& aAttribute,
     45                                                       const nsAString* aValue)
     46    : EditTransactionBase(),
     47      mEditorBase(&aEditorBase),
     48      mElement(&aElement),
     49      mAttribute(&aAttribute),
     50      mValue(aValue ? *aValue : u""_ns),
     51      mRemoveAttribute(!aValue),
     52      mAttributeWasSet(false) {}
     53 
     54 std::ostream& operator<<(std::ostream& aStream,
     55                         const ChangeAttributeTransaction& aTransaction) {
     56  aStream << "{ mElement=" << aTransaction.mElement.get();
     57  if (aTransaction.mElement) {
     58    aStream << " (" << *aTransaction.mElement << ")";
     59  }
     60  aStream << ", mAttribute=" << nsAtomCString(aTransaction.mAttribute).get()
     61          << ", mValue=\"" << NS_ConvertUTF16toUTF8(aTransaction.mValue).get()
     62          << "\", mUndoValue=\""
     63          << NS_ConvertUTF16toUTF8(aTransaction.mUndoValue).get()
     64          << "\", mRemoveAttribute="
     65          << (aTransaction.mRemoveAttribute ? "true" : "false")
     66          << ", mAttributeWasSet="
     67          << (aTransaction.mAttributeWasSet ? "true" : "false")
     68          << ", mEditorBase=" << aTransaction.mEditorBase.get() << " }";
     69  return aStream;
     70 }
     71 
     72 NS_IMPL_CYCLE_COLLECTION_INHERITED(ChangeAttributeTransaction,
     73                                   EditTransactionBase, mEditorBase, mElement)
     74 
     75 NS_IMPL_ADDREF_INHERITED(ChangeAttributeTransaction, EditTransactionBase)
     76 NS_IMPL_RELEASE_INHERITED(ChangeAttributeTransaction, EditTransactionBase)
     77 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ChangeAttributeTransaction)
     78 NS_INTERFACE_MAP_END_INHERITING(EditTransactionBase)
     79 
     80 NS_IMETHODIMP ChangeAttributeTransaction::DoTransaction() {
     81  MOZ_ASSERT(mEditorBase);
     82 
     83  // Need to get the current value of the attribute and save it, and set
     84  // mAttributeWasSet
     85  mAttributeWasSet = mElement->GetAttr(mAttribute, mUndoValue);
     86 
     87  // XXX: hack until attribute-was-set code is implemented
     88  if (!mUndoValue.IsEmpty()) {
     89    mAttributeWasSet = true;
     90  }
     91  // XXX: end hack
     92 
     93  MOZ_LOG(GetLogModule(), LogLevel::Info,
     94          ("%p ChangeAttributeTransaction::%s this=%s", this, __FUNCTION__,
     95           ToString(*this).c_str()));
     96 
     97  const OwningNonNull<EditorBase> editorBase = *mEditorBase;
     98  const OwningNonNull<Element> element = *mElement;
     99  // Now set the attribute to the new value
    100  if (mRemoveAttribute) {
    101    AutoElementAttrAPIWrapper elementWrapper(editorBase, element);
    102    nsresult rv = elementWrapper.UnsetAttr(MOZ_KnownLive(mAttribute), true);
    103    if (NS_FAILED(rv)) {
    104      NS_WARNING("AutoElementAttrAPIWrapper::UnsetAttr() failed");
    105      return rv;
    106    }
    107    NS_WARNING_ASSERTION(
    108        elementWrapper.IsExpectedResult(EmptyString()),
    109        "Removing attribute caused other mutations, but ignored");
    110    return NS_OK;
    111  }
    112 
    113  AutoElementAttrAPIWrapper elementWrapper(editorBase, element);
    114  nsresult rv = elementWrapper.SetAttr(MOZ_KnownLive(mAttribute), mValue, true);
    115  if (NS_FAILED(rv)) {
    116    NS_WARNING("AutoElementAttrAPIWrapper::SetAttr() failed");
    117    return rv;
    118  }
    119  NS_WARNING_ASSERTION(elementWrapper.IsExpectedResult(mValue),
    120                       "Setting attribute caused other mutations, but ignored");
    121  return rv;
    122 }
    123 
    124 NS_IMETHODIMP ChangeAttributeTransaction::UndoTransaction() {
    125  MOZ_LOG(GetLogModule(), LogLevel::Info,
    126          ("%p ChangeAttributeTransaction::%s this=%s", this, __FUNCTION__,
    127           ToString(*this).c_str()));
    128 
    129  if (NS_WARN_IF(!mEditorBase) || NS_WARN_IF(!mElement)) {
    130    return NS_ERROR_NOT_AVAILABLE;
    131  }
    132  const OwningNonNull<EditorBase> editorBase = *mEditorBase;
    133  const OwningNonNull<Element> element = *mElement;
    134  if (mAttributeWasSet) {
    135    AutoElementAttrAPIWrapper elementWrapper(editorBase, element);
    136    nsresult rv =
    137        elementWrapper.SetAttr(MOZ_KnownLive(mAttribute), mUndoValue, true);
    138    if (NS_FAILED(rv)) {
    139      NS_WARNING("AutoElementAttrAPIWrapper::SetAttr() failed");
    140      return rv;
    141    }
    142    NS_WARNING_ASSERTION(
    143        elementWrapper.IsExpectedResult(mUndoValue),
    144        "Setting attribute caused other mutations, but ignored");
    145    return NS_OK;
    146  }
    147  AutoElementAttrAPIWrapper elementWrapper(editorBase, element);
    148  nsresult rv = elementWrapper.UnsetAttr(MOZ_KnownLive(mAttribute), true);
    149  if (NS_FAILED(rv)) {
    150    NS_WARNING("AutoElementAttrAPIWrapper::UnsetAttr() failed");
    151    return rv;
    152  }
    153  NS_WARNING_ASSERTION(
    154      elementWrapper.IsExpectedResult(EmptyString()),
    155      "Removing attribute caused other mutations, but ignored");
    156  return NS_OK;
    157 }
    158 
    159 NS_IMETHODIMP ChangeAttributeTransaction::RedoTransaction() {
    160  MOZ_LOG(GetLogModule(), LogLevel::Info,
    161          ("%p ChangeAttributeTransaction::%s this=%s", this, __FUNCTION__,
    162           ToString(*this).c_str()));
    163 
    164  if (NS_WARN_IF(!mEditorBase) || NS_WARN_IF(!mElement)) {
    165    return NS_ERROR_NOT_AVAILABLE;
    166  }
    167  const OwningNonNull<EditorBase> editorBase = *mEditorBase;
    168  const OwningNonNull<Element> element = *mElement;
    169  if (mRemoveAttribute) {
    170    AutoElementAttrAPIWrapper elementWrapper(editorBase, element);
    171    nsresult rv = elementWrapper.UnsetAttr(MOZ_KnownLive(mAttribute), true);
    172    if (NS_FAILED(rv)) {
    173      NS_WARNING("AutoElementAttrAPIWrapper::UnsetAttr() failed");
    174      return rv;
    175    }
    176    NS_WARNING_ASSERTION(
    177        elementWrapper.IsExpectedResult(EmptyString()),
    178        "Removing attribute caused other mutations, but ignored");
    179    return NS_OK;
    180  }
    181 
    182  AutoElementAttrAPIWrapper elementWrapper(editorBase, element);
    183  nsresult rv = elementWrapper.SetAttr(MOZ_KnownLive(mAttribute), mValue, true);
    184  if (NS_FAILED(rv)) {
    185    NS_WARNING("AutoElementAttrAPIWrapper::SetAttr() failed");
    186    return rv;
    187  }
    188  NS_WARNING_ASSERTION(elementWrapper.IsExpectedResult(mValue),
    189                       "Setting attribute caused other mutations, but ignored");
    190  return NS_OK;
    191 }
    192 
    193 }  // namespace mozilla