Bug 1436216 - EditorBase::CreateElement() should call RangeUpdater::SelAdjCreateNode() with point of new element r?m_kato
Before
bug 1425091, we called RangeUpdater::SelAdjCreateNode() with point of
new node in EditorBase::CreateElement(). However, it was accidentally changed
to point *in* new element. Therefore, setting such DOM point causes warnings
in debug build and call of RangeUpdater::SelAdjCreateNode() must be failed
since the point stores wrong container node.
Additionally, this patch stops using another EditorRawDOMPoint instance which
is just redundant and renames |ret| to |newElement| for making its meaning
clearer.
MozReview-Commit-ID: Gc0YgaNLYcx
--- a/editor/libeditor/EditorBase.cpp
+++ b/editor/libeditor/EditorBase.cpp
@@ -1448,55 +1448,60 @@ EditorBase::SetSpellcheckUserOverride(bo
already_AddRefed<Element>
EditorBase::CreateNode(nsAtom* aTag,
const EditorRawDOMPoint& aPointToInsert)
{
MOZ_ASSERT(aTag);
MOZ_ASSERT(aPointToInsert.IsSetAndValid());
- EditorRawDOMPoint pointToInsert(aPointToInsert);
-
// XXX We need offset at new node for 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());
+ Unused << aPointToInsert.Offset();
AutoRules beginRulesSniffing(this, EditAction::createNode, nsIEditor::eNext);
- nsCOMPtr<Element> ret;
+ RefPtr<Element> newElement;
RefPtr<CreateElementTransaction> transaction =
- CreateElementTransaction::Create(*this, *aTag, pointToInsert);
+ CreateElementTransaction::Create(*this, *aTag, aPointToInsert);
nsresult rv = DoTransaction(transaction);
- if (NS_SUCCEEDED(rv)) {
- ret = transaction->GetNewNode();
- MOZ_ASSERT(ret);
- // Now, aPointToInsert may be invalid. I.e., GetChild() keeps
- // referring the next sibling of new node but Offset() refers the
- // new node. Let's make refer the new node.
- pointToInsert.Set(ret, offset);
- }
-
- mRangeUpdater.SelAdjCreateNode(pointToInsert.AsRaw());
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ // XXX Why do we do this even when DoTransaction() returned error?
+ mRangeUpdater.SelAdjCreateNode(aPointToInsert);
+ } else {
+ newElement = transaction->GetNewNode();
+ MOZ_ASSERT(newElement);
+
+ // If we succeeded to create and insert new element, we need to adjust
+ // ranges in mRangeUpdater. It currently requires offset of the new node.
+ // So, let's call it with original offset. Note that if aPointToInsert
+ // stores child node, it may not be at the offset since new element must
+ // be inserted before the old child. Although, mutation observer can do
+ // anything, but currently, we don't check it.
+ mRangeUpdater.SelAdjCreateNode(
+ EditorRawDOMPoint(aPointToInsert.GetContainer(),
+ aPointToInsert.Offset()));
+ }
if (mRules && mRules->AsHTMLEditRules()) {
RefPtr<HTMLEditRules> htmlEditRules = mRules->AsHTMLEditRules();
- htmlEditRules->DidCreateNode(ret);
+ htmlEditRules->DidCreateNode(newElement);
}
if (!mActionListeners.IsEmpty()) {
AutoActionListenerArray listeners(mActionListeners);
for (auto& listener : listeners) {
listener->DidCreateNode(nsDependentAtomString(aTag),
- GetAsDOMNode(ret), rv);
+ GetAsDOMNode(newElement), rv);
}
}
- return ret.forget();
+ return newElement.forget();
}
NS_IMETHODIMP
EditorBase::InsertNode(nsIDOMNode* aNodeToInsert,
nsIDOMNode* aContainer,
int32_t aOffset)
{
nsCOMPtr<nsIContent> contentToInsert = do_QueryInterface(aNodeToInsert);