Bug 1791224 - Use CreateNodeResultBase as the ok type of mozilla::Result r=m_kato

Similar to the previous patch, this changes a lot of lines.  However, I think
that it's not so hard to investigate regression point in this patch because
`CreateNodeResultBase` is not used so many times at handling on edit action.

Differential Revision: https://phabricator.services.mozilla.com/D157575
This commit is contained in:
Masayuki Nakano 2022-09-27 05:12:05 +00:00
parent 4e978b56b5
commit 6513faf43f
13 changed files with 1125 additions and 953 deletions

View file

@ -149,12 +149,15 @@ template EditorRawDOMPoint EditorBase::GetFirstIMESelectionStartPoint() const;
template EditorDOMPoint EditorBase::GetLastIMESelectionEndPoint() const;
template EditorRawDOMPoint EditorBase::GetLastIMESelectionEndPoint() const;
template CreateContentResult EditorBase::InsertNodeWithTransaction(
nsIContent& aContentToInsert, const EditorDOMPoint& aPointToInsert);
template CreateElementResult EditorBase::InsertNodeWithTransaction(
Element& aContentToInsert, const EditorDOMPoint& aPointToInsert);
template CreateTextResult EditorBase::InsertNodeWithTransaction(
Text& aContentToInsert, const EditorDOMPoint& aPointToInsert);
template Result<CreateContentResult, nsresult>
EditorBase::InsertNodeWithTransaction(nsIContent& aContentToInsert,
const EditorDOMPoint& aPointToInsert);
template Result<CreateElementResult, nsresult>
EditorBase::InsertNodeWithTransaction(Element& aContentToInsert,
const EditorDOMPoint& aPointToInsert);
template Result<CreateTextResult, nsresult>
EditorBase::InsertNodeWithTransaction(Text& aContentToInsert,
const EditorDOMPoint& aPointToInsert);
template EditorDOMPoint EditorBase::GetFirstSelectionStartPoint() const;
template EditorRawDOMPoint EditorBase::GetFirstSelectionStartPoint() const;
@ -1964,13 +1967,14 @@ NS_IMETHODIMP EditorBase::InsertNode(nsINode* aNodeToInsert,
}
const uint32_t offset = std::min(aOffset, aContainer->Length());
CreateContentResult insertContentResult = InsertNodeWithTransaction(
*contentToInsert, EditorDOMPoint(aContainer, offset));
if (insertContentResult.isErr()) {
Result<CreateContentResult, nsresult> insertContentResult =
InsertNodeWithTransaction(*contentToInsert,
EditorDOMPoint(aContainer, offset));
if (MOZ_UNLIKELY(insertContentResult.isErr())) {
NS_WARNING("EditorBase::InsertNodeWithTransaction() failed");
return EditorBase::ToGenericNSResult(insertContentResult.unwrapErr());
}
rv = insertContentResult.SuggestCaretPointTo(
rv = insertContentResult.inspect().SuggestCaretPointTo(
*this, {SuggestCaret::OnlyIfHasSuggestion,
SuggestCaret::OnlyIfTransactionsAllowedToDoIt,
SuggestCaret::AndIgnoreTrivialError});
@ -1985,15 +1989,14 @@ NS_IMETHODIMP EditorBase::InsertNode(nsINode* aNodeToInsert,
}
template <typename ContentNodeType>
CreateNodeResultBase<ContentNodeType> EditorBase::InsertNodeWithTransaction(
ContentNodeType& aContentToInsert, const EditorDOMPoint& aPointToInsert) {
Result<CreateNodeResultBase<ContentNodeType>, nsresult>
EditorBase::InsertNodeWithTransaction(ContentNodeType& aContentToInsert,
const EditorDOMPoint& aPointToInsert) {
MOZ_ASSERT(IsEditActionDataAvailable());
MOZ_ASSERT_IF(IsTextEditor(), !aContentToInsert.IsText());
using ResultType = CreateNodeResultBase<ContentNodeType>;
if (NS_WARN_IF(!aPointToInsert.IsSet())) {
return ResultType(NS_ERROR_INVALID_ARG);
return Err(NS_ERROR_INVALID_ARG);
}
MOZ_ASSERT(aPointToInsert.IsSetAndValid());
@ -2001,7 +2004,7 @@ CreateNodeResultBase<ContentNodeType> EditorBase::InsertNodeWithTransaction(
AutoEditSubActionNotifier startToHandleEditSubAction(
*this, EditSubAction::eInsertNode, nsIEditor::eNext, ignoredError);
if (NS_WARN_IF(ignoredError.ErrorCodeIs(NS_ERROR_EDITOR_DESTROYED))) {
return ResultType(ignoredError.StealNSResult());
return Err(ignoredError.StealNSResult());
}
NS_WARNING_ASSERTION(
!ignoredError.Failed(),
@ -2023,24 +2026,24 @@ CreateNodeResultBase<ContentNodeType> EditorBase::InsertNodeWithTransaction(
}
if (NS_WARN_IF(Destroyed())) {
return ResultType(NS_ERROR_EDITOR_DESTROYED);
return Err(NS_ERROR_EDITOR_DESTROYED);
}
if (NS_FAILED(rv)) {
return ResultType(rv);
return Err(rv);
}
return ResultType(&aContentToInsert,
transaction->SuggestPointToPutCaret<EditorDOMPoint>());
return CreateNodeResultBase<ContentNodeType>(
&aContentToInsert, transaction->SuggestPointToPutCaret<EditorDOMPoint>());
}
CreateElementResult
Result<CreateElementResult, nsresult>
EditorBase::InsertPaddingBRElementForEmptyLastLineWithTransaction(
const EditorDOMPoint& aPointToInsert) {
MOZ_ASSERT(IsEditActionDataAvailable());
MOZ_ASSERT(IsHTMLEditor() || !aPointToInsert.IsInTextNode());
if (MOZ_UNLIKELY(!aPointToInsert.IsSet())) {
return CreateElementResult(NS_ERROR_FAILURE);
return Err(NS_ERROR_FAILURE);
}
EditorDOMPoint pointToInsert;
@ -2050,7 +2053,7 @@ EditorBase::InsertPaddingBRElementForEmptyLastLineWithTransaction(
Result<EditorDOMPoint, nsresult> maybePointToInsert =
MOZ_KnownLive(AsHTMLEditor())->PrepareToInsertBRElement(aPointToInsert);
if (maybePointToInsert.isErr()) {
return CreateElementResult(maybePointToInsert.unwrapErr());
return maybePointToInsert.propagateErr();
}
MOZ_ASSERT(maybePointToInsert.inspect().IsSetAndValid());
pointToInsert = maybePointToInsert.unwrap();
@ -2058,11 +2061,11 @@ EditorBase::InsertPaddingBRElementForEmptyLastLineWithTransaction(
RefPtr<Element> newBRElement = CreateHTMLContent(nsGkAtoms::br);
if (NS_WARN_IF(!newBRElement)) {
return CreateElementResult(NS_ERROR_FAILURE);
return Err(NS_ERROR_FAILURE);
}
newBRElement->SetFlags(NS_PADDING_FOR_EMPTY_LAST_LINE);
CreateElementResult insertBRElementResult =
Result<CreateElementResult, nsresult> insertBRElementResult =
InsertNodeWithTransaction<Element>(*newBRElement, pointToInsert);
NS_WARNING_ASSERTION(insertBRElementResult.isOk(),
"EditorBase::InsertNodeWithTransaction() failed");
@ -2779,13 +2782,13 @@ Result<EditorDOMPoint, nsresult> EditorBase::InsertTextWithTransaction(
return Err(NS_ERROR_FAILURE);
}
// then we insert it into the dom tree
CreateTextResult insertTextNodeResult =
Result<CreateTextResult, nsresult> insertTextNodeResult =
InsertNodeWithTransaction<Text>(*newTextNode, pointToInsert);
if (insertTextNodeResult.isErr()) {
if (MOZ_UNLIKELY(insertTextNodeResult.isErr())) {
NS_WARNING("EditorBase::InsertNodeWithTransaction() failed");
return Err(insertTextNodeResult.unwrapErr());
return insertTextNodeResult.propagateErr();
}
nsresult rv = insertTextNodeResult.SuggestCaretPointTo(
nsresult rv = insertTextNodeResult.inspect().SuggestCaretPointTo(
*this, {SuggestCaret::OnlyIfHasSuggestion,
SuggestCaret::OnlyIfTransactionsAllowedToDoIt,
SuggestCaret::AndIgnoreTrivialError});
@ -2850,13 +2853,13 @@ Result<EditorDOMPoint, nsresult> EditorBase::InsertTextWithTransaction(
return Err(NS_ERROR_FAILURE);
}
// then we insert it into the dom tree
CreateTextResult insertTextNodeResult =
Result<CreateTextResult, nsresult> insertTextNodeResult =
InsertNodeWithTransaction<Text>(*newTextNode, pointToInsert);
if (insertTextNodeResult.isErr()) {
if (MOZ_UNLIKELY(insertTextNodeResult.isErr())) {
NS_WARNING("EditorBase::InsertNodeWithTransaction() failed");
return Err(insertTextNodeResult.unwrapErr());
}
nsresult rv = insertTextNodeResult.SuggestCaretPointTo(
nsresult rv = insertTextNodeResult.inspect().SuggestCaretPointTo(
*this, {SuggestCaret::OnlyIfHasSuggestion,
SuggestCaret::OnlyIfTransactionsAllowedToDoIt,
SuggestCaret::AndIgnoreTrivialError});
@ -2867,7 +2870,7 @@ Result<EditorDOMPoint, nsresult> EditorBase::InsertTextWithTransaction(
NS_WARNING_ASSERTION(
rv != NS_SUCCESS_EDITOR_BUT_IGNORED_TRIVIAL_ERROR,
"CreateTextResult::SuggestCaretPointTo() failed, but ignored");
return EditorDOMPoint(insertTextNodeResult.UnwrapNewNode(),
return EditorDOMPoint(insertTextNodeResult.inspect().GetNewNode(),
aStringToInsert.Length());
}
@ -3358,16 +3361,16 @@ nsresult EditorBase::EnsurePaddingBRElementInMultilineEditor() {
AutoTransactionsConserveSelection dontChangeMySelection(*this);
EditorDOMPoint endOfAnonymousDiv(
EditorDOMPoint::AtEndOf(*anonymousDivOrBodyElement));
CreateElementResult insertPaddingBRElementResult =
Result<CreateElementResult, nsresult> insertPaddingBRElementResult =
InsertPaddingBRElementForEmptyLastLineWithTransaction(
endOfAnonymousDiv);
if (insertPaddingBRElementResult.isErr()) {
if (MOZ_UNLIKELY(insertPaddingBRElementResult.isErr())) {
NS_WARNING(
"EditorBase::InsertPaddingBRElementForEmptyLastLineWithTransaction() "
"failed");
return insertPaddingBRElementResult.unwrapErr();
}
insertPaddingBRElementResult.IgnoreCaretPointSuggestion();
insertPaddingBRElementResult.inspect().IgnoreCaretPointSuggestion();
return NS_OK;
}

View file

@ -1718,7 +1718,8 @@ class EditorBase : public nsIEditor,
* point to put caret.
*/
template <typename ContentNodeType>
[[nodiscard]] MOZ_CAN_RUN_SCRIPT CreateNodeResultBase<ContentNodeType>
[[nodiscard]] MOZ_CAN_RUN_SCRIPT
Result<CreateNodeResultBase<ContentNodeType>, nsresult>
InsertNodeWithTransaction(ContentNodeType& aContentToInsert,
const EditorDOMPoint& aPointToInsert);
@ -1732,7 +1733,7 @@ class EditorBase : public nsIEditor,
* @return If succeeded, returns the new <br> element and
* point to put caret around it.
*/
[[nodiscard]] MOZ_CAN_RUN_SCRIPT CreateElementResult
[[nodiscard]] MOZ_CAN_RUN_SCRIPT Result<CreateElementResult, nsresult>
InsertPaddingBRElementForEmptyLastLineWithTransaction(
const EditorDOMPoint& aPointToInsert);

View file

@ -162,31 +162,12 @@ enum class SuggestCaret {
AndIgnoreTrivialError,
};
// TODO: Perhaps, we can make this inherits mozilla::Result for guaranteeing
// same API. Then, changing to/from Result<*, nsresult> can be easier.
// For now, we should give same API name rather than same as
// mozilla::ErrorResult.
template <typename NodeType>
class MOZ_STACK_CLASS CreateNodeResultBase final {
typedef CreateNodeResultBase<NodeType> SelfType;
using SelfType = CreateNodeResultBase<NodeType>;
public:
// FYI: NS_SUCCEEDED and NS_FAILED contain MOZ_(UN)LIKELY so that isOk() and
// isErr() must not required to wrap with them.
bool isOk() const { return NS_SUCCEEDED(mRv); }
bool isErr() const { return NS_FAILED(mRv); }
bool Handled() const {
MOZ_ASSERT_IF(mRv == NS_SUCCESS_DOM_NO_OPERATION, !mNode);
return isOk() && mRv == NS_SUCCESS_DOM_NO_OPERATION;
}
constexpr nsresult inspectErr() const { return mRv; }
constexpr nsresult unwrapErr() const { return inspectErr(); }
constexpr bool EditorDestroyed() const {
return MOZ_UNLIKELY(mRv == NS_ERROR_EDITOR_DESTROYED);
}
constexpr bool GotUnexpectedDOMTree() const {
return MOZ_UNLIKELY(mRv == NS_ERROR_EDITOR_UNEXPECTED_DOM_TREE);
}
bool Handled() const { return mNode; }
NodeType* GetNewNode() const { return mNode; }
RefPtr<NodeType> UnwrapNewNode() { return std::move(mNode); }
@ -223,72 +204,56 @@ class MOZ_STACK_CLASS CreateNodeResultBase final {
const EditorBase& aEditorBase,
const SuggestCaretOptions& aOptions);
explicit CreateNodeResultBase(nsresult aRv) : mRv(aRv) {
MOZ_DIAGNOSTIC_ASSERT(NS_FAILED(mRv));
}
explicit CreateNodeResultBase(NodeType* aNode)
: mNode(aNode), mRv(aNode ? NS_OK : NS_ERROR_FAILURE) {}
explicit CreateNodeResultBase(NodeType* aNode,
explicit CreateNodeResultBase(NodeType& aNode) : mNode(&aNode) {}
explicit CreateNodeResultBase(NodeType& aNode,
const EditorDOMPoint& aCandidateCaretPoint)
: mNode(aNode),
mCaretPoint(aCandidateCaretPoint),
mRv(aNode ? NS_OK : NS_ERROR_FAILURE) {}
explicit CreateNodeResultBase(NodeType* aNode,
: mNode(&aNode), mCaretPoint(aCandidateCaretPoint) {}
explicit CreateNodeResultBase(NodeType& aNode,
EditorDOMPoint&& aCandidateCaretPoint)
: mNode(aNode),
mCaretPoint(std::move(aCandidateCaretPoint)),
mRv(aNode ? NS_OK : NS_ERROR_FAILURE) {}
: mNode(&aNode), mCaretPoint(std::move(aCandidateCaretPoint)) {}
explicit CreateNodeResultBase(RefPtr<NodeType>&& aNode)
: mNode(std::move(aNode)), mRv(mNode.get() ? NS_OK : NS_ERROR_FAILURE) {}
: mNode(std::move(aNode)) {}
explicit CreateNodeResultBase(RefPtr<NodeType>&& aNode,
const EditorDOMPoint& aCandidateCaretPoint)
: mNode(std::move(aNode)),
mCaretPoint(aCandidateCaretPoint),
mRv(mNode.get() ? NS_OK : NS_ERROR_FAILURE) {}
: mNode(std::move(aNode)), mCaretPoint(aCandidateCaretPoint) {
MOZ_ASSERT(mNode);
}
explicit CreateNodeResultBase(RefPtr<NodeType>&& aNode,
EditorDOMPoint&& aCandidateCaretPoint)
: mNode(std::move(aNode)),
mCaretPoint(std::move(aCandidateCaretPoint)),
mRv(mNode.get() ? NS_OK : NS_ERROR_FAILURE) {}
[[nodiscard]] static SelfType NotHandled() {
SelfType result;
result.mRv = NS_SUCCESS_DOM_NO_OPERATION;
return result;
: mNode(std::move(aNode)), mCaretPoint(std::move(aCandidateCaretPoint)) {
MOZ_ASSERT(mNode);
}
[[nodiscard]] static SelfType NotHandled() { return SelfType(); }
[[nodiscard]] static SelfType NotHandled(
const EditorDOMPoint& aPointToPutCaret) {
SelfType result;
result.mRv = NS_SUCCESS_DOM_NO_OPERATION;
result.mCaretPoint = aPointToPutCaret;
return result;
}
[[nodiscard]] static SelfType NotHandled(EditorDOMPoint&& aPointToPutCaret) {
SelfType result;
result.mRv = NS_SUCCESS_DOM_NO_OPERATION;
result.mCaretPoint = std::move(aPointToPutCaret);
return result;
}
#ifdef DEBUG
~CreateNodeResultBase() {
MOZ_ASSERT_IF(isOk(), !mCaretPoint.IsSet() || mHandledCaretPoint);
MOZ_ASSERT(!mCaretPoint.IsSet() || mHandledCaretPoint);
}
#endif
CreateNodeResultBase(const SelfType& aOther) = delete;
SelfType& operator=(const SelfType& aOther) = delete;
CreateNodeResultBase(SelfType&& aOther) = default;
SelfType& operator=(SelfType&& aOther) = default;
CreateNodeResultBase(SelfType&& aOther) noexcept = default;
SelfType& operator=(SelfType&& aOther) noexcept = default;
private:
CreateNodeResultBase() = default;
RefPtr<NodeType> mNode;
EditorDOMPoint mCaretPoint;
nsresult mRv = NS_OK;
bool mutable mHandledCaretPoint = false;
};

View file

@ -698,19 +698,19 @@ nsresult HTMLEditor::SetPositionToAbsolute(Element& aElement) {
if (parentNode->GetChildCount() != 1) {
return NS_OK;
}
CreateElementResult insertBRElementResult =
Result<CreateElementResult, nsresult> insertBRElementResult =
InsertBRElement(WithTransaction::Yes, EditorDOMPoint(parentNode, 0u));
if (insertBRElementResult.isErr()) {
if (MOZ_UNLIKELY(insertBRElementResult.isErr())) {
NS_WARNING("HTMLEditor::InsertBRElement(WithTransaction::Yes) failed");
return insertBRElementResult.unwrapErr();
}
// XXX Is this intentional selection change?
nsresult rv = insertBRElementResult.SuggestCaretPointTo(
nsresult rv = insertBRElementResult.inspect().SuggestCaretPointTo(
*this, {SuggestCaret::OnlyIfHasSuggestion,
SuggestCaret::OnlyIfTransactionsAllowedToDoIt});
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
"CreateElementResult::SuggestCaretPointTo() failed");
MOZ_ASSERT(insertBRElementResult.GetNewNode());
MOZ_ASSERT(insertBRElementResult.inspect().GetNewNode());
return rv;
}
@ -823,29 +823,33 @@ nsresult HTMLEditor::SetPositionToStatic(Element& aElement) {
{
// MOZ_KnownLive(*styledElement): aElement's lifetime must be guarantted
// by the caller because of MOZ_CAN_RUN_SCRIPT method.
CreateElementResult maybeInsertBRElementBeforeFirstChildResult =
Result<CreateElementResult, nsresult>
maybeInsertBRElementBeforeFirstChildResult =
EnsureHardLineBeginsWithFirstChildOf(MOZ_KnownLive(*styledElement));
if (maybeInsertBRElementBeforeFirstChildResult.isErr()) {
if (MOZ_UNLIKELY(maybeInsertBRElementBeforeFirstChildResult.isErr())) {
NS_WARNING("HTMLEditor::EnsureHardLineBeginsWithFirstChildOf() failed");
return maybeInsertBRElementBeforeFirstChildResult.unwrapErr();
}
if (maybeInsertBRElementBeforeFirstChildResult.HasCaretPointSuggestion()) {
pointToPutCaret =
maybeInsertBRElementBeforeFirstChildResult.UnwrapCaretPoint();
CreateElementResult unwrappedResult =
maybeInsertBRElementBeforeFirstChildResult.unwrap();
if (unwrappedResult.HasCaretPointSuggestion()) {
pointToPutCaret = unwrappedResult.UnwrapCaretPoint();
}
}
{
// MOZ_KnownLive(*styledElement): aElement's lifetime must be guarantted
// by the caller because of MOZ_CAN_RUN_SCRIPT method.
CreateElementResult maybeInsertBRElementAfterLastChildResult =
Result<CreateElementResult, nsresult>
maybeInsertBRElementAfterLastChildResult =
EnsureHardLineEndsWithLastChildOf(MOZ_KnownLive(*styledElement));
if (maybeInsertBRElementAfterLastChildResult.isErr()) {
if (MOZ_UNLIKELY(maybeInsertBRElementAfterLastChildResult.isErr())) {
NS_WARNING("HTMLEditor::EnsureHardLineEndsWithLastChildOf() failed");
return maybeInsertBRElementAfterLastChildResult.unwrapErr();
}
if (maybeInsertBRElementAfterLastChildResult.HasCaretPointSuggestion()) {
pointToPutCaret =
maybeInsertBRElementAfterLastChildResult.UnwrapCaretPoint();
CreateElementResult unwrappedResult =
maybeInsertBRElementAfterLastChildResult.unwrap();
if (unwrappedResult.HasCaretPointSuggestion()) {
pointToPutCaret = unwrappedResult.UnwrapCaretPoint();
}
}
{

File diff suppressed because it is too large Load diff

View file

@ -138,15 +138,15 @@ void HTMLEditor::AutoSelectionRestorer::Abort() {
* HTMLEditor
*****************************************************************************/
template CreateContentResult
template Result<CreateContentResult, nsresult>
HTMLEditor::InsertNodeIntoProperAncestorWithTransaction(
nsIContent& aContentToInsert, const EditorDOMPoint& aPointToInsert,
SplitAtEdges aSplitAtEdges);
template CreateElementResult
template Result<CreateElementResult, nsresult>
HTMLEditor::InsertNodeIntoProperAncestorWithTransaction(
Element& aContentToInsert, const EditorDOMPoint& aPointToInsert,
SplitAtEdges aSplitAtEdges);
template CreateTextResult
template Result<CreateTextResult, nsresult>
HTMLEditor::InsertNodeIntoProperAncestorWithTransaction(
Text& aContentToInsert, const EditorDOMPoint& aPointToInsert,
SplitAtEdges aSplitAtEdges);
@ -495,7 +495,8 @@ NS_IMETHODIMP HTMLEditor::SetDocumentCharacterSet(
}
// Create a new meta charset tag
CreateElementResult createNewMetaElementResult = CreateAndInsertElement(
Result<CreateElementResult, nsresult> createNewMetaElementResult =
CreateAndInsertElement(
WithTransaction::Yes, *nsGkAtoms::meta,
EditorDOMPoint(primaryHeadElement, 0),
[&aCharacterSet](HTMLEditor&, Element& aMetaElement,
@ -510,13 +511,15 @@ NS_IMETHODIMP HTMLEditor::SetDocumentCharacterSet(
"%s) failed, but ignored",
aMetaElement.IsInComposedDoc() ? "true" : "false")
.get());
rvIgnored = aMetaElement.SetAttr(
kNameSpaceID_None, nsGkAtoms::content,
u"text/html;charset="_ns + NS_ConvertASCIItoUTF16(aCharacterSet),
rvIgnored =
aMetaElement.SetAttr(kNameSpaceID_None, nsGkAtoms::content,
u"text/html;charset="_ns +
NS_ConvertASCIItoUTF16(aCharacterSet),
aMetaElement.IsInComposedDoc());
NS_WARNING_ASSERTION(
NS_SUCCEEDED(rvIgnored),
nsPrintfCString("Element::SetAttr(nsGkAtoms::content, "
nsPrintfCString(
"Element::SetAttr(nsGkAtoms::content, "
"\"text/html;charset=%s\", %s) failed, but ignored",
nsPromiseFlatCString(aCharacterSet).get(),
aMetaElement.IsInComposedDoc() ? "true" : "false")
@ -528,7 +531,7 @@ NS_IMETHODIMP HTMLEditor::SetDocumentCharacterSet(
"Yes, nsGkAtoms::meta) failed, but ignored");
// Probably, we don't need to update selection in this case since we should
// not put selection into <head> element.
createNewMetaElementResult.IgnoreCaretPointSuggestion();
createNewMetaElementResult.inspect().IgnoreCaretPointSuggestion();
return NS_OK;
}
@ -1604,15 +1607,16 @@ nsresult HTMLEditor::ReplaceHeadContentsWithSourceWithTransaction(
// Loop over the contents of the fragment and move into the document
while (nsCOMPtr<nsIContent> child = documentFragment->GetFirstChild()) {
CreateContentResult insertChildContentResult = InsertNodeWithTransaction(
Result<CreateContentResult, nsresult> insertChildContentResult =
InsertNodeWithTransaction(
*child, EditorDOMPoint(primaryHeadElement, offsetOfNewNode++));
if (insertChildContentResult.isErr()) {
if (MOZ_UNLIKELY(insertChildContentResult.isErr())) {
NS_WARNING("EditorBase::InsertNodeWithTransaction() failed");
return insertChildContentResult.unwrapErr();
}
// We probably don't need to adjust selection here, although we've done it
// unless AutoTransactionsConserveSelection is created in a caller.
insertChildContentResult.IgnoreCaretPointSuggestion();
insertChildContentResult.inspect().IgnoreCaretPointSuggestion();
}
return NS_OK;
@ -1999,18 +2003,22 @@ nsresult HTMLEditor::InsertElementAtSelectionAsAction(
return NS_ERROR_FAILURE;
}
const CreateElementResult insertElementResult =
{
Result<CreateElementResult, nsresult> insertElementResult =
InsertNodeIntoProperAncestorWithTransaction<Element>(
*aElement, pointToInsert, SplitAtEdges::eAllowToCreateEmptyContainer);
if (insertElementResult.isErr()) {
*aElement, pointToInsert,
SplitAtEdges::eAllowToCreateEmptyContainer);
if (MOZ_UNLIKELY(insertElementResult.isErr())) {
NS_WARNING(
"HTMLEditor::InsertNodeIntoProperAncestorWithTransaction(SplitAtEdges::"
"HTMLEditor::InsertNodeIntoProperAncestorWithTransaction("
"SplitAtEdges::"
"eAllowToCreateEmptyContainer) failed");
return EditorBase::ToGenericNSResult(insertElementResult.unwrapErr());
}
insertElementResult.inspect().IgnoreCaretPointSuggestion();
}
// Set caret after element, but check for special case
// of inserting table-related elements: set in first cell instead
insertElementResult.IgnoreCaretPointSuggestion();
if (!SetCaretInTableCell(aElement)) {
if (NS_WARN_IF(Destroyed())) {
return EditorBase::ToGenericNSResult(NS_ERROR_EDITOR_DESTROYED);
@ -2032,29 +2040,27 @@ nsresult HTMLEditor::InsertElementAtSelectionAsAction(
const auto afterElement = EditorDOMPoint::After(*aElement);
// Collapse selection to the new `<br>` element node after creating it.
const CreateElementResult insertBRElementResult =
Result<CreateElementResult, nsresult> insertBRElementResult =
InsertBRElement(WithTransaction::Yes, afterElement, ePrevious);
if (insertBRElementResult.isErr()) {
if (MOZ_UNLIKELY(insertBRElementResult.isErr())) {
NS_WARNING(
"HTMLEditor::InsertBRElement(WithTransaction::Yes, ePrevious) failed");
return EditorBase::ToGenericNSResult(insertBRElementResult.unwrapErr());
}
rv = insertBRElementResult.SuggestCaretPointTo(*this, {});
rv = insertBRElementResult.inspect().SuggestCaretPointTo(*this, {});
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
"EditorBase::CollapseSelectionTo() failed");
MOZ_ASSERT(insertBRElementResult.GetNewNode());
MOZ_ASSERT(insertBRElementResult.inspect().GetNewNode());
return EditorBase::ToGenericNSResult(rv);
}
template <typename NodeType>
CreateNodeResultBase<NodeType>
Result<CreateNodeResultBase<NodeType>, nsresult>
HTMLEditor::InsertNodeIntoProperAncestorWithTransaction(
NodeType& aContentToInsert, const EditorDOMPoint& aPointToInsert,
SplitAtEdges aSplitAtEdges) {
using ResultType = CreateNodeResultBase<NodeType>;
if (NS_WARN_IF(!aPointToInsert.IsSet())) {
return ResultType(NS_ERROR_FAILURE);
return Err(NS_ERROR_FAILURE);
}
MOZ_ASSERT(aPointToInsert.IsSetAndValid());
@ -2071,7 +2077,7 @@ HTMLEditor::InsertNodeIntoProperAncestorWithTransaction(
NS_WARNING(
"There was no proper container element to insert the content node in "
"the document");
return ResultType(NS_ERROR_FAILURE);
return Err(NS_ERROR_FAILURE);
}
// Get the next point.
@ -2084,7 +2090,7 @@ HTMLEditor::InsertNodeIntoProperAncestorWithTransaction(
NS_WARNING(
"There was no proper container element to insert the content node in "
"the editing host");
return ResultType(NS_ERROR_FAILURE);
return Err(NS_ERROR_FAILURE);
}
}
@ -2096,7 +2102,7 @@ HTMLEditor::InsertNodeIntoProperAncestorWithTransaction(
aPointToInsert, aSplitAtEdges);
if (splitNodeResult.isErr()) {
NS_WARNING("HTMLEditor::SplitNodeDeepWithTransaction() failed");
return ResultType(splitNodeResult.unwrapErr());
return Err(splitNodeResult.unwrapErr());
}
pointToInsert = splitNodeResult.AtSplitPoint<EditorDOMPoint>();
MOZ_ASSERT(pointToInsert.IsSet());
@ -2106,7 +2112,7 @@ HTMLEditor::InsertNodeIntoProperAncestorWithTransaction(
}
// Now we can insert the new node.
ResultType insertContentNodeResult =
Result<CreateNodeResultBase<NodeType>, nsresult> insertContentNodeResult =
InsertNodeWithTransaction<NodeType>(aContentToInsert, pointToInsert);
if (MOZ_LIKELY(insertContentNodeResult.isOk()) &&
MOZ_UNLIKELY(NS_WARN_IF(!aContentToInsert.GetParentNode()) ||
@ -2115,8 +2121,8 @@ HTMLEditor::InsertNodeIntoProperAncestorWithTransaction(
NS_WARNING(
"EditorBase::InsertNodeWithTransaction() succeeded, but the inserted "
"node was moved or removed by the web app");
insertContentNodeResult.IgnoreCaretPointSuggestion();
return ResultType(NS_ERROR_EDITOR_UNEXPECTED_DOM_TREE);
insertContentNodeResult.inspect().IgnoreCaretPointSuggestion();
return Err(NS_ERROR_EDITOR_UNEXPECTED_DOM_TREE);
}
NS_WARNING_ASSERTION(insertContentNodeResult.isOk(),
"EditorBase::InsertNodeWithTransaction() failed");
@ -3170,7 +3176,7 @@ already_AddRefed<Element> HTMLEditor::GetSelectedElement(const nsAtom* aTagName,
return lastElementInRange.forget();
}
CreateElementResult HTMLEditor::CreateAndInsertElement(
Result<CreateElementResult, nsresult> HTMLEditor::CreateAndInsertElement(
WithTransaction aWithTransaction, nsAtom& aTagName,
const EditorDOMPoint& aPointToInsert,
const InitializeInsertingElement& aInitializer) {
@ -3186,7 +3192,7 @@ CreateElementResult HTMLEditor::CreateAndInsertElement(
AutoEditSubActionNotifier startToHandleEditSubAction(
*this, EditSubAction::eCreateNode, nsIEditor::eNext, ignoredError);
if (NS_WARN_IF(ignoredError.ErrorCodeIs(NS_ERROR_EDITOR_DESTROYED))) {
return CreateElementResult(NS_ERROR_EDITOR_DESTROYED);
return Err(NS_ERROR_EDITOR_DESTROYED);
}
NS_WARNING_ASSERTION(
!ignoredError.Failed(),
@ -3200,16 +3206,17 @@ CreateElementResult HTMLEditor::CreateAndInsertElement(
// CreatElementTransaction since we can use InsertNodeTransaction
// instead.
CreateElementResult createNewElementResult = [&]() MOZ_CAN_RUN_SCRIPT {
auto createNewElementResult =
[&]() MOZ_CAN_RUN_SCRIPT -> Result<CreateElementResult, nsresult> {
RefPtr<Element> newElement = CreateHTMLContent(&aTagName);
if (MOZ_UNLIKELY(!newElement)) {
NS_WARNING("EditorBase::CreateHTMLContent() failed");
return CreateElementResult(NS_ERROR_FAILURE);
return Err(NS_ERROR_FAILURE);
}
nsresult rv = MarkElementDirty(*newElement);
if (MOZ_UNLIKELY(rv == NS_ERROR_EDITOR_DESTROYED)) {
NS_WARNING("EditorBase::MarkElementDirty() caused destroying the editor");
return CreateElementResult(NS_ERROR_EDITOR_DESTROYED);
return Err(NS_ERROR_EDITOR_DESTROYED);
}
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
"EditorBase::MarkElementDirty() failed, but ignored");
@ -3217,7 +3224,7 @@ CreateElementResult HTMLEditor::CreateAndInsertElement(
rv = aInitializer(*this, *newElement, aPointToInsert);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "aInitializer failed");
if (NS_WARN_IF(Destroyed())) {
return CreateElementResult(NS_ERROR_EDITOR_DESTROYED);
return Err(NS_ERROR_EDITOR_DESTROYED);
}
}
RefPtr<InsertNodeTransaction> transaction =
@ -3230,30 +3237,30 @@ CreateElementResult HTMLEditor::CreateAndInsertElement(
NS_WARNING(
"InsertNodeTransaction::DoTransaction() caused destroying the "
"editor");
return CreateElementResult(NS_ERROR_EDITOR_DESTROYED);
return Err(NS_ERROR_EDITOR_DESTROYED);
}
if (NS_FAILED(rv)) {
NS_WARNING("InsertNodeTransaction::DoTransaction() failed");
return CreateElementResult(rv);
return Err(rv);
}
// Override the success code if new element was moved by the web apps.
if (newElement &&
newElement->GetParentNode() != aPointToInsert.GetContainer()) {
NS_WARNING("The new element was not inserted into the expected node");
return CreateElementResult(NS_ERROR_EDITOR_UNEXPECTED_DOM_TREE);
return Err(NS_ERROR_EDITOR_UNEXPECTED_DOM_TREE);
}
return CreateElementResult(
std::move(newElement),
transaction->SuggestPointToPutCaret<EditorDOMPoint>());
}();
if (createNewElementResult.isErr()) {
if (MOZ_UNLIKELY(createNewElementResult.isErr())) {
NS_WARNING("EditorBase::DoTransactionInternal() failed");
// XXX Why do we do this even when DoTransaction() returned error?
DebugOnly<nsresult> rvIgnored =
RangeUpdaterRef().SelAdjCreateNode(aPointToInsert);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rvIgnored),
"Rangeupdater::SelAdjCreateNode() failed");
"RangeUpdater::SelAdjCreateNode() failed");
return createNewElementResult;
}
@ -3267,24 +3274,24 @@ CreateElementResult HTMLEditor::CreateAndInsertElement(
RangeUpdaterRef().SelAdjCreateNode(EditorRawDOMPoint(
aPointToInsert.GetContainer(), aPointToInsert.Offset()));
NS_WARNING_ASSERTION(NS_SUCCEEDED(rvIgnored),
"Rangeupdater::SelAdjCreateNode() failed, but ignored");
if (createNewElementResult.GetNewNode()) {
"RangeUpdater::SelAdjCreateNode() failed, but ignored");
if (MOZ_LIKELY(createNewElementResult.inspect().GetNewNode())) {
TopLevelEditSubActionDataRef().DidCreateElement(
*this, *createNewElementResult.GetNewNode());
*this, *createNewElementResult.inspect().GetNewNode());
}
if (!StaticPrefs::editor_initialize_element_before_connect() &&
createNewElementResult.GetNewNode()) {
// MOZ_KnownLive(newElement) because it's grabbed by createNewElementResult.
nsresult rv =
aInitializer(*this, MOZ_KnownLive(*createNewElementResult.GetNewNode()),
MOZ_LIKELY(createNewElementResult.inspect().GetNewNode())) {
// MOZ_KnownLive because it's grabbed by createNewElementResult.
nsresult rv = aInitializer(
*this, MOZ_KnownLive(*createNewElementResult.inspect().GetNewNode()),
aPointToInsert);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "aInitializer failed");
if (MOZ_UNLIKELY(NS_WARN_IF(Destroyed()))) {
return CreateElementResult(NS_ERROR_EDITOR_DESTROYED);
return Err(NS_ERROR_EDITOR_DESTROYED);
}
if (NS_FAILED(rv)) {
return CreateElementResult(rv);
return Err(rv);
}
}
@ -3856,7 +3863,7 @@ Result<EditorDOMPoint, nsresult> HTMLEditor::PrepareToInsertBRElement(
return atNextContent;
}
CreateElementResult HTMLEditor::InsertBRElement(
Result<CreateElementResult, nsresult> HTMLEditor::InsertBRElement(
WithTransaction aWithTransaction, const EditorDOMPoint& aPointToInsert,
EDirection aSelect /* = eNone */) {
MOZ_ASSERT(IsEditActionDataAvailable());
@ -3868,22 +3875,26 @@ CreateElementResult HTMLEditor::InsertBRElement(
nsPrintfCString("HTMLEditor::PrepareToInsertBRElement(%s) failed",
ToString(aWithTransaction).c_str())
.get());
return CreateElementResult(maybePointToInsert.unwrapErr());
return maybePointToInsert.propagateErr();
}
MOZ_ASSERT(maybePointToInsert.inspect().IsSetAndValid());
CreateElementResult createNewBRElementResult = CreateAndInsertElement(
aWithTransaction, *nsGkAtoms::br, maybePointToInsert.inspect());
if (createNewBRElementResult.isErr()) {
Result<CreateElementResult, nsresult> createNewBRElementResult =
CreateAndInsertElement(aWithTransaction, *nsGkAtoms::br,
maybePointToInsert.inspect());
if (MOZ_UNLIKELY(createNewBRElementResult.isErr())) {
NS_WARNING(nsPrintfCString("HTMLEditor::CreateAndInsertElement(%s) failed",
ToString(aWithTransaction).c_str())
.get());
return CreateElementResult(createNewBRElementResult.unwrapErr());
return createNewBRElementResult.propagateErr();
}
RefPtr<Element> newBRElement = createNewBRElementResult.UnwrapNewNode();
CreateElementResult unwrappedCreateNewBRElementResult =
createNewBRElementResult.unwrap();
RefPtr<Element> newBRElement =
unwrappedCreateNewBRElementResult.UnwrapNewNode();
MOZ_ASSERT(newBRElement);
createNewBRElementResult.IgnoreCaretPointSuggestion();
unwrappedCreateNewBRElementResult.IgnoreCaretPointSuggestion();
switch (aSelect) {
case eNext: {
const auto pointToPutCaret = EditorDOMPoint::After(
@ -3901,17 +3912,19 @@ CreateElementResult HTMLEditor::InsertBRElement(
"by itself");
[[fallthrough]];
case eNone:
return CreateElementResult(std::move(newBRElement),
createNewBRElementResult.UnwrapCaretPoint());
return CreateElementResult(
std::move(newBRElement),
unwrappedCreateNewBRElementResult.UnwrapCaretPoint());
}
}
CreateElementResult HTMLEditor::InsertContainerWithTransactionInternal(
Result<CreateElementResult, nsresult>
HTMLEditor::InsertContainerWithTransactionInternal(
nsIContent& aContentToBeWrapped, nsAtom& aWrapperTagName,
nsAtom& aAttribute, const nsAString& aAttributeValue) {
EditorDOMPoint pointToInsertNewContainer(&aContentToBeWrapped);
if (NS_WARN_IF(!pointToInsertNewContainer.IsSet())) {
return CreateElementResult(NS_ERROR_FAILURE);
return Err(NS_ERROR_FAILURE);
}
// aContentToBeWrapped will be moved to the new container before inserting the
// new container. So, when we insert the container, the insertion point is
@ -3924,7 +3937,7 @@ CreateElementResult HTMLEditor::InsertContainerWithTransactionInternal(
// Create new container.
RefPtr<Element> newContainer = CreateHTMLContent(&aWrapperTagName);
if (NS_WARN_IF(!newContainer)) {
return CreateElementResult(NS_ERROR_FAILURE);
return Err(NS_ERROR_FAILURE);
}
// Set attribute if needed.
@ -3932,11 +3945,11 @@ CreateElementResult HTMLEditor::InsertContainerWithTransactionInternal(
nsresult rv = newContainer->SetAttr(kNameSpaceID_None, &aAttribute,
aAttributeValue, true);
if (NS_WARN_IF(Destroyed())) {
return CreateElementResult(NS_ERROR_EDITOR_DESTROYED);
return Err(NS_ERROR_EDITOR_DESTROYED);
}
if (NS_FAILED(rv)) {
NS_WARNING("Element::SetAttr() failed");
return CreateElementResult(rv);
return Err(rv);
}
}
@ -3948,7 +3961,7 @@ CreateElementResult HTMLEditor::InsertContainerWithTransactionInternal(
nsresult rv = DeleteNodeWithTransaction(aContentToBeWrapped);
if (NS_FAILED(rv)) {
NS_WARNING("EditorBase::DeleteNodeWithTransaction() failed");
return CreateElementResult(rv);
return Err(rv);
}
{
@ -3957,17 +3970,18 @@ CreateElementResult HTMLEditor::InsertContainerWithTransactionInternal(
// actions which may be caused by legacy mutation event listeners or
// chrome script.
AutoTransactionsConserveSelection conserveSelection(*this);
CreateContentResult insertContentNodeResult = InsertNodeWithTransaction(
aContentToBeWrapped, EditorDOMPoint(newContainer, 0u));
if (insertContentNodeResult.isErr()) {
Result<CreateContentResult, nsresult> insertContentNodeResult =
InsertNodeWithTransaction(aContentToBeWrapped,
EditorDOMPoint(newContainer, 0u));
if (MOZ_UNLIKELY(insertContentNodeResult.isErr())) {
NS_WARNING("EditorBase::InsertNodeWithTransaction() failed");
return CreateElementResult(insertContentNodeResult.unwrapErr());
return insertContentNodeResult.propagateErr();
}
insertContentNodeResult.IgnoreCaretPointSuggestion();
insertContentNodeResult.inspect().IgnoreCaretPointSuggestion();
}
// Put the new container where aNode was.
CreateElementResult insertNewContainerElementResult =
Result<CreateElementResult, nsresult> insertNewContainerElementResult =
InsertNodeWithTransaction<Element>(*newContainer,
pointToInsertNewContainer);
NS_WARNING_ASSERTION(insertNewContainerElementResult.isOk(),
@ -3975,19 +3989,20 @@ CreateElementResult HTMLEditor::InsertContainerWithTransactionInternal(
return insertNewContainerElementResult;
}
CreateElementResult HTMLEditor::ReplaceContainerWithTransactionInternal(
Result<CreateElementResult, nsresult>
HTMLEditor::ReplaceContainerWithTransactionInternal(
Element& aOldContainer, nsAtom& aTagName, nsAtom& aAttribute,
const nsAString& aAttributeValue, bool aCloneAllAttributes) {
MOZ_ASSERT(IsEditActionDataAvailable());
if (NS_WARN_IF(!HTMLEditUtils::IsRemovableNode(aOldContainer)) ||
NS_WARN_IF(!HTMLEditUtils::IsSimplyEditableNode(aOldContainer))) {
return CreateElementResult(NS_ERROR_FAILURE);
return Err(NS_ERROR_FAILURE);
}
const RefPtr<Element> newContainer = CreateHTMLContent(&aTagName);
if (NS_WARN_IF(!newContainer)) {
return CreateElementResult(NS_ERROR_FAILURE);
return Err(NS_ERROR_FAILURE);
}
// Set or clone attribute if needed.
@ -3999,7 +4014,7 @@ CreateElementResult HTMLEditor::ReplaceContainerWithTransactionInternal(
aAttributeValue, true);
if (NS_FAILED(rv)) {
NS_WARNING("Element::SetAttr() failed");
return CreateElementResult(NS_ERROR_FAILURE);
return Err(NS_ERROR_FAILURE);
}
}
@ -4028,7 +4043,7 @@ CreateElementResult HTMLEditor::ReplaceContainerWithTransactionInternal(
EditorDOMPoint(newContainer, 0u));
if (MOZ_UNLIKELY(moveChildResult.isErr())) {
NS_WARNING("HTMLEditor::MoveNodeWithTransaction() failed");
return CreateElementResult(moveChildResult.unwrapErr());
return moveChildResult.propagateErr();
}
// We'll suggest new caret point which is suggested by new container
// element insertion result. Therefore, we need to do nothing here.
@ -4041,7 +4056,7 @@ CreateElementResult HTMLEditor::ReplaceContainerWithTransactionInternal(
nsresult rv = DeleteNodeWithTransaction(aOldContainer);
if (NS_FAILED(rv)) {
NS_WARNING("EditorBase::DeleteNodeWithTransaction() failed");
return CreateElementResult(rv);
return Err(rv);
}
if (referenceNode && (!referenceNode->GetParentNode() ||
@ -4049,18 +4064,19 @@ CreateElementResult HTMLEditor::ReplaceContainerWithTransactionInternal(
NS_WARNING(
"The reference node for insertion has been moved to different parent, "
"so we got lost the insertion point");
return CreateElementResult(NS_ERROR_EDITOR_UNEXPECTED_DOM_TREE);
return Err(NS_ERROR_EDITOR_UNEXPECTED_DOM_TREE);
}
// Finally, insert the new node to where probably aOldContainer was.
CreateElementResult insertNewContainerElementResult =
Result<CreateElementResult, nsresult> insertNewContainerElementResult =
InsertNodeWithTransaction<Element>(
*newContainer, referenceNode ? EditorDOMPoint(referenceNode)
: EditorDOMPoint::AtEndOf(*parentNode));
NS_WARNING_ASSERTION(insertNewContainerElementResult.isOk(),
"EditorBase::InsertNodeWithTransaction() failed");
MOZ_ASSERT_IF(insertNewContainerElementResult.isOk(),
insertNewContainerElementResult.GetNewNode() == newContainer);
MOZ_ASSERT_IF(
insertNewContainerElementResult.isOk(),
insertNewContainerElementResult.inspect().GetNewNode() == newContainer);
return insertNewContainerElementResult;
}
@ -4547,16 +4563,19 @@ HTMLEditor::RemoveBlockContainerWithTransaction(Element& aElement) {
!previousSibling->IsHTMLElement(nsGkAtoms::br) &&
!HTMLEditUtils::IsBlockElement(*child)) {
// Insert br node
CreateElementResult insertBRElementResult = InsertBRElement(
WithTransaction::Yes, EditorDOMPoint(&aElement, 0u));
if (insertBRElementResult.isErr()) {
Result<CreateElementResult, nsresult> insertBRElementResult =
InsertBRElement(WithTransaction::Yes,
EditorDOMPoint(&aElement, 0u));
if (MOZ_UNLIKELY(insertBRElementResult.isErr())) {
NS_WARNING(
"HTMLEditor::InsertBRElement(WithTransaction::Yes) failed");
return Err(insertBRElementResult.unwrapErr());
return insertBRElementResult.propagateErr();
}
insertBRElementResult.MoveCaretPointTo(
CreateElementResult unwrappedInsertBRElementResult =
insertBRElementResult.unwrap();
unwrappedInsertBRElementResult.MoveCaretPointTo(
pointToPutCaret, {SuggestCaret::OnlyIfHasSuggestion});
MOZ_ASSERT(insertBRElementResult.GetNewNode());
MOZ_ASSERT(unwrappedInsertBRElementResult.GetNewNode());
}
}
@ -4573,16 +4592,19 @@ HTMLEditor::RemoveBlockContainerWithTransaction(Element& aElement) {
aElement, {WalkTreeOption::IgnoreNonEditableNode})) {
if (!HTMLEditUtils::IsBlockElement(*lastChild) &&
!lastChild->IsHTMLElement(nsGkAtoms::br)) {
CreateElementResult insertBRElementResult = InsertBRElement(
WithTransaction::Yes, EditorDOMPoint::AtEndOf(aElement));
if (insertBRElementResult.isErr()) {
Result<CreateElementResult, nsresult> insertBRElementResult =
InsertBRElement(WithTransaction::Yes,
EditorDOMPoint::AtEndOf(aElement));
if (MOZ_UNLIKELY(insertBRElementResult.isErr())) {
NS_WARNING(
"HTMLEditor::InsertBRElement(WithTransaction::Yes) failed");
return Err(insertBRElementResult.unwrapErr());
return insertBRElementResult.propagateErr();
}
insertBRElementResult.MoveCaretPointTo(
CreateElementResult unwrappedInsertBRElementResult =
insertBRElementResult.unwrap();
unwrappedInsertBRElementResult.MoveCaretPointTo(
pointToPutCaret, {SuggestCaret::OnlyIfHasSuggestion});
MOZ_ASSERT(insertBRElementResult.GetNewNode());
MOZ_ASSERT(unwrappedInsertBRElementResult.GetNewNode());
}
}
}
@ -4601,16 +4623,19 @@ HTMLEditor::RemoveBlockContainerWithTransaction(Element& aElement) {
aElement, {WalkTreeOption::IgnoreNonEditableNode})) {
if (!HTMLEditUtils::IsBlockElement(*nextSibling) &&
!nextSibling->IsHTMLElement(nsGkAtoms::br)) {
CreateElementResult insertBRElementResult = InsertBRElement(
WithTransaction::Yes, EditorDOMPoint(&aElement, 0u));
if (insertBRElementResult.isErr()) {
Result<CreateElementResult, nsresult> insertBRElementResult =
InsertBRElement(WithTransaction::Yes,
EditorDOMPoint(&aElement, 0u));
if (MOZ_UNLIKELY(insertBRElementResult.isErr())) {
NS_WARNING(
"HTMLEditor::InsertBRElement(WithTransaction::Yes) failed");
return Err(insertBRElementResult.unwrapErr());
return insertBRElementResult.propagateErr();
}
insertBRElementResult.MoveCaretPointTo(
CreateElementResult unwrappedInsertBRElementResult =
insertBRElementResult.unwrap();
unwrappedInsertBRElementResult.MoveCaretPointTo(
pointToPutCaret, {SuggestCaret::OnlyIfHasSuggestion});
MOZ_ASSERT(insertBRElementResult.GetNewNode());
MOZ_ASSERT(unwrappedInsertBRElementResult.GetNewNode());
}
}
}
@ -5410,24 +5435,25 @@ Result<RefPtr<Element>, nsresult> HTMLEditor::DeleteSelectionAndCreateElement(
if (!pointToInsert.IsSet()) {
return Err(NS_ERROR_FAILURE);
}
CreateElementResult createNewElementResult = CreateAndInsertElement(
WithTransaction::Yes, aTag, pointToInsert, aInitializer);
if (createNewElementResult.isErr()) {
Result<CreateElementResult, nsresult> createNewElementResult =
CreateAndInsertElement(WithTransaction::Yes, aTag, pointToInsert,
aInitializer);
if (MOZ_UNLIKELY(createNewElementResult.isErr())) {
NS_WARNING(
"HTMLEditor::CreateAndInsertElement(WithTransaction::Yes) failed");
return Err(createNewElementResult.unwrapErr());
return createNewElementResult.propagateErr();
}
MOZ_ASSERT(createNewElementResult.GetNewNode());
MOZ_ASSERT(createNewElementResult.inspect().GetNewNode());
// We want the selection to be just after the new node
createNewElementResult.IgnoreCaretPointSuggestion();
createNewElementResult.inspect().IgnoreCaretPointSuggestion();
rv = CollapseSelectionTo(
EditorRawDOMPoint::After(*createNewElementResult.GetNewNode()));
EditorRawDOMPoint::After(*createNewElementResult.inspect().GetNewNode()));
if (NS_FAILED(rv)) {
NS_WARNING("EditorBase::CollapseSelectionTo() failed");
return Err(rv);
}
return createNewElementResult.UnwrapNewNode();
return createNewElementResult.unwrap().UnwrapNewNode();
}
nsresult HTMLEditor::DeleteSelectionAndPrepareToCreateNode() {
@ -6076,12 +6102,13 @@ HTMLEditor::CopyLastEditableChildStylesWithTransaction(
// At first time, just create the most descendant inline container
// element.
if (!firstClonedElement) {
CreateElementResult createNewElementResult = CreateAndInsertElement(
Result<CreateElementResult, nsresult> createNewElementResult =
CreateAndInsertElement(
WithTransaction::Yes, tagName, EditorDOMPoint(&aNewBlock, 0u),
// MOZ_CAN_RUN_SCRIPT_BOUNDARY due to bug 1758868
[&elementInPreviousBlock](HTMLEditor& aHTMLEditor,
Element& aNewElement, const EditorDOMPoint&)
MOZ_CAN_RUN_SCRIPT_BOUNDARY {
[&elementInPreviousBlock](
HTMLEditor& aHTMLEditor, Element& aNewElement,
const EditorDOMPoint&) MOZ_CAN_RUN_SCRIPT_BOUNDARY {
// Clone all attributes. Note that despite the method name,
// CloneAttributesWithTransaction does not create
// transactions in this case because aNewElement has not
@ -6091,32 +6118,36 @@ HTMLEditor::CopyLastEditableChildStylesWithTransaction(
aNewElement, *elementInPreviousBlock);
return NS_OK;
});
if (createNewElementResult.isErr()) {
if (MOZ_UNLIKELY(createNewElementResult.isErr())) {
NS_WARNING(
"HTMLEditor::CreateAndInsertElement(WithTransaction::Yes) failed");
return Err(createNewElementResult.unwrapErr());
return createNewElementResult.propagateErr();
}
CreateElementResult unwrappedCreateNewElementResult =
createNewElementResult.unwrap();
// We'll return with a point suggesting new caret position and the
// following path does not require an update of selection here.
// Therefore, we don't need to update selection here.
createNewElementResult.IgnoreCaretPointSuggestion();
unwrappedCreateNewElementResult.IgnoreCaretPointSuggestion();
firstClonedElement = lastClonedElement =
createNewElementResult.UnwrapNewNode();
unwrappedCreateNewElementResult.UnwrapNewNode();
continue;
}
// Otherwise, inserts new parent inline container to the previous inserted
// inline container.
CreateElementResult wrapClonedElementResult =
Result<CreateElementResult, nsresult> wrapClonedElementResult =
InsertContainerWithTransaction(*lastClonedElement, tagName);
if (wrapClonedElementResult.isErr()) {
if (MOZ_UNLIKELY(wrapClonedElementResult.isErr())) {
NS_WARNING("HTMLEditor::InsertContainerWithTransaction() failed");
return Err(wrapClonedElementResult.unwrapErr());
return wrapClonedElementResult.propagateErr();
}
CreateElementResult unwrappedWrapClonedElementResult =
wrapClonedElementResult.unwrap();
// We'll return with a point suggesting new caret so that we don't need to
// update selection here.
wrapClonedElementResult.IgnoreCaretPointSuggestion();
MOZ_ASSERT(wrapClonedElementResult.GetNewNode());
lastClonedElement = wrapClonedElementResult.UnwrapNewNode();
unwrappedWrapClonedElementResult.IgnoreCaretPointSuggestion();
MOZ_ASSERT(unwrappedWrapClonedElementResult.GetNewNode());
lastClonedElement = unwrappedWrapClonedElementResult.UnwrapNewNode();
CloneAttributesWithTransaction(*lastClonedElement, *elementInPreviousBlock);
if (NS_WARN_IF(Destroyed())) {
return Err(NS_ERROR_EDITOR_DESTROYED);
@ -6129,15 +6160,15 @@ HTMLEditor::CopyLastEditableChildStylesWithTransaction(
return EditorDOMPoint(&aNewBlock, 0u);
}
CreateElementResult insertBRElementResult = InsertBRElement(
Result<CreateElementResult, nsresult> insertBRElementResult = InsertBRElement(
WithTransaction::Yes, EditorDOMPoint(firstClonedElement, 0u));
if (insertBRElementResult.isErr()) {
if (MOZ_UNLIKELY(insertBRElementResult.isErr())) {
NS_WARNING("HTMLEditor::InsertBRElement(WithTransaction::Yes) failed");
return Err(insertBRElementResult.unwrapErr());
return insertBRElementResult.propagateErr();
}
insertBRElementResult.IgnoreCaretPointSuggestion();
MOZ_ASSERT(insertBRElementResult.GetNewNode());
return EditorDOMPoint(insertBRElementResult.GetNewNode());
insertBRElementResult.inspect().IgnoreCaretPointSuggestion();
MOZ_ASSERT(insertBRElementResult.inspect().GetNewNode());
return EditorDOMPoint(insertBRElementResult.inspect().GetNewNode());
}
nsresult HTMLEditor::GetElementOrigin(Element& aElement, int32_t& aX,

View file

@ -746,7 +746,7 @@ class HTMLEditor final : public EditorBase,
* @return The new <br> node and suggesting point to put
* caret which respects aSelect.
*/
MOZ_CAN_RUN_SCRIPT CreateElementResult InsertBRElement(
MOZ_CAN_RUN_SCRIPT Result<CreateElementResult, nsresult> InsertBRElement(
WithTransaction aWithTransaction, const EditorDOMPoint& aPointToInsert,
EDirection aSelect = eNone);
@ -877,7 +877,7 @@ class HTMLEditor final : public EditorBase,
* Helper routines for font size changing.
*/
enum class FontSize { incr, decr };
[[nodiscard]] MOZ_CAN_RUN_SCRIPT CreateElementResult
[[nodiscard]] MOZ_CAN_RUN_SCRIPT Result<CreateElementResult, nsresult>
SetFontSizeOnTextNode(Text& aTextNode, uint32_t aStartOffset,
uint32_t aEndOffset, FontSize aIncrementOrDecrement);
@ -1156,8 +1156,9 @@ class HTMLEditor final : public EditorBase,
* @return If succeeded, returns new <br> element and
* candidate caret point.
*/
[[nodiscard]] MOZ_CAN_RUN_SCRIPT CreateElementResult HandleInsertBRElement(
const EditorDOMPoint& aPointToBreak, const Element& aEditingHost);
[[nodiscard]] MOZ_CAN_RUN_SCRIPT Result<CreateElementResult, nsresult>
HandleInsertBRElement(const EditorDOMPoint& aPointToBreak,
const Element& aEditingHost);
/**
* HandleInsertLinefeed() inserts a linefeed character into aInsertToBreak.
@ -1305,7 +1306,8 @@ class HTMLEditor final : public EditorBase,
* @return The created new element node and candidate caret
* position.
*/
[[nodiscard]] MOZ_CAN_RUN_SCRIPT CreateElementResult CreateAndInsertElement(
[[nodiscard]] MOZ_CAN_RUN_SCRIPT Result<CreateElementResult, nsresult>
CreateAndInsertElement(
WithTransaction aWithTransaction, nsAtom& aTagName,
const EditorDOMPoint& aPointToInsert,
const InitializeInsertingElement& aInitializer = DoNothingForNewElement);
@ -1356,7 +1358,7 @@ class HTMLEditor final : public EditorBase,
* suggesting point to put caret.
*/
enum class BRElementNextToSplitPoint { Keep, Delete };
[[nodiscard]] MOZ_CAN_RUN_SCRIPT CreateElementResult
[[nodiscard]] MOZ_CAN_RUN_SCRIPT Result<CreateElementResult, nsresult>
InsertElementWithSplittingAncestorsWithTransaction(
nsAtom& aTagName, const EditorDOMPoint& aPointToInsert,
BRElementNextToSplitPoint aBRElementNextToSplitPoint,
@ -1417,7 +1419,7 @@ class HTMLEditor final : public EditorBase,
* The caret suggestion may be unset if there is
* no suggestion.
*/
[[nodiscard]] MOZ_CAN_RUN_SCRIPT CreateElementResult
[[nodiscard]] MOZ_CAN_RUN_SCRIPT Result<CreateElementResult, nsresult>
WrapContentsInBlockquoteElementsWithTransaction(
const nsTArray<OwningNonNull<nsIContent>>& aArrayOfContents,
const Element& aEditingHost);
@ -1456,7 +1458,7 @@ class HTMLEditor final : public EditorBase,
* @return The latest created new block element and a
* suggest point to put caret.
*/
[[nodiscard]] MOZ_CAN_RUN_SCRIPT CreateElementResult
[[nodiscard]] MOZ_CAN_RUN_SCRIPT Result<CreateElementResult, nsresult>
CreateOrChangeBlockContainerElement(
nsTArray<OwningNonNull<nsIContent>>& aArrayOfContents, nsAtom& aBlockTag,
const Element& aEditingHost);
@ -1612,8 +1614,9 @@ class HTMLEditor final : public EditorBase,
* New list element may be aListElement if its
* tag name is same as aNewListTag.
*/
[[nodiscard]] MOZ_CAN_RUN_SCRIPT CreateElementResult ChangeListElementType(
Element& aListElement, nsAtom& aListType, nsAtom& aItemType);
[[nodiscard]] MOZ_CAN_RUN_SCRIPT Result<CreateElementResult, nsresult>
ChangeListElementType(Element& aListElement, nsAtom& aListType,
nsAtom& aItemType);
/**
* ConvertContentAroundRangesToList() converts contents around aRanges to
@ -1742,7 +1745,7 @@ class HTMLEditor final : public EditorBase,
* with new element.
* @param aTagName The name of new element node.
*/
[[nodiscard]] MOZ_CAN_RUN_SCRIPT CreateElementResult
[[nodiscard]] MOZ_CAN_RUN_SCRIPT Result<CreateElementResult, nsresult>
ReplaceContainerAndCloneAttributesWithTransaction(Element& aOldContainer,
nsAtom& aTagName) {
return ReplaceContainerWithTransactionInternal(
@ -1761,7 +1764,7 @@ class HTMLEditor final : public EditorBase,
* @param aAttribute Attribute name to be set to the new element.
* @param aAttributeValue Attribute value to be set to aAttribute.
*/
[[nodiscard]] MOZ_CAN_RUN_SCRIPT CreateElementResult
[[nodiscard]] MOZ_CAN_RUN_SCRIPT Result<CreateElementResult, nsresult>
ReplaceContainerWithTransaction(Element& aOldContainer, nsAtom& aTagName,
nsAtom& aAttribute,
const nsAString& aAttributeValue) {
@ -1778,7 +1781,7 @@ class HTMLEditor final : public EditorBase,
* with new element.
* @param aTagName The name of new element node.
*/
[[nodiscard]] MOZ_CAN_RUN_SCRIPT CreateElementResult
[[nodiscard]] MOZ_CAN_RUN_SCRIPT Result<CreateElementResult, nsresult>
ReplaceContainerWithTransaction(Element& aOldContainer, nsAtom& aTagName) {
return ReplaceContainerWithTransactionInternal(
aOldContainer, aTagName, *nsGkAtoms::_empty, u""_ns, false);
@ -1807,7 +1810,7 @@ class HTMLEditor final : public EditorBase,
* aContent and be inserted into where aContent
* was.
*/
[[nodiscard]] MOZ_CAN_RUN_SCRIPT CreateElementResult
[[nodiscard]] MOZ_CAN_RUN_SCRIPT Result<CreateElementResult, nsresult>
InsertContainerWithTransaction(nsIContent& aContentToBeWrapped,
nsAtom& aWrapperTagName) {
return InsertContainerWithTransactionInternal(
@ -1831,7 +1834,7 @@ class HTMLEditor final : public EditorBase,
* element.
* @param aAttributeValue Value to be set to aAttribute.
*/
[[nodiscard]] MOZ_CAN_RUN_SCRIPT CreateElementResult
[[nodiscard]] MOZ_CAN_RUN_SCRIPT Result<CreateElementResult, nsresult>
InsertContainerWithTransaction(nsIContent& aContentToBeWrapped,
nsAtom& aWrapperTagName, nsAtom& aAttribute,
const nsAString& aAttributeValue) {
@ -2475,7 +2478,7 @@ class HTMLEditor final : public EditorBase,
* first child of aRemovingContainerElement if it will not be start of a
* hard line after removing aRemovingContainerElement.
*/
[[nodiscard]] MOZ_CAN_RUN_SCRIPT CreateElementResult
[[nodiscard]] MOZ_CAN_RUN_SCRIPT Result<CreateElementResult, nsresult>
EnsureHardLineBeginsWithFirstChildOf(Element& aRemovingContainerElement);
/**
@ -2483,7 +2486,7 @@ class HTMLEditor final : public EditorBase,
* child of aRemovingContainerElement if it will not be end of a hard line
* after removing aRemovingContainerElement.
*/
[[nodiscard]] MOZ_CAN_RUN_SCRIPT CreateElementResult
[[nodiscard]] MOZ_CAN_RUN_SCRIPT Result<CreateElementResult, nsresult>
EnsureHardLineEndsWithLastChildOf(Element& aRemovingContainerElement);
/**
@ -2546,7 +2549,7 @@ class HTMLEditor final : public EditorBase,
* @return New <div> element which has only a padding <br>
* element and is styled to align contents.
*/
[[nodiscard]] MOZ_CAN_RUN_SCRIPT CreateElementResult
[[nodiscard]] MOZ_CAN_RUN_SCRIPT Result<CreateElementResult, nsresult>
InsertDivElementToAlignContents(const EditorDOMPoint& aPointToInsert,
const nsAString& aAlignType,
const Element& aEditingHost);
@ -2562,7 +2565,8 @@ class HTMLEditor final : public EditorBase,
* caret and candidate position which may be
* outside the <div> element.
*/
[[nodiscard]] MOZ_CAN_RUN_SCRIPT CreateElementResult AlignNodesAndDescendants(
[[nodiscard]] MOZ_CAN_RUN_SCRIPT Result<CreateElementResult, nsresult>
AlignNodesAndDescendants(
nsTArray<OwningNonNull<nsIContent>>& aArrayOfContents,
const nsAString& aAlignType, const Element& aEditingHost);
@ -3197,7 +3201,8 @@ class HTMLEditor final : public EditorBase,
* @param aSplitAtEdges Splitting can result in empty nodes?
*/
template <typename NodeType>
[[nodiscard]] MOZ_CAN_RUN_SCRIPT CreateNodeResultBase<NodeType>
[[nodiscard]] MOZ_CAN_RUN_SCRIPT
Result<CreateNodeResultBase<NodeType>, nsresult>
InsertNodeIntoProperAncestorWithTransaction(
NodeType& aContent, const EditorDOMPoint& aPointToInsert,
SplitAtEdges aSplitAtEdges);
@ -3229,7 +3234,7 @@ class HTMLEditor final : public EditorBase,
* @param aCloneAllAttributes If true, all attributes of aOldContainer will
* be copied to the new element.
*/
[[nodiscard]] MOZ_CAN_RUN_SCRIPT CreateElementResult
[[nodiscard]] MOZ_CAN_RUN_SCRIPT Result<CreateElementResult, nsresult>
ReplaceContainerWithTransactionInternal(Element& aElement, nsAtom& aTagName,
nsAtom& aAttribute,
const nsAString& aAttributeValue,
@ -3253,7 +3258,7 @@ class HTMLEditor final : public EditorBase,
* element.
* @param aAttributeValue Value to be set to aAttribute.
*/
[[nodiscard]] MOZ_CAN_RUN_SCRIPT CreateElementResult
[[nodiscard]] MOZ_CAN_RUN_SCRIPT Result<CreateElementResult, nsresult>
InsertContainerWithTransactionInternal(nsIContent& aContentToBeWrapped,
nsAtom& aWrapperTagName,
nsAtom& aAttribute,
@ -3507,7 +3512,7 @@ class HTMLEditor final : public EditorBase,
* start of the last inserted cell element
* as a point to put caret.
*/
[[nodiscard]] MOZ_CAN_RUN_SCRIPT CreateElementResult
[[nodiscard]] MOZ_CAN_RUN_SCRIPT Result<CreateElementResult, nsresult>
InsertTableCellsWithTransaction(const EditorDOMPoint& aPointToInsert,
int32_t aNumberOfCellsToInsert);

View file

@ -4,6 +4,7 @@
* 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/. */
#include "ErrorList.h"
#include "HTMLEditor.h"
#include <string.h>
@ -202,13 +203,15 @@ nsresult HTMLEditor::LoadHTML(const nsAString& aInputString) {
EditorDOMPoint pointToPutCaret;
for (nsCOMPtr<nsIContent> contentToInsert = documentFragment->GetFirstChild();
contentToInsert; contentToInsert = documentFragment->GetFirstChild()) {
CreateContentResult insertChildContentNodeResult =
Result<CreateContentResult, nsresult> insertChildContentNodeResult =
InsertNodeWithTransaction(*contentToInsert, pointToInsert);
if (insertChildContentNodeResult.isErr()) {
if (MOZ_UNLIKELY(insertChildContentNodeResult.isErr())) {
NS_WARNING("EditorBase::InsertNodeWithTransaction() failed");
return insertChildContentNodeResult.unwrapErr();
}
insertChildContentNodeResult.MoveCaretPointTo(
CreateContentResult unwrappedInsertChildContentNodeResult =
insertChildContentNodeResult.unwrap();
unwrappedInsertChildContentNodeResult.MoveCaretPointTo(
pointToPutCaret, *this,
{SuggestCaret::OnlyIfHasSuggestion,
SuggestCaret::OnlyIfTransactionsAllowedToDoIt});
@ -884,17 +887,17 @@ HTMLEditor::HTMLWithContextInserter::InsertContents(
EditorDOMPoint pointToPutCaret;
for (const OwningNonNull<nsIContent>& child : children) {
// MOZ_KnownLive(child) because of bug 1622253
CreateContentResult moveChildResult =
Result<CreateContentResult, nsresult> moveChildResult =
mHTMLEditor.InsertNodeIntoProperAncestorWithTransaction<nsIContent>(
MOZ_KnownLive(child), pointToInsert,
SplitAtEdges::eDoNotCreateEmptyContainer);
inserted |=
moveChildResult.isOk() || moveChildResult.GotUnexpectedDOMTree();
if (moveChildResult.isErr()) {
if (MOZ_UNLIKELY(moveChildResult.isErr())) {
// If moving node is moved to different place, we should ignore
// this result and keep trying to insert next content node to same
// position.
if (moveChildResult.GotUnexpectedDOMTree()) {
if (moveChildResult.inspectErr() ==
NS_ERROR_EDITOR_UNEXPECTED_DOM_TREE) {
inserted = true;
continue; // the inner `for` loop
}
NS_WARNING(
@ -903,10 +906,12 @@ HTMLEditor::HTMLWithContextInserter::InsertContents(
"ignored");
break; // from the inner `for` loop
}
inserted = true;
lastInsertedPoint.Set(child);
pointToInsert = lastInsertedPoint.NextPoint();
MOZ_ASSERT(pointToInsert.IsSet());
moveChildResult.MoveCaretPointTo(
CreateContentResult unwrappedMoveChildResult = moveChildResult.unwrap();
unwrappedMoveChildResult.MoveCaretPointTo(
pointToPutCaret, mHTMLEditor,
{SuggestCaret::OnlyIfHasSuggestion,
SuggestCaret::OnlyIfTransactionsAllowedToDoIt});
@ -961,24 +966,22 @@ HTMLEditor::HTMLWithContextInserter::InsertContents(
}
}
// MOZ_KnownLive(child) because of bug 1622253
CreateContentResult moveChildResult =
Result<CreateContentResult, nsresult> moveChildResult =
mHTMLEditor
.InsertNodeIntoProperAncestorWithTransaction<nsIContent>(
MOZ_KnownLive(child), pointToInsert,
SplitAtEdges::eDoNotCreateEmptyContainer);
inserted |=
moveChildResult.isOk() || moveChildResult.GotUnexpectedDOMTree();
if (moveChildResult.isErr()) {
if (MOZ_UNLIKELY(moveChildResult.isErr())) {
// If moving node is moved to different place, we should ignore
// this result and keep trying to insert next content node to
// same position.
if (moveChildResult.GotUnexpectedDOMTree()) {
if (moveChildResult.inspectErr() ==
NS_ERROR_EDITOR_UNEXPECTED_DOM_TREE) {
inserted = true;
continue; // the inner `for` loop
}
if (moveChildResult.EditorDestroyed()) {
NS_WARNING(
"HTMLEditor::InsertNodeIntoProperAncestorWithTransaction() "
"caused destroying the editor");
if (NS_WARN_IF(moveChildResult.inspectErr() ==
NS_ERROR_EDITOR_DESTROYED)) {
return Err(NS_ERROR_EDITOR_DESTROYED);
}
NS_WARNING(
@ -987,10 +990,13 @@ HTMLEditor::HTMLWithContextInserter::InsertContents(
"ignored");
break; // from the inner `for` loop
}
inserted = true;
lastInsertedPoint.Set(child);
pointToInsert = lastInsertedPoint.NextPoint();
MOZ_ASSERT(pointToInsert.IsSet());
moveChildResult.MoveCaretPointTo(
CreateContentResult unwrappedMoveChildResult =
moveChildResult.unwrap();
unwrappedMoveChildResult.MoveCaretPointTo(
pointToPutCaret, mHTMLEditor,
{SuggestCaret::OnlyIfHasSuggestion,
SuggestCaret::OnlyIfTransactionsAllowedToDoIt});
@ -1042,23 +1048,21 @@ HTMLEditor::HTMLWithContextInserter::InsertContents(
EditorDOMPoint pointToPutCaret;
for (const OwningNonNull<nsIContent>& child : children) {
// MOZ_KnownLive(child) because of bug 1622253
CreateContentResult moveChildResult =
Result<CreateContentResult, nsresult> moveChildResult =
mHTMLEditor.InsertNodeIntoProperAncestorWithTransaction<nsIContent>(
MOZ_KnownLive(child), pointToInsert,
SplitAtEdges::eDoNotCreateEmptyContainer);
inserted |=
moveChildResult.isOk() || moveChildResult.GotUnexpectedDOMTree();
if (moveChildResult.isErr()) {
if (MOZ_UNLIKELY(moveChildResult.isErr())) {
// If moving node is moved to different place, we should ignore
// this result and keep trying to insert next content node there.
if (moveChildResult.GotUnexpectedDOMTree()) {
if (moveChildResult.inspectErr() ==
NS_ERROR_EDITOR_UNEXPECTED_DOM_TREE) {
inserted = true;
continue; // the inner `for` loop
}
if (moveChildResult.EditorDestroyed()) {
NS_WARNING(
"HTMLEditor::InsertNodeIntoProperAncestorWithTransaction() "
"caused destroying the editor");
return Err(NS_ERROR_EDITOR_DESTROYED);
if (NS_WARN_IF(moveChildResult.inspectErr() ==
NS_ERROR_EDITOR_DESTROYED)) {
return moveChildResult.propagateErr();
}
NS_WARNING(
"HTMLEditor::InsertNodeIntoProperAncestorWithTransaction("
@ -1066,10 +1070,12 @@ HTMLEditor::HTMLWithContextInserter::InsertContents(
"ignored");
break; // from the inner `for` loop
}
CreateContentResult unwrappedMoveChildResult = moveChildResult.unwrap();
inserted = true;
lastInsertedPoint.Set(child);
pointToInsert = lastInsertedPoint.NextPoint();
MOZ_ASSERT(pointToInsert.IsSet());
moveChildResult.MoveCaretPointTo(
unwrappedMoveChildResult.MoveCaretPointTo(
pointToPutCaret, mHTMLEditor,
{SuggestCaret::OnlyIfHasSuggestion,
SuggestCaret::OnlyIfTransactionsAllowedToDoIt});
@ -1095,14 +1101,14 @@ HTMLEditor::HTMLWithContextInserter::InsertContents(
if (!inserted) {
// MOZ_KnownLive(content) because 'aArrayOfTopMostChildContents' is
// guaranteed to keep it alive.
const CreateContentResult moveContentResult =
Result<CreateContentResult, nsresult> moveContentResult =
mHTMLEditor.InsertNodeIntoProperAncestorWithTransaction<nsIContent>(
MOZ_KnownLive(content), pointToInsert,
SplitAtEdges::eDoNotCreateEmptyContainer);
if (moveContentResult.isOk()) {
if (MOZ_LIKELY(moveContentResult.isOk())) {
lastInsertedPoint.Set(content);
pointToInsert = lastInsertedPoint;
nsresult rv = moveContentResult.SuggestCaretPointTo(
nsresult rv = moveContentResult.inspect().SuggestCaretPointTo(
mHTMLEditor, {SuggestCaret::OnlyIfHasSuggestion,
SuggestCaret::OnlyIfTransactionsAllowedToDoIt,
SuggestCaret::AndIgnoreTrivialError});
@ -1113,7 +1119,8 @@ HTMLEditor::HTMLWithContextInserter::InsertContents(
NS_WARNING_ASSERTION(
rv != NS_SUCCESS_EDITOR_BUT_IGNORED_TRIVIAL_ERROR,
"CreateContentResult::SuggestCaretPointTo() failed, but ignored");
} else if (moveContentResult.GotUnexpectedDOMTree()) {
} else if (moveContentResult.inspectErr() ==
NS_ERROR_EDITOR_UNEXPECTED_DOM_TREE) {
// Moving node is moved to different place, we should keep trying to
// insert the next content to same position.
} else {
@ -1133,22 +1140,20 @@ HTMLEditor::HTMLWithContextInserter::InsertContents(
}
const OwningNonNull<nsIContent> oldParentContent =
*childContent->GetParent();
const CreateContentResult moveParentResult =
Result<CreateContentResult, nsresult> moveParentResult =
mHTMLEditor
.InsertNodeIntoProperAncestorWithTransaction<nsIContent>(
oldParentContent, pointToInsert,
SplitAtEdges::eDoNotCreateEmptyContainer);
if (moveParentResult.isErr()) {
if (MOZ_UNLIKELY(moveParentResult.isErr())) {
// Moving node is moved to different place, we should keep trying to
// insert the next content to same position.
if (moveParentResult.GotUnexpectedDOMTree()) {
if (moveParentResult.inspectErr() ==
NS_ERROR_EDITOR_UNEXPECTED_DOM_TREE) {
break; // from the inner `for` loop
}
if (moveParentResult.EditorDestroyed()) {
NS_WARNING(
"HTMLEditor::InsertNodeInToProperAncestorWithTransaction("
"SplitAtEdges::eDoNotCreateEmptyContainer) caused destroying "
"the editor");
if (NS_WARN_IF(moveParentResult.inspectErr() ==
NS_ERROR_EDITOR_DESTROYED)) {
return Err(NS_ERROR_EDITOR_DESTROYED);
}
NS_WARNING(
@ -1159,7 +1164,7 @@ HTMLEditor::HTMLWithContextInserter::InsertContents(
}
insertedContextParentContent = oldParentContent;
pointToInsert.Set(oldParentContent);
nsresult rv = moveParentResult.SuggestCaretPointTo(
nsresult rv = moveParentResult.inspect().SuggestCaretPointTo(
mHTMLEditor, {SuggestCaret::OnlyIfHasSuggestion,
SuggestCaret::OnlyIfTransactionsAllowedToDoIt,
SuggestCaret::AndIgnoreTrivialError});

View file

@ -5322,22 +5322,23 @@ Result<MoveNodeResult, nsresult> HTMLEditor::MoveNodeOrChildrenWithTransaction(
NS_WARNING_ASSERTION(!error.Failed(),
"Element::SetAttr(nsGkAtoms::span) failed");
if (MOZ_LIKELY(!error.Failed())) {
CreateElementResult insertSpanElementResult =
Result<CreateElementResult, nsresult> insertSpanElementResult =
InsertNodeWithTransaction<Element>(*newSpanElement,
aPointToInsert);
if (NS_WARN_IF(insertSpanElementResult.EditorDestroyed())) {
if (MOZ_UNLIKELY(insertSpanElementResult.isErr())) {
if (NS_WARN_IF(insertSpanElementResult.inspectErr() ==
NS_ERROR_EDITOR_DESTROYED)) {
return Err(NS_ERROR_EDITOR_DESTROYED);
}
NS_WARNING_ASSERTION(
insertSpanElementResult.isOk(),
NS_WARNING(
"HTMLEditor::InsertNodeWithTransaction() failed, but ignored");
if (MOZ_LIKELY(insertSpanElementResult.isOk())) {
} else {
// We should move the node into the new <span> to preserve the
// style.
pointToInsert.Set(newSpanElement, 0u);
// We should put caret after aContentToMove after moving it so that
// we do not need the suggested caret point here.
insertSpanElementResult.IgnoreCaretPointSuggestion();
insertSpanElementResult.inspect().IgnoreCaretPointSuggestion();
}
}
}
@ -5642,19 +5643,17 @@ nsresult HTMLEditor::DeleteMostAncestorMailCiteElementIfEmpty(
return NS_OK;
}
CreateElementResult insertBRElementResult =
Result<CreateElementResult, nsresult> insertBRElementResult =
InsertBRElement(WithTransaction::Yes, atEmptyMailCiteElement);
if (insertBRElementResult.isErr()) {
if (MOZ_UNLIKELY(insertBRElementResult.isErr())) {
NS_WARNING("HTMLEditor::InsertBRElement(WithTransaction::Yes) failed");
return insertBRElementResult.unwrapErr();
}
MOZ_ASSERT(insertBRElementResult.GetNewNode());
insertBRElementResult.IgnoreCaretPointSuggestion();
MOZ_ASSERT(insertBRElementResult.inspect().GetNewNode());
insertBRElementResult.inspect().IgnoreCaretPointSuggestion();
nsresult rv = CollapseSelectionTo(
EditorRawDOMPoint(insertBRElementResult.GetNewNode()));
if (MOZ_UNLIKELY(rv == NS_ERROR_EDITOR_DESTROYED)) {
NS_WARNING(
"EditorBase::CollapseSelectionTo() caused destroying the editor");
EditorRawDOMPoint(insertBRElementResult.inspect().GetNewNode()));
if (NS_WARN_IF(rv == NS_ERROR_EDITOR_DESTROYED)) {
return NS_ERROR_EDITOR_DESTROYED;
}
NS_WARNING_ASSERTION(
@ -5809,13 +5808,16 @@ HTMLEditor::AutoDeleteRangesHandler::AutoEmptyBlockAncestorDeleter::
if (HTMLEditUtils::IsAnyListElement(atParentOfEmptyListItem.GetContainer())) {
return RefPtr<Element>();
}
CreateElementResult insertBRElementResult = aHTMLEditor.InsertBRElement(
WithTransaction::Yes, atParentOfEmptyListItem);
if (insertBRElementResult.isErr()) {
Result<CreateElementResult, nsresult> insertBRElementResult =
aHTMLEditor.InsertBRElement(WithTransaction::Yes,
atParentOfEmptyListItem);
if (MOZ_UNLIKELY(insertBRElementResult.isErr())) {
NS_WARNING("HTMLEditor::InsertBRElement(WithTransaction::Yes) failed");
return Err(insertBRElementResult.unwrapErr());
return insertBRElementResult.propagateErr();
}
nsresult rv = insertBRElementResult.SuggestCaretPointTo(
CreateElementResult unwrappedInsertBRElementResult =
insertBRElementResult.unwrap();
nsresult rv = unwrappedInsertBRElementResult.SuggestCaretPointTo(
aHTMLEditor, {SuggestCaret::OnlyIfHasSuggestion,
SuggestCaret::OnlyIfTransactionsAllowedToDoIt,
SuggestCaret::AndIgnoreTrivialError});
@ -5823,8 +5825,8 @@ HTMLEditor::AutoDeleteRangesHandler::AutoEmptyBlockAncestorDeleter::
NS_WARNING("CreateElementResult::SuggestCaretPointTo() failed");
return Err(rv);
}
MOZ_ASSERT(insertBRElementResult.GetNewNode());
return insertBRElementResult.UnwrapNewNode();
MOZ_ASSERT(unwrappedInsertBRElementResult.GetNewNode());
return unwrappedInsertBRElementResult.UnwrapNewNode();
}
Result<EditorDOMPoint, nsresult> HTMLEditor::AutoDeleteRangesHandler::

View file

@ -801,18 +801,20 @@ Result<EditorDOMPoint, nsresult> HTMLEditor::SetInlinePropertyOnNodeImpl(
!aContent.AsElement()->GetAttrCount()) {
spanElement = aContent.AsElement();
} else {
CreateElementResult wrapWithSpanElementResult =
Result<CreateElementResult, nsresult> wrapInSpanElementResult =
InsertContainerWithTransaction(aContent, *nsGkAtoms::span);
if (wrapWithSpanElementResult.isErr()) {
if (MOZ_UNLIKELY(wrapInSpanElementResult.isErr())) {
NS_WARNING(
"HTMLEditor::InsertContainerWithTransaction(nsGkAtoms::span) "
"failed");
return Err(wrapWithSpanElementResult.unwrapErr());
return wrapInSpanElementResult.propagateErr();
}
MOZ_ASSERT(wrapWithSpanElementResult.GetNewNode());
wrapWithSpanElementResult.MoveCaretPointTo(
CreateElementResult unwrappedWrapInSpanElementResult =
wrapInSpanElementResult.unwrap();
MOZ_ASSERT(unwrappedWrapInSpanElementResult.GetNewNode());
unwrappedWrapInSpanElementResult.MoveCaretPointTo(
pointToPutCaret, {SuggestCaret::OnlyIfHasSuggestion});
spanElement = wrapWithSpanElementResult.UnwrapNewNode();
spanElement = unwrappedWrapInSpanElementResult.UnwrapNewNode();
}
// Add the CSS styles corresponding to the HTML style request
@ -858,16 +860,16 @@ Result<EditorDOMPoint, nsresult> HTMLEditor::SetInlinePropertyOnNodeImpl(
}
// ok, chuck it in its very own container
CreateElementResult wrapWithNewElementToFormatResult =
Result<CreateElementResult, nsresult> wrapWithNewElementToFormatResult =
InsertContainerWithTransaction(
aContent, aProperty, aAttribute ? *aAttribute : *nsGkAtoms::_empty,
aValue);
if (wrapWithNewElementToFormatResult.isErr()) {
if (MOZ_UNLIKELY(wrapWithNewElementToFormatResult.isErr())) {
NS_WARNING("HTMLEditor::InsertContainerWithTransaction() failed");
return Err(wrapWithNewElementToFormatResult.unwrapErr());
return wrapWithNewElementToFormatResult.propagateErr();
}
MOZ_ASSERT(wrapWithNewElementToFormatResult.GetNewNode());
return wrapWithNewElementToFormatResult.UnwrapCaretPoint();
MOZ_ASSERT(wrapWithNewElementToFormatResult.inspect().GetNewNode());
return wrapWithNewElementToFormatResult.unwrap().UnwrapCaretPoint();
}
Result<EditorDOMPoint, nsresult> HTMLEditor::SetInlinePropertyOnNode(
@ -1446,19 +1448,21 @@ Result<EditorDOMPoint, nsresult> HTMLEditor::RemoveStyleInside(
aElement.HasAttr(kNameSpaceID_None, nsGkAtoms::_class))) {
// Move `style` attribute and `class` element to span element before
// removing aElement from the tree.
CreateElementResult wrapWithSpanElementResult =
Result<CreateElementResult, nsresult> wrapInSpanElementResult =
InsertContainerWithTransaction(aElement, *nsGkAtoms::span);
if (wrapWithSpanElementResult.isErr()) {
if (wrapInSpanElementResult.isErr()) {
NS_WARNING(
"HTMLEditor::InsertContainerWithTransaction(nsGkAtoms::span) "
"failed");
return Err(wrapWithSpanElementResult.unwrapErr());
return wrapInSpanElementResult.propagateErr();
}
MOZ_ASSERT(wrapWithSpanElementResult.GetNewNode());
wrapWithSpanElementResult.MoveCaretPointTo(
CreateElementResult unwrappedWrapInSpanElementResult =
wrapInSpanElementResult.unwrap();
MOZ_ASSERT(unwrappedWrapInSpanElementResult.GetNewNode());
unwrappedWrapInSpanElementResult.MoveCaretPointTo(
pointToPutCaret, {SuggestCaret::OnlyIfHasSuggestion});
const RefPtr<Element> spanElement =
wrapWithSpanElementResult.UnwrapNewNode();
unwrappedWrapInSpanElementResult.UnwrapNewNode();
nsresult rv = CloneAttributeWithTransaction(*nsGkAtoms::style,
*spanElement, aElement);
if (NS_WARN_IF(Destroyed())) {
@ -2693,18 +2697,18 @@ nsresult HTMLEditor::IncrementOrDecrementFontSizeAsSubAction(
}
if (range.InSameContainer() && range.StartRef().IsInTextNode()) {
CreateElementResult wrapWithBigOrSmallElementResult =
Result<CreateElementResult, nsresult> wrapInBigOrSmallElementResult =
SetFontSizeOnTextNode(
MOZ_KnownLive(*range.StartRef().ContainerAs<Text>()),
range.StartRef().Offset(), range.EndRef().Offset(),
aIncrementOrDecrement);
if (wrapWithBigOrSmallElementResult.isErr()) {
if (MOZ_UNLIKELY(wrapInBigOrSmallElementResult.isErr())) {
NS_WARNING("HTMLEditor::SetFontSizeOnTextNode() failed");
return wrapWithBigOrSmallElementResult.unwrapErr();
return wrapInBigOrSmallElementResult.unwrapErr();
}
// There is an AutoTransactionsConserveSelection instance so that we don't
// need to update selection for this change.
wrapWithBigOrSmallElementResult.IgnoreCaretPointSuggestion();
wrapInBigOrSmallElementResult.inspect().IgnoreCaretPointSuggestion();
continue;
}
@ -2757,34 +2761,34 @@ nsresult HTMLEditor::IncrementOrDecrementFontSizeAsSubAction(
!range.StartRef().IsEndOfContainer() &&
EditorUtils::IsEditableContent(*range.StartRef().ContainerAs<Text>(),
EditorType::HTML)) {
CreateElementResult wrapWithBigOrSmallElementResult =
Result<CreateElementResult, nsresult> wrapInBigOrSmallElementResult =
SetFontSizeOnTextNode(
MOZ_KnownLive(*range.StartRef().ContainerAs<Text>()),
range.StartRef().Offset(),
range.StartRef().ContainerAs<Text>()->TextDataLength(),
aIncrementOrDecrement);
if (wrapWithBigOrSmallElementResult.isErr()) {
if (MOZ_UNLIKELY(wrapInBigOrSmallElementResult.isErr())) {
NS_WARNING("HTMLEditor::SetFontSizeOnTextNode() failed");
return wrapWithBigOrSmallElementResult.unwrapErr();
return wrapInBigOrSmallElementResult.unwrapErr();
}
// There is an AutoTransactionsConserveSelection instance so that we
// don't need to update selection for this change.
wrapWithBigOrSmallElementResult.IgnoreCaretPointSuggestion();
wrapInBigOrSmallElementResult.inspect().IgnoreCaretPointSuggestion();
}
if (range.EndRef().IsInTextNode() && !range.EndRef().IsStartOfContainer() &&
EditorUtils::IsEditableContent(*range.EndRef().ContainerAs<Text>(),
EditorType::HTML)) {
CreateElementResult wrapWithBigOrSmallElementResult =
Result<CreateElementResult, nsresult> wrapInBigOrSmallElementResult =
SetFontSizeOnTextNode(
MOZ_KnownLive(*range.EndRef().ContainerAs<Text>()), 0u,
range.EndRef().Offset(), aIncrementOrDecrement);
if (wrapWithBigOrSmallElementResult.isErr()) {
if (MOZ_UNLIKELY(wrapInBigOrSmallElementResult.isErr())) {
NS_WARNING("HTMLEditor::SetFontSizeOnTextNode() failed");
return wrapWithBigOrSmallElementResult.unwrapErr();
return wrapInBigOrSmallElementResult.unwrapErr();
}
// There is an AutoTransactionsConserveSelection instance so that we
// don't need to update selection for this change.
wrapWithBigOrSmallElementResult.IgnoreCaretPointSuggestion();
wrapInBigOrSmallElementResult.inspect().IgnoreCaretPointSuggestion();
}
}
@ -2798,7 +2802,7 @@ nsresult HTMLEditor::IncrementOrDecrementFontSizeAsSubAction(
return rv;
}
CreateElementResult HTMLEditor::SetFontSizeOnTextNode(
Result<CreateElementResult, nsresult> HTMLEditor::SetFontSizeOnTextNode(
Text& aTextNode, uint32_t aStartOffset, uint32_t aEndOffset,
FontSize aIncrementOrDecrement) {
// Don't need to do anything if no characters actually selected
@ -2878,7 +2882,7 @@ CreateElementResult HTMLEditor::SetFontSizeOnTextNode(
}();
if (MOZ_UNLIKELY(pointToPutCaretOrError.isErr())) {
// Don't warn here since it should be done in the lambda.
return CreateElementResult(pointToPutCaretOrError.unwrapErr());
return pointToPutCaretOrError.propagateErr();
}
pointToPutCaret = pointToPutCaretOrError.unwrap();
}
@ -2895,7 +2899,7 @@ CreateElementResult HTMLEditor::SetFontSizeOnTextNode(
MoveNodeToEndWithTransaction(*textNodeForTheRange, *sibling);
if (MOZ_UNLIKELY(moveTextNodeResult.isErr())) {
NS_WARNING("HTMLEditor::MoveNodeToEndWithTransaction() failed");
return CreateElementResult(moveTextNodeResult.unwrapErr());
return moveTextNodeResult.propagateErr();
}
MoveNodeResult unwrappedMoveTextNodeResult = moveTextNodeResult.unwrap();
unwrappedMoveTextNodeResult.MoveCaretPointTo(
@ -2912,7 +2916,7 @@ CreateElementResult HTMLEditor::SetFontSizeOnTextNode(
EditorDOMPoint(sibling, 0u));
if (MOZ_UNLIKELY(moveTextNodeResult.isErr())) {
NS_WARNING("HTMLEditor::MoveNodeWithTransaction() failed");
return CreateElementResult(moveTextNodeResult.unwrapErr());
return moveTextNodeResult.propagateErr();
}
MoveNodeResult unwrappedMoveTextNodeResult = moveTextNodeResult.unwrap();
unwrappedMoveTextNodeResult.MoveCaretPointTo(
@ -2922,17 +2926,19 @@ CreateElementResult HTMLEditor::SetFontSizeOnTextNode(
}
// Else wrap the node inside font node with appropriate relative size
CreateElementResult wrapTextWithBigOrSmallElementResult =
Result<CreateElementResult, nsresult> wrapTextInBigOrSmallElementResult =
InsertContainerWithTransaction(*textNodeForTheRange,
MOZ_KnownLive(*bigOrSmallTagName));
if (wrapTextWithBigOrSmallElementResult.isErr()) {
if (wrapTextInBigOrSmallElementResult.isErr()) {
NS_WARNING("HTMLEditor::InsertContainerWithTransaction() failed");
return wrapTextWithBigOrSmallElementResult;
return wrapTextInBigOrSmallElementResult;
}
wrapTextWithBigOrSmallElementResult.MoveCaretPointTo(
CreateElementResult unwrappedWrapTextInBigOrSmallElementResult =
wrapTextInBigOrSmallElementResult.unwrap();
unwrappedWrapTextInBigOrSmallElementResult.MoveCaretPointTo(
pointToPutCaret, {SuggestCaret::OnlyIfHasSuggestion});
return CreateElementResult(
wrapTextWithBigOrSmallElementResult.UnwrapNewNode(),
unwrappedWrapTextInBigOrSmallElementResult.UnwrapNewNode(),
std::move(pointToPutCaret));
}
@ -3066,15 +3072,17 @@ Result<EditorDOMPoint, nsresult> HTMLEditor::SetFontSizeWithBigOrSmallElement(
}
// Otherwise, wrap aContent in new <big> or <small>
CreateElementResult wrapInBigOrSmallElementResult =
Result<CreateElementResult, nsresult> wrapInBigOrSmallElementResult =
InsertContainerWithTransaction(aContent,
MOZ_KnownLive(*bigOrSmallTagName));
if (wrapInBigOrSmallElementResult.isErr()) {
if (MOZ_UNLIKELY(wrapInBigOrSmallElementResult.isErr())) {
NS_WARNING("HTMLEditor::InsertContainerWithTransaction() failed");
return Err(wrapInBigOrSmallElementResult.unwrapErr());
}
MOZ_ASSERT(wrapInBigOrSmallElementResult.GetNewNode());
wrapInBigOrSmallElementResult.MoveCaretPointTo(
CreateElementResult unwrappedWrapInBigOrSmallElementResult =
wrapInBigOrSmallElementResult.unwrap();
MOZ_ASSERT(unwrappedWrapInBigOrSmallElementResult.GetNewNode());
unwrappedWrapInBigOrSmallElementResult.MoveCaretPointTo(
pointToPutCaret, {SuggestCaret::OnlyIfHasSuggestion});
return pointToPutCaret;
}

View file

@ -273,15 +273,15 @@ nsresult HTMLEditor::InsertCell(Element* aCell, int32_t aRowSpan,
// actions which may be caused by legacy mutation event listeners or
// chrome script.
AutoTransactionsConserveSelection dontChangeSelection(*this);
CreateElementResult insertNewCellResult =
Result<CreateElementResult, nsresult> insertNewCellResult =
InsertNodeWithTransaction<Element>(*newCell, pointToInsert);
if (insertNewCellResult.isErr()) {
if (MOZ_UNLIKELY(insertNewCellResult.isErr())) {
NS_WARNING("EditorBase::InsertNodeWithTransaction() failed");
return insertNewCellResult.unwrapErr();
}
// Because of dontChangeSelection, we've never allowed to transactions to
// update selection here.
insertNewCellResult.IgnoreCaretPointSuggestion();
insertNewCellResult.inspect().IgnoreCaretPointSuggestion();
return NS_OK;
}
@ -350,18 +350,19 @@ NS_IMETHODIMP HTMLEditor::InsertTableCell(int32_t aNumberOfCellsToInsert,
advanced,
"Failed to set insertion point after current cell, but ignored");
}
const CreateElementResult insertCellElementResult =
Result<CreateElementResult, nsresult> insertCellElementResult =
InsertTableCellsWithTransaction(pointToInsert, aNumberOfCellsToInsert);
if (insertCellElementResult.isErr()) {
if (MOZ_UNLIKELY(insertCellElementResult.isErr())) {
NS_WARNING("HTMLEditor::InsertTableCellsWithTransaction() failed");
return EditorBase::ToGenericNSResult(insertCellElementResult.inspectErr());
return EditorBase::ToGenericNSResult(insertCellElementResult.unwrapErr());
}
// We don't need to modify selection here.
insertCellElementResult.IgnoreCaretPointSuggestion();
insertCellElementResult.inspect().IgnoreCaretPointSuggestion();
return NS_OK;
}
CreateElementResult HTMLEditor::InsertTableCellsWithTransaction(
Result<CreateElementResult, nsresult>
HTMLEditor::InsertTableCellsWithTransaction(
const EditorDOMPoint& aPointToInsert, int32_t aNumberOfCellsToInsert) {
MOZ_ASSERT(IsEditActionDataAvailable());
MOZ_ASSERT(aPointToInsert.IsSetAndValid());
@ -369,7 +370,7 @@ CreateElementResult HTMLEditor::InsertTableCellsWithTransaction(
if (!HTMLEditUtils::IsTableRow(aPointToInsert.GetContainer())) {
NS_WARNING("Tried to insert cell elements to non-<tr> element");
return CreateElementResult(NS_ERROR_FAILURE);
return Err(NS_ERROR_FAILURE);
}
AutoPlaceholderBatch treateAsOneTransaction(
@ -381,7 +382,7 @@ CreateElementResult HTMLEditor::InsertTableCellsWithTransaction(
AutoEditSubActionNotifier startToHandleEditSubAction(
*this, EditSubAction::eInsertNode, nsIEditor::eNext, error);
if (NS_WARN_IF(error.ErrorCodeIs(NS_ERROR_EDITOR_DESTROYED))) {
return CreateElementResult(error.StealNSResult());
return Err(error.StealNSResult());
}
NS_WARNING_ASSERTION(
!error.Failed(),
@ -422,22 +423,25 @@ CreateElementResult HTMLEditor::InsertTableCellsWithTransaction(
"HTMLEditor::CreateElementWithDefaults(nsGkAtoms::td) failed");
return NS_ERROR_FAILURE;
}
CreateElementResult insertNewCellResult = InsertNodeWithTransaction(
Result<CreateElementResult, nsresult> insertNewCellResult =
InsertNodeWithTransaction(
*newCell, referenceContent
? EditorDOMPoint(referenceContent)
: EditorDOMPoint::AtEndOf(
*aPointToInsert.ContainerAs<Element>()));
if (insertNewCellResult.isErr()) {
if (MOZ_UNLIKELY(insertNewCellResult.isErr())) {
NS_WARNING("EditorBase::InsertNodeWithTransaction() failed");
return insertNewCellResult.unwrapErr();
}
lastCellElement = insertNewCellResult.UnwrapNewNode();
CreateElementResult unwrappedInsertNewCellResult =
insertNewCellResult.unwrap();
lastCellElement = unwrappedInsertNewCellResult.UnwrapNewNode();
if (!firstCellElement) {
firstCellElement = lastCellElement;
}
// Because of dontChangeSelection, we've never allowed to transactions
// to update selection here.
insertNewCellResult.IgnoreCaretPointSuggestion();
unwrappedInsertNewCellResult.IgnoreCaretPointSuggestion();
if (!cellToPutCaret) {
cellToPutCaret = std::move(newCell); // This is first cell in the row.
}
@ -451,10 +455,10 @@ CreateElementResult HTMLEditor::InsertTableCellsWithTransaction(
}();
if (MOZ_UNLIKELY(rv == NS_ERROR_EDITOR_DESTROYED ||
NS_WARN_IF(Destroyed()))) {
return CreateElementResult(NS_ERROR_EDITOR_DESTROYED);
return Err(NS_ERROR_EDITOR_DESTROYED);
}
if (NS_FAILED(rv)) {
return CreateElementResult(rv);
return Err(rv);
}
MOZ_ASSERT(firstCellElement);
MOZ_ASSERT(lastCellElement);
@ -812,19 +816,22 @@ nsresult HTMLEditor::InsertTableColumnsWithTransaction(
if (NS_WARN_IF(!pointToInsert.IsInContentNode())) {
return Err(NS_ERROR_EDITOR_UNEXPECTED_DOM_TREE);
}
CreateElementResult insertCellElementsResult =
Result<CreateElementResult, nsresult> insertCellElementsResult =
InsertTableCellsWithTransaction(pointToInsert,
aNumberOfColumnsToInsert);
if (insertCellElementsResult.isErr()) {
if (MOZ_UNLIKELY(insertCellElementsResult.isErr())) {
NS_WARNING("HTMLEditor::InsertTableCellsWithTransaction() failed");
return Err(insertCellElementsResult.unwrapErr());
return insertCellElementsResult.propagateErr();
}
CreateElementResult unwrappedInsertCellElementsResult =
insertCellElementsResult.unwrap();
// We'll update selection later into the first inserted cell element in
// the current row.
insertCellElementsResult.IgnoreCaretPointSuggestion();
unwrappedInsertCellElementsResult.IgnoreCaretPointSuggestion();
if (pointToInsert.ContainerAs<Element>() ==
aPointToInsert.ContainerAs<Element>()) {
cellElementToPutCaret = insertCellElementsResult.UnwrapNewNode();
cellElementToPutCaret =
unwrappedInsertCellElementsResult.UnwrapNewNode();
MOZ_ASSERT(cellElementToPutCaret);
MOZ_ASSERT(HTMLEditUtils::IsTableCell(cellElementToPutCaret));
}
@ -1147,15 +1154,19 @@ nsresult HTMLEditor::InsertTableRowsWithTransaction(
}
AutoEditorDOMPointChildInvalidator lockOffset(pointToInsert);
CreateElementResult insertNewRowResult =
Result<CreateElementResult, nsresult> insertNewRowResult =
InsertNodeWithTransaction<Element>(*newRowElement, pointToInsert);
if (insertNewRowResult.isErr() && !insertNewRowResult.EditorDestroyed()) {
if (MOZ_UNLIKELY(insertNewRowResult.isErr())) {
if (insertNewRowResult.inspectErr() == NS_ERROR_EDITOR_DESTROYED) {
NS_WARNING("EditorBase::InsertNodeWithTransaction() failed");
return Err(insertNewRowResult.unwrapErr());
return insertNewRowResult.propagateErr();
}
NS_WARNING(
"EditorBase::InsertNodeWithTransaction() failed, but ignored");
}
firstInsertedTRElement = std::move(newRowElement);
// We'll update selection later.
insertNewRowResult.IgnoreCaretPointSuggestion();
insertNewRowResult.inspect().IgnoreCaretPointSuggestion();
}
return firstInsertedTRElement;
}();
@ -2909,21 +2920,21 @@ NS_IMETHODIMP HTMLEditor::SwitchTableCellHeaderType(Element* aSourceCell,
// This creates new node, moves children, copies attributes (true)
// and manages the selection!
CreateElementResult newCellElementOrError =
Result<CreateElementResult, nsresult> newCellElementOrError =
ReplaceContainerAndCloneAttributesWithTransaction(
*aSourceCell, MOZ_KnownLive(*newCellName));
if (newCellElementOrError.isErr()) {
if (MOZ_UNLIKELY(newCellElementOrError.isErr())) {
NS_WARNING(
"EditorBase::ReplaceContainerAndCloneAttributesWithTransaction() "
"failed");
return newCellElementOrError.unwrapErr();
}
// restoreSelectionLater will change selection
newCellElementOrError.IgnoreCaretPointSuggestion();
newCellElementOrError.inspect().IgnoreCaretPointSuggestion();
// Return the new cell
if (aNewCell) {
newCellElementOrError.UnwrapNewNode().forget(aNewCell);
newCellElementOrError.unwrap().UnwrapNewNode().forget(aNewCell);
}
return NS_OK;
@ -3384,13 +3395,16 @@ nsresult HTMLEditor::MergeCells(RefPtr<Element> aTargetCell,
NS_WARNING("EditorBase::DeleteNodeWithTransaction() failed");
return rv;
}
CreateContentResult insertChildContentResult = InsertNodeWithTransaction(
*cellChild, EditorDOMPoint(aTargetCell, insertIndex));
if (insertChildContentResult.isErr()) {
Result<CreateContentResult, nsresult> insertChildContentResult =
InsertNodeWithTransaction(*cellChild,
EditorDOMPoint(aTargetCell, insertIndex));
if (MOZ_UNLIKELY(insertChildContentResult.isErr())) {
NS_WARNING("EditorBase::InsertNodeWithTransaction() failed");
return insertChildContentResult.unwrapErr();
}
insertChildContentResult.MoveCaretPointTo(
CreateContentResult unwrappedInsertChildContentResult =
insertChildContentResult.unwrap();
unwrappedInsertChildContentResult.MoveCaretPointTo(
pointToPutCaret, *this,
{SuggestCaret::OnlyIfHasSuggestion,
SuggestCaret::OnlyIfTransactionsAllowedToDoIt});

View file

@ -678,19 +678,20 @@ EditActionResult WhiteSpaceVisibilityKeeper::
"HTMLEditor::JoinNearestEditableNodesWithTransaction()"
" failed, but ignored");
if (aListElementTagName.isSome() && atFirstChildOfRightNode.IsSet()) {
CreateElementResult convertListTypeResult =
Result<CreateElementResult, nsresult> convertListTypeResult =
aHTMLEditor.ChangeListElementType(
aRightBlockElement, MOZ_KnownLive(*aListElementTagName.ref()),
*nsGkAtoms::li);
if (NS_WARN_IF(convertListTypeResult.EditorDestroyed())) {
if (MOZ_UNLIKELY(convertListTypeResult.isErr())) {
if (NS_WARN_IF(convertListTypeResult.inspectErr() ==
NS_ERROR_EDITOR_DESTROYED)) {
return EditActionResult(NS_ERROR_EDITOR_DESTROYED);
}
NS_WARNING("HTMLEditor::ChangeListElementType() failed, but ignored");
}
// There is AutoTransactionConserveSelection above, therefore, we don't
// need to update selection here.
convertListTypeResult.IgnoreCaretPointSuggestion();
NS_WARNING_ASSERTION(
convertListTypeResult.isOk(),
"HTMLEditor::ChangeListElementType() failed, but ignored");
convertListTypeResult.inspect().IgnoreCaretPointSuggestion();
}
ret.MarkAsHandled();
} else {
@ -748,11 +749,12 @@ EditActionResult WhiteSpaceVisibilityKeeper::
}
// static
CreateElementResult WhiteSpaceVisibilityKeeper::InsertBRElement(
Result<CreateElementResult, nsresult>
WhiteSpaceVisibilityKeeper::InsertBRElement(
HTMLEditor& aHTMLEditor, const EditorDOMPoint& aPointToInsert,
const Element& aEditingHost) {
if (MOZ_UNLIKELY(NS_WARN_IF(!aPointToInsert.IsSet()))) {
return CreateElementResult(NS_ERROR_INVALID_ARG);
return Err(NS_ERROR_INVALID_ARG);
}
// MOOSE: for now, we always assume non-PRE formatting. Fix this later.
@ -763,7 +765,7 @@ CreateElementResult WhiteSpaceVisibilityKeeper::InsertBRElement(
&aEditingHost);
if (MOZ_UNLIKELY(
NS_WARN_IF(!textFragmentDataAtInsertionPoint.IsInitialized()))) {
return CreateElementResult(NS_ERROR_FAILURE);
return Err(NS_ERROR_FAILURE);
}
EditorDOMRange invisibleLeadingWhiteSpaceRangeOfNewLine =
textFragmentDataAtInsertionPoint
@ -782,11 +784,11 @@ CreateElementResult WhiteSpaceVisibilityKeeper::InsertBRElement(
: PointPosition::NotInSameDOMTree;
EditorDOMPoint pointToInsert(aPointToInsert);
EditorDOMPoint atNBSPReplacableWithSP;
EditorDOMPoint atNBSPReplaceableWithSP;
if (!invisibleLeadingWhiteSpaceRangeOfNewLine.IsPositioned() &&
(pointPositionWithVisibleWhiteSpaces == PointPosition::MiddleOfFragment ||
pointPositionWithVisibleWhiteSpaces == PointPosition::EndOfFragment)) {
atNBSPReplacableWithSP =
atNBSPReplaceableWithSP =
textFragmentDataAtInsertionPoint
.GetPreviousNBSPPointIfNeedToReplaceWithASCIIWhiteSpace(
pointToInsert)
@ -802,7 +804,7 @@ CreateElementResult WhiteSpaceVisibilityKeeper::InsertBRElement(
AutoTrackDOMPoint trackPointToInsert(aHTMLEditor.RangeUpdaterRef(),
&pointToInsert);
AutoTrackDOMPoint trackEndOfLineNBSP(aHTMLEditor.RangeUpdaterRef(),
&atNBSPReplacableWithSP);
&atNBSPReplaceableWithSP);
AutoTrackDOMRange trackLeadingWhiteSpaceRange(
aHTMLEditor.RangeUpdaterRef(),
&invisibleLeadingWhiteSpaceRangeOfNewLine);
@ -810,10 +812,10 @@ CreateElementResult WhiteSpaceVisibilityKeeper::InsertBRElement(
invisibleTrailingWhiteSpaceRangeOfCurrentLine.StartRef(),
invisibleTrailingWhiteSpaceRangeOfCurrentLine.EndRef(),
HTMLEditor::TreatEmptyTextNodes::KeepIfContainerOfRangeBoundaries);
if (MOZ_UNLIKELY(NS_FAILED(rv))) {
if (NS_FAILED(rv)) {
NS_WARNING(
"HTMLEditor::DeleteTextAndTextNodesWithTransaction() failed");
return CreateElementResult(rv);
return Err(rv);
}
// Don't refer the following variables anymore unless tracking the
// change.
@ -842,7 +844,7 @@ CreateElementResult WhiteSpaceVisibilityKeeper::InsertBRElement(
AutoTrackDOMPoint trackPointToInsert(aHTMLEditor.RangeUpdaterRef(),
&pointToInsert);
AutoTrackDOMPoint trackEndOfLineNBSP(aHTMLEditor.RangeUpdaterRef(),
&atNBSPReplacableWithSP);
&atNBSPReplaceableWithSP);
AutoTrackDOMRange trackLeadingWhiteSpaceRange(
aHTMLEditor.RangeUpdaterRef(),
&invisibleLeadingWhiteSpaceRangeOfNewLine);
@ -861,7 +863,7 @@ CreateElementResult WhiteSpaceVisibilityKeeper::InsertBRElement(
NS_WARNING(
"WhiteSpaceVisibilityKeeper::"
"ReplaceTextAndRemoveEmptyTextNodes() failed");
return CreateElementResult(rv);
return Err(rv);
}
// Don't refer the following variables anymore unless tracking the
// change.
@ -881,24 +883,24 @@ CreateElementResult WhiteSpaceVisibilityKeeper::InsertBRElement(
invisibleLeadingWhiteSpaceRangeOfNewLine.StartRef(),
invisibleLeadingWhiteSpaceRangeOfNewLine.EndRef(),
HTMLEditor::TreatEmptyTextNodes::KeepIfContainerOfRangeBoundaries);
if (MOZ_UNLIKELY(NS_FAILED(rv))) {
if (NS_FAILED(rv)) {
NS_WARNING(
"WhiteSpaceVisibilityKeeper::"
"DeleteTextAndTextNodesWithTransaction() failed");
return CreateElementResult(rv);
return Err(rv);
}
// Don't refer the following variables anymore unless tracking the
// change.
atNBSPReplacableWithSP.Clear();
atNBSPReplaceableWithSP.Clear();
invisibleLeadingWhiteSpaceRangeOfNewLine.Clear();
invisibleTrailingWhiteSpaceRangeOfCurrentLine.Clear();
}
}
// If the `<br>` element is put immediately after an NBSP, it should be
// replaced with an ASCII white-space.
else if (atNBSPReplacableWithSP.IsInTextNode()) {
else if (atNBSPReplaceableWithSP.IsInTextNode()) {
const EditorDOMPointInText atNBSPReplacedWithASCIIWhiteSpace =
atNBSPReplacableWithSP.AsInText();
atNBSPReplaceableWithSP.AsInText();
if (!atNBSPReplacedWithASCIIWhiteSpace.IsEndOfContainer() &&
atNBSPReplacedWithASCIIWhiteSpace.IsCharNBSP()) {
AutoTrackDOMPoint trackPointToInsert(aHTMLEditor.RangeUpdaterRef(),
@ -908,21 +910,22 @@ CreateElementResult WhiteSpaceVisibilityKeeper::InsertBRElement(
MOZ_KnownLive(
*atNBSPReplacedWithASCIIWhiteSpace.ContainerAs<Text>()),
atNBSPReplacedWithASCIIWhiteSpace.Offset(), 1, u" "_ns);
if (MOZ_UNLIKELY(NS_FAILED(rv))) {
if (NS_FAILED(rv)) {
NS_WARNING("HTMLEditor::ReplaceTextWithTransaction() failed failed");
return CreateElementResult(rv);
return Err(rv);
}
// Don't refer the following variables anymore unless tracking the
// change.
atNBSPReplacableWithSP.Clear();
atNBSPReplaceableWithSP.Clear();
invisibleLeadingWhiteSpaceRangeOfNewLine.Clear();
invisibleTrailingWhiteSpaceRangeOfCurrentLine.Clear();
}
}
}
CreateElementResult insertBRElementResult = aHTMLEditor.InsertBRElement(
HTMLEditor::WithTransaction::Yes, pointToInsert);
Result<CreateElementResult, nsresult> insertBRElementResult =
aHTMLEditor.InsertBRElement(HTMLEditor::WithTransaction::Yes,
pointToInsert);
NS_WARNING_ASSERTION(
insertBRElementResult.isOk(),
"HTMLEditor::InsertBRElement(WithTransaction::Yes, eNone) failed");
@ -3169,16 +3172,16 @@ nsresult WhiteSpaceVisibilityKeeper::NormalizeVisibleWhiteSpacesAt(
// the beginning of soft wrapped lines, and lets the user see 2 spaces
// when they type 2 spaces.
const CreateElementResult insertBRElementResult =
Result<CreateElementResult, nsresult> insertBRElementResult =
aHTMLEditor.InsertBRElement(HTMLEditor::WithTransaction::Yes,
atEndOfVisibleWhiteSpaces);
if (insertBRElementResult.isErr()) {
if (MOZ_UNLIKELY(insertBRElementResult.isErr())) {
NS_WARNING(
"HTMLEditor::InsertBRElement(WithTransaction::Yes) failed");
return insertBRElementResult.unwrapErr();
}
// XXX Is this intentional selection change?
nsresult rv = insertBRElementResult.SuggestCaretPointTo(
nsresult rv = insertBRElementResult.inspect().SuggestCaretPointTo(
aHTMLEditor, {SuggestCaret::OnlyIfHasSuggestion,
SuggestCaret::OnlyIfTransactionsAllowedToDoIt,
SuggestCaret::AndIgnoreTrivialError});
@ -3189,7 +3192,7 @@ nsresult WhiteSpaceVisibilityKeeper::NormalizeVisibleWhiteSpacesAt(
NS_WARNING_ASSERTION(
rv != NS_SUCCESS_EDITOR_BUT_IGNORED_TRIVIAL_ERROR,
"CreateElementResult::SuggestCaretPointTo() failed, but ignored");
MOZ_ASSERT(insertBRElementResult.GetNewNode());
MOZ_ASSERT(insertBRElementResult.inspect().GetNewNode());
atPreviousCharOfEndOfVisibleWhiteSpaces =
textFragmentData.GetPreviousEditableCharPoint(

View file

@ -1473,8 +1473,8 @@ class WhiteSpaceVisibilityKeeper final {
* @return If succeeded, returns the new <br> element and
* point to put caret.
*/
[[nodiscard]] MOZ_CAN_RUN_SCRIPT static CreateElementResult InsertBRElement(
HTMLEditor& aHTMLEditor, const EditorDOMPoint& aPointToInsert,
[[nodiscard]] MOZ_CAN_RUN_SCRIPT static Result<CreateElementResult, nsresult>
InsertBRElement(HTMLEditor& aHTMLEditor, const EditorDOMPoint& aPointToInsert,
const Element& aEditingHost);
/**