Bug 1415445 - part 4: EditorBase::CreateNode() should take EditorRawDOMPoint as insertion point instead of a set of container, child and offset of the child in the container r=m_kato

EditorBase::CreateNode() should take EditorRawDOMPoint as insertion point of
the new element instead of a set of container, child and offset of the child
in the container.

This patch initializes EditorRawDOMPoint with original 3 arguments as far as
possible.  If the relation of them are broken, MOZ_ASSERT in RawRangeBoundary
constructor detects existing bugs.

MozReview-Commit-ID: 2N55S6pRv7k

--HG--
extra : rebase_source : 2b14a7715815ca0007635b8f791ca9edbe5b65f1
This commit is contained in:
Masayuki Nakano 2017-11-08 20:23:10 +09:00
parent 82358b9f2e
commit 68294ac1d3
7 changed files with 200 additions and 135 deletions

View File

@ -87,10 +87,11 @@ protected:
MOZ_RELEASE_ASSERT(aContainer,
"This constructor shouldn't be used when pointing nowhere");
if (!mRef) {
MOZ_ASSERT(mOffset.value() == 0);
MOZ_ASSERT(!mParent->IsContainerNode() || mOffset.value() == 0);
return;
}
MOZ_ASSERT(mOffset.value() > 0);
MOZ_ASSERT(mParent == mRef->GetParentNode());
MOZ_ASSERT(mParent->GetChildAt(mOffset.value() - 1) == mRef);
}

View File

@ -1419,24 +1419,15 @@ EditorBase::SetSpellcheckUserOverride(bool enable)
already_AddRefed<Element>
EditorBase::CreateNode(nsAtom* aTag,
nsINode* aParent,
int32_t aPosition,
nsIContent* aChildAtPosition)
EditorRawDOMPoint& aPointToInsert)
{
MOZ_ASSERT(aTag && aParent);
MOZ_ASSERT(aTag);
MOZ_ASSERT(aPointToInsert.IsSetAndValid());
EditorRawDOMPoint pointToInsert;
if (aPosition == -1) {
pointToInsert.Set(aParent, aParent->Length());
} else if (aChildAtPosition) {
pointToInsert.Set(aChildAtPosition);
} else {
pointToInsert.Set(aParent, aPosition);
}
// XXX We need to offset at new node to mRangeUpdater. Therefore, we need
// to compute the offset now but this is expensive. So, if it's possible,
// we need to redesign mRangeUpdater as avoiding using indices.
int32_t offset = static_cast<int32_t>(pointToInsert.Offset());
int32_t offset = static_cast<int32_t>(aPointToInsert.Offset());
AutoRules beginRulesSniffing(this, EditAction::createNode, nsIEditor::eNext);
@ -1444,21 +1435,25 @@ EditorBase::CreateNode(nsAtom* aTag,
AutoActionListenerArray listeners(mActionListeners);
for (auto& listener : listeners) {
listener->WillCreateNode(nsDependentAtomString(aTag),
GetAsDOMNode(pointToInsert.GetChildAtOffset()));
GetAsDOMNode(aPointToInsert.GetChildAtOffset()));
}
}
nsCOMPtr<Element> ret;
RefPtr<CreateElementTransaction> transaction =
CreateTxnForCreateElement(*aTag, pointToInsert);
CreateTxnForCreateElement(*aTag, aPointToInsert);
nsresult rv = DoTransaction(transaction);
if (NS_SUCCEEDED(rv)) {
ret = transaction->GetNewNode();
MOZ_ASSERT(ret);
// Now, aPointToInsert may be invalid. I.e., ChildAtOffset() keeps
// referring the next sibling of new node but Offset() refers the
// new node. Let's make refer the new node.
aPointToInsert.Set(ret);
}
mRangeUpdater.SelAdjCreateNode(pointToInsert.Container(), offset);
mRangeUpdater.SelAdjCreateNode(aPointToInsert.Container(), offset);
{
AutoActionListenerArray listeners(mActionListeners);
@ -4226,16 +4221,29 @@ EditorBase::DeleteSelectionAndCreateElement(nsAtom& aTag)
RefPtr<Selection> selection = GetSelection();
NS_ENSURE_TRUE(selection, nullptr);
nsCOMPtr<nsINode> node = selection->GetAnchorNode();
uint32_t offset = selection->AnchorOffset();
nsIContent* child = selection->GetChildAtAnchorOffset();
nsCOMPtr<Element> newElement = CreateNode(&aTag, node, offset, child);
EditorRawDOMPoint pointToInsert(selection->GetChildAtAnchorOffset());
if (!pointToInsert.IsSet()) {
// Perhaps, the anchor point is in a text node.
pointToInsert.Set(selection->GetAnchorNode(), selection->AnchorOffset());
if (NS_WARN_IF(!pointToInsert.IsSet())) {
return nullptr;
}
}
RefPtr<Element> newElement = CreateNode(&aTag, pointToInsert);
// We want the selection to be just after the new node
rv = selection->Collapse(node, offset + 1);
NS_ENSURE_SUCCESS(rv, nullptr);
DebugOnly<bool> advanced = pointToInsert.AdvanceOffset();
NS_WARNING_ASSERTION(advanced,
"Failed to move offset next to the new element");
ErrorResult error;
selection->Collapse(pointToInsert, error);
if (NS_WARN_IF(error.Failed())) {
// XXX Even if it succeeded to create new element, this returns error
// when Selection.Collapse() fails something. This could occur with
// mutation observer or mutation event listener.
error.SuppressException();
return nullptr;
}
return newElement.forget();
}

View File

@ -410,9 +410,23 @@ protected:
CreateTxnForCreateElement(nsAtom& aTag,
const EditorRawDOMPoint& aPointToInsert);
already_AddRefed<Element> CreateNode(nsAtom* aTag, nsINode* aParent,
int32_t aPosition,
nsIContent* aChildAtPosition = nullptr);
/**
* Create an element node whose name is aTag at before aPointToInsert. When
* this succeed to create an element node, this sets aPointToInsert to the
* new element because the relation of child and offset may be broken.
* If the caller needs to collapse the selection to next to the new element
* node, it should call |aPointToInsert.AdvanceOffset()| after calling this.
*
* @param aTag The element name to create.
* @param aPointToInsert The insertion point of new element. If this refers
* end of the container or after, the transaction
* will append the element to the container.
* Otherwise, will insert the element before the
* child node referred by this.
* @return The created new element node.
*/
already_AddRefed<Element> CreateNode(nsAtom* aTag,
EditorRawDOMPoint& aPointToInsert);
/**
* Create a transaction for inserting aNode as a child of aParent.

View File

@ -59,15 +59,16 @@ public:
aPointedNode && aPointedNode->IsContent() ?
aPointedNode->GetParentNode() : nullptr,
aPointedNode && aPointedNode->IsContent() ?
GetRef(aPointedNode->AsContent()) : nullptr)
GetRef(aPointedNode->GetParentNode(),
aPointedNode->AsContent()) : nullptr)
{
}
EditorDOMPointBase(nsINode* aConatiner,
EditorDOMPointBase(nsINode* aContainer,
nsIContent* aPointedNode,
int32_t aOffset)
: RangeBoundaryBase<ParentType, RefType>(aConatiner,
GetRef(aPointedNode),
: RangeBoundaryBase<ParentType, RefType>(aContainer,
GetRef(aContainer, aPointedNode),
aOffset)
{
}
@ -84,10 +85,18 @@ public:
}
private:
static nsIContent* GetRef(nsIContent* aPointedNode)
static nsIContent* GetRef(nsINode* aContainerNode, nsIContent* aPointedNode)
{
MOZ_ASSERT(aPointedNode);
return aPointedNode ? aPointedNode->GetPreviousSibling() : nullptr;
// If referring one of a child of the container, the 'ref' should be the
// previous sibling of the referring child.
if (aPointedNode) {
return aPointedNode->GetPreviousSibling();
}
// If referring after the last child, the 'ref' should be the last child.
if (aContainerNode && aContainerNode->IsContainerNode()) {
return aContainerNode->GetLastChild();
}
return nullptr;
}
};

View File

@ -3396,23 +3396,29 @@ HTMLEditRules::WillMakeList(Selection* aSelection,
address_of(child));
NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_STATE(mHTMLEditor);
nsCOMPtr<Element> theList =
mHTMLEditor->CreateNode(listType, container, offset, child);
EditorRawDOMPoint atListItemToInsertBefore(container, child, offset);
RefPtr<Element> theList =
mHTMLEditor->CreateNode(listType, atListItemToInsertBefore);
NS_ENSURE_STATE(theList);
NS_ENSURE_STATE(mHTMLEditor);
nsCOMPtr<Element> theListItem =
mHTMLEditor->CreateNode(itemType, theList, 0, theList->GetFirstChild());
EditorRawDOMPoint atFirstListItemToInsertBefore(theList, 0);
RefPtr<Element> theListItem =
mHTMLEditor->CreateNode(itemType, atFirstListItemToInsertBefore);
NS_ENSURE_STATE(theListItem);
// remember our new block for postprocessing
mNewBlock = theListItem;
// put selection in new list item
*aHandled = true;
rv = aSelection->Collapse(theListItem, 0);
ErrorResult error;
aSelection->Collapse(EditorRawDOMPoint(theListItem, 0), error);
// Don't restore the selection
selectionRestorer.Abort();
return rv;
if (NS_WARN_IF(!error.Failed())) {
return error.StealNSResult();
}
return NS_OK;
}
// if there is only one node in the array, and it is a list, div, or
@ -3498,13 +3504,9 @@ HTMLEditRules::WillMakeList(Selection* aSelection,
mHTMLEditor->SplitNode(*curParent->AsContent(), offset, rv);
NS_ENSURE_TRUE(!rv.Failed(), rv.StealNSResult());
newBlock = splitNode ? splitNode->AsElement() : nullptr;
int32_t offset;
nsCOMPtr<nsINode> parent = EditorBase::GetNodeLocation(curParent,
&offset);
NS_ENSURE_STATE(mHTMLEditor);
curList = mHTMLEditor->CreateNode(listType, parent, offset,
curParent ? curParent->AsContent()
: nullptr);
EditorRawDOMPoint atCurParent(curParent);
curList = mHTMLEditor->CreateNode(listType, atCurParent);
NS_ENSURE_STATE(curList);
}
// move list item to new list
@ -3575,8 +3577,8 @@ HTMLEditRules::WillMakeList(Selection* aSelection,
address_of(curChild));
NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_STATE(mHTMLEditor);
curList = mHTMLEditor->CreateNode(listType, curParent, offset,
curChild);
EditorRawDOMPoint atCurChild(curParent, curChild, offset);
curList = mHTMLEditor->CreateNode(listType, atCurChild);
// remember our new block for postprocessing
mNewBlock = curList;
// curList is now the correct thing to put curNode in
@ -3781,13 +3783,15 @@ HTMLEditRules::MakeBasicBlock(Selection& aSelection, nsAtom& blockType)
NS_ENSURE_SUCCESS(rv, rv);
// We don't need to act on this node any more
arrayOfNodes.RemoveElement(brNode);
child = nullptr;
// XXX We need to recompute child here because SplitAsNeeded() and
// EditorBase::SplitNodeDeep() don't compute child in some cases.
child = container->GetChildAt(offset);
}
// Make sure we can put a block here
rv = SplitAsNeeded(blockType, container, offset, address_of(child));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<Element> block =
htmlEditor->CreateNode(&blockType, container, offset, child);
EditorRawDOMPoint atChild(container, child, offset);
RefPtr<Element> block = htmlEditor->CreateNode(&blockType, atChild);
NS_ENSURE_STATE(block);
// Remember our new block for postprocessing
mNewBlock = block;
@ -3928,9 +3932,9 @@ HTMLEditRules::WillCSSIndent(Selection* aSelection,
rv = SplitAsNeeded(*nsGkAtoms::div, container, offset, address_of(child));
NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_STATE(mHTMLEditor);
nsCOMPtr<Element> theBlock = mHTMLEditor->CreateNode(nsGkAtoms::div,
container, offset,
child);
EditorRawDOMPoint atChild(container, child, offset);
RefPtr<Element> theBlock =
mHTMLEditor->CreateNode(nsGkAtoms::div, atChild);
NS_ENSURE_STATE(theBlock);
// remember our new block for postprocessing
mNewBlock = theBlock;
@ -3945,10 +3949,15 @@ HTMLEditRules::WillCSSIndent(Selection* aSelection,
}
// put selection in new block
*aHandled = true;
rv = aSelection->Collapse(theBlock, 0);
EditorRawDOMPoint atStartOfTheBlock(theBlock, 0);
ErrorResult error;
aSelection->Collapse(atStartOfTheBlock, error);
// Don't restore the selection
selectionRestorer.Abort();
return rv;
if (NS_WARN_IF(!error.Failed())) {
return error.StealNSResult();
}
return NS_OK;
}
// Ok, now go through all the nodes and put them in a blockquote,
@ -4025,8 +4034,9 @@ HTMLEditRules::WillCSSIndent(Selection* aSelection,
address_of(curChild));
NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_STATE(mHTMLEditor);
EditorRawDOMPoint atCurChild(curParent, curChild, offset);
curList = mHTMLEditor->CreateNode(curParent->NodeInfo()->NameAtom(),
curParent, offset, curChild);
atCurChild);
NS_ENSURE_STATE(curList);
// curList is now the correct thing to put curNode in
// remember our new block for postprocessing
@ -4058,8 +4068,8 @@ HTMLEditRules::WillCSSIndent(Selection* aSelection,
address_of(curChild));
NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_STATE(mHTMLEditor);
curQuote = mHTMLEditor->CreateNode(nsGkAtoms::div, curParent,
offset, curChild);
EditorRawDOMPoint atCurChild(curParent, curChild, offset);
curQuote = mHTMLEditor->CreateNode(nsGkAtoms::div, atCurChild);
NS_ENSURE_STATE(curQuote);
ChangeIndentation(*curQuote, Change::plus);
// remember our new block for postprocessing
@ -4127,9 +4137,9 @@ HTMLEditRules::WillHTMLIndent(Selection* aSelection,
address_of(child));
NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_STATE(mHTMLEditor);
nsCOMPtr<Element> theBlock = mHTMLEditor->CreateNode(nsGkAtoms::blockquote,
container, offset,
child);
EditorRawDOMPoint atChild(container, child, offset);
RefPtr<Element> theBlock =
mHTMLEditor->CreateNode(nsGkAtoms::blockquote, atChild);
NS_ENSURE_STATE(theBlock);
// remember our new block for postprocessing
mNewBlock = theBlock;
@ -4143,10 +4153,15 @@ HTMLEditRules::WillHTMLIndent(Selection* aSelection,
}
// put selection in new block
*aHandled = true;
rv = aSelection->Collapse(theBlock, 0);
EditorRawDOMPoint atStartOfTheBlock(theBlock, 0);
ErrorResult error;
aSelection->Collapse(atStartOfTheBlock, error);
// Don't restore the selection
selectionRestorer.Abort();
return rv;
if (NS_WARN_IF(!error.Failed())) {
return error.StealNSResult();
}
return NS_OK;
}
// Ok, now go through all the nodes and put them in a blockquote,
@ -4224,8 +4239,9 @@ HTMLEditRules::WillHTMLIndent(Selection* aSelection,
address_of(curChild));
NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_STATE(mHTMLEditor);
EditorRawDOMPoint atCurChild(curParent, curChild, offset);
curList = mHTMLEditor->CreateNode(curParent->NodeInfo()->NameAtom(),
curParent, offset, curChild);
atCurChild);
NS_ENSURE_STATE(curList);
// curList is now the correct thing to put curNode in
// remember our new block for postprocessing
@ -4269,8 +4285,9 @@ HTMLEditRules::WillHTMLIndent(Selection* aSelection,
offset, address_of(curChild));
NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_STATE(mHTMLEditor);
EditorRawDOMPoint atCurChild(curParent, curChild, offset);
curList = mHTMLEditor->CreateNode(curParent->NodeInfo()->NameAtom(),
curParent, offset, curChild);
atCurChild);
NS_ENSURE_STATE(curList);
}
NS_ENSURE_STATE(mHTMLEditor);
@ -4301,8 +4318,8 @@ HTMLEditRules::WillHTMLIndent(Selection* aSelection,
address_of(curChild));
NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_STATE(mHTMLEditor);
curQuote = mHTMLEditor->CreateNode(nsGkAtoms::blockquote, curParent,
offset, curChild);
EditorRawDOMPoint atCurChild(curParent, curChild, offset);
curQuote = mHTMLEditor->CreateNode(nsGkAtoms::blockquote, atCurChild);
NS_ENSURE_STATE(curQuote);
// remember our new block for postprocessing
mNewBlock = curQuote;
@ -4916,8 +4933,8 @@ HTMLEditRules::WillAlign(Selection& aSelection,
NS_ENSURE_SUCCESS(rv, rv);
}
}
nsCOMPtr<Element> div = htmlEditor->CreateNode(nsGkAtoms::div, parent,
offset, child);
EditorRawDOMPoint atChild(parent, child, offset);
RefPtr<Element> div = htmlEditor->CreateNode(nsGkAtoms::div, atChild);
NS_ENSURE_STATE(div);
// Remember our new block for postprocessing
mNewBlock = div;
@ -4928,10 +4945,14 @@ HTMLEditRules::WillAlign(Selection& aSelection,
// Put in a moz-br so that it won't get deleted
rv = CreateMozBR(div->AsDOMNode(), 0);
NS_ENSURE_SUCCESS(rv, rv);
rv = aSelection.Collapse(div, 0);
EditorRawDOMPoint atStartOfDiv(div, 0);
ErrorResult error;
aSelection.Collapse(atStartOfDiv, error);
// Don't restore the selection
selectionRestorer.Abort();
NS_ENSURE_SUCCESS(rv, rv);
if (NS_WARN_IF(error.Failed())) {
return error.StealNSResult();
}
return NS_OK;
}
@ -5022,8 +5043,8 @@ HTMLEditRules::WillAlign(Selection& aSelection,
rv = SplitAsNeeded(*nsGkAtoms::div, curParent, offset,
address_of(curChild));
NS_ENSURE_SUCCESS(rv, rv);
curDiv = htmlEditor->CreateNode(nsGkAtoms::div, curParent, offset,
curChild);
EditorRawDOMPoint atCurChild(curParent, curChild, offset);
curDiv = htmlEditor->CreateNode(nsGkAtoms::div, atCurChild);
NS_ENSURE_STATE(curDiv);
// Remember our new block for postprocessing
mNewBlock = curDiv;
@ -5099,8 +5120,9 @@ HTMLEditRules::AlignBlockContents(nsIDOMNode* aNode,
} else {
// else we need to put in a div, set the alignment, and toss in all the children
NS_ENSURE_STATE(mHTMLEditor);
RefPtr<Element> divElem = mHTMLEditor->CreateNode(nsGkAtoms::div, node, 0,
node->GetFirstChild());
EditorRawDOMPoint atStartOfNode(node, 0);
RefPtr<Element> divElem =
mHTMLEditor->CreateNode(nsGkAtoms::div, atStartOfNode);
NS_ENSURE_STATE(divElem);
// set up the alignment on the div
NS_ENSURE_STATE(mHTMLEditor);
@ -6618,10 +6640,11 @@ HTMLEditRules::ReturnInHeader(Selection& aSelection,
// Create a paragraph
nsAtom& paraAtom = DefaultParagraphSeparator();
// We want a wrapper element even if we separate with <br>
nsCOMPtr<Element> pNode =
htmlEditor->CreateNode(&paraAtom == nsGkAtoms::br ? nsGkAtoms::p
: &paraAtom,
headerParent, offset + 1);
EditorRawDOMPoint nextToHeader(headerParent, offset + 1);
RefPtr<Element> pNode =
htmlEditor->CreateNode(&paraAtom == nsGkAtoms::br ?
nsGkAtoms::p : &paraAtom,
nextToHeader);
NS_ENSURE_STATE(pNode);
// Append a <br> to it
@ -6899,10 +6922,11 @@ HTMLEditRules::ReturnInListItem(Selection& aSelection,
// Time to insert a paragraph
nsAtom& paraAtom = DefaultParagraphSeparator();
// We want a wrapper even if we separate with <br>
nsCOMPtr<Element> pNode =
htmlEditor->CreateNode(&paraAtom == nsGkAtoms::br ? nsGkAtoms::p
: &paraAtom,
listParent, offset + 1);
EditorRawDOMPoint atNextListItem(listParent, offset + 1);
RefPtr<Element> pNode =
htmlEditor->CreateNode(&paraAtom == nsGkAtoms::br ?
nsGkAtoms::p : &paraAtom,
atNextListItem);
NS_ENSURE_STATE(pNode);
// Append a <br> to it
@ -6948,9 +6972,11 @@ HTMLEditRules::ReturnInListItem(Selection& aSelection,
nsAtom* listAtom = nodeAtom == nsGkAtoms::dt ? nsGkAtoms::dd
: nsGkAtoms::dt;
nsCOMPtr<Element> newListItem =
htmlEditor->CreateNode(listAtom, list, itemOffset + 1,
aListItem.GetNextSibling());
MOZ_DIAGNOSTIC_ASSERT(itemOffset != -1);
EditorRawDOMPoint atNextListItem(list, aListItem.GetNextSibling(),
itemOffset + 1);
RefPtr<Element> newListItem =
htmlEditor->CreateNode(listAtom, atNextListItem);
NS_ENSURE_STATE(newListItem);
rv = htmlEditor->DeleteNode(&aListItem);
NS_ENSURE_SUCCESS(rv, rv);
@ -7053,8 +7079,8 @@ HTMLEditRules::MakeBlockquote(nsTArray<OwningNonNull<nsINode>>& aNodeArray)
address_of(curChild));
NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_STATE(mHTMLEditor);
curBlock = mHTMLEditor->CreateNode(nsGkAtoms::blockquote, curParent,
offset, curChild);
EditorRawDOMPoint atCurChild(curParent, curChild, offset);
curBlock = mHTMLEditor->CreateNode(nsGkAtoms::blockquote, atCurChild);
NS_ENSURE_STATE(curBlock);
// remember our new block for postprocessing
mNewBlock = curBlock;
@ -7223,9 +7249,9 @@ HTMLEditRules::ApplyBlockStyle(nsTArray<OwningNonNull<nsINode>>& aNodeArray,
nsresult rv = SplitAsNeeded(aBlockTag, curParent, offset,
address_of(curChild));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<Element> theBlock =
htmlEditor->CreateNode(&aBlockTag, curParent, offset,
curChild);
EditorRawDOMPoint atCurChild(curParent, curChild, offset);
RefPtr<Element> theBlock =
htmlEditor->CreateNode(&aBlockTag, atCurChild);
NS_ENSURE_STATE(theBlock);
// Remember our new block for postprocessing
mNewBlock = theBlock;
@ -7245,8 +7271,8 @@ HTMLEditRules::ApplyBlockStyle(nsTArray<OwningNonNull<nsINode>>& aNodeArray,
nsresult rv = SplitAsNeeded(aBlockTag, curParent, offset,
address_of(curChild));
NS_ENSURE_SUCCESS(rv, rv);
curBlock = htmlEditor->CreateNode(&aBlockTag, curParent, offset,
curChild);
EditorRawDOMPoint atCurChild(curParent, curChild, offset);
curBlock = htmlEditor->CreateNode(&aBlockTag, atCurChild);
NS_ENSURE_STATE(curBlock);
// Remember our new block for postprocessing
mNewBlock = curBlock;
@ -7273,8 +7299,8 @@ HTMLEditRules::ApplyBlockStyle(nsTArray<OwningNonNull<nsINode>>& aNodeArray,
nsresult rv = SplitAsNeeded(aBlockTag, curParent, offset,
address_of(curChild));
NS_ENSURE_SUCCESS(rv, rv);
curBlock = htmlEditor->CreateNode(&aBlockTag, curParent, offset,
curChild);
EditorRawDOMPoint atCurChild(curParent, curChild, offset);
curBlock = htmlEditor->CreateNode(&aBlockTag, atCurChild);
NS_ENSURE_STATE(curBlock);
// Remember our new block for postprocessing
mNewBlock = curBlock;
@ -9025,8 +9051,9 @@ HTMLEditRules::WillAbsolutePosition(Selection& aSelection,
rv = SplitAsNeeded(*nsGkAtoms::div, parent, offset,
address_of(child));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<Element> positionedDiv =
htmlEditor->CreateNode(nsGkAtoms::div, parent, offset, child);
EditorRawDOMPoint atChild(parent, child, offset);
RefPtr<Element> positionedDiv =
htmlEditor->CreateNode(nsGkAtoms::div, atChild);
NS_ENSURE_STATE(positionedDiv);
// Remember our new block for postprocessing
mNewBlock = positionedDiv;
@ -9081,16 +9108,15 @@ HTMLEditRules::WillAbsolutePosition(Selection& aSelection,
SplitAsNeeded(*curParent->NodeInfo()->NameAtom(), curParent, offset);
NS_ENSURE_SUCCESS(rv, rv);
if (!curPositionedDiv) {
nsCOMPtr<nsINode> curParentParent = curParent->GetParentNode();
int32_t parentOffset = curParentParent
? curParentParent->IndexOf(curParent) : -1;
curPositionedDiv = htmlEditor->CreateNode(nsGkAtoms::div, curParentParent,
parentOffset);
EditorRawDOMPoint atCurParent(curParent);
curPositionedDiv =
htmlEditor->CreateNode(nsGkAtoms::div, atCurParent);
mNewBlock = curPositionedDiv;
}
EditorRawDOMPoint atEndOfCurPositionedDiv(curPositionedDiv,
curPositionedDiv->Length());
curList = htmlEditor->CreateNode(curParent->NodeInfo()->NameAtom(),
curPositionedDiv, -1,
curPositionedDiv->GetLastChild());
atEndOfCurPositionedDiv);
NS_ENSURE_STATE(curList);
// curList is now the correct thing to put curNode in. Remember our
// new block for postprocessing.
@ -9125,18 +9151,15 @@ HTMLEditRules::WillAbsolutePosition(Selection& aSelection,
offset);
NS_ENSURE_SUCCESS(rv, rv);
if (!curPositionedDiv) {
nsCOMPtr<nsINode> curParentParent = curParent->GetParentNode();
int32_t parentOffset = curParentParent ?
curParentParent->IndexOf(curParent) : -1;
curPositionedDiv = htmlEditor->CreateNode(nsGkAtoms::div,
curParentParent,
parentOffset,
curParent->AsContent());
EditorRawDOMPoint atCurParent(curParent);
curPositionedDiv =
htmlEditor->CreateNode(nsGkAtoms::div, atCurParent);
mNewBlock = curPositionedDiv;
}
EditorRawDOMPoint atEndOfCurPositionedDiv(curPositionedDiv,
curPositionedDiv->Length());
curList = htmlEditor->CreateNode(curParent->NodeInfo()->NameAtom(),
curPositionedDiv, -1,
curPositionedDiv->GetLastChild());
atEndOfCurPositionedDiv);
NS_ENSURE_STATE(curList);
}
rv = htmlEditor->MoveNode(listItem, curList, -1);
@ -9157,8 +9180,8 @@ HTMLEditRules::WillAbsolutePosition(Selection& aSelection,
rv = SplitAsNeeded(*nsGkAtoms::div, curParent, offset,
address_of(curChild));
NS_ENSURE_SUCCESS(rv, rv);
curPositionedDiv = htmlEditor->CreateNode(nsGkAtoms::div, curParent,
offset, curChild);
EditorRawDOMPoint atCurChild(curParent, curChild, offset);
curPositionedDiv = htmlEditor->CreateNode(nsGkAtoms::div, atCurChild);
NS_ENSURE_STATE(curPositionedDiv);
// Remember our new block for postprocessing
mNewBlock = curPositionedDiv;

View File

@ -6,6 +6,7 @@
#include "mozilla/HTMLEditor.h"
#include "mozilla/DebugOnly.h"
#include "mozilla/EditorDOMPoint.h"
#include "mozilla/EventStates.h"
#include "mozilla/TextEvents.h"
@ -2021,11 +2022,13 @@ HTMLEditor::MakeOrChangeList(const nsAString& aListType,
}
// make a list
nsCOMPtr<Element> newList = CreateNode(listAtom, parent, offset, child);
MOZ_DIAGNOSTIC_ASSERT(child);
EditorRawDOMPoint atChild(parent, child, offset);
RefPtr<Element> newList = CreateNode(listAtom, atChild);
NS_ENSURE_STATE(newList);
// make a list item
nsCOMPtr<Element> newItem = CreateNode(nsGkAtoms::li, newList, 0,
newList->GetFirstChild());
EditorRawDOMPoint atStartOfNewList(newList, 0);
RefPtr<Element> newItem = CreateNode(nsGkAtoms::li, atStartOfNewList);
NS_ENSURE_STATE(newItem);
rv = selection->Collapse(newItem, 0);
NS_ENSURE_SUCCESS(rv, rv);
@ -2164,7 +2167,9 @@ HTMLEditor::InsertBasicBlock(const nsAString& aBlockType)
}
// make a block
nsCOMPtr<Element> newBlock = CreateNode(blockAtom, parent, offset, child);
MOZ_DIAGNOSTIC_ASSERT(child);
EditorRawDOMPoint atChild(parent, child, offset);
RefPtr<Element> newBlock = CreateNode(blockAtom, atChild);
NS_ENSURE_STATE(newBlock);
// reposition selection to inside the block
@ -2238,8 +2243,9 @@ HTMLEditor::Indent(const nsAString& aIndent)
}
// make a blockquote
nsCOMPtr<Element> newBQ =
CreateNode(nsGkAtoms::blockquote, parent, offset, child);
MOZ_DIAGNOSTIC_ASSERT(child);
EditorRawDOMPoint atChild(parent, child, offset);
RefPtr<Element> newBQ = CreateNode(nsGkAtoms::blockquote, atChild);
NS_ENSURE_STATE(newBQ);
// put a space in it so layout will draw the list item
rv = selection->Collapse(newBQ, 0);
@ -4532,9 +4538,9 @@ HTMLEditor::CopyLastEditableChildStyles(nsINode* aPreviousBlock,
childElement->NodeInfo()->NameAtom());
NS_ENSURE_STATE(newStyles);
} else {
EditorRawDOMPoint atStartOfNewBlock(newBlock, 0);
deepestStyle = newStyles =
CreateNode(childElement->NodeInfo()->NameAtom(), newBlock, 0,
newBlock->GetFirstChild());
CreateNode(childElement->NodeInfo()->NameAtom(), atStartOfNewBlock);
NS_ENSURE_STATE(newStyles);
}
CloneAttributes(newStyles, childElement);

View File

@ -242,7 +242,8 @@ TextEditor::SetDocumentCharacterSet(const nsACString& characterSet)
}
// Create a new meta charset tag
RefPtr<Element> metaElement = CreateNode(nsGkAtoms::meta, headNode, 0);
EditorRawDOMPoint atStartOfHeadNode(headNode, 0);
RefPtr<Element> metaElement = CreateNode(nsGkAtoms::meta, atStartOfHeadNode);
if (NS_WARN_IF(!metaElement)) {
return NS_OK;
}
@ -443,14 +444,15 @@ TextEditor::CreateBRImpl(nsCOMPtr<nsIDOMNode>* aInOutParent,
int32_t theOffset = *aInOutOffset;
RefPtr<Element> brNode;
if (IsTextNode(node)) {
int32_t offset;
nsCOMPtr<nsINode> tmp = GetNodeLocation(node, &offset);
NS_ENSURE_TRUE(tmp, NS_ERROR_FAILURE);
EditorRawDOMPoint atNode(node);
if (NS_WARN_IF(!atNode.IsSetAndValid())) {
return NS_ERROR_FAILURE;
}
if (!theOffset) {
// we are already set to go
} else if (theOffset == static_cast<int32_t>(node->Length())) {
// update offset to point AFTER the text node
offset++;
atNode.AdvanceOffset();
} else {
// split the text node
ErrorResult rv;
@ -458,17 +460,19 @@ TextEditor::CreateBRImpl(nsCOMPtr<nsIDOMNode>* aInOutParent,
if (NS_WARN_IF(rv.Failed())) {
return rv.StealNSResult();
}
tmp = GetNodeLocation(node, &offset);
atNode.Clear();
atNode.Set(node);
}
// create br
brNode = CreateNode(nsGkAtoms::br, tmp, offset);
brNode = CreateNode(nsGkAtoms::br, atNode);
if (NS_WARN_IF(!brNode)) {
return NS_ERROR_FAILURE;
}
*aInOutParent = GetAsDOMNode(tmp);
*aInOutOffset = offset+1;
*aInOutParent = GetAsDOMNode(atNode.Container());
*aInOutOffset = atNode.Offset() + 1;
} else {
brNode = CreateNode(nsGkAtoms::br, node, theOffset);
EditorRawDOMPoint atTheOffset(node, theOffset);
brNode = CreateNode(nsGkAtoms::br, atTheOffset);
if (NS_WARN_IF(!brNode)) {
return NS_ERROR_FAILURE;
}