Bug 1358025 - Part 4. Disable undo when input.value setter isn't user interaction. r?masayuki draft
authorMakoto Kato <m_kato@ga2.so-net.ne.jp>
Thu, 18 May 2017 16:32:29 +0900
changeset 584339 8064d6b4577293109c426faa1f4f3e7d72f6e61e
parent 584338 e24b0dee2de201eafbb7623547840d43b7ba17eb
child 584340 f9a95ccec9789c01824a5c761f672dc080812bd1
child 584341 9ebc1185a406a9f9889ba0e06586ba4503805b35
child 584850 69167bafbcafd65f0cf8c8da92141f69ebfad13b
push id60696
push userm_kato@ga2.so-net.ne.jp
push dateThu, 25 May 2017 09:12:31 +0000
reviewersmasayuki
bugs1358025, 1346723
milestone55.0a1
Bug 1358025 - Part 4. Disable undo when input.value setter isn't user interaction. r?masayuki See bug 1346723. I would like to turn off undo when not user interaction. Except to Gecko, other browsers don't create undo history by input.value setter. MozReview-Commit-ID: 9P1eOKTXCXN
dom/html/nsTextEditorState.cpp
--- a/dom/html/nsTextEditorState.cpp
+++ b/dom/html/nsTextEditorState.cpp
@@ -167,16 +167,45 @@ public:
 private:
   nsIEditor* mEditor;
   nsIPlaintextEditor* mPlaintextEditor;
   uint32_t mSavedFlags;
   int32_t mSavedMaxLength;
   MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
 };
 
+class MOZ_RAII AutoDisableUndo final
+{
+public:
+  explicit AutoDisableUndo(nsIEditor* aEditor
+                           MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
+    : mEditor(aEditor)
+    , mPreviousEnabled(true)
+  {
+    MOZ_GUARD_OBJECT_NOTIFIER_INIT;
+    MOZ_ASSERT(mEditor);
+
+    bool canUndo;
+    DebugOnly<nsresult> rv = mEditor->CanUndo(&mPreviousEnabled, &canUndo);
+    MOZ_ASSERT(NS_SUCCEEDED(rv));
+
+    mEditor->EnableUndo(false);
+  }
+
+  ~AutoDisableUndo()
+  {
+    mEditor->EnableUndo(mPreviousEnabled);
+  }
+
+private:
+  nsIEditor* mEditor;
+  bool mPreviousEnabled;
+  MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
+};
+
 /*static*/
 bool
 nsITextControlElement::GetWrapPropertyEnum(nsIContent* aContent,
   nsITextControlElement::nsHTMLTextWrap& aWrapProp)
 {
   // soft is the default; "physical" defaults to soft as well because all other
   // browsers treat it that way and there is no real reason to maintain physical
   // and virtual as separate entities if no one else does.  Only hard and off
@@ -1547,26 +1576,21 @@ nsTextEditorState::PrepareEditor(const n
   if (!defaultValue.IsEmpty()) {
     rv = newEditor->SetFlags(editorFlags);
     NS_ENSURE_SUCCESS(rv, rv);
 
     // Now call SetValue() which will make the necessary editor calls to set
     // the default value.  Make sure to turn off undo before setting the default
     // value, and turn it back on afterwards. This will make sure we can't undo
     // past the default value.
-
-    rv = newEditor->EnableUndo(false);
-    NS_ENSURE_SUCCESS(rv, rv);
+    // So, we use eSetValue_Internal flag only that it will turn off undo.
 
     bool success = SetValue(defaultValue, eSetValue_Internal);
     NS_ENSURE_TRUE(success, NS_ERROR_OUT_OF_MEMORY);
 
-    rv = newEditor->EnableUndo(true);
-    NS_ASSERTION(NS_SUCCEEDED(rv),"Transaction Manager must have failed");
-
     // Now restore the original editor flags.
     rv = newEditor->SetFlags(editorFlags);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   nsCOMPtr<nsITransactionManager> transMgr;
   newEditor->GetTransactionManager(getter_AddRefs(transMgr));
   NS_ENSURE_TRUE(transMgr, NS_ERROR_FAILURE);
@@ -2629,16 +2653,18 @@ nsTextEditorState::SetValue(const nsAStr
               StringTail(newValue, newlength - currentLength);
 
             if (insertValue.IsEmpty()) {
               mEditor->DeleteSelection(nsIEditor::eNone, nsIEditor::eStrip);
             } else {
               plaintextEditor->InsertText(insertValue);
             }
           } else {
+            AutoDisableUndo disableUndo(mEditor);
+
             plaintextEditor->SetText(newValue);
           }
 
           mTextListener->SetValueChanged(true);
           mTextListener->SettingValue(false);
         }
 
         if (!weakFrame.IsAlive()) {