Coverage Report

Created: 2018-09-25 14:53

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