зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1414713 - EditorUtils::IsDescendantOf() should take EditorDOMPoint and EditorRawDOMPoint as out param r=catalinb,m_kato
EditorUtils::IsDescendantOf() current takes a pointer to offset or a pointer to child content if the caller needs to know the child of the most ancestor node. However, some callers should get a child as EditorDOMPoint or EditorRawDOMPoint. Then, they can be used for some editor methods which need to take child node for performance optimization. This patch makes EditorUtils::IsDescendantOf() as only two overloads. One takes pointer to EditorRawDOMPoint as optional out argument. The other takes pointer to EditorDOMPoint as an out param. Additionally, this creates new constructor of AutoTrackDOMPoint for making it can treat EditorDOMPoint directly. MozReview-Commit-ID: IsAGTUvKI19 --HG-- extra : rebase_source : 97469a21b974c6a1dd515ab472bbc4a88c1899c8
This commit is contained in:
Родитель
ed4206c563
Коммит
365f79c262
|
@ -203,6 +203,11 @@ public:
|
|||
return mOffset.value();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set() sets a point to aOffset or aChild.
|
||||
* If it's set with offset, mRef is invalidated. If it's set with aChild,
|
||||
* mOffset may be invalidated unless the offset can be computed simply.
|
||||
*/
|
||||
void
|
||||
Set(nsINode* aContainer, int32_t aOffset)
|
||||
{
|
||||
|
@ -210,6 +215,29 @@ public:
|
|||
mRef = nullptr;
|
||||
mOffset = mozilla::Some(aOffset);
|
||||
}
|
||||
void
|
||||
Set(const nsIContent* aChild)
|
||||
{
|
||||
MOZ_ASSERT(aChild);
|
||||
mParent = aChild->GetParentNode();
|
||||
mRef = aChild->GetPreviousSibling();
|
||||
if (!mRef) {
|
||||
mOffset = mozilla::Some(0);
|
||||
} else {
|
||||
mOffset.reset();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear() makes the instance not point anywhere.
|
||||
*/
|
||||
void
|
||||
Clear()
|
||||
{
|
||||
mParent = nullptr;
|
||||
mRef = nullptr;
|
||||
mOffset.reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* AdvanceOffset() tries to reference next sibling of mRef if its container
|
||||
|
|
|
@ -3969,7 +3969,7 @@ EditorBase::SplitNodeDeep(nsIContent& aNode,
|
|||
nsCOMPtr<nsIContent>* ioChildAtSplitPointOffset)
|
||||
{
|
||||
MOZ_ASSERT(&aSplitPointParent == &aNode ||
|
||||
EditorUtils::IsDescendantOf(&aSplitPointParent, &aNode));
|
||||
EditorUtils::IsDescendantOf(aSplitPointParent, aNode));
|
||||
int32_t offset = aSplitPointOffset;
|
||||
|
||||
nsCOMPtr<nsIContent> leftNode, rightNode;
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
#include "mozilla/EditorUtils.h"
|
||||
|
||||
#include "mozilla/EditorDOMPoint.h"
|
||||
#include "mozilla/OwningNonNull.h"
|
||||
#include "mozilla/dom/Selection.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
|
@ -135,19 +136,23 @@ DOMSubtreeIterator::~DOMSubtreeIterator()
|
|||
*****************************************************************************/
|
||||
|
||||
bool
|
||||
EditorUtils::IsDescendantOf(nsINode* aNode,
|
||||
nsINode* aParent,
|
||||
int32_t* aOffset)
|
||||
EditorUtils::IsDescendantOf(const nsINode& aNode,
|
||||
const nsINode& aParent,
|
||||
EditorRawDOMPoint* aOutPoint /* = nullptr */)
|
||||
{
|
||||
MOZ_ASSERT(aNode && aParent);
|
||||
if (aNode == aParent) {
|
||||
if (aOutPoint) {
|
||||
aOutPoint->Clear();
|
||||
}
|
||||
|
||||
if (&aNode == &aParent) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (nsCOMPtr<nsINode> node = aNode; node; node = node->GetParentNode()) {
|
||||
if (node->GetParentNode() == aParent) {
|
||||
if (aOffset) {
|
||||
*aOffset = aParent->IndexOf(node);
|
||||
for (const nsINode* node = &aNode; node; node = node->GetParentNode()) {
|
||||
if (node->GetParentNode() == &aParent) {
|
||||
if (aOutPoint) {
|
||||
MOZ_ASSERT(node->IsContent());
|
||||
aOutPoint->Set(node->AsContent());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -157,19 +162,20 @@ EditorUtils::IsDescendantOf(nsINode* aNode,
|
|||
}
|
||||
|
||||
bool
|
||||
EditorUtils::IsDescendantOf(nsINode* aNode,
|
||||
nsINode* aParent,
|
||||
nsIContent** aChild)
|
||||
EditorUtils::IsDescendantOf(const nsINode& aNode,
|
||||
const nsINode& aParent,
|
||||
EditorDOMPoint* aOutPoint)
|
||||
{
|
||||
MOZ_ASSERT(aNode && aParent && aChild);
|
||||
*aChild = nullptr;
|
||||
if (aNode == aParent) {
|
||||
MOZ_ASSERT(aOutPoint);
|
||||
aOutPoint->Clear();
|
||||
if (&aNode == &aParent) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (nsCOMPtr<nsINode> node = aNode; node; node = node->GetParentNode()) {
|
||||
if (node->GetParentNode() == aParent) {
|
||||
*aChild = node->AsContent();
|
||||
for (const nsINode* node = &aNode; node; node = node->GetParentNode()) {
|
||||
if (node->GetParentNode() == &aParent) {
|
||||
MOZ_ASSERT(node->IsContent());
|
||||
aOutPoint->Set(node->AsContent());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -177,17 +183,6 @@ EditorUtils::IsDescendantOf(nsINode* aNode,
|
|||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
EditorUtils::IsDescendantOf(nsIDOMNode* aNode,
|
||||
nsIDOMNode* aParent,
|
||||
int32_t* aOffset)
|
||||
{
|
||||
nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
|
||||
nsCOMPtr<nsINode> parent = do_QueryInterface(aParent);
|
||||
NS_ENSURE_TRUE(node && parent, false);
|
||||
return IsDescendantOf(node, parent, aOffset);
|
||||
}
|
||||
|
||||
bool
|
||||
EditorUtils::IsLeafNode(nsIDOMNode* aNode)
|
||||
{
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include "mozilla/dom/Selection.h"
|
||||
#include "mozilla/EditorBase.h"
|
||||
#include "mozilla/EditorDOMPoint.h"
|
||||
#include "mozilla/GuardObjects.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsDebug.h"
|
||||
|
@ -378,13 +379,19 @@ public:
|
|||
class EditorUtils final
|
||||
{
|
||||
public:
|
||||
// Note that aChild isn't a normal XPCOM outparam and won't get AddRef'ed.
|
||||
static bool IsDescendantOf(nsINode* aNode, nsINode* aParent,
|
||||
nsIContent** aChild);
|
||||
static bool IsDescendantOf(nsINode* aNode, nsINode* aParent,
|
||||
int32_t* aOffset = nullptr);
|
||||
static bool IsDescendantOf(nsIDOMNode* aNode, nsIDOMNode* aParent,
|
||||
int32_t* aOffset = nullptr);
|
||||
/**
|
||||
* IsDescendantOf() checks if aNode is a child or a descendant of aParent.
|
||||
* aOutPoint is set to the child of aParent.
|
||||
*
|
||||
* @return true if aNode is a child or a descendant of aParent.
|
||||
*/
|
||||
static bool IsDescendantOf(const nsINode& aNode,
|
||||
const nsINode& aParent,
|
||||
EditorRawDOMPoint* aOutPoint = nullptr);
|
||||
static bool IsDescendantOf(const nsINode& aNode,
|
||||
const nsINode& aParent,
|
||||
EditorDOMPoint* aOutPoint);
|
||||
|
||||
static bool IsLeafNode(nsIDOMNode* aNode);
|
||||
};
|
||||
|
||||
|
|
|
@ -2858,19 +2858,20 @@ HTMLEditRules::TryToJoinBlocks(nsIContent& aLeftNode,
|
|||
// different lists, join the lists instead.
|
||||
bool mergeLists = false;
|
||||
nsAtom* existingList = nsGkAtoms::_empty;
|
||||
nsIContent* childInBlock = nullptr;
|
||||
EditorDOMPoint childInBlock;
|
||||
nsCOMPtr<Element> leftList, rightList;
|
||||
if (HTMLEditUtils::IsListItem(leftBlock) &&
|
||||
HTMLEditUtils::IsListItem(rightBlock)) {
|
||||
leftList = leftBlock->GetParentElement();
|
||||
rightList = rightBlock->GetParentElement();
|
||||
if (leftList && rightList && leftList != rightList &&
|
||||
!EditorUtils::IsDescendantOf(leftList, rightBlock, &childInBlock) &&
|
||||
!EditorUtils::IsDescendantOf(rightList, leftBlock, &childInBlock)) {
|
||||
!EditorUtils::IsDescendantOf(*leftList, *rightBlock, &childInBlock) &&
|
||||
!EditorUtils::IsDescendantOf(*rightList, *leftBlock, &childInBlock)) {
|
||||
// There are some special complications if the lists are descendants of
|
||||
// the other lists' items. Note that it is okay for them to be
|
||||
// descendants of the other lists themselves, which is the usual case for
|
||||
// sublists in our implementation.
|
||||
MOZ_DIAGNOSTIC_ASSERT(!childInBlock.IsSet());
|
||||
leftBlock = leftList;
|
||||
rightBlock = rightList;
|
||||
mergeLists = true;
|
||||
|
@ -2880,15 +2881,13 @@ HTMLEditRules::TryToJoinBlocks(nsIContent& aLeftNode,
|
|||
|
||||
AutoTransactionsConserveSelection dontChangeMySelection(htmlEditor);
|
||||
|
||||
int32_t rightOffset = 0;
|
||||
int32_t leftOffset = -1;
|
||||
|
||||
// offset below is where you find yourself in rightBlock when you traverse
|
||||
// upwards from leftBlock
|
||||
if (EditorUtils::IsDescendantOf(leftBlock, rightBlock, &rightOffset)) {
|
||||
EditorDOMPoint rightBlockChild;
|
||||
if (EditorUtils::IsDescendantOf(*leftBlock, *rightBlock, &rightBlockChild)) {
|
||||
// Tricky case. Left block is inside right block. Do ws adjustment. This
|
||||
// just destroys non-visible ws at boundaries we will be joining.
|
||||
rightOffset++;
|
||||
rightBlockChild.AdvanceOffset();
|
||||
nsresult rv = WSRunObject::ScrubBlockBoundary(htmlEditor,
|
||||
WSRunObject::kBlockEnd,
|
||||
leftBlock);
|
||||
|
@ -2898,23 +2897,25 @@ HTMLEditRules::TryToJoinBlocks(nsIContent& aLeftNode,
|
|||
|
||||
{
|
||||
// We can't just track rightBlock because it's an Element.
|
||||
nsCOMPtr<nsINode> trackingRightBlock(rightBlock);
|
||||
AutoTrackDOMPoint tracker(htmlEditor->mRangeUpdater,
|
||||
address_of(trackingRightBlock), &rightOffset);
|
||||
AutoTrackDOMPoint tracker(htmlEditor->mRangeUpdater, &rightBlockChild);
|
||||
rv = WSRunObject::ScrubBlockBoundary(htmlEditor,
|
||||
WSRunObject::kAfterBlock,
|
||||
rightBlock, rightOffset);
|
||||
rightBlock,
|
||||
rightBlockChild.Offset());
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return EditActionIgnored(rv);
|
||||
}
|
||||
|
||||
if (trackingRightBlock->IsElement()) {
|
||||
rightBlock = trackingRightBlock->AsElement();
|
||||
// XXX AutoTrackDOMPoint instance, tracker, hasn't been destroyed here.
|
||||
// Do we really need to do update rightBlock here??
|
||||
MOZ_ASSERT(rightBlock == rightBlockChild.Container());
|
||||
if (rightBlockChild.Container()->IsElement()) {
|
||||
rightBlock = rightBlockChild.Container()->AsElement();
|
||||
} else {
|
||||
if (NS_WARN_IF(!trackingRightBlock->GetParentElement())) {
|
||||
if (NS_WARN_IF(!rightBlockChild.Container()->GetParentElement())) {
|
||||
return EditActionIgnored(NS_ERROR_UNEXPECTED);
|
||||
}
|
||||
rightBlock = trackingRightBlock->GetParentElement();
|
||||
rightBlock = rightBlockChild.Container()->GetParentElement();
|
||||
}
|
||||
}
|
||||
// Do br adjustment.
|
||||
|
@ -2924,8 +2925,12 @@ HTMLEditRules::TryToJoinBlocks(nsIContent& aLeftNode,
|
|||
if (mergeLists) {
|
||||
// The idea here is to take all children in rightList that are past
|
||||
// offset, and pull them into leftlist.
|
||||
for (nsCOMPtr<nsIContent> child = childInBlock;
|
||||
child; child = rightList->GetChildAt(rightOffset)) {
|
||||
// XXX Looks like that when mergeLists is true, childInBlock has never
|
||||
// been set. So, this block must be dead code.
|
||||
MOZ_DIAGNOSTIC_ASSERT(childInBlock.IsSet());
|
||||
uint32_t offset = rightBlockChild.Offset();
|
||||
for (nsCOMPtr<nsIContent> child = childInBlock.GetChildAtOffset();
|
||||
child; child = rightList->GetChildAt(offset)) {
|
||||
rv = htmlEditor->MoveNode(child, leftList, -1);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return EditActionIgnored(rv);
|
||||
|
@ -2933,13 +2938,21 @@ HTMLEditRules::TryToJoinBlocks(nsIContent& aLeftNode,
|
|||
}
|
||||
// XXX Should this set to true only when above for loop moves the node?
|
||||
ret.MarkAsHandled();
|
||||
// childInBlock and rightBlockChild were moved to leftList. So, they
|
||||
// are now invalid.
|
||||
rightBlockChild.Clear();
|
||||
childInBlock.Clear();
|
||||
} else {
|
||||
// XXX Why do we ignore the result of MoveBlock()?
|
||||
EditActionResult retMoveBlock =
|
||||
MoveBlock(*leftBlock, *rightBlock, leftOffset, rightOffset);
|
||||
MoveBlock(*leftBlock, *rightBlock,
|
||||
-1, rightBlockChild.Offset());
|
||||
if (retMoveBlock.Handled()) {
|
||||
ret.MarkAsHandled();
|
||||
}
|
||||
// Now, all children of rightBlock were moved to leftBlock. So,
|
||||
// rightBlockChild is now invalid.
|
||||
rightBlockChild.Clear();
|
||||
}
|
||||
if (brNode && NS_SUCCEEDED(htmlEditor->DeleteNode(brNode))) {
|
||||
ret.MarkAsHandled();
|
||||
|
@ -2947,9 +2960,12 @@ HTMLEditRules::TryToJoinBlocks(nsIContent& aLeftNode,
|
|||
return ret;
|
||||
}
|
||||
|
||||
MOZ_DIAGNOSTIC_ASSERT(!rightBlockChild.IsSet());
|
||||
|
||||
// Offset below is where you find yourself in leftBlock when you traverse
|
||||
// upwards from rightBlock
|
||||
if (EditorUtils::IsDescendantOf(rightBlock, leftBlock, &leftOffset)) {
|
||||
EditorDOMPoint leftBlockChild;
|
||||
if (EditorUtils::IsDescendantOf(*rightBlock, *leftBlock, &leftBlockChild)) {
|
||||
// Tricky case. Right block is inside left block. Do ws adjustment. This
|
||||
// just destroys non-visible ws at boundaries we will be joining.
|
||||
nsresult rv = WSRunObject::ScrubBlockBoundary(htmlEditor,
|
||||
|
@ -2962,50 +2978,51 @@ HTMLEditRules::TryToJoinBlocks(nsIContent& aLeftNode,
|
|||
{
|
||||
// We can't just track leftBlock because it's an Element, so track
|
||||
// something else.
|
||||
nsCOMPtr<nsINode> trackingLeftBlock(leftBlock);
|
||||
AutoTrackDOMPoint tracker(htmlEditor->mRangeUpdater,
|
||||
address_of(trackingLeftBlock), &leftOffset);
|
||||
AutoTrackDOMPoint tracker(htmlEditor->mRangeUpdater, &leftBlockChild);
|
||||
rv = WSRunObject::ScrubBlockBoundary(htmlEditor,
|
||||
WSRunObject::kBeforeBlock,
|
||||
leftBlock, leftOffset);
|
||||
leftBlock, leftBlockChild.Offset());
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return EditActionIgnored(rv);
|
||||
}
|
||||
|
||||
if (trackingLeftBlock->IsElement()) {
|
||||
leftBlock = trackingLeftBlock->AsElement();
|
||||
// XXX AutoTrackDOMPoint instance, tracker, hasn't been destroyed here.
|
||||
// Do we really need to do update rightBlock here??
|
||||
MOZ_DIAGNOSTIC_ASSERT(leftBlock == leftBlockChild.Container());
|
||||
if (leftBlockChild.Container()->IsElement()) {
|
||||
leftBlock = leftBlockChild.Container()->AsElement();
|
||||
} else {
|
||||
if (NS_WARN_IF(!trackingLeftBlock->GetParentElement())) {
|
||||
if (NS_WARN_IF(!leftBlockChild.Container()->GetParentElement())) {
|
||||
return EditActionIgnored(NS_ERROR_UNEXPECTED);
|
||||
}
|
||||
leftBlock = trackingLeftBlock->GetParentElement();
|
||||
leftBlock = leftBlockChild.Container()->GetParentElement();
|
||||
}
|
||||
}
|
||||
// Do br adjustment.
|
||||
nsCOMPtr<Element> brNode =
|
||||
CheckForInvisibleBR(*leftBlock, BRLocation::beforeBlock, leftOffset);
|
||||
CheckForInvisibleBR(*leftBlock, BRLocation::beforeBlock,
|
||||
leftBlockChild.Offset());
|
||||
EditActionResult ret(NS_OK);
|
||||
if (mergeLists) {
|
||||
// XXX Why do we ignore the result of MoveContents()?
|
||||
int32_t offset = leftBlockChild.Offset();
|
||||
EditActionResult retMoveContents =
|
||||
MoveContents(*rightList, *leftList, &leftOffset);
|
||||
MoveContents(*rightList, *leftList, &offset);
|
||||
if (retMoveContents.Handled()) {
|
||||
ret.MarkAsHandled();
|
||||
}
|
||||
// leftBlockChild was moved to rightList. So, it's invalid now.
|
||||
leftBlockChild.Clear();
|
||||
} else {
|
||||
// Left block is a parent of right block, and the parent of the previous
|
||||
// visible content. Right block is a child and contains the contents we
|
||||
// want to move.
|
||||
|
||||
int32_t previousContentOffset;
|
||||
nsCOMPtr<nsINode> previousContentParent;
|
||||
|
||||
EditorDOMPoint previousContent;
|
||||
if (&aLeftNode == leftBlock) {
|
||||
// We are working with valid HTML, aLeftNode is a block node, and is
|
||||
// therefore allowed to contain rightBlock. This is the simple case,
|
||||
// we will simply move the content in rightBlock out of its block.
|
||||
previousContentParent = leftBlock;
|
||||
previousContentOffset = leftOffset;
|
||||
previousContent = leftBlockChild;
|
||||
} else {
|
||||
// We try to work as well as possible with HTML that's already invalid.
|
||||
// Although "right block" is a block, and a block must not be contained
|
||||
|
@ -3016,13 +3033,10 @@ HTMLEditRules::TryToJoinBlocks(nsIContent& aLeftNode,
|
|||
// However, in some situations this strategy moves the content to an
|
||||
// unexpected position. (see bug 200416) The new idea is to make the
|
||||
// moving content a sibling, next to the previous visible content.
|
||||
|
||||
previousContentParent = aLeftNode.GetParentNode();
|
||||
previousContentOffset = previousContentParent ?
|
||||
previousContentParent->IndexOf(&aLeftNode) : -1;
|
||||
previousContent.Set(&aLeftNode);
|
||||
|
||||
// We want to move our content just after the previous visible node.
|
||||
previousContentOffset++;
|
||||
previousContent.AdvanceOffset();
|
||||
}
|
||||
|
||||
// Because we don't want the moving content to receive the style of the
|
||||
|
@ -3031,6 +3045,8 @@ HTMLEditRules::TryToJoinBlocks(nsIContent& aLeftNode,
|
|||
nsCOMPtr<Element> editorRoot = htmlEditor->GetEditorRoot();
|
||||
if (!editorRoot || &aLeftNode != editorRoot) {
|
||||
nsCOMPtr<nsIContent> splittedPreviousContent;
|
||||
nsCOMPtr<nsINode> previousContentParent = previousContent.Container();
|
||||
int32_t previousContentOffset = previousContent.Offset();
|
||||
rv = htmlEditor->SplitStyleAbovePoint(
|
||||
address_of(previousContentParent),
|
||||
&previousContentOffset,
|
||||
|
@ -3041,18 +3057,18 @@ HTMLEditRules::TryToJoinBlocks(nsIContent& aLeftNode,
|
|||
}
|
||||
|
||||
if (splittedPreviousContent) {
|
||||
previousContentParent = splittedPreviousContent->GetParentNode();
|
||||
previousContentOffset = previousContentParent ?
|
||||
previousContentParent->IndexOf(splittedPreviousContent) : -1;
|
||||
previousContent.Set(splittedPreviousContent);
|
||||
} else {
|
||||
previousContent.Set(previousContentParent, previousContentOffset);
|
||||
}
|
||||
}
|
||||
|
||||
if (NS_WARN_IF(!previousContentParent)) {
|
||||
if (NS_WARN_IF(!previousContent.IsSet())) {
|
||||
return EditActionIgnored(NS_ERROR_NULL_POINTER);
|
||||
}
|
||||
|
||||
ret |= MoveBlock(*previousContentParent->AsElement(), *rightBlock,
|
||||
previousContentOffset, rightOffset);
|
||||
ret |= MoveBlock(*previousContent.Container()->AsElement(), *rightBlock,
|
||||
previousContent.Offset(), 0);
|
||||
if (NS_WARN_IF(ret.Failed())) {
|
||||
return ret;
|
||||
}
|
||||
|
@ -3063,6 +3079,9 @@ HTMLEditRules::TryToJoinBlocks(nsIContent& aLeftNode,
|
|||
return ret;
|
||||
}
|
||||
|
||||
MOZ_DIAGNOSTIC_ASSERT(!rightBlockChild.IsSet());
|
||||
MOZ_DIAGNOSTIC_ASSERT(!leftBlockChild.IsSet());
|
||||
|
||||
// Normal case. Blocks are siblings, or at least close enough. An example
|
||||
// of the latter is <p>paragraph</p><ul><li>one<li>two<li>three</ul>. The
|
||||
// first li and the p are not true siblings, but we still want to join them
|
||||
|
@ -3089,7 +3108,7 @@ HTMLEditRules::TryToJoinBlocks(nsIContent& aLeftNode,
|
|||
ret.MarkAsHandled();
|
||||
} else {
|
||||
// Nodes are dissimilar types.
|
||||
ret |= MoveBlock(*leftBlock, *rightBlock, leftOffset, rightOffset);
|
||||
ret |= MoveBlock(*leftBlock, *rightBlock, -1, 0);
|
||||
if (NS_WARN_IF(ret.Failed())) {
|
||||
return ret;
|
||||
}
|
||||
|
@ -3438,7 +3457,7 @@ HTMLEditRules::WillMakeList(Selection* aSelection,
|
|||
|
||||
if (HTMLEditUtils::IsList(curNode)) {
|
||||
// do we have a curList already?
|
||||
if (curList && !EditorUtils::IsDescendantOf(curNode, curList)) {
|
||||
if (curList && !EditorUtils::IsDescendantOf(*curNode, *curList)) {
|
||||
// move all of our children into curList. cheezy way to do it: move
|
||||
// whole list and then RemoveContainer() on the list. ConvertListType
|
||||
// first: that routine handles converting the list item types, if
|
||||
|
@ -3469,7 +3488,7 @@ HTMLEditRules::WillMakeList(Selection* aSelection,
|
|||
if (!curParent->IsHTMLElement(listType)) {
|
||||
// list item is in wrong type of list. if we don't have a curList,
|
||||
// split the old list and make a new list of correct type.
|
||||
if (!curList || EditorUtils::IsDescendantOf(curNode, curList)) {
|
||||
if (!curList || EditorUtils::IsDescendantOf(*curNode, *curList)) {
|
||||
NS_ENSURE_STATE(mHTMLEditor);
|
||||
NS_ENSURE_STATE(curParent->IsContent());
|
||||
ErrorResult rv;
|
||||
|
@ -4405,7 +4424,7 @@ HTMLEditRules::WillOutdent(Selection& aSelection,
|
|||
// Do we have a blockquote that we are already committed to removing?
|
||||
if (curBlockQuote) {
|
||||
// If so, is this node a descendant?
|
||||
if (EditorUtils::IsDescendantOf(curNode, curBlockQuote)) {
|
||||
if (EditorUtils::IsDescendantOf(*curNode, *curBlockQuote)) {
|
||||
lastBQChild = curNode;
|
||||
// Then we don't need to do anything different for this node
|
||||
continue;
|
||||
|
@ -4532,7 +4551,7 @@ HTMLEditRules::WillOutdent(Selection& aSelection,
|
|||
int32_t startOffset = aSelection.GetRangeAt(0)->StartOffset();
|
||||
if (rememberedLeftBQ &&
|
||||
(startNode == rememberedLeftBQ ||
|
||||
EditorUtils::IsDescendantOf(startNode, rememberedLeftBQ))) {
|
||||
EditorUtils::IsDescendantOf(*startNode, *rememberedLeftBQ))) {
|
||||
// Selection is inside rememberedLeftBQ - push it past it.
|
||||
startNode = rememberedLeftBQ->GetParentNode();
|
||||
startOffset = startNode ? 1 + startNode->IndexOf(rememberedLeftBQ) : 0;
|
||||
|
@ -4543,7 +4562,7 @@ HTMLEditRules::WillOutdent(Selection& aSelection,
|
|||
startOffset = aSelection.GetRangeAt(0)->StartOffset();
|
||||
if (rememberedRightBQ &&
|
||||
(startNode == rememberedRightBQ ||
|
||||
EditorUtils::IsDescendantOf(startNode, rememberedRightBQ))) {
|
||||
EditorUtils::IsDescendantOf(*startNode, *rememberedRightBQ))) {
|
||||
// Selection is inside rememberedRightBQ - push it before it.
|
||||
startNode = rememberedRightBQ->GetParentNode();
|
||||
startOffset = startNode ? startNode->IndexOf(rememberedRightBQ) : -1;
|
||||
|
@ -4584,8 +4603,8 @@ HTMLEditRules::SplitBlock(Element& aBlock,
|
|||
nsIContent** aOutMiddleNode)
|
||||
{
|
||||
// aStartChild and aEndChild must be exclusive descendants of aBlock
|
||||
MOZ_ASSERT(EditorUtils::IsDescendantOf(&aStartChild, &aBlock) &&
|
||||
EditorUtils::IsDescendantOf(&aEndChild, &aBlock));
|
||||
MOZ_ASSERT(EditorUtils::IsDescendantOf(aStartChild, aBlock) &&
|
||||
EditorUtils::IsDescendantOf(aEndChild, aBlock));
|
||||
NS_ENSURE_TRUE_VOID(mHTMLEditor);
|
||||
RefPtr<HTMLEditor> htmlEditor(mHTMLEditor);
|
||||
|
||||
|
@ -6396,7 +6415,7 @@ HTMLEditRules::GetHighestInlineParent(nsINode& aNode)
|
|||
// such elements for now.
|
||||
// XXX This should be MOZ_ASSERT after fixing bug 1413131 for avoiding
|
||||
// calling this expensive method.
|
||||
if (NS_WARN_IF(!EditorUtils::IsDescendantOf(&aNode, host))) {
|
||||
if (NS_WARN_IF(!EditorUtils::IsDescendantOf(aNode, *host))) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -7088,7 +7107,7 @@ HTMLEditRules::RemoveBlockStyle(nsTArray<OwningNonNull<nsINode>>& aNodeArray)
|
|||
} else if (IsInlineNode(curNode)) {
|
||||
if (curBlock) {
|
||||
// If so, is this node a descendant?
|
||||
if (EditorUtils::IsDescendantOf(curNode, curBlock)) {
|
||||
if (EditorUtils::IsDescendantOf(*curNode, *curBlock)) {
|
||||
// Then we don't need to do anything different for this node
|
||||
lastNode = curNode->AsContent();
|
||||
continue;
|
||||
|
@ -8160,7 +8179,7 @@ HTMLEditRules::SelectionEndpointInNode(nsINode* aNode,
|
|||
*aResult = true;
|
||||
return NS_OK;
|
||||
}
|
||||
if (EditorUtils::IsDescendantOf(startContainer, aNode)) {
|
||||
if (EditorUtils::IsDescendantOf(*startContainer, *aNode)) {
|
||||
*aResult = true;
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -8174,7 +8193,7 @@ HTMLEditRules::SelectionEndpointInNode(nsINode* aNode,
|
|||
*aResult = true;
|
||||
return NS_OK;
|
||||
}
|
||||
if (EditorUtils::IsDescendantOf(endContainer, aNode)) {
|
||||
if (EditorUtils::IsDescendantOf(*endContainer, *aNode)) {
|
||||
*aResult = true;
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -758,7 +758,7 @@ HTMLEditor::GetBlockNodeParent(nsINode* aNode,
|
|||
MOZ_ASSERT(aNode);
|
||||
MOZ_ASSERT(!aAncestorLimiter ||
|
||||
aNode == aAncestorLimiter ||
|
||||
EditorUtils::IsDescendantOf(aNode, aAncestorLimiter),
|
||||
EditorUtils::IsDescendantOf(*aNode, *aAncestorLimiter),
|
||||
"aNode isn't in aAncestorLimiter");
|
||||
|
||||
// The caller has already reached the limiter.
|
||||
|
@ -791,7 +791,7 @@ HTMLEditor::GetBlock(nsINode& aNode,
|
|||
{
|
||||
MOZ_ASSERT(!aAncestorLimiter ||
|
||||
&aNode == aAncestorLimiter ||
|
||||
EditorUtils::IsDescendantOf(&aNode, aAncestorLimiter),
|
||||
EditorUtils::IsDescendantOf(aNode, *aAncestorLimiter),
|
||||
"aNode isn't in aAncestorLimiter");
|
||||
|
||||
if (NodeIsBlockStatic(&aNode)) {
|
||||
|
|
|
@ -442,7 +442,11 @@ HTMLEditor::DoInsertHTMLWithContext(const nsAString& aInputString,
|
|||
if (insertedContextParent) {
|
||||
// if we had to insert something higher up in the paste hierarchy, we want to
|
||||
// skip any further paste nodes that descend from that. Else we will paste twice.
|
||||
if (EditorUtils::IsDescendantOf(curNode, insertedContextParent)) {
|
||||
nsCOMPtr<nsINode> insertedContextParentNode =
|
||||
do_QueryInterface(insertedContextParent);
|
||||
if (NS_WARN_IF(!insertedContextParentNode) ||
|
||||
EditorUtils::IsDescendantOf(*nodeList[j],
|
||||
*insertedContextParentNode)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -2380,7 +2384,7 @@ HTMLEditor::ReplaceOrphanedStructure(
|
|||
(i - removedCount) : (originalLength - i - 1);
|
||||
OwningNonNull<nsINode> endpoint = aNodeArray[idx];
|
||||
if (endpoint == replaceNode ||
|
||||
EditorUtils::IsDescendantOf(endpoint, replaceNode)) {
|
||||
EditorUtils::IsDescendantOf(*endpoint, *replaceNode)) {
|
||||
aNodeArray.RemoveElementAt(idx);
|
||||
removedCount++;
|
||||
}
|
||||
|
|
|
@ -287,7 +287,7 @@ RangeUpdater::SelAdjDeleteNode(nsINode* aNode)
|
|||
|
||||
// check for range endpoints that are in descendants of aNode
|
||||
nsCOMPtr<nsINode> oldStart;
|
||||
if (EditorUtils::IsDescendantOf(item->mStartContainer, aNode)) {
|
||||
if (EditorUtils::IsDescendantOf(*item->mStartContainer, *aNode)) {
|
||||
oldStart = item->mStartContainer; // save for efficiency hack below.
|
||||
item->mStartContainer = parent;
|
||||
item->mStartOffset = offset;
|
||||
|
@ -295,7 +295,7 @@ RangeUpdater::SelAdjDeleteNode(nsINode* aNode)
|
|||
|
||||
// avoid having to call IsDescendantOf() for common case of range startnode == range endnode.
|
||||
if (item->mEndContainer == oldStart ||
|
||||
EditorUtils::IsDescendantOf(item->mEndContainer, aNode)) {
|
||||
EditorUtils::IsDescendantOf(*item->mEndContainer, *aNode)) {
|
||||
item->mEndContainer = parent;
|
||||
item->mEndOffset = offset;
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#ifndef mozilla_SelectionState_h
|
||||
#define mozilla_SelectionState_h
|
||||
|
||||
#include "mozilla/EditorDOMPoint.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIDOMNode.h"
|
||||
#include "nsINode.h"
|
||||
|
@ -180,6 +181,7 @@ private:
|
|||
nsCOMPtr<nsINode>* mNode;
|
||||
nsCOMPtr<nsIDOMNode>* mDOMNode;
|
||||
int32_t* mOffset;
|
||||
EditorDOMPoint* mPoint;
|
||||
RefPtr<RangeItem> mRangeItem;
|
||||
|
||||
public:
|
||||
|
@ -189,6 +191,7 @@ public:
|
|||
, mNode(aNode)
|
||||
, mDOMNode(nullptr)
|
||||
, mOffset(aOffset)
|
||||
, mPoint(nullptr)
|
||||
{
|
||||
mRangeItem = new RangeItem();
|
||||
mRangeItem->mStartContainer = *mNode;
|
||||
|
@ -204,6 +207,7 @@ public:
|
|||
, mNode(nullptr)
|
||||
, mDOMNode(aNode)
|
||||
, mOffset(aOffset)
|
||||
, mPoint(nullptr)
|
||||
{
|
||||
mRangeItem = new RangeItem();
|
||||
mRangeItem->mStartContainer = do_QueryInterface(*mDOMNode);
|
||||
|
@ -213,9 +217,29 @@ public:
|
|||
mRangeUpdater.RegisterRangeItem(mRangeItem);
|
||||
}
|
||||
|
||||
AutoTrackDOMPoint(RangeUpdater& aRangeUpdater,
|
||||
EditorDOMPoint* aPoint)
|
||||
: mRangeUpdater(aRangeUpdater)
|
||||
, mNode(nullptr)
|
||||
, mDOMNode(nullptr)
|
||||
, mOffset(nullptr)
|
||||
, mPoint(aPoint)
|
||||
{
|
||||
mRangeItem = new RangeItem();
|
||||
mRangeItem->mStartContainer = mPoint->Container();
|
||||
mRangeItem->mEndContainer = mPoint->Container();
|
||||
mRangeItem->mStartOffset = mPoint->Offset();
|
||||
mRangeItem->mEndOffset = mPoint->Offset();
|
||||
mRangeUpdater.RegisterRangeItem(mRangeItem);
|
||||
}
|
||||
|
||||
~AutoTrackDOMPoint()
|
||||
{
|
||||
mRangeUpdater.DropRangeItem(mRangeItem);
|
||||
if (mPoint) {
|
||||
mPoint->Set(mRangeItem->mStartContainer, mRangeItem->mStartOffset);
|
||||
return;
|
||||
}
|
||||
if (mNode) {
|
||||
*mNode = mRangeItem->mStartContainer;
|
||||
} else {
|
||||
|
|
Загрузка…
Ссылка в новой задаче