|
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- |
|
2 * |
|
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 |
|
8 #include "nsDocShellEditorData.h" |
|
9 #include "nsIInterfaceRequestorUtils.h" |
|
10 #include "nsComponentManagerUtils.h" |
|
11 #include "nsIDOMWindow.h" |
|
12 #include "nsIDOMDocument.h" |
|
13 #include "nsIEditor.h" |
|
14 #include "nsIEditingSession.h" |
|
15 #include "nsIDocShell.h" |
|
16 |
|
17 /*--------------------------------------------------------------------------- |
|
18 |
|
19 nsDocShellEditorData |
|
20 |
|
21 ----------------------------------------------------------------------------*/ |
|
22 |
|
23 nsDocShellEditorData::nsDocShellEditorData(nsIDocShell* inOwningDocShell) |
|
24 : mDocShell(inOwningDocShell) |
|
25 , mMakeEditable(false) |
|
26 , mIsDetached(false) |
|
27 , mDetachedMakeEditable(false) |
|
28 , mDetachedEditingState(nsIHTMLDocument::eOff) |
|
29 { |
|
30 NS_ASSERTION(mDocShell, "Where is my docShell?"); |
|
31 } |
|
32 |
|
33 |
|
34 /*--------------------------------------------------------------------------- |
|
35 |
|
36 ~nsDocShellEditorData |
|
37 |
|
38 ----------------------------------------------------------------------------*/ |
|
39 nsDocShellEditorData::~nsDocShellEditorData() |
|
40 { |
|
41 TearDownEditor(); |
|
42 } |
|
43 |
|
44 void |
|
45 nsDocShellEditorData::TearDownEditor() |
|
46 { |
|
47 if (mEditor) { |
|
48 mEditor->PreDestroy(false); |
|
49 mEditor = nullptr; |
|
50 } |
|
51 mEditingSession = nullptr; |
|
52 mIsDetached = false; |
|
53 } |
|
54 |
|
55 |
|
56 /*--------------------------------------------------------------------------- |
|
57 |
|
58 MakeEditable |
|
59 |
|
60 ----------------------------------------------------------------------------*/ |
|
61 nsresult |
|
62 nsDocShellEditorData::MakeEditable(bool inWaitForUriLoad) |
|
63 { |
|
64 if (mMakeEditable) |
|
65 return NS_OK; |
|
66 |
|
67 // if we are already editable, and are getting turned off, |
|
68 // nuke the editor. |
|
69 if (mEditor) |
|
70 { |
|
71 NS_WARNING("Destroying existing editor on frame"); |
|
72 |
|
73 mEditor->PreDestroy(false); |
|
74 mEditor = nullptr; |
|
75 } |
|
76 |
|
77 if (inWaitForUriLoad) |
|
78 mMakeEditable = true; |
|
79 return NS_OK; |
|
80 } |
|
81 |
|
82 |
|
83 /*--------------------------------------------------------------------------- |
|
84 |
|
85 GetEditable |
|
86 |
|
87 ----------------------------------------------------------------------------*/ |
|
88 bool |
|
89 nsDocShellEditorData::GetEditable() |
|
90 { |
|
91 return mMakeEditable || (mEditor != nullptr); |
|
92 } |
|
93 |
|
94 /*--------------------------------------------------------------------------- |
|
95 |
|
96 CreateEditor |
|
97 |
|
98 ----------------------------------------------------------------------------*/ |
|
99 nsresult |
|
100 nsDocShellEditorData::CreateEditor() |
|
101 { |
|
102 nsCOMPtr<nsIEditingSession> editingSession; |
|
103 nsresult rv = GetEditingSession(getter_AddRefs(editingSession)); |
|
104 if (NS_FAILED(rv)) return rv; |
|
105 |
|
106 nsCOMPtr<nsIDOMWindow> domWindow = do_GetInterface(mDocShell); |
|
107 rv = editingSession->SetupEditorOnWindow(domWindow); |
|
108 if (NS_FAILED(rv)) return rv; |
|
109 |
|
110 return NS_OK; |
|
111 } |
|
112 |
|
113 |
|
114 /*--------------------------------------------------------------------------- |
|
115 |
|
116 GetEditingSession |
|
117 |
|
118 ----------------------------------------------------------------------------*/ |
|
119 nsresult |
|
120 nsDocShellEditorData::GetEditingSession(nsIEditingSession **outEditingSession) |
|
121 { |
|
122 nsresult rv = EnsureEditingSession(); |
|
123 NS_ENSURE_SUCCESS(rv, rv); |
|
124 |
|
125 NS_ADDREF(*outEditingSession = mEditingSession); |
|
126 |
|
127 return NS_OK; |
|
128 } |
|
129 |
|
130 |
|
131 /*--------------------------------------------------------------------------- |
|
132 |
|
133 GetEditor |
|
134 |
|
135 ----------------------------------------------------------------------------*/ |
|
136 nsresult |
|
137 nsDocShellEditorData::GetEditor(nsIEditor **outEditor) |
|
138 { |
|
139 NS_ENSURE_ARG_POINTER(outEditor); |
|
140 NS_IF_ADDREF(*outEditor = mEditor); |
|
141 return NS_OK; |
|
142 } |
|
143 |
|
144 |
|
145 /*--------------------------------------------------------------------------- |
|
146 |
|
147 SetEditor |
|
148 |
|
149 ----------------------------------------------------------------------------*/ |
|
150 nsresult |
|
151 nsDocShellEditorData::SetEditor(nsIEditor *inEditor) |
|
152 { |
|
153 // destroy any editor that we have. Checks for equality are |
|
154 // necessary to ensure that assigment into the nsCOMPtr does |
|
155 // not temporarily reduce the refCount of the editor to zero |
|
156 if (mEditor.get() != inEditor) |
|
157 { |
|
158 if (mEditor) |
|
159 { |
|
160 mEditor->PreDestroy(false); |
|
161 mEditor = nullptr; |
|
162 } |
|
163 |
|
164 mEditor = inEditor; // owning addref |
|
165 if (!mEditor) |
|
166 mMakeEditable = false; |
|
167 } |
|
168 |
|
169 return NS_OK; |
|
170 } |
|
171 |
|
172 |
|
173 /*--------------------------------------------------------------------------- |
|
174 |
|
175 EnsureEditingSession |
|
176 |
|
177 This creates the editing session on the content docShell that owns |
|
178 'this'. |
|
179 |
|
180 ----------------------------------------------------------------------------*/ |
|
181 nsresult |
|
182 nsDocShellEditorData::EnsureEditingSession() |
|
183 { |
|
184 NS_ASSERTION(mDocShell, "Should have docShell here"); |
|
185 NS_ASSERTION(!mIsDetached, "This will stomp editing session!"); |
|
186 |
|
187 nsresult rv = NS_OK; |
|
188 |
|
189 if (!mEditingSession) |
|
190 { |
|
191 mEditingSession = |
|
192 do_CreateInstance("@mozilla.org/editor/editingsession;1", &rv); |
|
193 } |
|
194 |
|
195 return rv; |
|
196 } |
|
197 |
|
198 nsresult |
|
199 nsDocShellEditorData::DetachFromWindow() |
|
200 { |
|
201 NS_ASSERTION(mEditingSession, |
|
202 "Can't detach when we don't have a session to detach!"); |
|
203 |
|
204 nsCOMPtr<nsIDOMWindow> domWindow = do_GetInterface(mDocShell); |
|
205 nsresult rv = mEditingSession->DetachFromWindow(domWindow); |
|
206 NS_ENSURE_SUCCESS(rv, rv); |
|
207 |
|
208 mIsDetached = true; |
|
209 mDetachedMakeEditable = mMakeEditable; |
|
210 mMakeEditable = false; |
|
211 |
|
212 nsCOMPtr<nsIDOMDocument> domDoc; |
|
213 domWindow->GetDocument(getter_AddRefs(domDoc)); |
|
214 nsCOMPtr<nsIHTMLDocument> htmlDoc = do_QueryInterface(domDoc); |
|
215 if (htmlDoc) |
|
216 mDetachedEditingState = htmlDoc->GetEditingState(); |
|
217 |
|
218 mDocShell = nullptr; |
|
219 |
|
220 return NS_OK; |
|
221 } |
|
222 |
|
223 nsresult |
|
224 nsDocShellEditorData::ReattachToWindow(nsIDocShell* aDocShell) |
|
225 { |
|
226 mDocShell = aDocShell; |
|
227 |
|
228 nsCOMPtr<nsIDOMWindow> domWindow = do_GetInterface(mDocShell); |
|
229 nsresult rv = mEditingSession->ReattachToWindow(domWindow); |
|
230 NS_ENSURE_SUCCESS(rv, rv); |
|
231 |
|
232 mIsDetached = false; |
|
233 mMakeEditable = mDetachedMakeEditable; |
|
234 |
|
235 nsCOMPtr<nsIDOMDocument> domDoc; |
|
236 domWindow->GetDocument(getter_AddRefs(domDoc)); |
|
237 nsCOMPtr<nsIHTMLDocument> htmlDoc = do_QueryInterface(domDoc); |
|
238 if (htmlDoc) |
|
239 htmlDoc->SetEditingState(mDetachedEditingState); |
|
240 |
|
241 return NS_OK; |
|
242 } |