diff -r 000000000000 -r 6474c204b198 docshell/base/nsDocShellEditorData.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/docshell/base/nsDocShellEditorData.cpp Wed Dec 31 06:09:35 2014 +0100 @@ -0,0 +1,242 @@ +/* -*- Mode: C++; tab-width: 2; 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 "nsIDOMWindow.h" +#include "nsIDOMDocument.h" +#include "nsIEditor.h" +#include "nsIEditingSession.h" +#include "nsIDocShell.h" + +/*--------------------------------------------------------------------------- + + nsDocShellEditorData + +----------------------------------------------------------------------------*/ + +nsDocShellEditorData::nsDocShellEditorData(nsIDocShell* inOwningDocShell) +: mDocShell(inOwningDocShell) +, mMakeEditable(false) +, mIsDetached(false) +, mDetachedMakeEditable(false) +, mDetachedEditingState(nsIHTMLDocument::eOff) +{ + NS_ASSERTION(mDocShell, "Where is my docShell?"); +} + + +/*--------------------------------------------------------------------------- + + ~nsDocShellEditorData + +----------------------------------------------------------------------------*/ +nsDocShellEditorData::~nsDocShellEditorData() +{ + TearDownEditor(); +} + +void +nsDocShellEditorData::TearDownEditor() +{ + if (mEditor) { + mEditor->PreDestroy(false); + mEditor = nullptr; + } + mEditingSession = nullptr; + mIsDetached = false; +} + + +/*--------------------------------------------------------------------------- + + MakeEditable + +----------------------------------------------------------------------------*/ +nsresult +nsDocShellEditorData::MakeEditable(bool inWaitForUriLoad) +{ + 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 (inWaitForUriLoad) + mMakeEditable = true; + return NS_OK; +} + + +/*--------------------------------------------------------------------------- + + GetEditable + +----------------------------------------------------------------------------*/ +bool +nsDocShellEditorData::GetEditable() +{ + return mMakeEditable || (mEditor != nullptr); +} + +/*--------------------------------------------------------------------------- + + CreateEditor + +----------------------------------------------------------------------------*/ +nsresult +nsDocShellEditorData::CreateEditor() +{ + nsCOMPtr editingSession; + nsresult rv = GetEditingSession(getter_AddRefs(editingSession)); + if (NS_FAILED(rv)) return rv; + + nsCOMPtr domWindow = do_GetInterface(mDocShell); + rv = editingSession->SetupEditorOnWindow(domWindow); + if (NS_FAILED(rv)) return rv; + + return NS_OK; +} + + +/*--------------------------------------------------------------------------- + + GetEditingSession + +----------------------------------------------------------------------------*/ +nsresult +nsDocShellEditorData::GetEditingSession(nsIEditingSession **outEditingSession) +{ + nsresult rv = EnsureEditingSession(); + NS_ENSURE_SUCCESS(rv, rv); + + NS_ADDREF(*outEditingSession = mEditingSession); + + return NS_OK; +} + + +/*--------------------------------------------------------------------------- + + GetEditor + +----------------------------------------------------------------------------*/ +nsresult +nsDocShellEditorData::GetEditor(nsIEditor **outEditor) +{ + NS_ENSURE_ARG_POINTER(outEditor); + NS_IF_ADDREF(*outEditor = mEditor); + return NS_OK; +} + + +/*--------------------------------------------------------------------------- + + SetEditor + +----------------------------------------------------------------------------*/ +nsresult +nsDocShellEditorData::SetEditor(nsIEditor *inEditor) +{ + // 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() != inEditor) + { + if (mEditor) + { + mEditor->PreDestroy(false); + mEditor = nullptr; + } + + mEditor = inEditor; // owning addref + if (!mEditor) + mMakeEditable = false; + } + + return NS_OK; +} + + +/*--------------------------------------------------------------------------- + + EnsureEditingSession + + 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 domWindow = do_GetInterface(mDocShell); + nsresult rv = mEditingSession->DetachFromWindow(domWindow); + NS_ENSURE_SUCCESS(rv, rv); + + mIsDetached = true; + mDetachedMakeEditable = mMakeEditable; + mMakeEditable = false; + + nsCOMPtr domDoc; + domWindow->GetDocument(getter_AddRefs(domDoc)); + nsCOMPtr htmlDoc = do_QueryInterface(domDoc); + if (htmlDoc) + mDetachedEditingState = htmlDoc->GetEditingState(); + + mDocShell = nullptr; + + return NS_OK; +} + +nsresult +nsDocShellEditorData::ReattachToWindow(nsIDocShell* aDocShell) +{ + mDocShell = aDocShell; + + nsCOMPtr domWindow = do_GetInterface(mDocShell); + nsresult rv = mEditingSession->ReattachToWindow(domWindow); + NS_ENSURE_SUCCESS(rv, rv); + + mIsDetached = false; + mMakeEditable = mDetachedMakeEditable; + + nsCOMPtr domDoc; + domWindow->GetDocument(getter_AddRefs(domDoc)); + nsCOMPtr htmlDoc = do_QueryInterface(domDoc); + if (htmlDoc) + htmlDoc->SetEditingState(mDetachedEditingState); + + return NS_OK; +}