mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-29 15:52:07 +00:00
Bug 1415062 - part 2: Editor should use Selection::Collapse(const RawRangeBoundary&) as far as possible r=m_kato
In some places, editor computes index from child node for collapsing selection at the child node. However, it's expensive. Therefore, editor should use Selection::Collapse(const RawRangeBoundary&) as far as possible. MozReview-Commit-ID: LF2MwASuXzZ --HG-- extra : rebase_source : b7afc35c0d9d88845391b6f18de57cbff1935ae4
This commit is contained in:
parent
898bbb3137
commit
806668b21a
@ -216,9 +216,13 @@ public:
|
|||||||
mOffset = mozilla::Some(aOffset);
|
mOffset = mozilla::Some(aOffset);
|
||||||
}
|
}
|
||||||
void
|
void
|
||||||
Set(const nsIContent* aChild)
|
Set(const nsINode* aChild)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(aChild);
|
MOZ_ASSERT(aChild);
|
||||||
|
if (!aChild->IsContent()) {
|
||||||
|
Clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
mParent = aChild->GetParentNode();
|
mParent = aChild->GetParentNode();
|
||||||
mRef = aChild->GetPreviousSibling();
|
mRef = aChild->GetPreviousSibling();
|
||||||
if (!mRef) {
|
if (!mRef) {
|
||||||
@ -246,12 +250,14 @@ public:
|
|||||||
* If the container can have children and there is no next sibling, this
|
* If the container can have children and there is no next sibling, this
|
||||||
* outputs warning and does nothing. So, callers need to check if there is
|
* outputs warning and does nothing. So, callers need to check if there is
|
||||||
* next sibling which you need to refer.
|
* next sibling which you need to refer.
|
||||||
|
*
|
||||||
|
* @return true if there is a next sibling to refer.
|
||||||
*/
|
*/
|
||||||
void
|
bool
|
||||||
AdvanceOffset()
|
AdvanceOffset()
|
||||||
{
|
{
|
||||||
if (NS_WARN_IF(!mParent)) {
|
if (NS_WARN_IF(!mParent)) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
EnsureRef();
|
EnsureRef();
|
||||||
if (!mRef) {
|
if (!mRef) {
|
||||||
@ -260,30 +266,31 @@ public:
|
|||||||
MOZ_ASSERT(mOffset.isSome());
|
MOZ_ASSERT(mOffset.isSome());
|
||||||
if (NS_WARN_IF(mOffset.value() == mParent->Length())) {
|
if (NS_WARN_IF(mOffset.value() == mParent->Length())) {
|
||||||
// Already referring the end of the node.
|
// Already referring the end of the node.
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
mOffset = mozilla::Some(mOffset.value() + 1);
|
mOffset = mozilla::Some(mOffset.value() + 1);
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
mRef = mParent->GetFirstChild();
|
mRef = mParent->GetFirstChild();
|
||||||
if (NS_WARN_IF(!mRef)) {
|
if (NS_WARN_IF(!mRef)) {
|
||||||
// No children in the container.
|
// No children in the container.
|
||||||
mOffset = mozilla::Some(0);
|
mOffset = mozilla::Some(0);
|
||||||
} else {
|
return false;
|
||||||
mOffset = mozilla::Some(1);
|
|
||||||
}
|
}
|
||||||
return;
|
mOffset = mozilla::Some(1);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsIContent* nextSibling = mRef->GetNextSibling();
|
nsIContent* nextSibling = mRef->GetNextSibling();
|
||||||
if (NS_WARN_IF(!nextSibling)) {
|
if (NS_WARN_IF(!nextSibling)) {
|
||||||
// Already referring the end of the container.
|
// Already referring the end of the container.
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
mRef = nextSibling;
|
mRef = nextSibling;
|
||||||
if (mOffset.isSome()) {
|
if (mOffset.isSome()) {
|
||||||
mOffset = mozilla::Some(mOffset.value() + 1);
|
mOffset = mozilla::Some(mOffset.value() + 1);
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -293,34 +300,37 @@ public:
|
|||||||
* If the container can have children and there is no next previous, this
|
* If the container can have children and there is no next previous, this
|
||||||
* outputs warning and does nothing. So, callers need to check if there is
|
* outputs warning and does nothing. So, callers need to check if there is
|
||||||
* previous sibling which you need to refer.
|
* previous sibling which you need to refer.
|
||||||
|
*
|
||||||
|
* @return true if there is a previous sibling to refer.
|
||||||
*/
|
*/
|
||||||
void
|
bool
|
||||||
RewindOffset()
|
RewindOffset()
|
||||||
{
|
{
|
||||||
if (NS_WARN_IF(!mParent)) {
|
if (NS_WARN_IF(!mParent)) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
EnsureRef();
|
EnsureRef();
|
||||||
if (!mRef) {
|
if (!mRef) {
|
||||||
if (NS_WARN_IF(mParent->IsContainerNode())) {
|
if (NS_WARN_IF(mParent->IsContainerNode())) {
|
||||||
// Already referring the start of the container
|
// Already referring the start of the container
|
||||||
mOffset = mozilla::Some(0);
|
mOffset = mozilla::Some(0);
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
// In text node or something, just decrement the offset.
|
// In text node or something, just decrement the offset.
|
||||||
MOZ_ASSERT(mOffset.isSome());
|
MOZ_ASSERT(mOffset.isSome());
|
||||||
if (NS_WARN_IF(mOffset.value() == 0)) {
|
if (NS_WARN_IF(mOffset.value() == 0)) {
|
||||||
// Already referring the start of the node.
|
// Already referring the start of the node.
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
mOffset = mozilla::Some(mOffset.value() - 1);
|
mOffset = mozilla::Some(mOffset.value() - 1);
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
mRef = mRef->GetPreviousSibling();
|
mRef = mRef->GetPreviousSibling();
|
||||||
if (mOffset.isSome()) {
|
if (mOffset.isSome()) {
|
||||||
mOffset = mozilla::Some(mOffset.value() - 1);
|
mOffset = mozilla::Some(mOffset.value() - 1);
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
#include "mozilla/Casting.h"
|
#include "mozilla/Casting.h"
|
||||||
#include "mozilla/EditorBase.h"
|
#include "mozilla/EditorBase.h"
|
||||||
|
#include "mozilla/EditorDOMPoint.h"
|
||||||
|
|
||||||
#include "nsAlgorithm.h"
|
#include "nsAlgorithm.h"
|
||||||
#include "nsAString.h"
|
#include "nsAString.h"
|
||||||
@ -103,7 +104,14 @@ CreateElementTransaction::DoTransaction()
|
|||||||
RefPtr<Selection> selection = mEditorBase->GetSelection();
|
RefPtr<Selection> selection = mEditorBase->GetSelection();
|
||||||
NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER);
|
NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER);
|
||||||
|
|
||||||
rv = selection->Collapse(mParent, mParent->IndexOf(mNewNode) + 1);
|
EditorRawDOMPoint afterNewNode(mNewNode);
|
||||||
|
if (NS_WARN_IF(!afterNewNode.AdvanceOffset())) {
|
||||||
|
// If mutation observer or mutation event listener moved or removed the
|
||||||
|
// new node, we hit this case. Should we use script blocker while we're
|
||||||
|
// in this method?
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
rv = selection->Collapse(afterNewNode);
|
||||||
NS_ASSERTION(!rv.Failed(),
|
NS_ASSERTION(!rv.Failed(),
|
||||||
"selection could not be collapsed after insert");
|
"selection could not be collapsed after insert");
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
@ -4278,22 +4278,30 @@ EditorBase::DeleteSelectionAndPrepareToCreateNode()
|
|||||||
uint32_t offset = selection->AnchorOffset();
|
uint32_t offset = selection->AnchorOffset();
|
||||||
|
|
||||||
if (!offset) {
|
if (!offset) {
|
||||||
nsresult rv = selection->Collapse(node->GetParentNode(),
|
EditorRawDOMPoint atNode(node);
|
||||||
node->GetParentNode()->IndexOf(node));
|
if (NS_WARN_IF(!atNode.IsSetAndValid())) {
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
nsresult rv = selection->Collapse(atNode);
|
||||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
} else if (offset == node->Length()) {
|
} else if (offset == node->Length()) {
|
||||||
nsresult rv =
|
EditorRawDOMPoint afterNode(node);
|
||||||
selection->Collapse(node->GetParentNode(),
|
if (NS_WARN_IF(!afterNode.AdvanceOffset())) {
|
||||||
node->GetParentNode()->IndexOf(node) + 1);
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
nsresult rv = selection->Collapse(afterNode);
|
||||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
} else {
|
} else {
|
||||||
nsCOMPtr<nsIDOMNode> tmp;
|
nsCOMPtr<nsIDOMNode> tmp;
|
||||||
nsresult rv = SplitNode(node->AsDOMNode(), offset, getter_AddRefs(tmp));
|
nsresult rv = SplitNode(node->AsDOMNode(), offset, getter_AddRefs(tmp));
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
rv = selection->Collapse(node->GetParentNode(),
|
EditorRawDOMPoint atNode(node);
|
||||||
node->GetParentNode()->IndexOf(node));
|
if (NS_WARN_IF(!atNode.IsSetAndValid())) {
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
rv = selection->Collapse(atNode);
|
||||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
}
|
}
|
||||||
|
@ -49,15 +49,17 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Different from RangeBoundary, aReferenceChild should be a child node
|
* Different from RangeBoundary, aPointedNode should be a child node
|
||||||
* which you want to refer. So, set non-nullptr if offset is
|
* which you want to refer. So, set non-nullptr if offset is
|
||||||
* 0 - Length() - 1. Otherwise, set nullptr, i.e., if offset is same as
|
* 0 - Length() - 1. Otherwise, set nullptr, i.e., if offset is same as
|
||||||
* Length().
|
* Length().
|
||||||
*/
|
*/
|
||||||
EditorDOMPointBase(nsINode* aContainer,
|
explicit EditorDOMPointBase(nsINode* aPointedNode)
|
||||||
nsIContent* aPointedNode)
|
: RangeBoundaryBase<ParentType, RefType>(
|
||||||
: RangeBoundaryBase<ParentType, RefType>(aContainer,
|
aPointedNode && aPointedNode->IsContent() ?
|
||||||
GetRef(aPointedNode))
|
aPointedNode->GetParentNode() : nullptr,
|
||||||
|
aPointedNode && aPointedNode->IsContent() ?
|
||||||
|
GetRef(aPointedNode->AsContent()) : nullptr)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1265,9 +1265,8 @@ HTMLEditRules::WillInsert(Selection& aSelection,
|
|||||||
// If we are here then the selection is right after a mozBR that is in
|
// If we are here then the selection is right after a mozBR that is in
|
||||||
// the same block as the selection. We need to move the selection start
|
// the same block as the selection. We need to move the selection start
|
||||||
// to be before the mozBR.
|
// to be before the mozBR.
|
||||||
selNode = priorNode->GetParentNode();
|
EditorRawDOMPoint point(priorNode);
|
||||||
selOffset = selNode->IndexOf(priorNode);
|
nsresult rv = aSelection.Collapse(point.AsRaw());
|
||||||
nsresult rv = aSelection.Collapse(selNode, selOffset);
|
|
||||||
NS_ENSURE_SUCCESS_VOID(rv);
|
NS_ENSURE_SUCCESS_VOID(rv);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1493,7 +1492,9 @@ HTMLEditRules::WillInsertText(EditAction aAction,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
aSelection->SetInterlinePosition(false);
|
aSelection->SetInterlinePosition(false);
|
||||||
if (curNode) aSelection->Collapse(curNode, curOffset);
|
if (curNode) {
|
||||||
|
aSelection->Collapse(curNode, curOffset);
|
||||||
|
}
|
||||||
// manually update the doc changed range so that AfterEdit will clean up
|
// manually update the doc changed range so that AfterEdit will clean up
|
||||||
// the correct portion of the document.
|
// the correct portion of the document.
|
||||||
if (!mDocChangeRange) {
|
if (!mDocChangeRange) {
|
||||||
@ -1802,15 +1803,16 @@ HTMLEditRules::StandardBreakImpl(nsINode& aNode,
|
|||||||
}
|
}
|
||||||
node = brNode->GetParentNode();
|
node = brNode->GetParentNode();
|
||||||
NS_ENSURE_TRUE(node, NS_ERROR_NULL_POINTER);
|
NS_ENSURE_TRUE(node, NS_ERROR_NULL_POINTER);
|
||||||
int32_t offset = node->IndexOf(brNode);
|
|
||||||
if (bAfterBlock && bBeforeBlock) {
|
if (bAfterBlock && bBeforeBlock) {
|
||||||
// We just placed a br between block boundaries. This is the one case
|
// We just placed a br between block boundaries. This is the one case
|
||||||
// where we want the selection to be before the br we just placed, as the
|
// where we want the selection to be before the br we just placed, as the
|
||||||
// br will be on a new line, rather than at end of prior line.
|
// br will be on a new line, rather than at end of prior line.
|
||||||
aSelection.SetInterlinePosition(true);
|
aSelection.SetInterlinePosition(true);
|
||||||
nsresult rv = aSelection.Collapse(node, offset);
|
EditorRawDOMPoint point(brNode);
|
||||||
|
nsresult rv = aSelection.Collapse(point.AsRaw());
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
} else {
|
} else {
|
||||||
|
int32_t offset = node->IndexOf(brNode);
|
||||||
WSRunObject wsObj(htmlEditor, node, offset + 1);
|
WSRunObject wsObj(htmlEditor, node, offset + 1);
|
||||||
nsCOMPtr<nsINode> secondBR;
|
nsCOMPtr<nsINode> secondBR;
|
||||||
int32_t visOffset = 0;
|
int32_t visOffset = 0;
|
||||||
@ -2309,7 +2311,7 @@ HTMLEditRules::WillDeleteSelection(Selection* aSelection,
|
|||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
// Fix up selection
|
// Fix up selection
|
||||||
rv = aSelection->Collapse(pt.Container(), pt.Offset());
|
rv = aSelection->Collapse(pt.AsRaw());
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
}
|
}
|
||||||
rv = InsertBRIfNeeded(aSelection);
|
rv = InsertBRIfNeeded(aSelection);
|
||||||
@ -2380,7 +2382,7 @@ HTMLEditRules::WillDeleteSelection(Selection* aSelection,
|
|||||||
if (NS_WARN_IF(!newSel.IsSet())) {
|
if (NS_WARN_IF(!newSel.IsSet())) {
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
aSelection->Collapse(newSel.Container(), newSel.Offset());
|
aSelection->Collapse(newSel.AsRaw());
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2572,7 +2574,7 @@ HTMLEditRules::WillDeleteSelection(Selection* aSelection,
|
|||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
// Fix up selection
|
// Fix up selection
|
||||||
rv = aSelection->Collapse(pt.Container(), pt.Offset());
|
rv = aSelection->Collapse(pt.AsRaw());
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
@ -2792,7 +2794,7 @@ HTMLEditRules::GetGoodSelPointForNode(nsINode& aNode,
|
|||||||
return EditorDOMPoint();
|
return EditorDOMPoint();
|
||||||
}
|
}
|
||||||
|
|
||||||
EditorDOMPoint ret(aNode.GetParentNode(), aNode.AsContent());
|
EditorDOMPoint ret(&aNode);
|
||||||
if ((!aNode.IsHTMLElement(nsGkAtoms::br) ||
|
if ((!aNode.IsHTMLElement(nsGkAtoms::br) ||
|
||||||
mHTMLEditor->IsVisibleBRElement(&aNode)) && isPreviousAction) {
|
mHTMLEditor->IsVisibleBRElement(&aNode)) && isPreviousAction) {
|
||||||
ret.AdvanceOffset();
|
ret.AdvanceOffset();
|
||||||
@ -4552,25 +4554,22 @@ HTMLEditRules::WillOutdent(Selection& aSelection,
|
|||||||
NS_ENSURE_TRUE(aSelection.GetRangeAt(0), NS_OK);
|
NS_ENSURE_TRUE(aSelection.GetRangeAt(0), NS_OK);
|
||||||
nsCOMPtr<nsINode> startNode =
|
nsCOMPtr<nsINode> startNode =
|
||||||
aSelection.GetRangeAt(0)->GetStartContainer();
|
aSelection.GetRangeAt(0)->GetStartContainer();
|
||||||
int32_t startOffset = aSelection.GetRangeAt(0)->StartOffset();
|
|
||||||
if (rememberedLeftBQ &&
|
if (rememberedLeftBQ &&
|
||||||
(startNode == rememberedLeftBQ ||
|
(startNode == rememberedLeftBQ ||
|
||||||
EditorUtils::IsDescendantOf(*startNode, *rememberedLeftBQ))) {
|
EditorUtils::IsDescendantOf(*startNode, *rememberedLeftBQ))) {
|
||||||
// Selection is inside rememberedLeftBQ - push it past it.
|
// Selection is inside rememberedLeftBQ - push it past it.
|
||||||
startNode = rememberedLeftBQ->GetParentNode();
|
EditorRawDOMPoint afterRememberedLeftBQ(rememberedLeftBQ);
|
||||||
startOffset = startNode ? 1 + startNode->IndexOf(rememberedLeftBQ) : 0;
|
afterRememberedLeftBQ.AdvanceOffset();
|
||||||
aSelection.Collapse(startNode, startOffset);
|
aSelection.Collapse(afterRememberedLeftBQ);
|
||||||
}
|
}
|
||||||
// And pull selection before beginning of rememberedRightBQ
|
// And pull selection before beginning of rememberedRightBQ
|
||||||
startNode = aSelection.GetRangeAt(0)->GetStartContainer();
|
startNode = aSelection.GetRangeAt(0)->GetStartContainer();
|
||||||
startOffset = aSelection.GetRangeAt(0)->StartOffset();
|
|
||||||
if (rememberedRightBQ &&
|
if (rememberedRightBQ &&
|
||||||
(startNode == rememberedRightBQ ||
|
(startNode == rememberedRightBQ ||
|
||||||
EditorUtils::IsDescendantOf(*startNode, *rememberedRightBQ))) {
|
EditorUtils::IsDescendantOf(*startNode, *rememberedRightBQ))) {
|
||||||
// Selection is inside rememberedRightBQ - push it before it.
|
// Selection is inside rememberedRightBQ - push it before it.
|
||||||
startNode = rememberedRightBQ->GetParentNode();
|
EditorRawDOMPoint atRememberedRightBQ(rememberedRightBQ);
|
||||||
startOffset = startNode ? startNode->IndexOf(rememberedRightBQ) : -1;
|
aSelection.Collapse(atRememberedRightBQ);
|
||||||
aSelection.Collapse(startNode, startOffset);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
@ -5188,37 +5187,45 @@ HTMLEditRules::CheckForEmptyBlock(nsINode* aStartNode,
|
|||||||
// AfterEdit()
|
// AfterEdit()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
int32_t offset = blockParent->IndexOf(emptyBlock);
|
|
||||||
|
|
||||||
if (aAction == nsIEditor::eNext || aAction == nsIEditor::eNextWord ||
|
if (aAction == nsIEditor::eNext || aAction == nsIEditor::eNextWord ||
|
||||||
aAction == nsIEditor::eToEndOfLine) {
|
aAction == nsIEditor::eToEndOfLine) {
|
||||||
// Move to the start of the next node, if any
|
// Move to the start of the next node, if any
|
||||||
nsINode* child = emptyBlock->GetNextSibling();
|
nsINode* child = emptyBlock->GetNextSibling();
|
||||||
|
int32_t offset = blockParent->IndexOf(emptyBlock);
|
||||||
nsCOMPtr<nsIContent> nextNode =
|
nsCOMPtr<nsIContent> nextNode =
|
||||||
htmlEditor->GetNextNode(blockParent, offset + 1, child, true);
|
htmlEditor->GetNextNode(blockParent, offset + 1, child, true);
|
||||||
if (nextNode) {
|
if (nextNode) {
|
||||||
EditorDOMPoint pt = GetGoodSelPointForNode(*nextNode, aAction);
|
EditorDOMPoint pt = GetGoodSelPointForNode(*nextNode, aAction);
|
||||||
nsresult rv = aSelection->Collapse(pt.Container(), pt.Offset());
|
nsresult rv = aSelection->Collapse(pt.AsRaw());
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
} else {
|
} else {
|
||||||
// Adjust selection to be right after it.
|
// Adjust selection to be right after it.
|
||||||
nsresult rv = aSelection->Collapse(blockParent, offset + 1);
|
EditorRawDOMPoint afterEmptyBlock(emptyBlock);
|
||||||
|
if (NS_WARN_IF(!afterEmptyBlock.AdvanceOffset())) {
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
nsresult rv = aSelection->Collapse(afterEmptyBlock);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
}
|
}
|
||||||
} else if (aAction == nsIEditor::ePrevious ||
|
} else if (aAction == nsIEditor::ePrevious ||
|
||||||
aAction == nsIEditor::ePreviousWord ||
|
aAction == nsIEditor::ePreviousWord ||
|
||||||
aAction == nsIEditor::eToBeginningOfLine) {
|
aAction == nsIEditor::eToBeginningOfLine) {
|
||||||
// Move to the end of the previous node
|
// Move to the end of the previous node
|
||||||
|
int32_t offset = blockParent->IndexOf(emptyBlock);
|
||||||
nsCOMPtr<nsIContent> priorNode = htmlEditor->GetPriorNode(blockParent,
|
nsCOMPtr<nsIContent> priorNode = htmlEditor->GetPriorNode(blockParent,
|
||||||
offset,
|
offset,
|
||||||
emptyBlock,
|
emptyBlock,
|
||||||
true);
|
true);
|
||||||
if (priorNode) {
|
if (priorNode) {
|
||||||
EditorDOMPoint pt = GetGoodSelPointForNode(*priorNode, aAction);
|
EditorDOMPoint pt = GetGoodSelPointForNode(*priorNode, aAction);
|
||||||
nsresult rv = aSelection->Collapse(pt.Container(), pt.Offset());
|
nsresult rv = aSelection->Collapse(pt.AsRaw());
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
} else {
|
} else {
|
||||||
nsresult rv = aSelection->Collapse(blockParent, offset + 1);
|
EditorRawDOMPoint afterEmptyBlock(emptyBlock);
|
||||||
|
if (NS_WARN_IF(!afterEmptyBlock.AdvanceOffset())) {
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
nsresult rv = aSelection->Collapse(afterEmptyBlock);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
}
|
}
|
||||||
} else if (aAction != nsIEditor::eNone) {
|
} else if (aAction != nsIEditor::eNone) {
|
||||||
@ -6625,10 +6632,12 @@ HTMLEditRules::ReturnInHeader(Selection& aSelection,
|
|||||||
rv = aSelection.Collapse(pNode, 0);
|
rv = aSelection.Collapse(pNode, 0);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
} else {
|
} else {
|
||||||
headerParent = sibling->GetParentNode();
|
EditorRawDOMPoint afterSibling(sibling);
|
||||||
offset = headerParent ? headerParent->IndexOf(sibling) : -1;
|
if (NS_WARN_IF(!afterSibling.AdvanceOffset())) {
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
// Put selection after break
|
// Put selection after break
|
||||||
rv = aSelection.Collapse(headerParent, offset + 1);
|
rv = aSelection.Collapse(afterSibling);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -6825,15 +6834,13 @@ HTMLEditRules::SplitParagraph(nsIDOMNode *aPara,
|
|||||||
// look inside any containers that are up front.
|
// look inside any containers that are up front.
|
||||||
nsCOMPtr<nsINode> rightParaNode = do_QueryInterface(rightPara);
|
nsCOMPtr<nsINode> rightParaNode = do_QueryInterface(rightPara);
|
||||||
NS_ENSURE_STATE(mHTMLEditor && rightParaNode);
|
NS_ENSURE_STATE(mHTMLEditor && rightParaNode);
|
||||||
nsCOMPtr<nsIDOMNode> child =
|
nsIContent* child = mHTMLEditor->GetLeftmostChild(rightParaNode, true);
|
||||||
GetAsDOMNode(mHTMLEditor->GetLeftmostChild(rightParaNode, true));
|
|
||||||
if (EditorBase::IsTextNode(child) ||
|
if (EditorBase::IsTextNode(child) ||
|
||||||
mHTMLEditor->IsContainer(child)) {
|
mHTMLEditor->IsContainer(child)) {
|
||||||
aSelection->Collapse(child,0);
|
aSelection->Collapse(child,0);
|
||||||
} else {
|
} else {
|
||||||
int32_t offset;
|
EditorRawDOMPoint atChild(child);
|
||||||
nsCOMPtr<nsIDOMNode> parent = EditorBase::GetNodeLocation(child, &offset);
|
aSelection->Collapse(atChild);
|
||||||
aSelection->Collapse(parent,offset);
|
|
||||||
}
|
}
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
@ -6959,9 +6966,11 @@ HTMLEditRules::ReturnInListItem(Selection& aSelection,
|
|||||||
getter_AddRefs(brNode));
|
getter_AddRefs(brNode));
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
if (brNode) {
|
if (brNode) {
|
||||||
nsCOMPtr<nsINode> brParent = brNode->GetParentNode();
|
EditorRawDOMPoint atBrNode(brNode);
|
||||||
int32_t offset = brParent ? brParent->IndexOf(brNode) : -1;
|
if (NS_WARN_IF(!atBrNode.IsSetAndValid())) {
|
||||||
rv = aSelection.Collapse(brParent, offset);
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
rv = aSelection.Collapse(atBrNode);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
@ -6974,9 +6983,11 @@ HTMLEditRules::ReturnInListItem(Selection& aSelection,
|
|||||||
&visOffset, &wsType);
|
&visOffset, &wsType);
|
||||||
if (wsType == WSType::special || wsType == WSType::br ||
|
if (wsType == WSType::special || wsType == WSType::br ||
|
||||||
visNode->IsHTMLElement(nsGkAtoms::hr)) {
|
visNode->IsHTMLElement(nsGkAtoms::hr)) {
|
||||||
nsCOMPtr<nsINode> parent = visNode->GetParentNode();
|
EditorRawDOMPoint atVisNode(visNode);
|
||||||
int32_t offset = parent ? parent->IndexOf(visNode) : -1;
|
if (NS_WARN_IF(!atVisNode.IsSetAndValid())) {
|
||||||
rv = aSelection.Collapse(parent, offset);
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
rv = aSelection.Collapse(atVisNode);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
} else {
|
} else {
|
||||||
@ -7681,36 +7692,42 @@ HTMLEditRules::PinSelectionToNewBlock(Selection* aSelection)
|
|||||||
|
|
||||||
if (nodeBefore && nodeAfter) {
|
if (nodeBefore && nodeAfter) {
|
||||||
return NS_OK; // selection is inside block
|
return NS_OK; // selection is inside block
|
||||||
} else if (nodeBefore) {
|
}
|
||||||
|
|
||||||
|
if (nodeBefore) {
|
||||||
// selection is after block. put at end of block.
|
// selection is after block. put at end of block.
|
||||||
NS_ENSURE_STATE(mHTMLEditor);
|
NS_ENSURE_STATE(mHTMLEditor);
|
||||||
nsCOMPtr<nsINode> tmp = mHTMLEditor->GetLastEditableChild(*mNewBlock);
|
nsCOMPtr<nsINode> tmp = mHTMLEditor->GetLastEditableChild(*mNewBlock);
|
||||||
if (!tmp) {
|
if (!tmp) {
|
||||||
tmp = mNewBlock;
|
tmp = mNewBlock;
|
||||||
}
|
}
|
||||||
uint32_t endPoint;
|
EditorRawDOMPoint endPoint;
|
||||||
if (EditorBase::IsTextNode(tmp) ||
|
if (EditorBase::IsTextNode(tmp) ||
|
||||||
mHTMLEditor->IsContainer(tmp)) {
|
mHTMLEditor->IsContainer(tmp)) {
|
||||||
endPoint = tmp->Length();
|
endPoint.Set(tmp, tmp->Length());
|
||||||
} else {
|
} else {
|
||||||
tmp = EditorBase::GetNodeLocation(tmp, (int32_t*)&endPoint);
|
endPoint.Set(tmp);
|
||||||
endPoint++; // want to be after this node
|
if (NS_WARN_IF(!endPoint.AdvanceOffset())) {
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return aSelection->Collapse(tmp, (int32_t)endPoint);
|
return aSelection->Collapse(endPoint);
|
||||||
} else {
|
|
||||||
// selection is before block. put at start of block.
|
|
||||||
NS_ENSURE_STATE(mHTMLEditor);
|
|
||||||
nsCOMPtr<nsINode> tmp = mHTMLEditor->GetFirstEditableChild(*mNewBlock);
|
|
||||||
if (!tmp) {
|
|
||||||
tmp = mNewBlock;
|
|
||||||
}
|
|
||||||
int32_t offset;
|
|
||||||
if (EditorBase::IsTextNode(tmp) ||
|
|
||||||
mHTMLEditor->IsContainer(tmp)) {
|
|
||||||
tmp = EditorBase::GetNodeLocation(tmp, &offset);
|
|
||||||
}
|
|
||||||
return aSelection->Collapse(tmp, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// selection is before block. put at start of block.
|
||||||
|
NS_ENSURE_STATE(mHTMLEditor);
|
||||||
|
nsCOMPtr<nsINode> tmp = mHTMLEditor->GetFirstEditableChild(*mNewBlock);
|
||||||
|
if (!tmp) {
|
||||||
|
tmp = mNewBlock;
|
||||||
|
}
|
||||||
|
EditorRawDOMPoint atStartOfBlock;
|
||||||
|
if (EditorBase::IsTextNode(tmp) ||
|
||||||
|
mHTMLEditor->IsContainer(tmp)) {
|
||||||
|
atStartOfBlock.Set(tmp);
|
||||||
|
} else {
|
||||||
|
atStartOfBlock.Set(tmp, 0);
|
||||||
|
}
|
||||||
|
return aSelection->Collapse(atStartOfBlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -7904,7 +7921,7 @@ HTMLEditRules::AdjustSelection(Selection* aSelection,
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
EditorDOMPoint pt = GetGoodSelPointForNode(*nearNode, aAction);
|
EditorDOMPoint pt = GetGoodSelPointForNode(*nearNode, aAction);
|
||||||
rv = aSelection->Collapse(pt.Container(), pt.Offset());
|
rv = aSelection->Collapse(pt.AsRaw());
|
||||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
@ -1086,10 +1086,18 @@ HTMLEditor::InsertBR(nsCOMPtr<nsIDOMNode>* outBRNode)
|
|||||||
rv = CreateBR(selNode, selOffset, outBRNode);
|
rv = CreateBR(selNode, selOffset, outBRNode);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
// position selection after br
|
|
||||||
selNode = GetNodeLocation(*outBRNode, &selOffset);
|
|
||||||
selection->SetInterlinePosition(true);
|
selection->SetInterlinePosition(true);
|
||||||
return selection->Collapse(selNode, selOffset+1);
|
|
||||||
|
// position selection after br
|
||||||
|
nsCOMPtr<nsINode> brNode = do_QueryInterface(*outBRNode);
|
||||||
|
if (NS_WARN_IF(!brNode)) {
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
EditorRawDOMPoint afterBrNode(brNode);
|
||||||
|
if (NS_WARN_IF(!afterBrNode.AdvanceOffset())) {
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
return selection->Collapse(afterBrNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -1692,9 +1700,12 @@ HTMLEditor::SetCaretAfterElement(nsIDOMElement* aElement)
|
|||||||
nsresult rv = aElement->GetParentNode(getter_AddRefs(parent));
|
nsresult rv = aElement->GetParentNode(getter_AddRefs(parent));
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
NS_ENSURE_TRUE(parent, NS_ERROR_NULL_POINTER);
|
NS_ENSURE_TRUE(parent, NS_ERROR_NULL_POINTER);
|
||||||
int32_t offsetInParent = GetChildOffset(aElement, parent);
|
|
||||||
// Collapse selection to just after desired element,
|
// Collapse selection to just after desired element,
|
||||||
return selection->Collapse(parent, offsetInParent + 1);
|
EditorRawDOMPoint afterElement(element);
|
||||||
|
if (NS_WARN_IF(!afterElement.AdvanceOffset())) {
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
return selection->Collapse(afterElement);
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
#include "mozilla/ArrayUtils.h"
|
#include "mozilla/ArrayUtils.h"
|
||||||
#include "mozilla/Base64.h"
|
#include "mozilla/Base64.h"
|
||||||
#include "mozilla/BasicEvents.h"
|
#include "mozilla/BasicEvents.h"
|
||||||
|
#include "mozilla/EditorDOMPoint.h"
|
||||||
#include "mozilla/EditorUtils.h"
|
#include "mozilla/EditorUtils.h"
|
||||||
#include "mozilla/OwningNonNull.h"
|
#include "mozilla/OwningNonNull.h"
|
||||||
#include "mozilla/Preferences.h"
|
#include "mozilla/Preferences.h"
|
||||||
@ -657,8 +658,10 @@ HTMLEditor::DoInsertHTMLWithContext(const nsAString& aInputString,
|
|||||||
SplitNodeDeep(*linkContent, *selContent, selOffset,
|
SplitNodeDeep(*linkContent, *selContent, selOffset,
|
||||||
EmptyContainers::no, getter_AddRefs(leftLink));
|
EmptyContainers::no, getter_AddRefs(leftLink));
|
||||||
if (leftLink) {
|
if (leftLink) {
|
||||||
selNode = GetNodeLocation(GetAsDOMNode(leftLink), &selOffset);
|
EditorRawDOMPoint afterLeftLink(leftLink);
|
||||||
selection->Collapse(selNode, selOffset+1);
|
if (afterLeftLink.AdvanceOffset()) {
|
||||||
|
selection->Collapse(afterLeftLink);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1898,10 +1901,9 @@ HTMLEditor::InsertAsPlaintextQuotation(const nsAString& aQuotedText,
|
|||||||
|
|
||||||
// Set the selection to just after the inserted node:
|
// Set the selection to just after the inserted node:
|
||||||
if (NS_SUCCEEDED(rv) && newNode) {
|
if (NS_SUCCEEDED(rv) && newNode) {
|
||||||
nsCOMPtr<nsINode> parent = newNode->GetParentNode();
|
EditorRawDOMPoint afterNewNode(newNode);
|
||||||
int32_t offset = parent ? parent->IndexOf(newNode) : -1;
|
if (afterNewNode.AdvanceOffset()) {
|
||||||
if (parent) {
|
selection->Collapse(afterNewNode);
|
||||||
selection->Collapse(parent, offset + 1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return rv;
|
return rv;
|
||||||
@ -1978,10 +1980,9 @@ HTMLEditor::InsertAsCitedQuotation(const nsAString& aQuotedText,
|
|||||||
|
|
||||||
// Set the selection to just after the inserted node:
|
// Set the selection to just after the inserted node:
|
||||||
if (NS_SUCCEEDED(rv) && newNode) {
|
if (NS_SUCCEEDED(rv) && newNode) {
|
||||||
nsCOMPtr<nsINode> parent = newNode->GetParentNode();
|
EditorRawDOMPoint afterNewNode(newNode);
|
||||||
int32_t offset = parent ? parent->IndexOf(newNode) : -1;
|
if (afterNewNode.AdvanceOffset()) {
|
||||||
if (parent) {
|
selection->Collapse(afterNewNode);
|
||||||
selection->Collapse(parent, offset + 1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return rv;
|
return rv;
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
#include "HTMLEditUtils.h"
|
#include "HTMLEditUtils.h"
|
||||||
#include "mozilla/Assertions.h"
|
#include "mozilla/Assertions.h"
|
||||||
|
#include "mozilla/EditorDOMPoint.h"
|
||||||
#include "mozilla/EditorUtils.h"
|
#include "mozilla/EditorUtils.h"
|
||||||
#include "mozilla/FlushType.h"
|
#include "mozilla/FlushType.h"
|
||||||
#include "mozilla/dom/Selection.h"
|
#include "mozilla/dom/Selection.h"
|
||||||
@ -3157,8 +3158,15 @@ HTMLEditor::SetSelectionAfterTableEdit(nsIDOMElement* aTable,
|
|||||||
nsCOMPtr<nsIDOMNode> tableParent;
|
nsCOMPtr<nsIDOMNode> tableParent;
|
||||||
nsresult rv = aTable->GetParentNode(getter_AddRefs(tableParent));
|
nsresult rv = aTable->GetParentNode(getter_AddRefs(tableParent));
|
||||||
if (NS_SUCCEEDED(rv) && tableParent) {
|
if (NS_SUCCEEDED(rv) && tableParent) {
|
||||||
int32_t tableOffset = GetChildOffset(aTable, tableParent);
|
nsCOMPtr<nsIContent> table = do_QueryInterface(aTable);
|
||||||
selection->Collapse(tableParent, tableOffset);
|
if (NS_WARN_IF(!table)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
EditorRawDOMPoint atTable(table);
|
||||||
|
if (NS_WARN_IF(!atTable.IsSetAndValid())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
selection->Collapse(atTable);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Last resort: Set selection to start of doc
|
// Last resort: Set selection to start of doc
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
#include "TextEditUtils.h"
|
#include "TextEditUtils.h"
|
||||||
#include "mozilla/Assertions.h"
|
#include "mozilla/Assertions.h"
|
||||||
|
#include "mozilla/EditorDOMPoint.h"
|
||||||
#include "mozilla/EditorUtils.h"
|
#include "mozilla/EditorUtils.h"
|
||||||
#include "mozilla/LookAndFeel.h"
|
#include "mozilla/LookAndFeel.h"
|
||||||
#include "mozilla/Preferences.h"
|
#include "mozilla/Preferences.h"
|
||||||
@ -494,8 +495,11 @@ TextEditRules::CollapseSelectionToTrailingBRIfNeeded(Selection* aSelection)
|
|||||||
|
|
||||||
nsINode* nextNode = selNode->GetNextSibling();
|
nsINode* nextNode = selNode->GetNextSibling();
|
||||||
if (nextNode && TextEditUtils::IsMozBR(nextNode)) {
|
if (nextNode && TextEditUtils::IsMozBR(nextNode)) {
|
||||||
int32_t offsetInParent = EditorBase::GetChildOffset(selNode, parentNode);
|
EditorRawDOMPoint afterSelNode(selNode);
|
||||||
rv = aSelection->Collapse(parentNode, offsetInParent + 1);
|
if (NS_WARN_IF(!afterSelNode.AdvanceOffset())) {
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
rv = aSelection->Collapse(afterSelNode);
|
||||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
@ -778,6 +782,8 @@ TextEditRules::WillInsertText(EditAction aAction,
|
|||||||
!outString->IsEmpty() && outString->Last() == nsCRT::LF;
|
!outString->IsEmpty() && outString->Last() == nsCRT::LF;
|
||||||
aSelection->SetInterlinePosition(endsWithLF);
|
aSelection->SetInterlinePosition(endsWithLF);
|
||||||
|
|
||||||
|
MOZ_ASSERT(!selChild,
|
||||||
|
"After inserting text into a text node, selChild should be nullptr");
|
||||||
aSelection->Collapse(curNode, curOffset);
|
aSelection->Collapse(curNode, curOffset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include "TextEditUtils.h"
|
#include "TextEditUtils.h"
|
||||||
#include "gfxFontUtils.h"
|
#include "gfxFontUtils.h"
|
||||||
#include "mozilla/Assertions.h"
|
#include "mozilla/Assertions.h"
|
||||||
|
#include "mozilla/EditorDOMPoint.h"
|
||||||
#include "mozilla/EditorUtils.h" // AutoPlaceholderBatch, AutoRules
|
#include "mozilla/EditorUtils.h" // AutoPlaceholderBatch, AutoRules
|
||||||
#include "mozilla/HTMLEditor.h"
|
#include "mozilla/HTMLEditor.h"
|
||||||
#include "mozilla/mozalloc.h"
|
#include "mozilla/mozalloc.h"
|
||||||
@ -476,19 +477,24 @@ TextEditor::CreateBRImpl(nsCOMPtr<nsIDOMNode>* aInOutParent,
|
|||||||
|
|
||||||
*outBRNode = GetAsDOMNode(brNode);
|
*outBRNode = GetAsDOMNode(brNode);
|
||||||
if (*outBRNode && (aSelect != eNone)) {
|
if (*outBRNode && (aSelect != eNone)) {
|
||||||
int32_t offset;
|
|
||||||
nsCOMPtr<nsINode> parent = GetNodeLocation(brNode, &offset);
|
|
||||||
|
|
||||||
RefPtr<Selection> selection = GetSelection();
|
RefPtr<Selection> selection = GetSelection();
|
||||||
NS_ENSURE_STATE(selection);
|
NS_ENSURE_STATE(selection);
|
||||||
if (aSelect == eNext) {
|
if (aSelect == eNext) {
|
||||||
|
selection->SetInterlinePosition(true);
|
||||||
// position selection after br
|
// position selection after br
|
||||||
selection->SetInterlinePosition(true);
|
EditorRawDOMPoint afterBrNode(brNode);
|
||||||
selection->Collapse(parent, offset + 1);
|
if (NS_WARN_IF(!afterBrNode.AdvanceOffset())) {
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
selection->Collapse(afterBrNode);
|
||||||
} else if (aSelect == ePrevious) {
|
} else if (aSelect == ePrevious) {
|
||||||
// position selection before br
|
|
||||||
selection->SetInterlinePosition(true);
|
selection->SetInterlinePosition(true);
|
||||||
selection->Collapse(parent, offset);
|
// position selection before br
|
||||||
|
EditorRawDOMPoint atBrNode(brNode);
|
||||||
|
if (NS_WARN_IF(!atBrNode.IsSetAndValid())) {
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
selection->Collapse(atBrNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
@ -729,7 +735,9 @@ TextEditor::InsertLineBreak()
|
|||||||
}
|
}
|
||||||
if (NS_SUCCEEDED(rv)) {
|
if (NS_SUCCEEDED(rv)) {
|
||||||
// set the selection to the correct location
|
// set the selection to the correct location
|
||||||
rv = selection->Collapse(selNode, selOffset);
|
MOZ_ASSERT(!selChild,
|
||||||
|
"After inserting text into a text node, selChild should be nullptr");
|
||||||
|
rv = selection->Collapse(EditorRawDOMPoint(selNode, selOffset));
|
||||||
if (NS_SUCCEEDED(rv)) {
|
if (NS_SUCCEEDED(rv)) {
|
||||||
// see if we're at the end of the editor range
|
// see if we're at the end of the editor range
|
||||||
nsCOMPtr<nsIDOMNode> endNode;
|
nsCOMPtr<nsIDOMNode> endNode;
|
||||||
|
Loading…
Reference in New Issue
Block a user