--- a/editor/libeditor/HTMLEditRules.cpp
+++ b/editor/libeditor/HTMLEditRules.cpp
@@ -1245,30 +1245,34 @@ HTMLEditRules::WillInsert(Selection& aSe
// work with when not collapsed. (no good way to extend start or end of
// selection), so we ignore those types of selections.
if (!aSelection.Collapsed()) {
return;
}
// If we are after a mozBR in the same block, then move selection to be
// before it
- NS_ENSURE_TRUE_VOID(aSelection.GetRangeAt(0) &&
- aSelection.GetRangeAt(0)->GetStartContainer());
- OwningNonNull<nsINode> selNode =
- *aSelection.GetRangeAt(0)->GetStartContainer();
- nsIContent* selChild = aSelection.GetRangeAt(0)->GetChildAtStartOffset();
- int32_t selOffset = aSelection.GetRangeAt(0)->StartOffset();
+ nsRange* firstRange = aSelection.GetRangeAt(0);
+ if (NS_WARN_IF(!firstRange)) {
+ return;
+ }
+
+ EditorRawDOMPoint atStartOfSelection(firstRange->StartRef());
+ if (NS_WARN_IF(!atStartOfSelection.IsSet())) {
+ return;
+ }
+ MOZ_ASSERT(atStartOfSelection.IsSetAndValid());
// Get prior node
- nsCOMPtr<nsIContent> priorNode = htmlEditor->GetPriorHTMLNode(selNode,
- selOffset,
- selChild);
+ nsCOMPtr<nsIContent> priorNode =
+ htmlEditor->GetPreviousEditableHTMLNode(atStartOfSelection);
if (priorNode && TextEditUtils::IsMozBR(priorNode)) {
- nsCOMPtr<Element> block1 = htmlEditor->GetBlock(selNode);
- nsCOMPtr<Element> block2 = htmlEditor->GetBlockNodeParent(priorNode);
+ RefPtr<Element> block1 =
+ htmlEditor->GetBlock(*atStartOfSelection.Container());
+ RefPtr<Element> block2 = htmlEditor->GetBlockNodeParent(priorNode);
if (block1 && block1 == block2) {
// 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
// to be before the mozBR.
EditorRawDOMPoint point(priorNode);
nsresult rv = aSelection.Collapse(point.AsRaw());
NS_ENSURE_SUCCESS_VOID(rv);
@@ -2475,17 +2479,17 @@ HTMLEditRules::WillDeleteSelection(Selec
*aCancel = true;
return NS_OK;
}
// First find the relevant nodes
nsCOMPtr<nsINode> leftNode, rightNode;
if (aAction == nsIEditor::ePrevious) {
NS_ENSURE_STATE(mHTMLEditor);
- leftNode = mHTMLEditor->GetPriorHTMLNode(visNode);
+ leftNode = mHTMLEditor->GetPreviousEditableHTMLNode(*visNode);
rightNode = startNode;
} else {
NS_ENSURE_STATE(mHTMLEditor);
rightNode = mHTMLEditor->GetNextHTMLNode(visNode);
leftNode = startNode;
}
// Nothing to join
@@ -5581,19 +5585,18 @@ HTMLEditRules::NormalizeSelection(Select
int32_t offset = -1;
newEndNode = EditorBase::GetNodeLocation(child, &offset);
// offset *after* child
newEndOffset = static_cast<uint32_t>(offset + 1);
}
// else block is empty - we can leave selection alone here, i think.
} else if (wsEndObj.mStartReason == WSType::thisBlock) {
// endpoint is just after start of this block
- nsINode* child =
- htmlEditor->GetPriorHTMLNode(endNode, static_cast<int32_t>(endOffset),
- endChild);
+ EditorRawDOMPoint atEnd(endNode, endChild, endOffset);
+ nsINode* child = htmlEditor->GetPreviousEditableHTMLNode(atEnd);
if (child) {
int32_t offset = -1;
newEndNode = EditorBase::GetNodeLocation(child, &offset);
// offset *after* child
newEndOffset = static_cast<uint32_t>(offset + 1);
}
// else block is empty - we can leave selection alone here, i think.
} else if (wsEndObj.mStartReason == WSType::br) {
@@ -5721,111 +5724,105 @@ HTMLEditRules::GetPromotedPoint(RulesEnd
} else {
break;
}
}
return EditorDOMPoint(content, newOffset);
}
- nsCOMPtr<nsINode> node = &aNode;
- nsINode* child = node->GetChildAt(aOffset);
- int32_t offset = aOffset;
+ EditorDOMPoint point(&aNode, aOffset);
// else not a text section. In this case we want to see if we should grab
// any adjacent inline nodes and/or parents and other ancestors
if (aWhere == kStart) {
// some special casing for text nodes
- if (node->IsNodeOfType(nsINode::eTEXT)) {
- if (!node->GetParentNode()) {
+ if (point.Container()->IsNodeOfType(nsINode::eTEXT)) {
+ if (!point.Container()->GetParentNode()) {
// Okay, can't promote any further
- return EditorDOMPoint(node, offset);
- }
- offset = node->GetParentNode()->IndexOf(node);
- child = node;
- node = node->GetParentNode();
+ return point;
+ }
+ point.Set(point.Container());
}
// look back through any further inline nodes that aren't across a <br>
// from us, and that are enclosed in the same block.
nsCOMPtr<nsINode> priorNode =
- htmlEditor->GetPriorHTMLNode(node, offset, child, true);
+ htmlEditor->GetPreviousEditableHTMLNodeInBlock(point.AsRaw());
while (priorNode && priorNode->GetParentNode() &&
!htmlEditor->IsVisibleBRElement(priorNode) &&
!IsBlockNode(*priorNode)) {
- offset = priorNode->GetParentNode()->IndexOf(priorNode);
- child = priorNode;
- node = priorNode->GetParentNode();
- priorNode = htmlEditor->GetPriorHTMLNode(node, offset, child, true);
+ point.Set(priorNode);
+ priorNode = htmlEditor->GetPreviousEditableHTMLNodeInBlock(point.AsRaw());
}
// finding the real start for this point. look up the tree for as long as
// we are the first node in the container, and as long as we haven't hit
// the body node.
nsCOMPtr<nsIContent> nearNode =
- htmlEditor->GetPriorHTMLNode(node, offset, child, true);
- while (!nearNode && !node->IsHTMLElement(nsGkAtoms::body) &&
- node->GetParentNode()) {
+ htmlEditor->GetPreviousEditableHTMLNodeInBlock(point.AsRaw());
+ while (!nearNode &&
+ !point.Container()->IsHTMLElement(nsGkAtoms::body) &&
+ point.Container()->GetParentNode()) {
// some cutoffs are here: we don't need to also include them in the
// aWhere == kEnd case. as long as they are in one or the other it will
// work. special case for outdent: don't keep looking up if we have
// found a blockquote element to act on
if (actionID == EditAction::outdent &&
- node->IsHTMLElement(nsGkAtoms::blockquote)) {
+ point.Container()->IsHTMLElement(nsGkAtoms::blockquote)) {
break;
}
- int32_t parentOffset = node->GetParentNode()->IndexOf(node);
- nsCOMPtr<nsINode> parent = node->GetParentNode();
-
// Don't walk past the editable section. Note that we need to check
// before walking up to a parent because we need to return the parent
// object, so the parent itself might not be in the editable area, but
// it's OK if we're not performing a block-level action.
bool blockLevelAction = actionID == EditAction::indent ||
actionID == EditAction::outdent ||
actionID == EditAction::align ||
actionID == EditAction::makeBasicBlock;
- if (!htmlEditor->IsDescendantOfEditorRoot(parent) &&
+ if (!htmlEditor->IsDescendantOfEditorRoot(
+ point.Container()->GetParentNode()) &&
(blockLevelAction ||
- !htmlEditor->IsDescendantOfEditorRoot(node))) {
+ !htmlEditor->IsDescendantOfEditorRoot(point.Container()))) {
break;
}
- child = node;
- node = parent;
- offset = parentOffset;
- nearNode = htmlEditor->GetPriorHTMLNode(node, offset, child, true);
- }
- return EditorDOMPoint(node, offset);
+ point.Set(point.Container());
+ nearNode = htmlEditor->GetPreviousEditableHTMLNodeInBlock(point.AsRaw());
+ }
+ return point;
}
// aWhere == kEnd
// some special casing for text nodes
- if (node->IsNodeOfType(nsINode::eTEXT)) {
- if (!node->GetParentNode()) {
+ if (point.Container()->IsNodeOfType(nsINode::eTEXT)) {
+ if (!point.Container()->GetParentNode()) {
// Okay, can't promote any further
- return EditorDOMPoint(node, offset);
+ return point;
}
// want to be after the text node
- offset = 1 + node->GetParentNode()->IndexOf(node);
- child = node->GetNextSibling();
- node = node->GetParentNode();
+ point.Set(point.Container());
+ DebugOnly<bool> advanced = point.AdvanceOffset();
+ NS_WARNING_ASSERTION(advanced,
+ "Failed to advance offset to after the text node");
}
// look ahead through any further inline nodes that aren't across a <br> from
// us, and that are enclosed in the same block.
nsCOMPtr<nsIContent> nextNode =
- htmlEditor->GetNextHTMLNode(node, offset, child, true);
+ htmlEditor->GetNextHTMLNode(point.Container(), point.Offset(),
+ point.GetChildAtOffset(), true);
while (nextNode && !IsBlockNode(*nextNode) && nextNode->GetParentNode()) {
- offset = 1 + nextNode->GetParentNode()->IndexOf(nextNode);
- child = nextNode->GetNextSibling();
- node = nextNode->GetParentNode();
+ point.Set(nextNode);
+ if (NS_WARN_IF(!point.AdvanceOffset())) {
+ break;
+ }
if (htmlEditor->IsVisibleBRElement(nextNode)) {
break;
}
// Check for newlines in pre-formatted text nodes.
bool isPRE;
htmlEditor->IsPreformatted(nextNode->AsDOMNode(), &isPRE);
if (isPRE) {
@@ -5837,44 +5834,46 @@ HTMLEditRules::GetPromotedPoint(RulesEnd
if (static_cast<uint32_t>(newlinePos) + 1 == tempString.Length()) {
// No need for special processing if the newline is at the end.
break;
}
return EditorDOMPoint(nextNode, newlinePos + 1);
}
}
}
- nextNode = htmlEditor->GetNextHTMLNode(node, offset, child, true);
+ nextNode = htmlEditor->GetNextHTMLNode(point.Container(), point.Offset(),
+ point.GetChildAtOffset(), true);
}
// finding the real end for this point. look up the tree for as long as we
// are the last node in the container, and as long as we haven't hit the body
// node.
nsCOMPtr<nsIContent> nearNode =
- htmlEditor->GetNextHTMLNode(node, offset, child, true);
- while (!nearNode && !node->IsHTMLElement(nsGkAtoms::body) &&
- node->GetParentNode()) {
- int32_t parentOffset = node->GetParentNode()->IndexOf(node);
- nsCOMPtr<nsINode> parent = node->GetParentNode();
-
+ htmlEditor->GetNextHTMLNode(point.Container(), point.Offset(),
+ point.GetChildAtOffset(), true);
+ while (!nearNode &&
+ !point.Container()->IsHTMLElement(nsGkAtoms::body) &&
+ point.Container()->GetParentNode()) {
// Don't walk past the editable section. Note that we need to check before
// walking up to a parent because we need to return the parent object, so
// the parent itself might not be in the editable area, but it's OK.
- if (!htmlEditor->IsDescendantOfEditorRoot(node) &&
- !htmlEditor->IsDescendantOfEditorRoot(parent)) {
+ if (!htmlEditor->IsDescendantOfEditorRoot(point.Container()) &&
+ !htmlEditor->IsDescendantOfEditorRoot(
+ point.Container()->GetParentNode())) {
break;
}
- child = node->GetNextSibling();
- node = parent;
- // we want to be AFTER nearNode
- offset = parentOffset + 1;
- nearNode = htmlEditor->GetNextHTMLNode(node, offset, child, true);
- }
- return EditorDOMPoint(node, offset);
+ point.Set(point.Container());
+ if (NS_WARN_IF(!point.AdvanceOffset())) {
+ break;
+ }
+ nearNode = htmlEditor->GetNextHTMLNode(point.Container(), point.Offset(),
+ point.GetChildAtOffset(), true);
+ }
+ return point;
}
/**
* GetPromotedRanges() runs all the selection range endpoint through
* GetPromotedPoint().
*/
void
HTMLEditRules::GetPromotedRanges(Selection& aSelection,
@@ -6791,17 +6790,19 @@ HTMLEditRules::ReturnInParagraph(Selecti
newBRneeded = true;
offset++;
}
} else {
// not in a text node.
// is there a BR prior to it?
nsCOMPtr<nsIContent> nearNode;
NS_ENSURE_STATE(mHTMLEditor);
- nearNode = mHTMLEditor->GetPriorHTMLNode(node, aOffset, aChildAtOffset);
+ nearNode =
+ mHTMLEditor->GetPreviousEditableHTMLNode(
+ EditorRawDOMPoint(node, aChildAtOffset, aOffset));
NS_ENSURE_STATE(mHTMLEditor);
if (!nearNode || !mHTMLEditor->IsVisibleBRElement(nearNode) ||
TextEditUtils::HasMozAttr(GetAsDOMNode(nearNode))) {
// is there a BR after it?
NS_ENSURE_STATE(mHTMLEditor);
nearNode = mHTMLEditor->GetNextHTMLNode(node, aOffset, aChildAtOffset);
NS_ENSURE_STATE(mHTMLEditor);
if (!nearNode || !mHTMLEditor->IsVisibleBRElement(nearNode) ||
@@ -7806,47 +7807,53 @@ HTMLEditRules::CheckInterlinePosition(Se
if (!aSelection.Collapsed()) {
return;
}
NS_ENSURE_TRUE_VOID(mHTMLEditor);
RefPtr<HTMLEditor> htmlEditor(mHTMLEditor);
// Get the (collapsed) selection location
- NS_ENSURE_TRUE_VOID(aSelection.GetRangeAt(0) &&
- aSelection.GetRangeAt(0)->GetStartContainer());
- OwningNonNull<nsINode> selNode =
- *aSelection.GetRangeAt(0)->GetStartContainer();
- int32_t selOffset = aSelection.GetRangeAt(0)->StartOffset();
- nsIContent* child = aSelection.GetRangeAt(0)->GetChildAtStartOffset();
+ nsRange* firstRange = aSelection.GetRangeAt(0);
+ if (NS_WARN_IF(!firstRange)) {
+ return;
+ }
+
+ EditorDOMPoint atStartOfSelection(firstRange->StartRef());
+ if (NS_WARN_IF(!atStartOfSelection.IsSet())) {
+ return;
+ }
+ MOZ_ASSERT(atStartOfSelection.IsSetAndValid());
// First, let's check to see if we are after a <br>. We take care of this
// special-case first so that we don't accidentally fall through into one of
// the other conditionals.
nsCOMPtr<nsIContent> node =
- htmlEditor->GetPriorHTMLNode(selNode, selOffset, child, true);
+ htmlEditor->GetPreviousEditableHTMLNodeInBlock(atStartOfSelection.AsRaw());
if (node && node->IsHTMLElement(nsGkAtoms::br)) {
aSelection.SetInterlinePosition(true);
return;
}
// Are we after a block? If so try set caret to following content
- if (child) {
- node = htmlEditor->GetPriorHTMLSibling(child);
+ if (atStartOfSelection.GetChildAtOffset()) {
+ node =
+ htmlEditor->GetPriorHTMLSibling(atStartOfSelection.GetChildAtOffset());
} else {
node = nullptr;
}
if (node && IsBlockNode(*node)) {
aSelection.SetInterlinePosition(true);
return;
}
// Are we before a block? If so try set caret to prior content
- if (child) {
- node = htmlEditor->GetNextHTMLSibling(child);
+ if (atStartOfSelection.GetChildAtOffset()) {
+ node =
+ htmlEditor->GetNextHTMLSibling(atStartOfSelection.GetChildAtOffset());
} else {
node = nullptr;
}
if (node && IsBlockNode(*node)) {
aSelection.SetInterlinePosition(false);
}
}
@@ -7859,138 +7866,139 @@ HTMLEditRules::AdjustSelection(Selection
// if the selection isn't collapsed, do nothing.
// moose: one thing to do instead is check for the case of
// only a single break selected, and collapse it. Good thing? Beats me.
if (!aSelection->Collapsed()) {
return NS_OK;
}
// get the (collapsed) selection location
- nsCOMPtr<nsINode> selNode, temp;
- int32_t selOffset;
- nsresult rv =
- EditorBase::GetStartNodeAndOffset(aSelection,
- getter_AddRefs(selNode), &selOffset);
- NS_ENSURE_SUCCESS(rv, rv);
- nsINode* child = aSelection->GetRangeAt(0)->GetChildAtStartOffset();
- temp = selNode;
+ EditorDOMPoint point(EditorBase::GetStartPoint(aSelection));
+ if (NS_WARN_IF(!point.IsSet())) {
+ return NS_ERROR_FAILURE;
+ }
// are we in an editable node?
NS_ENSURE_STATE(mHTMLEditor);
- while (!mHTMLEditor->IsEditable(selNode)) {
+ while (!mHTMLEditor->IsEditable(point.Container())) {
// scan up the tree until we find an editable place to be
- child = temp;
- selNode = EditorBase::GetNodeLocation(temp, &selOffset);
- NS_ENSURE_TRUE(selNode, NS_ERROR_FAILURE);
- temp = selNode;
- NS_ENSURE_STATE(mHTMLEditor);
+ point.Set(point.Container());
+ if (NS_WARN_IF(!point.IsSet())) {
+ return NS_ERROR_FAILURE;
+ }
}
// make sure we aren't in an empty block - user will see no cursor. If this
// is happening, put a <br> in the block if allowed.
NS_ENSURE_STATE(mHTMLEditor);
- nsCOMPtr<Element> theblock = mHTMLEditor->GetBlock(*selNode);
+ nsCOMPtr<Element> theblock = mHTMLEditor->GetBlock(*point.Container());
if (theblock && mHTMLEditor->IsEditable(theblock)) {
bool bIsEmptyNode;
NS_ENSURE_STATE(mHTMLEditor);
- rv = mHTMLEditor->IsEmptyNode(theblock, &bIsEmptyNode, false, false);
+ nsresult rv =
+ mHTMLEditor->IsEmptyNode(theblock, &bIsEmptyNode, false, false);
NS_ENSURE_SUCCESS(rv, rv);
// check if br can go into the destination node
NS_ENSURE_STATE(mHTMLEditor);
- if (bIsEmptyNode && mHTMLEditor->CanContainTag(*selNode, *nsGkAtoms::br)) {
+ if (bIsEmptyNode &&
+ mHTMLEditor->CanContainTag(*point.Container(), *nsGkAtoms::br)) {
NS_ENSURE_STATE(mHTMLEditor);
nsCOMPtr<Element> rootNode = mHTMLEditor->GetRoot();
NS_ENSURE_TRUE(rootNode, NS_ERROR_FAILURE);
- if (selNode == rootNode) {
+ if (point.Container() == rootNode) {
// Our root node is completely empty. Don't add a <br> here.
// AfterEditInner() will add one for us when it calls
// CreateBogusNodeIfNeeded()!
return NS_OK;
}
// we know we can skip the rest of this routine given the cirumstance
- return CreateMozBR(GetAsDOMNode(selNode), selOffset);
+ return CreateMozBR(GetAsDOMNode(point.Container()), point.Offset());
}
}
// are we in a text node?
- if (EditorBase::IsTextNode(selNode)) {
+ if (EditorBase::IsTextNode(point.Container())) {
return NS_OK; // we LIKE it when we are in a text node. that RULZ
}
// do we need to insert a special mozBR? We do if we are:
// 1) prior node is in same block where selection is AND
// 2) prior node is a br AND
// 3) that br is not visible
NS_ENSURE_STATE(mHTMLEditor);
nsCOMPtr<nsIContent> nearNode =
- mHTMLEditor->GetPriorHTMLNode(selNode, selOffset, child);
+ mHTMLEditor->GetPreviousEditableHTMLNode(point.AsRaw());
if (nearNode) {
// is nearNode also a descendant of same block?
NS_ENSURE_STATE(mHTMLEditor);
- nsCOMPtr<Element> block = mHTMLEditor->GetBlock(*selNode);
+ nsCOMPtr<Element> block = mHTMLEditor->GetBlock(*point.Container());
nsCOMPtr<Element> nearBlock = mHTMLEditor->GetBlockNodeParent(nearNode);
if (block && block == nearBlock) {
if (nearNode && TextEditUtils::IsBreak(nearNode)) {
NS_ENSURE_STATE(mHTMLEditor);
if (!mHTMLEditor->IsVisibleBRElement(nearNode)) {
// need to insert special moz BR. Why? Because if we don't
// the user will see no new line for the break. Also, things
// like table cells won't grow in height.
nsCOMPtr<nsIDOMNode> brNode;
- rv = CreateMozBR(GetAsDOMNode(selNode), selOffset,
- getter_AddRefs(brNode));
+ nsresult rv =
+ CreateMozBR(GetAsDOMNode(point.Container()), point.Offset(),
+ getter_AddRefs(brNode));
NS_ENSURE_SUCCESS(rv, rv);
- nsCOMPtr<nsIDOMNode> brParent =
- EditorBase::GetNodeLocation(brNode, &selOffset);
nsCOMPtr<nsIContent> br = do_QueryInterface(brNode);
- child = br;
+ point.Set(br);
// selection stays *before* moz-br, sticking to it
aSelection->SetInterlinePosition(true);
- rv = aSelection->Collapse(brParent, selOffset);
- NS_ENSURE_SUCCESS(rv, rv);
+ ErrorResult error;
+ aSelection->Collapse(point.AsRaw(), error);
+ if (NS_WARN_IF(error.Failed())) {
+ return error.StealNSResult();
+ }
} else {
NS_ENSURE_STATE(mHTMLEditor);
nsCOMPtr<nsIContent> nextNode =
mHTMLEditor->GetNextHTMLNode(nearNode, true);
if (nextNode && TextEditUtils::IsMozBR(nextNode)) {
// selection between br and mozbr. make it stick to mozbr
// so that it will be on blank line.
aSelection->SetInterlinePosition(true);
}
}
}
}
}
// we aren't in a textnode: are we adjacent to text or a break or an image?
NS_ENSURE_STATE(mHTMLEditor);
- nearNode = mHTMLEditor->GetPriorHTMLNode(selNode, selOffset, child, true);
+ nearNode = mHTMLEditor->GetPreviousEditableHTMLNodeInBlock(point.AsRaw());
if (nearNode && (TextEditUtils::IsBreak(nearNode) ||
EditorBase::IsTextNode(nearNode) ||
HTMLEditUtils::IsImage(nearNode) ||
nearNode->IsHTMLElement(nsGkAtoms::hr))) {
// this is a good place for the caret to be
return NS_OK;
}
NS_ENSURE_STATE(mHTMLEditor);
- nearNode = mHTMLEditor->GetNextHTMLNode(selNode, selOffset, child, true);
+ nearNode = mHTMLEditor->GetNextHTMLNode(point.Container(), point.Offset(),
+ point.GetChildAtOffset(), true);
if (nearNode && (TextEditUtils::IsBreak(nearNode) ||
EditorBase::IsTextNode(nearNode) ||
nearNode->IsAnyOfHTMLElements(nsGkAtoms::img,
nsGkAtoms::hr))) {
return NS_OK; // this is a good place for the caret to be
}
// look for a nearby text node.
// prefer the correct direction.
- rv = FindNearSelectableNode(selNode, selOffset, child, aAction,
- address_of(nearNode));
+ nsresult rv = FindNearSelectableNode(point.Container(), point.Offset(),
+ point.GetChildAtOffset(), aAction,
+ address_of(nearNode));
NS_ENSURE_SUCCESS(rv, rv);
if (!nearNode) {
return NS_OK;
}
EditorDOMPoint pt = GetGoodSelPointForNode(*nearNode, aAction);
rv = aSelection->Collapse(pt.AsRaw());
if (NS_WARN_IF(NS_FAILED(rv))) {
@@ -8005,67 +8013,69 @@ HTMLEditRules::FindNearSelectableNode(ns
int32_t aSelOffset,
nsINode* aChildAtOffset,
nsIEditor::EDirection& aDirection,
nsCOMPtr<nsIContent>* outSelectableNode)
{
NS_ENSURE_TRUE(aSelNode && outSelectableNode, NS_ERROR_NULL_POINTER);
*outSelectableNode = nullptr;
+ EditorRawDOMPoint point(aSelNode,
+ aChildAtOffset && aChildAtOffset->IsContent() ?
+ aChildAtOffset->AsContent() : nullptr,
+ aSelOffset);
+
nsCOMPtr<nsIContent> nearNode, curNode;
if (aDirection == nsIEditor::ePrevious) {
NS_ENSURE_STATE(mHTMLEditor);
- nearNode = mHTMLEditor->GetPriorHTMLNode(aSelNode, aSelOffset,
- aChildAtOffset);
+ nearNode = mHTMLEditor->GetPreviousEditableHTMLNode(point);
if (NS_WARN_IF(!nearNode)) {
return NS_ERROR_FAILURE;
}
} else {
NS_ENSURE_STATE(mHTMLEditor);
- nearNode = mHTMLEditor->GetNextHTMLNode(aSelNode, aSelOffset,
- aChildAtOffset);
+ nearNode = mHTMLEditor->GetNextHTMLNode(point.Container(), point.Offset(),
+ point.GetChildAtOffset());
if (NS_WARN_IF(!nearNode)) {
return NS_ERROR_FAILURE;
}
}
// Try the other direction then.
if (!nearNode) {
if (aDirection == nsIEditor::ePrevious) {
aDirection = nsIEditor::eNext;
} else {
aDirection = nsIEditor::ePrevious;
}
if (aDirection == nsIEditor::ePrevious) {
NS_ENSURE_STATE(mHTMLEditor);
- nearNode = mHTMLEditor->GetPriorHTMLNode(aSelNode, aSelOffset,
- aChildAtOffset);
+ nearNode = mHTMLEditor->GetPreviousEditableHTMLNode(point);
if (NS_WARN_IF(!nearNode)) {
return NS_ERROR_FAILURE;
}
} else {
NS_ENSURE_STATE(mHTMLEditor);
- nearNode = mHTMLEditor->GetPriorHTMLNode(aSelNode, aSelOffset,
- aChildAtOffset);
+ nearNode = mHTMLEditor->GetPreviousEditableHTMLNode(point);
if (NS_WARN_IF(!nearNode)) {
return NS_ERROR_FAILURE;
}
}
}
// scan in the right direction until we find an eligible text node,
// but don't cross any breaks, images, or table elements.
while (nearNode && !(EditorBase::IsTextNode(nearNode) ||
TextEditUtils::IsBreak(nearNode) ||
HTMLEditUtils::IsImage(nearNode))) {
curNode = nearNode;
if (aDirection == nsIEditor::ePrevious) {
NS_ENSURE_STATE(mHTMLEditor);
- nearNode = mHTMLEditor->GetPriorHTMLNode(curNode);
+ nearNode = mHTMLEditor->GetPreviousEditableHTMLNode(*curNode);
if (NS_WARN_IF(!nearNode)) {
return NS_ERROR_FAILURE;
}
} else {
NS_ENSURE_STATE(mHTMLEditor);
nearNode = mHTMLEditor->GetNextHTMLNode(curNode);
if (NS_WARN_IF(!nearNode)) {
return NS_ERROR_FAILURE;
--- a/editor/libeditor/HTMLEditor.cpp
+++ b/editor/libeditor/HTMLEditor.cpp
@@ -890,17 +890,17 @@ HTMLEditor::IsVisibleBRElement(nsINode*
}
if (IsBlockNode(nextNode)) {
// Break is right before a block, it's not visible
return false;
}
// If there's an inline node after this one that's not a break, and also a
// prior break, this break must be visible.
- nsCOMPtr<nsINode> priorNode = GetPriorHTMLNode(aNode, true);
+ nsCOMPtr<nsINode> priorNode = GetPreviousEditableHTMLNodeInBlock(*aNode);
if (priorNode && TextEditUtils::IsBreak(priorNode)) {
return true;
}
// Sigh. We have to use expensive whitespace calculation code to
// determine what is going on
int32_t selOffset;
nsCOMPtr<nsINode> selNode = GetNodeLocation(aNode, &selOffset);
@@ -3862,56 +3862,36 @@ HTMLEditor::GetNextHTMLSibling(nsINode*
nsIContent* node = aNode->GetNextSibling();
while (node && !IsEditable(node)) {
node = node->GetNextSibling();
}
return node;
}
-/**
- * GetPriorHTMLNode() returns the previous editable leaf node, if there is
- * one within the <body>.
- */
nsIContent*
-HTMLEditor::GetPriorHTMLNode(nsINode* aNode,
- bool aNoBlockCrossing)
+HTMLEditor::GetPreviousEditableHTMLNodeInternal(nsINode& aNode,
+ bool aNoBlockCrossing)
{
- MOZ_ASSERT(aNode);
-
if (!GetActiveEditingHost()) {
return nullptr;
}
-
- return aNoBlockCrossing ? GetPreviousEditableNodeInBlock(*aNode) :
- GetPreviousEditableNode(*aNode);
+ return aNoBlockCrossing ? GetPreviousEditableNodeInBlock(aNode) :
+ GetPreviousEditableNode(aNode);
}
-/**
- * GetPriorHTMLNode() is same as above but takes {parent,offset} instead of
- * node.
- */
nsIContent*
-HTMLEditor::GetPriorHTMLNode(nsINode* aParent,
- int32_t aOffset,
- nsINode* aChildAtOffset,
- bool aNoBlockCrossing)
+HTMLEditor::GetPreviousEditableHTMLNodeInternal(const EditorRawDOMPoint& aPoint,
+ bool aNoBlockCrossing)
{
- MOZ_ASSERT(aParent);
-
if (!GetActiveEditingHost()) {
return nullptr;
}
-
- EditorRawDOMPoint point(aParent,
- aChildAtOffset && aChildAtOffset->IsContent() ?
- aChildAtOffset->AsContent() : nullptr,
- aOffset);
- return aNoBlockCrossing ? GetPreviousEditableNodeInBlock(point) :
- GetPreviousEditableNode(point);
+ return aNoBlockCrossing ? GetPreviousEditableNodeInBlock(aPoint) :
+ GetPreviousEditableNode(aPoint);
}
/**
* GetNextHTMLNode() returns the next editable leaf node, if there is
* one within the <body>.
*/
nsIContent*
HTMLEditor::GetNextHTMLNode(nsINode* aNode,
@@ -4014,17 +3994,17 @@ HTMLEditor::GetFirstEditableLeaf(nsINode
return child;
}
nsIContent*
HTMLEditor::GetLastEditableLeaf(nsINode& aNode)
{
nsCOMPtr<nsIContent> child = GetRightmostChild(&aNode, false);
while (child && (!IsEditable(child) || child->HasChildren())) {
- child = GetPriorHTMLNode(child);
+ child = GetPreviousEditableHTMLNode(*child);
// Only accept nodes that are descendants of aNode
if (!aNode.Contains(child)) {
return nullptr;
}
}
return child;
@@ -4529,17 +4509,17 @@ HTMLEditor::CopyLastEditableChildStyles(
// now find and clone the styles
child = aPreviousBlock;
tmp = aPreviousBlock;
while (tmp) {
child = tmp;
tmp = GetLastEditableChild(*child);
}
while (child && TextEditUtils::IsBreak(child)) {
- child = GetPriorHTMLNode(child);
+ child = GetPreviousEditableHTMLNode(*child);
}
nsCOMPtr<Element> newStyles, deepestStyle;
nsCOMPtr<nsINode> childNode = child;
nsCOMPtr<Element> childElement;
if (childNode) {
childElement = childNode->IsElement() ? childNode->AsElement()
: childNode->GetParentElement();
}