Bug 1387406 - part1: nsDocShellEditorData should store editor as HTMLEditor r?smaug draft
authorMasayuki Nakano <masayuki@d-toybox.com>
Fri, 04 Aug 2017 21:42:13 +0900
changeset 643904 c62283bdcd72f02ba894bded8ed9ac99baa1d2d5
parent 643898 302caa681489a403795fe3ddb39ab00aa3a355ee
child 643905 71279f8f5269e0bd00293d88376aaa569a0564a7
push id73250
push usermasayuki@d-toybox.com
push dateThu, 10 Aug 2017 07:58:50 +0000
reviewerssmaug
bugs1387406
milestone57.0a1
Bug 1387406 - part1: nsDocShellEditorData should store editor as HTMLEditor r?smaug The editor stored by nsDocShellEditorData should be always HTMLEditor. So, it should store the editor as HTMLEditor and its getter and setter should treat the editor as HTMLEditor too. MozReview-Commit-ID: GgfCd3zB887
docshell/base/nsDocShell.cpp
docshell/base/nsDocShellEditorData.cpp
docshell/base/nsDocShellEditorData.h
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -19,16 +19,17 @@
 #include "mozilla/dom/TabChild.h"
 #include "mozilla/dom/ProfileTimelineMarkerBinding.h"
 #include "mozilla/dom/ScreenOrientation.h"
 #include "mozilla/dom/ToJSValue.h"
 #include "mozilla/dom/PermissionMessageUtils.h"
 #include "mozilla/dom/workers/ServiceWorkerManager.h"
 #include "mozilla/EventStateManager.h"
 #include "mozilla/LoadInfo.h"
+#include "mozilla/HTMLEditor.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Services.h"
 #include "mozilla/StartupTimeline.h"
 #include "mozilla/Telemetry.h"
 #include "mozilla/Unused.h"
 #include "Navigator.h"
 #include "URIUtils.h"
 #include "mozilla/dom/DocGroup.h"
@@ -13152,28 +13153,40 @@ nsDocShell::GetEditor(nsIEditor** aEdito
 {
   NS_ENSURE_ARG_POINTER(aEditor);
 
   if (!mEditorData) {
     *aEditor = nullptr;
     return NS_OK;
   }
 
-  return mEditorData->GetEditor(aEditor);
+  RefPtr<HTMLEditor> htmlEditor = mEditorData->GetHTMLEditor();
+  htmlEditor.forget(aEditor);
+  return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDocShell::SetEditor(nsIEditor* aEditor)
 {
+  if (!aEditor && !mEditorData) {
+    return NS_OK;
+  }
+
+  HTMLEditor* htmlEditor = aEditor ? aEditor->AsHTMLEditor() : nullptr;
+  // If TextEditor comes, throw an error.
+  if (aEditor && !htmlEditor) {
+    return NS_ERROR_INVALID_ARG;
+  }
+
   nsresult rv = EnsureEditorData();
   if (NS_FAILED(rv)) {
     return rv;
   }
 
-  return mEditorData->SetEditor(aEditor);
+  return mEditorData->SetHTMLEditor(htmlEditor);
 }
 
 NS_IMETHODIMP
 nsDocShell::GetEditable(bool* aEditable)
 {
   NS_ENSURE_ARG_POINTER(aEditable);
   *aEditable = mEditorData && mEditorData->GetEditable();
   return NS_OK;
--- a/docshell/base/nsDocShellEditorData.cpp
+++ b/docshell/base/nsDocShellEditorData.cpp
@@ -8,68 +8,70 @@
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsComponentManagerUtils.h"
 #include "nsPIDOMWindow.h"
 #include "nsIDOMDocument.h"
 #include "nsIEditor.h"
 #include "nsIEditingSession.h"
 #include "nsIDocShell.h"
 
+using namespace mozilla;
+
 nsDocShellEditorData::nsDocShellEditorData(nsIDocShell* aOwningDocShell)
   : mDocShell(aOwningDocShell)
+  , mDetachedEditingState(nsIHTMLDocument::eOff)
   , mMakeEditable(false)
   , mIsDetached(false)
   , mDetachedMakeEditable(false)
-  , mDetachedEditingState(nsIHTMLDocument::eOff)
 {
   NS_ASSERTION(mDocShell, "Where is my docShell?");
 }
 
 nsDocShellEditorData::~nsDocShellEditorData()
 {
   TearDownEditor();
 }
 
 void
 nsDocShellEditorData::TearDownEditor()
 {
-  if (mEditor) {
-    mEditor->PreDestroy(false);
-    mEditor = nullptr;
+  if (mHTMLEditor) {
+    RefPtr<HTMLEditor> htmlEditor = mHTMLEditor.forget();
+    htmlEditor->PreDestroy(false);
   }
   mEditingSession = nullptr;
   mIsDetached = false;
 }
 
 nsresult
 nsDocShellEditorData::MakeEditable(bool aInWaitForUriLoad)
 {
   if (mMakeEditable) {
     return NS_OK;
   }
 
   // if we are already editable, and are getting turned off,
   // nuke the editor.
-  if (mEditor) {
+  if (mHTMLEditor) {
     NS_WARNING("Destroying existing editor on frame");
 
-    mEditor->PreDestroy(false);
-    mEditor = nullptr;
+    RefPtr<HTMLEditor> htmlEditor = mHTMLEditor.forget();
+    htmlEditor->PreDestroy(false);
   }
 
   if (aInWaitForUriLoad) {
     mMakeEditable = true;
   }
   return NS_OK;
 }
 
 bool
 nsDocShellEditorData::GetEditable()
 {
-  return mMakeEditable || (mEditor != nullptr);
+  return mMakeEditable || (mHTMLEditor != nullptr);
 }
 
 nsresult
 nsDocShellEditorData::CreateEditor()
 {
   nsCOMPtr<nsIEditingSession> editingSession;
   nsresult rv = GetEditingSession(getter_AddRefs(editingSession));
   if (NS_FAILED(rv)) {
@@ -93,39 +95,35 @@ nsDocShellEditorData::GetEditingSession(
   NS_ENSURE_SUCCESS(rv, rv);
 
   NS_ADDREF(*aResult = mEditingSession);
 
   return NS_OK;
 }
 
 nsresult
-nsDocShellEditorData::GetEditor(nsIEditor** aResult)
-{
-  NS_ENSURE_ARG_POINTER(aResult);
-  NS_IF_ADDREF(*aResult = mEditor);
-  return NS_OK;
-}
-
-nsresult
-nsDocShellEditorData::SetEditor(nsIEditor* aEditor)
+nsDocShellEditorData::SetHTMLEditor(HTMLEditor* aHTMLEditor)
 {
   // destroy any editor that we have. Checks for equality are
   // necessary to ensure that assigment into the nsCOMPtr does
   // not temporarily reduce the refCount of the editor to zero
-  if (mEditor.get() != aEditor) {
-    if (mEditor) {
-      mEditor->PreDestroy(false);
-      mEditor = nullptr;
-    }
+  if (mHTMLEditor == aHTMLEditor) {
+    return NS_OK;
+  }
 
-    mEditor = aEditor;  // owning addref
-    if (!mEditor) {
-      mMakeEditable = false;
-    }
+  if (mHTMLEditor) {
+    RefPtr<HTMLEditor> htmlEditor = mHTMLEditor.forget();
+    htmlEditor->PreDestroy(false);
+    MOZ_ASSERT(!mHTMLEditor,
+      "Nested call of nsDocShellEditorData::SetHTMLEditor() detected");
+  }
+
+  mHTMLEditor = aHTMLEditor;  // owning addref
+  if (!mHTMLEditor) {
+    mMakeEditable = false;
   }
 
   return NS_OK;
 }
 
 // This creates the editing session on the content docShell that owns 'this'.
 nsresult
 nsDocShellEditorData::EnsureEditingSession()
--- a/docshell/base/nsDocShellEditorData.h
+++ b/docshell/base/nsDocShellEditorData.h
@@ -5,59 +5,63 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 #ifndef nsDocShellEditorData_h__
 #define nsDocShellEditorData_h__
 
 #ifndef nsCOMPtr_h___
 #include "nsCOMPtr.h"
 #endif
 
+#include "mozilla/HTMLEditor.h"
+#include "mozilla/RefPtr.h"
 #include "nsIHTMLDocument.h"
 
 class nsIDocShell;
 class nsIEditingSession;
-class nsIEditor;
 
 class nsDocShellEditorData
 {
 public:
   explicit nsDocShellEditorData(nsIDocShell* aOwningDocShell);
   ~nsDocShellEditorData();
 
   nsresult MakeEditable(bool aWaitForUriLoad);
   bool GetEditable();
   nsresult CreateEditor();
   nsresult GetEditingSession(nsIEditingSession** aResult);
-  nsresult GetEditor(nsIEditor** aResult);
-  nsresult SetEditor(nsIEditor* aEditor);
+  mozilla::HTMLEditor* GetHTMLEditor() const
+  {
+    return mHTMLEditor;
+  }
+  nsresult SetHTMLEditor(mozilla::HTMLEditor* aHTMLEditor);
   void TearDownEditor();
   nsresult DetachFromWindow();
   nsresult ReattachToWindow(nsIDocShell* aDocShell);
   bool WaitingForLoad() const { return mMakeEditable; }
 
 protected:
   nsresult EnsureEditingSession();
 
   // The doc shell that owns us. Weak ref, since it always outlives us.
   nsIDocShell* mDocShell;
 
   // Only present for the content root docShell. Session is owned here.
   nsCOMPtr<nsIEditingSession> mEditingSession;
 
+  // If this frame is editable, store HTML editor here. It's owned here.
+  RefPtr<mozilla::HTMLEditor> mHTMLEditor;
+
+  // Backup for the corresponding nsIHTMLDocument's  editing state while
+  // the editor is detached.
+  nsIHTMLDocument::EditingState mDetachedEditingState;
+
   // Indicates whether to make an editor after a url load.
   bool mMakeEditable;
 
-  // If this frame is editable, store editor here. Editor is owned here.
-  nsCOMPtr<nsIEditor> mEditor;
-
   // Denotes if the editor is detached from its window. The editor is detached
   // while it's stored in the session history bfcache.
   bool mIsDetached;
 
   // Backup for mMakeEditable while the editor is detached.
   bool mDetachedMakeEditable;
-
-  // Backup for the corresponding nsIHTMLDocument's  editing state while
-  // the editor is detached.
-  nsIHTMLDocument::EditingState mDetachedEditingState;
 };
 
 #endif // nsDocShellEditorData_h__