123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193 |
- /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
- /* 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 "nsIDocument.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;
- }
|