diff options
Diffstat (limited to 'docshell/base/nsDocShellEditorData.cpp')
-rw-r--r-- | docshell/base/nsDocShellEditorData.cpp | 139 |
1 files changed, 139 insertions, 0 deletions
diff --git a/docshell/base/nsDocShellEditorData.cpp b/docshell/base/nsDocShellEditorData.cpp new file mode 100644 index 0000000000..890191aaf4 --- /dev/null +++ b/docshell/base/nsDocShellEditorData.cpp @@ -0,0 +1,139 @@ +/* -*- 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 "mozilla/dom/Document.h" +#include "mozilla/HTMLEditor.h" +#include "nsIInterfaceRequestorUtils.h" +#include "nsComponentManagerUtils.h" +#include "nsPIDOMWindow.h" +#include "nsEditingSession.h" +#include "nsIDocShell.h" + +using namespace mozilla; +using namespace mozilla::dom; + +nsDocShellEditorData::nsDocShellEditorData(nsIDocShell* aOwningDocShell) + : mDocShell(aOwningDocShell), + mDetachedEditingState(Document::EditingState::eOff), + mMakeEditable(false), + mIsDetached(false), + mDetachedMakeEditable(false) { + NS_ASSERTION(mDocShell, "Where is my docShell?"); +} + +nsDocShellEditorData::~nsDocShellEditorData() { TearDownEditor(); } + +void nsDocShellEditorData::TearDownEditor() { + if (mHTMLEditor) { + RefPtr<HTMLEditor> htmlEditor = std::move(mHTMLEditor); + 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 (mHTMLEditor) { + NS_WARNING("Destroying existing editor on frame"); + + RefPtr<HTMLEditor> htmlEditor = std::move(mHTMLEditor); + htmlEditor->PreDestroy(false); + } + + if (aInWaitForUriLoad) { + mMakeEditable = true; + } + return NS_OK; +} + +bool nsDocShellEditorData::GetEditable() { + return mMakeEditable || (mHTMLEditor != nullptr); +} + +nsEditingSession* nsDocShellEditorData::GetEditingSession() { + EnsureEditingSession(); + + return mEditingSession.get(); +} + +nsresult 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 (mHTMLEditor == aHTMLEditor) { + return NS_OK; + } + + if (mHTMLEditor) { + RefPtr<HTMLEditor> htmlEditor = std::move(mHTMLEditor); + 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'. +void nsDocShellEditorData::EnsureEditingSession() { + NS_ASSERTION(mDocShell, "Should have docShell here"); + NS_ASSERTION(!mIsDetached, "This will stomp editing session!"); + + if (!mEditingSession) { + mEditingSession = new nsEditingSession(); + } +} + +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<dom::Document> doc = domWindow->GetDoc(); + mDetachedEditingState = doc->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; + + RefPtr<dom::Document> doc = domWindow->GetDoc(); + doc->SetEditingState(mDetachedEditingState); + + return NS_OK; +} |