nsDocShellEditorData.cpp (3954B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "nsDocShellEditorData.h" 8 9 #include "mozilla/dom/Document.h" 10 #include "mozilla/HTMLEditor.h" 11 #include "nsIInterfaceRequestorUtils.h" 12 #include "nsComponentManagerUtils.h" 13 #include "nsPIDOMWindow.h" 14 #include "nsEditingSession.h" 15 #include "nsIDocShell.h" 16 17 using namespace mozilla; 18 using namespace mozilla::dom; 19 20 nsDocShellEditorData::nsDocShellEditorData(nsDocShell* aOwningDocShell) 21 : mDocShell(aOwningDocShell), 22 mDetachedEditingState(Document::EditingState::eOff), 23 mMakeEditable(false), 24 mIsDetached(false), 25 mDetachedMakeEditable(false) { 26 NS_ASSERTION(mDocShell, "Where is my docShell?"); 27 } 28 29 nsDocShellEditorData::~nsDocShellEditorData() { TearDownEditor(); } 30 31 void nsDocShellEditorData::TearDownEditor() { 32 if (mHTMLEditor) { 33 RefPtr<HTMLEditor> htmlEditor = std::move(mHTMLEditor); 34 htmlEditor->PreDestroy(); 35 } 36 mEditingSession = nullptr; 37 mIsDetached = false; 38 } 39 40 nsresult nsDocShellEditorData::MakeEditable(bool aInWaitForUriLoad) { 41 if (mMakeEditable) { 42 return NS_OK; 43 } 44 45 // if we are already editable, and are getting turned off, 46 // nuke the editor. 47 if (mHTMLEditor) { 48 NS_WARNING("Destroying existing editor on frame"); 49 50 RefPtr<HTMLEditor> htmlEditor = std::move(mHTMLEditor); 51 htmlEditor->PreDestroy(); 52 } 53 54 if (aInWaitForUriLoad) { 55 mMakeEditable = true; 56 } 57 return NS_OK; 58 } 59 60 bool nsDocShellEditorData::GetEditable() { 61 return mMakeEditable || (mHTMLEditor != nullptr); 62 } 63 64 nsEditingSession* nsDocShellEditorData::GetEditingSession() { 65 EnsureEditingSession(); 66 67 return mEditingSession.get(); 68 } 69 70 nsresult nsDocShellEditorData::SetHTMLEditor(HTMLEditor* aHTMLEditor) { 71 // destroy any editor that we have. Checks for equality are 72 // necessary to ensure that assigment into the nsCOMPtr does 73 // not temporarily reduce the refCount of the editor to zero 74 if (mHTMLEditor == aHTMLEditor) { 75 return NS_OK; 76 } 77 78 if (mHTMLEditor) { 79 RefPtr<HTMLEditor> htmlEditor = std::move(mHTMLEditor); 80 htmlEditor->PreDestroy(); 81 MOZ_ASSERT(!mHTMLEditor, 82 "Nested call of nsDocShellEditorData::SetHTMLEditor() detected"); 83 } 84 85 mHTMLEditor = aHTMLEditor; // owning addref 86 if (!mHTMLEditor) { 87 mMakeEditable = false; 88 } 89 90 return NS_OK; 91 } 92 93 // This creates the editing session on the content docShell that owns 'this'. 94 void nsDocShellEditorData::EnsureEditingSession() { 95 NS_ASSERTION(mDocShell, "Should have docShell here"); 96 NS_ASSERTION(!mIsDetached, "This will stomp editing session!"); 97 98 if (!mEditingSession) { 99 mEditingSession = new nsEditingSession(); 100 } 101 } 102 103 nsresult nsDocShellEditorData::DetachFromWindow() { 104 NS_ASSERTION(mEditingSession, 105 "Can't detach when we don't have a session to detach!"); 106 107 nsCOMPtr<nsPIDOMWindowOuter> domWindow = 108 mDocShell ? mDocShell->GetWindow() : nullptr; 109 nsresult rv = mEditingSession->DetachFromWindow(domWindow); 110 NS_ENSURE_SUCCESS(rv, rv); 111 112 mIsDetached = true; 113 mDetachedMakeEditable = mMakeEditable; 114 mMakeEditable = false; 115 116 nsCOMPtr<dom::Document> doc = domWindow->GetDoc(); 117 mDetachedEditingState = doc->GetEditingState(); 118 119 mDocShell = nullptr; 120 121 return NS_OK; 122 } 123 124 nsresult nsDocShellEditorData::ReattachToWindow(nsDocShell* aDocShell) { 125 mDocShell = aDocShell; 126 127 nsCOMPtr<nsPIDOMWindowOuter> domWindow = 128 mDocShell ? mDocShell->GetWindow() : nullptr; 129 nsresult rv = mEditingSession->ReattachToWindow(domWindow); 130 NS_ENSURE_SUCCESS(rv, rv); 131 132 mIsDetached = false; 133 mMakeEditable = mDetachedMakeEditable; 134 135 RefPtr<dom::Document> doc = domWindow->GetDoc(); 136 doc->SetEditingState(mDetachedEditingState); 137 138 return NS_OK; 139 }