summaryrefslogtreecommitdiffstats
path: root/docshell/base/nsDocShellEditorData.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'docshell/base/nsDocShellEditorData.cpp')
-rw-r--r--docshell/base/nsDocShellEditorData.cpp192
1 files changed, 192 insertions, 0 deletions
diff --git a/docshell/base/nsDocShellEditorData.cpp b/docshell/base/nsDocShellEditorData.cpp
new file mode 100644
index 000000000..7e4068eb9
--- /dev/null
+++ b/docshell/base/nsDocShellEditorData.cpp
@@ -0,0 +1,192 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsDocShellEditorData.h"
+#include "nsIInterfaceRequestorUtils.h"
+#include "nsComponentManagerUtils.h"
+#include "nsPIDOMWindow.h"
+#include "nsIDOMDocument.h"
+#include "nsIEditor.h"
+#include "nsIEditingSession.h"
+#include "nsIDocShell.h"
+
+nsDocShellEditorData::nsDocShellEditorData(nsIDocShell* aOwningDocShell)
+ : mDocShell(aOwningDocShell)
+ , 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;
+ }
+ 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) {
+ NS_WARNING("Destroying existing editor on frame");
+
+ mEditor->PreDestroy(false);
+ mEditor = nullptr;
+ }
+
+ if (aInWaitForUriLoad) {
+ mMakeEditable = true;
+ }
+ return NS_OK;
+}
+
+bool
+nsDocShellEditorData::GetEditable()
+{
+ return mMakeEditable || (mEditor != nullptr);
+}
+
+nsresult
+nsDocShellEditorData::CreateEditor()
+{
+ nsCOMPtr<nsIEditingSession> editingSession;
+ nsresult rv = GetEditingSession(getter_AddRefs(editingSession));
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+
+ nsCOMPtr<nsPIDOMWindowOuter> domWindow =
+ mDocShell ? mDocShell->GetWindow() : nullptr;
+ rv = editingSession->SetupEditorOnWindow(domWindow);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+
+ return NS_OK;
+}
+
+nsresult
+nsDocShellEditorData::GetEditingSession(nsIEditingSession** aResult)
+{
+ nsresult rv = EnsureEditingSession();
+ 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)
+{
+ // 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;
+ }
+
+ mEditor = aEditor; // owning addref
+ if (!mEditor) {
+ mMakeEditable = false;
+ }
+ }
+
+ return NS_OK;
+}
+
+// This creates the editing session on the content docShell that owns 'this'.
+nsresult
+nsDocShellEditorData::EnsureEditingSession()
+{
+ NS_ASSERTION(mDocShell, "Should have docShell here");
+ NS_ASSERTION(!mIsDetached, "This will stomp editing session!");
+
+ nsresult rv = NS_OK;
+
+ if (!mEditingSession) {
+ mEditingSession =
+ do_CreateInstance("@mozilla.org/editor/editingsession;1", &rv);
+ }
+
+ return rv;
+}
+
+nsresult
+nsDocShellEditorData::DetachFromWindow()
+{
+ NS_ASSERTION(mEditingSession,
+ "Can't detach when we don't have a session to detach!");
+
+ nsCOMPtr<nsPIDOMWindowOuter> domWindow =
+ mDocShell ? mDocShell->GetWindow() : nullptr;
+ nsresult rv = mEditingSession->DetachFromWindow(domWindow);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ mIsDetached = true;
+ mDetachedMakeEditable = mMakeEditable;
+ mMakeEditable = false;
+
+ nsCOMPtr<nsIDocument> doc = domWindow->GetDoc();
+ nsCOMPtr<nsIHTMLDocument> htmlDoc = do_QueryInterface(doc);
+ if (htmlDoc) {
+ mDetachedEditingState = htmlDoc->GetEditingState();
+ }
+
+ mDocShell = nullptr;
+
+ return NS_OK;
+}
+
+nsresult
+nsDocShellEditorData::ReattachToWindow(nsIDocShell* aDocShell)
+{
+ mDocShell = aDocShell;
+
+ nsCOMPtr<nsPIDOMWindowOuter> domWindow =
+ mDocShell ? mDocShell->GetWindow() : nullptr;
+ nsresult rv = mEditingSession->ReattachToWindow(domWindow);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ mIsDetached = false;
+ mMakeEditable = mDetachedMakeEditable;
+
+ nsCOMPtr<nsIDocument> doc = domWindow->GetDoc();
+ nsCOMPtr<nsIHTMLDocument> htmlDoc = do_QueryInterface(doc);
+ if (htmlDoc) {
+ htmlDoc->SetEditingState(mDetachedEditingState);
+ }
+
+ return NS_OK;
+}