--- a/editor/libeditor/EditorBase.cpp
+++ b/editor/libeditor/EditorBase.cpp
@@ -4033,42 +4033,16 @@ EditorBase::GetNodeAtRangeOffsetPoint(co
return nullptr;
}
if (aPoint.Container()->GetAsText()) {
return aPoint.Container()->AsContent();
}
return aPoint.GetChildAtOffset();
}
-/**
- * GetStartNodeAndOffset() returns whatever the start parent & offset is of
- * the first range in the selection.
- */
-nsresult
-EditorBase::GetStartNodeAndOffset(Selection* aSelection,
- nsINode** aStartContainer,
- int32_t* aStartOffset)
-{
- MOZ_ASSERT(aSelection);
- MOZ_ASSERT(aStartContainer);
- MOZ_ASSERT(aStartOffset);
-
- *aStartContainer = nullptr;
- *aStartOffset = 0;
-
- EditorRawDOMPoint point = EditorBase::GetStartPoint(aSelection);
- if (!point.IsSet()) {
- return NS_ERROR_FAILURE;
- }
-
- NS_ADDREF(*aStartContainer = point.GetContainer());
- *aStartOffset = point.Offset();
- return NS_OK;
-}
-
// static
EditorRawDOMPoint
EditorBase::GetStartPoint(Selection* aSelection)
{
MOZ_ASSERT(aSelection);
if (NS_WARN_IF(!aSelection->RangeCount())) {
return EditorRawDOMPoint();
@@ -4078,42 +4052,16 @@ EditorBase::GetStartPoint(Selection* aSe
if (NS_WARN_IF(!range) ||
NS_WARN_IF(!range->IsPositioned())) {
return EditorRawDOMPoint();
}
return EditorRawDOMPoint(range->StartRef());
}
-/**
- * GetEndNodeAndOffset() returns whatever the end parent & offset is of
- * the first range in the selection.
- */
-nsresult
-EditorBase::GetEndNodeAndOffset(Selection* aSelection,
- nsINode** aEndContainer,
- int32_t* aEndOffset)
-{
- MOZ_ASSERT(aSelection);
- MOZ_ASSERT(aEndContainer);
- MOZ_ASSERT(aEndOffset);
-
- *aEndContainer = nullptr;
- *aEndOffset = 0;
-
- EditorRawDOMPoint point = EditorBase::GetEndPoint(aSelection);
- if (!point.IsSet()) {
- return NS_ERROR_FAILURE;
- }
-
- NS_ADDREF(*aEndContainer = point.GetContainer());
- *aEndOffset = point.Offset();
- return NS_OK;
-}
-
// static
EditorRawDOMPoint
EditorBase::GetEndPoint(Selection* aSelection)
{
MOZ_ASSERT(aSelection);
if (NS_WARN_IF(!aSelection->RangeCount())) {
return EditorRawDOMPoint();
--- a/editor/libeditor/EditorBase.h
+++ b/editor/libeditor/EditorBase.h
@@ -1116,23 +1116,17 @@ public:
*/
static nsIContent* GetNodeAtRangeOffsetPoint(nsINode* aContainer,
int32_t aOffset)
{
return GetNodeAtRangeOffsetPoint(RawRangeBoundary(aContainer, aOffset));
}
static nsIContent* GetNodeAtRangeOffsetPoint(const RawRangeBoundary& aPoint);
- static nsresult GetStartNodeAndOffset(Selection* aSelection,
- nsINode** aStartContainer,
- int32_t* aStartOffset);
static EditorRawDOMPoint GetStartPoint(Selection* aSelection);
- static nsresult GetEndNodeAndOffset(Selection* aSelection,
- nsINode** aEndContainer,
- int32_t* aEndOffset);
static EditorRawDOMPoint GetEndPoint(Selection* aSelection);
static nsresult GetEndChildNode(Selection* aSelection,
nsIContent** aEndNode);
Selection* GetSelection(SelectionType aSelectionType =
SelectionType::eNormal)
{
--- a/editor/libeditor/HTMLEditRules.cpp
+++ b/editor/libeditor/HTMLEditRules.cpp
@@ -1020,52 +1020,58 @@ HTMLEditRules::GetIndentState(bool* aCan
// if the number part is strictly positive, outdent is possible
if (0 < f) {
*aCanOutdent = true;
break;
}
}
}
- if (!*aCanOutdent) {
- // if we haven't found something to outdent yet, also check the parents
- // of selection endpoints. We might have a blockquote or list item
- // in the parent hierarchy.
-
- // gather up info we need for test
- NS_ENSURE_STATE(mHTMLEditor);
- nsCOMPtr<nsINode> parent, root = mHTMLEditor->GetRoot();
- NS_ENSURE_TRUE(root, NS_ERROR_NULL_POINTER);
- int32_t selOffset;
- NS_ENSURE_STATE(mHTMLEditor);
- RefPtr<Selection> selection = mHTMLEditor->GetSelection();
- NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER);
-
- // test start parent hierarchy
- rv = EditorBase::GetStartNodeAndOffset(selection, getter_AddRefs(parent),
- &selOffset);
- NS_ENSURE_SUCCESS(rv, rv);
- while (parent && parent != root) {
- if (HTMLEditUtils::IsNodeThatCanOutdent(parent)) {
- *aCanOutdent = true;
- break;
- }
- parent = parent->GetParentNode();
- }
-
- // test end parent hierarchy
- rv = EditorBase::GetEndNodeAndOffset(selection, getter_AddRefs(parent),
- &selOffset);
- NS_ENSURE_SUCCESS(rv, rv);
- while (parent && parent != root) {
- if (HTMLEditUtils::IsNodeThatCanOutdent(parent)) {
- *aCanOutdent = true;
- break;
- }
- parent = parent->GetParentNode();
+ if (*aCanOutdent) {
+ return NS_OK;
+ }
+
+ // if we haven't found something to outdent yet, also check the parents
+ // of selection endpoints. We might have a blockquote or list item
+ // in the parent hierarchy.
+
+ if (NS_WARN_IF(!mHTMLEditor)) {
+ return NS_ERROR_FAILURE;
+ }
+
+ Element* rootElement = mHTMLEditor->GetRoot();
+ if (NS_WARN_IF(!rootElement)) {
+ return NS_ERROR_FAILURE;
+ }
+
+ // Test selection start container hierarchy.
+ EditorRawDOMPoint selectionStartPoint(EditorBase::GetStartPoint(selection));
+ if (NS_WARN_IF(!selectionStartPoint.IsSet())) {
+ return NS_ERROR_FAILURE;
+ }
+ for (nsINode* node = selectionStartPoint.GetContainer();
+ node && node != rootElement;
+ node = node->GetParentNode()) {
+ if (HTMLEditUtils::IsNodeThatCanOutdent(node)) {
+ *aCanOutdent = true;
+ return NS_OK;
+ }
+ }
+
+ // Test selection end container hierarchy.
+ EditorRawDOMPoint selectionEndPoint(EditorBase::GetEndPoint(selection));
+ if (NS_WARN_IF(!selectionEndPoint.IsSet())) {
+ return NS_ERROR_FAILURE;
+ }
+ for (nsINode* node = selectionEndPoint.GetContainer();
+ node && node != rootElement;
+ node = node->GetParentNode()) {
+ if (HTMLEditUtils::IsNodeThatCanOutdent(node)) {
+ *aCanOutdent = true;
+ return NS_OK;
}
}
return NS_OK;
}
nsresult
HTMLEditRules::GetParagraphState(bool* aMixed,
@@ -1097,26 +1103,28 @@ HTMLEditRules::GetParagraphState(bool* a
rv = AppendInnerFormatNodes(arrayOfNodes, curNode);
NS_ENSURE_SUCCESS(rv, rv);
}
}
// we might have an empty node list. if so, find selection parent
// and put that on the list
if (arrayOfNodes.IsEmpty()) {
- nsCOMPtr<nsINode> selNode;
- int32_t selOffset;
- NS_ENSURE_STATE(mHTMLEditor);
- RefPtr<Selection> selection = mHTMLEditor->GetSelection();
- NS_ENSURE_STATE(selection);
- rv = EditorBase::GetStartNodeAndOffset(selection, getter_AddRefs(selNode),
- &selOffset);
- NS_ENSURE_SUCCESS(rv, rv);
- NS_ENSURE_TRUE(selNode, NS_ERROR_NULL_POINTER);
- arrayOfNodes.AppendElement(*selNode);
+ if (NS_WARN_IF(!mHTMLEditor)) {
+ return NS_ERROR_NOT_AVAILABLE;
+ }
+ Selection* selection = mHTMLEditor->GetSelection();
+ if (NS_WARN_IF(!selection)) {
+ return NS_ERROR_FAILURE;
+ }
+ EditorRawDOMPoint selectionStartPoint(EditorBase::GetStartPoint(selection));
+ if (NS_WARN_IF(!selectionStartPoint.IsSet())) {
+ return NS_ERROR_FAILURE;
+ }
+ arrayOfNodes.AppendElement(*selectionStartPoint.GetContainer());
}
// remember root node
NS_ENSURE_STATE(mHTMLEditor);
nsCOMPtr<Element> rootElem = mHTMLEditor->GetRoot();
NS_ENSURE_TRUE(rootElem, NS_ERROR_NULL_POINTER);
// loop through the nodes in selection and examine their paragraph format
@@ -1978,162 +1986,180 @@ HTMLEditRules::SplitMailCites(Selection*
return NS_ERROR_INVALID_ARG;
}
if (NS_WARN_IF(!mHTMLEditor)) {
return NS_ERROR_NOT_AVAILABLE;
}
RefPtr<HTMLEditor> htmlEditor(mHTMLEditor);
- nsCOMPtr<nsINode> selNode;
- nsCOMPtr<Element> citeNode;
- int32_t selOffset;
- nsresult rv =
- EditorBase::GetStartNodeAndOffset(aSelection, getter_AddRefs(selNode),
- &selOffset);
- NS_ENSURE_SUCCESS(rv, rv);
- citeNode = GetTopEnclosingMailCite(*selNode);
- if (citeNode) {
- // If our selection is just before a break, nudge it to be
- // just after it. This does two things for us. It saves us the trouble of having to add
- // a break here ourselves to preserve the "blockness" of the inline span mailquote
- // (in the inline case), and :
- // it means the break won't end up making an empty line that happens to be inside a
- // mailquote (in either inline or block case).
- // The latter can confuse a user if they click there and start typing,
- // because being in the mailquote may affect wrapping behavior, or font color, etc.
- WSRunObject wsObj(htmlEditor, selNode, selOffset);
+ EditorRawDOMPoint pointToSplit(EditorBase::GetStartPoint(aSelection));
+ if (NS_WARN_IF(!pointToSplit.IsSet())) {
+ return NS_ERROR_FAILURE;
+ }
+
+ RefPtr<Element> citeNode =
+ GetTopEnclosingMailCite(*pointToSplit.GetContainer());
+ if (!citeNode) {
+ return NS_OK;
+ }
+
+ // If our selection is just before a break, nudge it to be just after it.
+ // This does two things for us. It saves us the trouble of having to add
+ // a break here ourselves to preserve the "blockness" of the inline span
+ // mailquote (in the inline case), and :
+ // it means the break won't end up making an empty line that happens to be
+ // inside a mailquote (in either inline or block case).
+ // The latter can confuse a user if they click there and start typing,
+ // because being in the mailquote may affect wrapping behavior, or font
+ // color, etc.
+ WSRunObject wsObj(htmlEditor, pointToSplit);
+ nsCOMPtr<nsINode> visNode;
+ int32_t visOffset=0;
+ WSType wsType;
+ wsObj.NextVisibleNode(pointToSplit, address_of(visNode), &visOffset, &wsType);
+ // If selection start point is before a break and it's inside the mailquote,
+ // let's split it after the visible node.
+ if (wsType == WSType::br &&
+ visNode != citeNode && citeNode->Contains(visNode)) {
+ pointToSplit.Set(visNode);
+ DebugOnly<bool> advanced = pointToSplit.AdvanceOffset();
+ NS_WARNING_ASSERTION(advanced,
+ "Failed to advance offset to after the visible node");
+ }
+
+ if (NS_WARN_IF(!pointToSplit.GetContainerAsContent())) {
+ return NS_ERROR_FAILURE;
+ }
+
+ SplitNodeResult splitCiteNodeResult =
+ htmlEditor->SplitNodeDeep(*citeNode, pointToSplit,
+ SplitAtEdges::eDoNotCreateEmptyContainer);
+ if (NS_WARN_IF(splitCiteNodeResult.Failed())) {
+ return splitCiteNodeResult.Rv();
+ }
+ pointToSplit.Clear();
+
+ // Add an invisible <br> to the end of current cite node (If new left cite
+ // has not been created, we're at the end of it. Otherwise, we're still at
+ // the right node) if it was a <span> of style="display: block". This is
+ // important, since when serializing the cite to plain text, the span which
+ // caused the visual break is discarded. So the added <br> will guarantee
+ // that the serializer will insert a break where the user saw one.
+ // FYI: splitCiteNodeResult grabs the previous node with nsCOMPtr. So, it's
+ // safe to access previousNodeOfSplitPoint even after changing the DOM
+ // tree and/or selection even though it's raw pointer.
+ nsIContent* previousNodeOfSplitPoint =
+ splitCiteNodeResult.GetPreviousNode();
+ if (previousNodeOfSplitPoint &&
+ previousNodeOfSplitPoint->IsHTMLElement(nsGkAtoms::span) &&
+ previousNodeOfSplitPoint->GetPrimaryFrame()->
+ IsFrameOfType(nsIFrame::eBlockFrame)) {
+ nsCOMPtr<nsINode> lastChild =
+ previousNodeOfSplitPoint->GetLastChild();
+ if (lastChild && !lastChild->IsHTMLElement(nsGkAtoms::br)) {
+ // We ignore the result here.
+ EditorRawDOMPoint endOfPreviousNodeOfSplitPoint;
+ endOfPreviousNodeOfSplitPoint.SetToEndOf(previousNodeOfSplitPoint);
+ RefPtr<Element> invisBR =
+ htmlEditor->CreateBR(endOfPreviousNodeOfSplitPoint);
+ }
+ }
+
+ // In most cases, <br> should be inserted after current cite. However, if
+ // left cite hasn't been created because the split point was start of the
+ // cite node, <br> should be inserted before the current cite.
+ EditorRawDOMPoint pointToInsertBrNode(splitCiteNodeResult.SplitPoint());
+ RefPtr<Element> brNode = htmlEditor->CreateBR(pointToInsertBrNode);
+ if (NS_WARN_IF(!brNode)) {
+ return NS_ERROR_FAILURE;
+ }
+ // Now, offset of pointToInsertBrNode is invalid. Let's clear it.
+ pointToInsertBrNode.Clear();
+
+ // Want selection before the break, and on same line.
+ EditorDOMPoint atBrNode(brNode);
+ Unused << atBrNode.Offset(); // Needs offset after collapsing the selection.
+ aSelection->SetInterlinePosition(true);
+ ErrorResult error;
+ aSelection->Collapse(atBrNode, error);
+ if (NS_WARN_IF(error.Failed())) {
+ return error.StealNSResult();
+ }
+
+ // if citeNode wasn't a block, we might also want another break before it.
+ // We need to examine the content both before the br we just added and also
+ // just after it. If we don't have another br or block boundary adjacent,
+ // then we will need a 2nd br added to achieve blank line that user expects.
+ if (IsInlineNode(*citeNode)) {
+ // Use DOM point which we tried to collapse to.
+ EditorRawDOMPoint pointToCreateNewBrNode(atBrNode.GetContainer(),
+ atBrNode.Offset());
+
+ WSRunObject wsObj(htmlEditor, pointToCreateNewBrNode);
nsCOMPtr<nsINode> visNode;
int32_t visOffset=0;
WSType wsType;
- wsObj.NextVisibleNode(EditorRawDOMPoint(selNode, selOffset),
- address_of(visNode), &visOffset, &wsType);
- if (wsType == WSType::br) {
- // ok, we are just before a break. is it inside the mailquote?
- if (visNode != citeNode && citeNode->Contains(visNode)) {
- // it is. so lets reset our selection to be just after it.
- selNode = EditorBase::GetNodeLocation(visNode, &selOffset);
- ++selOffset;
- }
- }
-
- NS_ENSURE_STATE(selNode->IsContent());
- SplitNodeResult splitCiteNodeResult =
- htmlEditor->SplitNodeDeep(*citeNode,
- EditorRawDOMPoint(selNode, selOffset),
- SplitAtEdges::eDoNotCreateEmptyContainer);
- if (NS_WARN_IF(splitCiteNodeResult.Failed())) {
- return splitCiteNodeResult.Rv();
- }
-
- // Add an invisible <br> to the end of current cite node (If new left cite
- // has not been created, we're at the end of it. Otherwise, we're still at
- // the right node) if it was a <span> of style="display: block". This is
- // important, since when serializing the cite to plain text, the span which
- // caused the visual break is discarded. So the added <br> will guarantee
- // that the serializer will insert a break where the user saw one.
- // FYI: splitCiteNodeResult grabs the previous node with nsCOMPtr.
- // So, it's safe to access previousNodeOfSplitPoint even after
- // changing the DOM tree and/or selection even though it's raw pointer.
- nsIContent* previousNodeOfSplitPoint =
- splitCiteNodeResult.GetPreviousNode();
- if (previousNodeOfSplitPoint &&
- previousNodeOfSplitPoint->IsHTMLElement(nsGkAtoms::span) &&
- previousNodeOfSplitPoint->GetPrimaryFrame()->
- IsFrameOfType(nsIFrame::eBlockFrame)) {
- nsCOMPtr<nsINode> lastChild =
- previousNodeOfSplitPoint->GetLastChild();
- if (lastChild && !lastChild->IsHTMLElement(nsGkAtoms::br)) {
- // We ignore the result here.
- EditorRawDOMPoint endOfPreviousNodeOfSplitPoint;
- endOfPreviousNodeOfSplitPoint.SetToEndOf(previousNodeOfSplitPoint);
- RefPtr<Element> invisBR =
- htmlEditor->CreateBR(endOfPreviousNodeOfSplitPoint);
- }
- }
-
- // In most cases, <br> should be inserted after current cite. However, if
- // left cite hasn't been created because the split point was start of the
- // cite node, <br> should be inserted before the current cite.
- EditorRawDOMPoint pointToInsertBrNode(splitCiteNodeResult.SplitPoint());
- RefPtr<Element> brNode = htmlEditor->CreateBR(pointToInsertBrNode);
- if (NS_WARN_IF(!brNode)) {
- return NS_ERROR_FAILURE;
- }
- // Now, offset of pointToInsertBrNode is invalid. Let's clear it.
- pointToInsertBrNode.Clear();
-
- // Want selection before the break, and on same line.
- EditorRawDOMPoint atBrNode(brNode);
- aSelection->SetInterlinePosition(true);
- ErrorResult error;
- aSelection->Collapse(atBrNode, error);
- if (NS_WARN_IF(error.Failed())) {
- return error.StealNSResult();
- }
-
- selNode = atBrNode.GetContainer();
- selOffset = atBrNode.Offset();
-
- // if citeNode wasn't a block, we might also want another break before it.
- // We need to examine the content both before the br we just added and also
- // just after it. If we don't have another br or block boundary adjacent,
- // then we will need a 2nd br added to achieve blank line that user expects.
- if (IsInlineNode(*citeNode)) {
- WSRunObject wsObj(htmlEditor, selNode, selOffset);
- nsCOMPtr<nsINode> visNode;
- int32_t visOffset=0;
- WSType wsType;
- wsObj.PriorVisibleNode(EditorRawDOMPoint(selNode, selOffset),
- address_of(visNode), &visOffset, &wsType);
+ wsObj.PriorVisibleNode(pointToCreateNewBrNode,
+ address_of(visNode), &visOffset, &wsType);
+ if (wsType == WSType::normalWS || wsType == WSType::text ||
+ wsType == WSType::special) {
+ EditorRawDOMPoint pointAfterNewBrNode(pointToCreateNewBrNode);
+ DebugOnly<bool> advanced = pointAfterNewBrNode.AdvanceOffset();
+ NS_WARNING_ASSERTION(advanced,
+ "Failed to advance offset after the <br> node");
+ WSRunObject wsObjAfterBR(htmlEditor, pointAfterNewBrNode);
+ wsObjAfterBR.NextVisibleNode(pointAfterNewBrNode,
+ address_of(visNode), &visOffset, &wsType);
if (wsType == WSType::normalWS || wsType == WSType::text ||
- wsType == WSType::special) {
- WSRunObject wsObjAfterBR(htmlEditor, selNode, selOffset + 1);
- wsObjAfterBR.NextVisibleNode(EditorRawDOMPoint(selNode, selOffset + 1),
- address_of(visNode), &visOffset, &wsType);
- if (wsType == WSType::normalWS || wsType == WSType::text ||
- wsType == WSType::special ||
- // In case we're at the very end.
- wsType == WSType::thisBlock) {
- brNode = htmlEditor->CreateBR(EditorRawDOMPoint(selNode, selOffset));
- NS_ENSURE_STATE(brNode);
+ wsType == WSType::special ||
+ // In case we're at the very end.
+ wsType == WSType::thisBlock) {
+ brNode = htmlEditor->CreateBR(pointToCreateNewBrNode);
+ if (NS_WARN_IF(!brNode)) {
+ return NS_ERROR_FAILURE;
}
- }
- }
-
- // delete any empty cites
- bool bEmptyCite = false;
- if (previousNodeOfSplitPoint) {
- rv = htmlEditor->IsEmptyNode(previousNodeOfSplitPoint, &bEmptyCite,
- true, false);
+ // Now, those points may be invalid.
+ pointToCreateNewBrNode.Clear();
+ pointAfterNewBrNode.Clear();
+ }
+ }
+ }
+
+ // delete any empty cites
+ bool bEmptyCite = false;
+ if (previousNodeOfSplitPoint) {
+ nsresult rv =
+ htmlEditor->IsEmptyNode(previousNodeOfSplitPoint, &bEmptyCite,
+ true, false);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
+ if (bEmptyCite) {
+ rv = htmlEditor->DeleteNode(previousNodeOfSplitPoint);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
- if (bEmptyCite) {
- rv = htmlEditor->DeleteNode(previousNodeOfSplitPoint);
- if (NS_WARN_IF(NS_FAILED(rv))) {
- return rv;
- }
- }
- }
-
- if (citeNode) {
- rv = htmlEditor->IsEmptyNode(citeNode, &bEmptyCite, true, false);
+ }
+ }
+
+ if (citeNode) {
+ nsresult rv = htmlEditor->IsEmptyNode(citeNode, &bEmptyCite, true, false);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
+ if (bEmptyCite) {
+ rv = htmlEditor->DeleteNode(citeNode);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
- if (bEmptyCite) {
- rv = htmlEditor->DeleteNode(citeNode);
- if (NS_WARN_IF(NS_FAILED(rv))) {
- return rv;
- }
- }
- }
- *aHandled = true;
- }
+ }
+ }
+
+ *aHandled = true;
return NS_OK;
}
nsresult
HTMLEditRules::WillDeleteSelection(Selection* aSelection,
nsIEditor::EDirection aAction,
nsIEditor::EStripWrappers aStripWrappers,
@@ -4063,23 +4089,23 @@ HTMLEditRules::WillCSSIndent(Selection*
nsTArray<OwningNonNull<nsRange>> arrayOfRanges;
nsTArray<OwningNonNull<nsINode>> arrayOfNodes;
// short circuit: detect case of collapsed selection inside an <li>.
// just sublist that <li>. This prevents bug 97797.
nsCOMPtr<Element> liNode;
if (aSelection->Collapsed()) {
- nsCOMPtr<nsINode> node;
- int32_t offset;
- nsresult rv =
- EditorBase::GetStartNodeAndOffset(aSelection,
- getter_AddRefs(node), &offset);
- NS_ENSURE_SUCCESS(rv, rv);
- RefPtr<Element> block = htmlEditor->GetBlock(*node);
+ EditorRawDOMPoint selectionStartPoint(
+ EditorBase::GetStartPoint(aSelection));
+ if (NS_WARN_IF(!selectionStartPoint.IsSet())) {
+ return NS_ERROR_FAILURE;
+ }
+ Element* block =
+ htmlEditor->GetBlock(*selectionStartPoint.GetContainer());
if (block && HTMLEditUtils::IsListItem(block)) {
liNode = block;
}
}
if (liNode) {
arrayOfNodes.AppendElement(*liNode);
} else {
@@ -7991,60 +8017,55 @@ HTMLEditRules::AdjustSpecialBreaks()
return;
}
}
}
nsresult
HTMLEditRules::AdjustWhitespace(Selection* aSelection)
{
- // get selection point
- nsCOMPtr<nsINode> selNode;
- int32_t selOffset;
- nsresult rv =
- EditorBase::GetStartNodeAndOffset(aSelection,
- getter_AddRefs(selNode), &selOffset);
- NS_ENSURE_SUCCESS(rv, rv);
-
- // ask whitespace object to tweak nbsp's
- NS_ENSURE_STATE(mHTMLEditor);
- return WSRunObject(mHTMLEditor, selNode, selOffset).AdjustWhitespace();
+ EditorRawDOMPoint selectionStartPoint(EditorBase::GetStartPoint(aSelection));
+ if (NS_WARN_IF(!selectionStartPoint.IsSet())) {
+ return NS_ERROR_FAILURE;
+ }
+
+ // Ask whitespace object to tweak nbsp's
+ if (NS_WARN_IF(!mHTMLEditor)) {
+ return NS_ERROR_NOT_AVAILABLE;
+ }
+ return WSRunObject(mHTMLEditor, selectionStartPoint).AdjustWhitespace();
}
nsresult
HTMLEditRules::PinSelectionToNewBlock(Selection* aSelection)
{
NS_ENSURE_TRUE(aSelection, NS_ERROR_NULL_POINTER);
if (!aSelection->Collapsed()) {
return NS_OK;
}
if (NS_WARN_IF(!mNewBlock)) {
return NS_ERROR_NULL_POINTER;
}
- // get the (collapsed) selection location
- nsCOMPtr<nsINode> selNode;
- int32_t selOffset;
- nsresult rv =
- EditorBase::GetStartNodeAndOffset(aSelection,
- getter_AddRefs(selNode), &selOffset);
+ EditorRawDOMPoint selectionStartPoint(EditorBase::GetStartPoint(aSelection));
+ if (NS_WARN_IF(!selectionStartPoint.IsSet())) {
+ return NS_ERROR_FAILURE;
+ }
+
+ // Use ranges and nsRange::CompareNodeToRange() to compare selection start
+ // to new block.
+ // XXX It's too expensive to use nsRange and set it only for comparing a
+ // DOM point with a node.
+ RefPtr<nsRange> range = new nsRange(selectionStartPoint.GetContainer());
+ nsresult rv = range->CollapseTo(selectionStartPoint);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
- if (NS_WARN_IF(!selNode)) {
- return NS_ERROR_FAILURE;
- }
-
- // use ranges and sRangeHelper to compare sel point to new block
- RefPtr<nsRange> range = new nsRange(selNode);
- rv = range->CollapseTo(selNode, selOffset);
- if (NS_WARN_IF(NS_FAILED(rv))) {
- return rv;
- }
+
bool nodeBefore, nodeAfter;
rv = nsRange::CompareNodeToRange(mNewBlock, range, &nodeBefore, &nodeAfter);
NS_ENSURE_SUCCESS(rv, rv);
if (nodeBefore && nodeAfter) {
return NS_OK; // selection is inside block
}
@@ -8712,75 +8733,67 @@ HTMLEditRules::RemoveListStructure(Eleme
// Delete the now-empty list
nsresult rv = htmlEditor->RemoveBlockContainer(aList);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
+// XXX This method is not necessary because even if selection is outside the
+// <body> element, the element can be editable.
nsresult
HTMLEditRules::ConfirmSelectionInBody()
{
- // get the body
- NS_ENSURE_STATE(mHTMLEditor);
- RefPtr<Element> rootElement = mHTMLEditor->GetRoot();
+ if (NS_WARN_IF(!mHTMLEditor)) {
+ return NS_ERROR_NOT_AVAILABLE;
+ }
+
+ Element* rootElement = mHTMLEditor->GetRoot();
if (NS_WARN_IF(!rootElement)) {
return NS_ERROR_UNEXPECTED;
}
- // get the selection
- NS_ENSURE_STATE(mHTMLEditor);
- RefPtr<Selection> selection = mHTMLEditor->GetSelection();
+ Selection* selection = mHTMLEditor->GetSelection();
if (NS_WARN_IF(!selection)) {
return NS_ERROR_UNEXPECTED;
}
- // get the selection start location
- nsCOMPtr<nsINode> selNode;
- int32_t selOffset;
- nsresult rv =
- EditorBase::GetStartNodeAndOffset(selection,
- getter_AddRefs(selNode), &selOffset);
- if (NS_FAILED(rv)) {
- return rv;
- }
-
- nsINode* temp = selNode;
+ EditorRawDOMPoint selectionStartPoint(EditorBase::GetStartPoint(selection));
+ if (NS_WARN_IF(!selectionStartPoint.IsSet())) {
+ return NS_ERROR_FAILURE;
+ }
+
+ // Check that selection start container is inside the <body> element.
+ //XXXsmaug this code is insane.
+ nsINode* temp = selectionStartPoint.GetContainer();
+ while (temp && !temp->IsHTMLElement(nsGkAtoms::body)) {
+ temp = temp->GetParentOrHostNode();
+ }
+
+ // If we aren't in the <body> element, force the issue.
+ if (!temp) {
+ selection->Collapse(rootElement, 0);
+ return NS_OK;
+ }
+
+ EditorRawDOMPoint selectionEndPoint(EditorBase::GetEndPoint(selection));
+ if (NS_WARN_IF(!selectionEndPoint.IsSet())) {
+ return NS_ERROR_FAILURE;
+ }
// check that selNode is inside body
//XXXsmaug this code is insane.
+ temp = selectionEndPoint.GetContainer();
while (temp && !temp->IsHTMLElement(nsGkAtoms::body)) {
temp = temp->GetParentOrHostNode();
}
- // if we aren't in the body, force the issue
+ // If we aren't in the <body> element, force the issue.
if (!temp) {
-// uncomment this to see when we get bad selections
-// NS_NOTREACHED("selection not in body");
- selection->Collapse(rootElement, 0);
- return NS_OK;
- }
-
- // get the selection end location
- rv = EditorBase::GetEndNodeAndOffset(selection,
- getter_AddRefs(selNode), &selOffset);
- NS_ENSURE_SUCCESS(rv, rv);
- temp = selNode;
-
- // check that selNode is inside body
- //XXXsmaug this code is insane.
- while (temp && !temp->IsHTMLElement(nsGkAtoms::body)) {
- temp = temp->GetParentOrHostNode();
- }
-
- // if we aren't in the body, force the issue
- if (!temp) {
-// uncomment this to see when we get bad selections
-// NS_NOTREACHED("selection not in body");
selection->Collapse(rootElement, 0);
}
return NS_OK;
}
nsresult
HTMLEditRules::UpdateDocChangeRange(nsRange* aRange)
--- a/editor/libeditor/HTMLEditorDataTransfer.cpp
+++ b/editor/libeditor/HTMLEditorDataTransfer.cpp
@@ -189,17 +189,17 @@ HTMLEditor::InsertHTMLWithContext(const
}
nsresult
HTMLEditor::DoInsertHTMLWithContext(const nsAString& aInputString,
const nsAString& aContextStr,
const nsAString& aInfoStr,
const nsAString& aFlavor,
nsIDOMDocument* aSourceDoc,
- nsIDOMNode* aDestNode,
+ nsIDOMNode* aDestDOMNode,
int32_t aDestOffset,
bool aDeleteSelection,
bool aTrustedInput,
bool aClearStyle)
{
NS_ENSURE_TRUE(mRules, NS_ERROR_NOT_INITIALIZED);
// Prevent the edit rules object from dying
@@ -222,49 +222,50 @@ HTMLEditor::DoInsertHTMLWithContext(cons
address_of(fragmentAsNode),
address_of(streamStartParent),
address_of(streamEndParent),
&streamStartOffset,
&streamEndOffset,
aTrustedInput);
NS_ENSURE_SUCCESS(rv, rv);
- nsCOMPtr<nsINode> targetNode;
- int32_t targetOffset=0;
-
- if (!aDestNode) {
+ EditorDOMPoint targetPoint;
+ if (!aDestDOMNode) {
// if caller didn't provide the destination/target node,
// fetch the paste insertion point from our selection
- rv = GetStartNodeAndOffset(selection, getter_AddRefs(targetNode), &targetOffset);
- NS_ENSURE_SUCCESS(rv, rv);
- if (!targetNode || !IsEditable(targetNode)) {
+ targetPoint = EditorBase::GetStartPoint(selection);
+ if (NS_WARN_IF(!targetPoint.IsSet()) ||
+ !IsEditable(targetPoint.GetContainer())) {
return NS_ERROR_FAILURE;
}
} else {
- targetNode = do_QueryInterface(aDestNode);
- targetOffset = aDestOffset;
+ nsCOMPtr<nsINode> destNode = do_QueryInterface(aDestDOMNode);
+ targetPoint.Set(destNode, aDestOffset);
}
// if we have a destination / target node, we want to insert there
// rather than in place of the selection
- // ignore aDeleteSelection here if no aDestNode since deletion will
+ // ignore aDeleteSelection here if no aDestDOMNode since deletion will
// also occur later; this block is intended to cover the various
// scenarios where we are dropping in an editor (and may want to delete
// the selection before collapsing the selection in the new destination)
- if (aDestNode) {
+ if (aDestDOMNode) {
if (aDeleteSelection) {
// Use an auto tracker so that our drop point is correctly
// positioned after the delete.
- AutoTrackDOMPoint tracker(mRangeUpdater, &targetNode, &targetOffset);
+ AutoTrackDOMPoint tracker(mRangeUpdater, &targetPoint);
rv = DeleteSelection(eNone, eStrip);
NS_ENSURE_SUCCESS(rv, rv);
}
- rv = selection->Collapse(targetNode, targetOffset);
- NS_ENSURE_SUCCESS(rv, rv);
+ ErrorResult error;
+ selection->Collapse(targetPoint, error);
+ if (NS_WARN_IF(error.Failed())) {
+ return error.StealNSResult();
+ }
}
// we need to recalculate various things based on potentially new offsets
// this is work to be completed at a later date (probably by jfrancis)
// make a list of what nodes in docFrag we need to move
nsTArray<OwningNonNull<nsINode>> nodeList;
CreateListOfNodesToPaste(*static_cast<DocumentFragment*>(fragmentAsNode.get()),
--- a/editor/libeditor/TextEditRules.cpp
+++ b/editor/libeditor/TextEditRules.cpp
@@ -458,91 +458,95 @@ TextEditRules::CollapseSelectionToTraili
{
// we only need to execute the stuff below if we are a plaintext editor.
// html editors have a different mechanism for putting in mozBR's
// (because there are a bunch more places you have to worry about it in html)
if (!IsPlaintextEditor()) {
return NS_OK;
}
- NS_ENSURE_STATE(mTextEditor);
+ if (NS_WARN_IF(!mTextEditor)) {
+ return NS_ERROR_NOT_AVAILABLE;
+ }
+ RefPtr<TextEditor> textEditor(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->CollapseSelectionToEnd(aSelection);
+ textEditor->CollapseSelectionToEnd(aSelection);
+ if (!mTextEditor) {
+ // The editor has been destroyed.
+ return NS_ERROR_FAILURE;
+ }
}
- // 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,
- getter_AddRefs(selNode), &selOffset);
- if (NS_WARN_IF(NS_FAILED(rv))) {
- return rv;
+ // If we are at the end of the <textarea> element, we need to set the
+ // selection to stick to the moz-<br> at the end of the <textarea>.
+ EditorRawDOMPoint selectionStartPoint(EditorBase::GetStartPoint(aSelection));
+ if (NS_WARN_IF(!selectionStartPoint.IsSet())) {
+ return NS_ERROR_FAILURE;
}
- if (!EditorBase::IsTextNode(selNode)) {
- return NS_OK; // Nothing to do if we're not at a text node.
- }
-
- // nothing to do if we're not at the end of the text node
- if (selOffset != static_cast<int32_t>(selNode->Length())) {
+ // Nothing to do if we're not at the end of the text node.
+ if (!selectionStartPoint.IsInTextNode() ||
+ !selectionStartPoint.IsEndOfContainer()) {
return NS_OK;
}
- NS_ENSURE_STATE(mTextEditor);
- nsINode* root = mTextEditor->GetRoot();
- if (NS_WARN_IF(!root)) {
+ Element* rootElement = textEditor->GetRoot();
+ if (NS_WARN_IF(!rootElement)) {
return NS_ERROR_NULL_POINTER;
}
- nsINode* parentNode = selNode->GetParentNode();
- if (parentNode != root) {
+ nsINode* parentNode = selectionStartPoint.GetContainer()->GetParentNode();
+ if (parentNode != rootElement) {
return NS_OK;
}
- nsINode* nextNode = selNode->GetNextSibling();
- if (nextNode && TextEditUtils::IsMozBR(nextNode)) {
- EditorRawDOMPoint afterSelNode(selNode);
- if (NS_WARN_IF(!afterSelNode.AdvanceOffset())) {
- return NS_ERROR_FAILURE;
- }
- rv = aSelection->Collapse(afterSelNode);
- if (NS_WARN_IF(NS_FAILED(rv))) {
- return rv;
- }
+ nsINode* nextNode = selectionStartPoint.GetContainer()->GetNextSibling();
+ if (!nextNode || !TextEditUtils::IsMozBR(nextNode)) {
+ return NS_OK;
+ }
+
+ EditorRawDOMPoint afterStartContainer(selectionStartPoint.GetContainer());
+ if (NS_WARN_IF(!afterStartContainer.AdvanceOffset())) {
+ return NS_ERROR_FAILURE;
+ }
+ ErrorResult error;
+ aSelection->Collapse(afterStartContainer, error);
+ if (NS_WARN_IF(error.Failed())) {
+ return error.StealNSResult();
}
return NS_OK;
}
static inline already_AddRefed<nsINode>
-GetTextNode(Selection* selection)
+GetTextNode(Selection* aSelection)
{
- int32_t selOffset;
- nsCOMPtr<nsINode> selNode;
- nsresult rv =
- EditorBase::GetStartNodeAndOffset(selection,
- getter_AddRefs(selNode), &selOffset);
- NS_ENSURE_SUCCESS(rv, nullptr);
- if (!EditorBase::IsTextNode(selNode)) {
- // This should be the root node, walk the tree looking for text nodes
- RefPtr<NodeIterator> iter =
- new NodeIterator(selNode, NodeFilterBinding::SHOW_TEXT, nullptr);
- while (!EditorBase::IsTextNode(selNode)) {
- selNode = iter->NextNode(IgnoreErrors());
- if (!selNode) {
- return nullptr;
- }
+ EditorRawDOMPoint selectionStartPoint(EditorBase::GetStartPoint(aSelection));
+ if (NS_WARN_IF(!selectionStartPoint.IsSet())) {
+ return nullptr;
+ }
+ if (selectionStartPoint.IsInTextNode()) {
+ nsCOMPtr<nsINode> node = selectionStartPoint.GetContainer();
+ return node.forget();
+ }
+ // This should be the root node, walk the tree looking for text nodes.
+ nsCOMPtr<nsINode> node = selectionStartPoint.GetContainer();
+ RefPtr<NodeIterator> iter =
+ new NodeIterator(node, NodeFilterBinding::SHOW_TEXT, nullptr);
+ while (!EditorBase::IsTextNode(node)) {
+ node = iter->NextNode(IgnoreErrors());
+ if (!node) {
+ return nullptr;
}
}
- return selNode.forget();
+ return node.forget();
}
+
#ifdef DEBUG
#define ASSERT_PASSWORD_LENGTHS_EQUAL() \
if (IsPasswordEditor() && mTextEditor->GetRoot()) { \
int32_t txtLen; \
mTextEditor->GetTextLength(&txtLen); \
NS_ASSERTION(mPasswordText.Length() == uint32_t(txtLen), \
"password length not equal to number of asterisks"); \
}
@@ -1027,32 +1031,29 @@ TextEditRules::WillDeleteSelection(Selec
}
// Otherwise nothing to do for this collapsed selection.
}
// Extended selection.
else {
mPasswordText.Cut(start, end-start);
}
} else {
- nsCOMPtr<nsINode> startNode;
- int32_t startOffset;
- nsresult rv =
- EditorBase::GetStartNodeAndOffset(aSelection, getter_AddRefs(startNode),
- &startOffset);
- NS_ENSURE_SUCCESS(rv, rv);
- NS_ENSURE_TRUE(startNode, NS_ERROR_FAILURE);
+ EditorRawDOMPoint selectionStartPoint(
+ EditorBase::GetStartPoint(aSelection));
+ if (NS_WARN_IF(!selectionStartPoint.IsSet())) {
+ return NS_ERROR_FAILURE;
+ }
if (!aSelection->IsCollapsed()) {
return NS_OK;
}
// Test for distance between caret and text that will be deleted
- rv = CheckBidiLevelForDeletion(aSelection,
- EditorRawDOMPoint(startNode, startOffset),
- aCollapsedAction, aCancel);
+ nsresult rv = CheckBidiLevelForDeletion(aSelection, selectionStartPoint,
+ aCollapsedAction, aCancel);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
if (*aCancel) {
return NS_OK;
}
NS_ENSURE_STATE(mTextEditor);
@@ -1070,39 +1071,35 @@ TextEditRules::WillDeleteSelection(Selec
return NS_OK;
}
nsresult
TextEditRules::DidDeleteSelection(Selection* aSelection,
nsIEditor::EDirection aCollapsedAction,
nsresult aResult)
{
- nsCOMPtr<nsINode> startNode;
- int32_t startOffset;
- nsresult rv =
- EditorBase::GetStartNodeAndOffset(aSelection,
- getter_AddRefs(startNode), &startOffset);
- if (NS_WARN_IF(NS_FAILED(rv))) {
- return rv;
- }
- if (NS_WARN_IF(!startNode)) {
+ EditorRawDOMPoint selectionStartPoint(EditorBase::GetStartPoint(aSelection));
+ if (NS_WARN_IF(!selectionStartPoint.IsSet())) {
return NS_ERROR_FAILURE;
}
- // delete empty text nodes at selection
- if (EditorBase::IsTextNode(startNode)) {
- // are we in an empty text node?
- if (!startNode->Length()) {
- NS_ENSURE_STATE(mTextEditor);
- rv = mTextEditor->DeleteNode(startNode);
- if (NS_WARN_IF(NS_FAILED(rv))) {
- return rv;
- }
+ // Delete empty text nodes at selection.
+ if (selectionStartPoint.IsInTextNode() &&
+ !selectionStartPoint.GetContainer()->Length()) {
+ if (NS_WARN_IF(!mTextEditor)) {
+ return NS_ERROR_NOT_AVAILABLE;
}
+ RefPtr<TextEditor> textEditor(mTextEditor);
+ nsresult rv = textEditor->DeleteNode(selectionStartPoint.GetContainer());
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
+ // Be aware, mTextEditor may be nullptr here.
}
+
if (mDidExplicitlySetInterline) {
return NS_OK;
}
// We prevent the caret from sticking on the left of prior BR
// (i.e. the end of previous line) after this deletion. Bug 92124
return aSelection->SetInterlinePosition(true);
}
--- a/editor/libeditor/TypeInState.cpp
+++ b/editor/libeditor/TypeInState.cpp
@@ -34,91 +34,92 @@ using namespace dom;
/********************************************************************
* mozilla::TypeInState
*******************************************************************/
NS_IMPL_CYCLE_COLLECTION_CLASS(TypeInState)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(TypeInState)
- NS_IMPL_CYCLE_COLLECTION_UNLINK(mLastSelectionContainer)
+ NS_IMPL_CYCLE_COLLECTION_UNLINK(mLastSelectionPoint)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(TypeInState)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mLastSelectionContainer)
+ NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mLastSelectionPoint)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(TypeInState, AddRef)
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(TypeInState, Release)
TypeInState::TypeInState()
: mRelativeFontSize(0)
- , mLastSelectionOffset(0)
{
Reset();
}
TypeInState::~TypeInState()
{
// Call Reset() to release any data that may be in
// mClearedArray and mSetArray.
Reset();
}
nsresult
TypeInState::UpdateSelState(Selection* aSelection)
{
- NS_ENSURE_TRUE(aSelection, NS_ERROR_NULL_POINTER);
+ if (NS_WARN_IF(!aSelection)) {
+ return NS_ERROR_INVALID_ARG;
+ }
if (!aSelection->Collapsed()) {
return NS_OK;
}
- return EditorBase::GetStartNodeAndOffset(
- aSelection, getter_AddRefs(mLastSelectionContainer),
- &mLastSelectionOffset);
+ mLastSelectionPoint = EditorBase::GetStartPoint(aSelection);
+ if (!mLastSelectionPoint.IsSet()) {
+ return NS_ERROR_FAILURE;
+ }
+ // We need to store only offset because referring child may be removed by
+ // we'll check the point later.
+ AutoEditorDOMPointChildInvalidator saveOnlyOffset(mLastSelectionPoint);
+ return NS_OK;
}
void
TypeInState::OnSelectionChange(Selection& aSelection)
{
// XXX: Selection currently generates bogus selection changed notifications
// XXX: (bug 140303). It can notify us when the selection hasn't actually
// XXX: changed, and it notifies us more than once for the same change.
// XXX:
// XXX: The following code attempts to work around the bogus notifications,
// XXX: and should probably be removed once bug 140303 is fixed.
// XXX:
// XXX: This code temporarily fixes the problem where clicking the mouse in
// XXX: the same location clears the type-in-state.
if (aSelection.IsCollapsed() && aSelection.RangeCount()) {
- nsCOMPtr<nsINode> selNode;
- int32_t selOffset = 0;
-
- nsresult rv =
- EditorBase::GetStartNodeAndOffset(&aSelection, getter_AddRefs(selNode),
- &selOffset);
- if (NS_WARN_IF(NS_FAILED(rv))) {
+ EditorRawDOMPoint selectionStartPoint(
+ EditorBase::GetStartPoint(&aSelection));
+ if (NS_WARN_IF(!selectionStartPoint.IsSet())) {
return;
}
- if (selNode &&
- selNode == mLastSelectionContainer &&
- selOffset == mLastSelectionOffset) {
+ if (mLastSelectionPoint == selectionStartPoint) {
// We got a bogus selection changed notification!
return;
}
- mLastSelectionContainer = selNode;
- mLastSelectionOffset = selOffset;
+ mLastSelectionPoint = selectionStartPoint;
+ // We need to store only offset because referring child may be removed by
+ // we'll check the point later.
+ AutoEditorDOMPointChildInvalidator saveOnlyOffset(mLastSelectionPoint);
} else {
- mLastSelectionContainer = nullptr;
- mLastSelectionOffset = 0;
+ mLastSelectionPoint.Clear();
}
Reset();
}
void
TypeInState::Reset()
{
--- a/editor/libeditor/TypeInState.h
+++ b/editor/libeditor/TypeInState.h
@@ -1,16 +1,17 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef TypeInState_h
#define TypeInState_h
+#include "mozilla/EditorDOMPoint.h"
#include "mozilla/UniquePtr.h"
#include "nsCOMPtr.h"
#include "nsCycleCollectionParticipant.h"
#include "nsISupportsImpl.h"
#include "nsString.h"
#include "nsTArray.h"
#include "nscore.h"
@@ -91,19 +92,18 @@ protected:
bool IsPropSet(nsAtom* aProp, nsAtom* aAttr, nsAString* outValue);
bool IsPropSet(nsAtom* aProp, nsAtom* aAttr, nsAString* outValue,
int32_t& outIndex);
bool IsPropCleared(nsAtom* aProp, nsAtom* aAttr);
bool IsPropCleared(nsAtom* aProp, nsAtom* aAttr, int32_t& outIndex);
nsTArray<PropItem*> mSetArray;
nsTArray<PropItem*> mClearedArray;
+ EditorDOMPoint mLastSelectionPoint;
int32_t mRelativeFontSize;
- nsCOMPtr<nsINode> mLastSelectionContainer;
- int32_t mLastSelectionOffset;
friend class HTMLEditRules;
};
} // namespace mozilla
#endif // #ifndef TypeInState_h