Line data Source code
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 : #include "nsIInterfaceRequestorUtils.h"
9 : #include "nsComponentManagerUtils.h"
10 : #include "nsPIDOMWindow.h"
11 : #include "nsIDOMDocument.h"
12 : #include "nsIEditor.h"
13 : #include "nsIEditingSession.h"
14 : #include "nsIDocShell.h"
15 :
16 0 : nsDocShellEditorData::nsDocShellEditorData(nsIDocShell* aOwningDocShell)
17 : : mDocShell(aOwningDocShell)
18 : , mMakeEditable(false)
19 : , mIsDetached(false)
20 : , mDetachedMakeEditable(false)
21 0 : , mDetachedEditingState(nsIHTMLDocument::eOff)
22 : {
23 0 : NS_ASSERTION(mDocShell, "Where is my docShell?");
24 0 : }
25 :
26 0 : nsDocShellEditorData::~nsDocShellEditorData()
27 : {
28 0 : TearDownEditor();
29 0 : }
30 :
31 : void
32 0 : nsDocShellEditorData::TearDownEditor()
33 : {
34 0 : if (mEditor) {
35 0 : mEditor->PreDestroy(false);
36 0 : mEditor = nullptr;
37 : }
38 0 : mEditingSession = nullptr;
39 0 : mIsDetached = false;
40 0 : }
41 :
42 : nsresult
43 0 : nsDocShellEditorData::MakeEditable(bool aInWaitForUriLoad)
44 : {
45 0 : if (mMakeEditable) {
46 0 : return NS_OK;
47 : }
48 :
49 : // if we are already editable, and are getting turned off,
50 : // nuke the editor.
51 0 : if (mEditor) {
52 0 : NS_WARNING("Destroying existing editor on frame");
53 :
54 0 : mEditor->PreDestroy(false);
55 0 : mEditor = nullptr;
56 : }
57 :
58 0 : if (aInWaitForUriLoad) {
59 0 : mMakeEditable = true;
60 : }
61 0 : return NS_OK;
62 : }
63 :
64 : bool
65 0 : nsDocShellEditorData::GetEditable()
66 : {
67 0 : return mMakeEditable || (mEditor != nullptr);
68 : }
69 :
70 : nsresult
71 0 : nsDocShellEditorData::CreateEditor()
72 : {
73 0 : nsCOMPtr<nsIEditingSession> editingSession;
74 0 : nsresult rv = GetEditingSession(getter_AddRefs(editingSession));
75 0 : if (NS_FAILED(rv)) {
76 0 : return rv;
77 : }
78 :
79 : nsCOMPtr<nsPIDOMWindowOuter> domWindow =
80 0 : mDocShell ? mDocShell->GetWindow() : nullptr;
81 0 : rv = editingSession->SetupEditorOnWindow(domWindow);
82 0 : if (NS_FAILED(rv)) {
83 0 : return rv;
84 : }
85 :
86 0 : return NS_OK;
87 : }
88 :
89 : nsresult
90 0 : nsDocShellEditorData::GetEditingSession(nsIEditingSession** aResult)
91 : {
92 0 : nsresult rv = EnsureEditingSession();
93 0 : NS_ENSURE_SUCCESS(rv, rv);
94 :
95 0 : NS_ADDREF(*aResult = mEditingSession);
96 :
97 0 : return NS_OK;
98 : }
99 :
100 : nsresult
101 0 : nsDocShellEditorData::GetEditor(nsIEditor** aResult)
102 : {
103 0 : NS_ENSURE_ARG_POINTER(aResult);
104 0 : NS_IF_ADDREF(*aResult = mEditor);
105 0 : return NS_OK;
106 : }
107 :
108 : nsresult
109 0 : nsDocShellEditorData::SetEditor(nsIEditor* aEditor)
110 : {
111 : // destroy any editor that we have. Checks for equality are
112 : // necessary to ensure that assigment into the nsCOMPtr does
113 : // not temporarily reduce the refCount of the editor to zero
114 0 : if (mEditor.get() != aEditor) {
115 0 : if (mEditor) {
116 0 : mEditor->PreDestroy(false);
117 0 : mEditor = nullptr;
118 : }
119 :
120 0 : mEditor = aEditor; // owning addref
121 0 : if (!mEditor) {
122 0 : mMakeEditable = false;
123 : }
124 : }
125 :
126 0 : return NS_OK;
127 : }
128 :
129 : // This creates the editing session on the content docShell that owns 'this'.
130 : nsresult
131 0 : nsDocShellEditorData::EnsureEditingSession()
132 : {
133 0 : NS_ASSERTION(mDocShell, "Should have docShell here");
134 0 : NS_ASSERTION(!mIsDetached, "This will stomp editing session!");
135 :
136 0 : nsresult rv = NS_OK;
137 :
138 0 : if (!mEditingSession) {
139 : mEditingSession =
140 0 : do_CreateInstance("@mozilla.org/editor/editingsession;1", &rv);
141 : }
142 :
143 0 : return rv;
144 : }
145 :
146 : nsresult
147 0 : nsDocShellEditorData::DetachFromWindow()
148 : {
149 0 : NS_ASSERTION(mEditingSession,
150 : "Can't detach when we don't have a session to detach!");
151 :
152 : nsCOMPtr<nsPIDOMWindowOuter> domWindow =
153 0 : mDocShell ? mDocShell->GetWindow() : nullptr;
154 0 : nsresult rv = mEditingSession->DetachFromWindow(domWindow);
155 0 : NS_ENSURE_SUCCESS(rv, rv);
156 :
157 0 : mIsDetached = true;
158 0 : mDetachedMakeEditable = mMakeEditable;
159 0 : mMakeEditable = false;
160 :
161 0 : nsCOMPtr<nsIDocument> doc = domWindow->GetDoc();
162 0 : nsCOMPtr<nsIHTMLDocument> htmlDoc = do_QueryInterface(doc);
163 0 : if (htmlDoc) {
164 0 : mDetachedEditingState = htmlDoc->GetEditingState();
165 : }
166 :
167 0 : mDocShell = nullptr;
168 :
169 0 : return NS_OK;
170 : }
171 :
172 : nsresult
173 0 : nsDocShellEditorData::ReattachToWindow(nsIDocShell* aDocShell)
174 : {
175 0 : mDocShell = aDocShell;
176 :
177 : nsCOMPtr<nsPIDOMWindowOuter> domWindow =
178 0 : mDocShell ? mDocShell->GetWindow() : nullptr;
179 0 : nsresult rv = mEditingSession->ReattachToWindow(domWindow);
180 0 : NS_ENSURE_SUCCESS(rv, rv);
181 :
182 0 : mIsDetached = false;
183 0 : mMakeEditable = mDetachedMakeEditable;
184 :
185 0 : nsCOMPtr<nsIDocument> doc = domWindow->GetDoc();
186 0 : nsCOMPtr<nsIHTMLDocument> htmlDoc = do_QueryInterface(doc);
187 0 : if (htmlDoc) {
188 0 : htmlDoc->SetEditingState(mDetachedEditingState);
189 : }
190 :
191 0 : return NS_OK;
192 : }
|