Bug 1391165 - part4: nsIEditor::EndOfDocument() should be implemented with an internal method which takes pointer to Selection r?smaug
EditorBase::GetSelection() sometimes appears in profile. So, it shouldn't be
called in nsIEditor::EndOfDocument() if the callers of
nsIEditor::EndOfDocument() has a pointer to Selection.
This patch adds EditorBase::CollapseSelectionToEnd() for the internal method
and make all callers of nsIEditor::EndOfDocument() use it.
MozReview-Commit-ID: 8H4ThxzdKDf
--- a/editor/libeditor/EditorBase.cpp
+++ b/editor/libeditor/EditorBase.cpp
@@ -1128,37 +1128,46 @@ EditorBase::BeginningOfDocument()
int32_t offsetInParent = parent->IndexOf(firstNode);
return selection->Collapse(parent, offsetInParent);
}
NS_IMETHODIMP
EditorBase::EndOfDocument()
{
+ RefPtr<Selection> selection = GetSelection();
+ return CollapseSelectionToEnd(selection);
+}
+
+nsresult
+EditorBase::CollapseSelectionToEnd(Selection* aSelection)
+{
// XXX Why doesn't this check if the document is alive?
if (NS_WARN_IF(!IsInitialized())) {
return NS_ERROR_NOT_INITIALIZED;
}
- // get selection
- RefPtr<Selection> selection = GetSelection();
- NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER);
+ if (NS_WARN_IF(!aSelection)) {
+ return NS_ERROR_NULL_POINTER;
+ }
// get the root element
nsINode* node = GetRoot();
- NS_ENSURE_TRUE(node, NS_ERROR_NULL_POINTER);
+ if (NS_WARN_IF(!node)) {
+ return NS_ERROR_NULL_POINTER;
+ }
+
nsINode* child = node->GetLastChild();
-
- while (child && IsContainer(child->AsDOMNode())) {
+ while (child && IsContainer(child)) {
node = child;
child = node->GetLastChild();
}
uint32_t length = node->Length();
- return selection->Collapse(node, int32_t(length));
+ return aSelection->Collapse(node, static_cast<int32_t>(length));
}
NS_IMETHODIMP
EditorBase::GetDocumentModified(bool* outDocModified)
{
NS_ENSURE_TRUE(outDocModified, NS_ERROR_NULL_POINTER);
int32_t modCount = 0;
--- a/editor/libeditor/EditorBase.h
+++ b/editor/libeditor/EditorBase.h
@@ -900,16 +900,21 @@ public:
if (!sc) {
return nullptr;
}
Selection* selection = sc->GetDOMSelection(ToRawSelectionType(aSelectionType));
return selection;
}
/**
+ * CollapseSelectionToEnd() collapses the selection to the end of the editor.
+ */
+ nsresult CollapseSelectionToEnd(Selection* aSelection);
+
+ /**
* Helpers to add a node to the selection.
* Used by table cell selection methods.
*/
nsresult CreateRange(nsIDOMNode* aStartContainer, int32_t aStartOffset,
nsIDOMNode* aEndContainer, int32_t aEndOffset,
nsRange** aRange);
/**
--- a/editor/libeditor/TextEditRules.cpp
+++ b/editor/libeditor/TextEditRules.cpp
@@ -131,17 +131,17 @@ TextEditRules::Init(TextEditor* aTextEdi
NS_ENSURE_SUCCESS(rv, rv);
// If the selection hasn't been set up yet, set it up collapsed to the end of
// our editable content.
int32_t rangeCount;
rv = selection->GetRangeCount(&rangeCount);
NS_ENSURE_SUCCESS(rv, rv);
if (!rangeCount) {
- rv = mTextEditor->EndOfDocument();
+ rv = mTextEditor->CollapseSelectionToEnd(selection);
NS_ENSURE_SUCCESS(rv, rv);
}
if (IsPlaintextEditor()) {
// ensure trailing br node
rv = CreateTrailingBRIfNeeded();
NS_ENSURE_SUCCESS(rv, rv);
}
@@ -477,17 +477,17 @@ TextEditRules::CollapseSelectionToTraili
}
NS_ENSURE_STATE(mTextEditor);
// If there is no selection ranges, we should set to the end of the editor.
// This is usually performed in TextEditRules::Init(), however, if the
// editor is reframed, this may be called by AfterEdit().
if (!aSelection->RangeCount()) {
- mTextEditor->EndOfDocument();
+ mTextEditor->CollapseSelectionToEnd(aSelection);
}
// if we are at the end of the textarea, we need to set the
// selection to stick to the mozBR at the end of the textarea.
int32_t selOffset;
nsCOMPtr<nsINode> selNode;
nsresult rv =
EditorBase::GetStartNodeAndOffset(aSelection,