Bug 1770877 - part 33: Make HTMLEditor::RelativeFontChangeOnTextNode stop touching Selection directly r=m_kato
Differential Revision: https://phabricator.services.mozilla.com/D149104
This commit is contained in:
@@ -2547,13 +2547,17 @@ nsresult HTMLEditor::RelativeFontChange(FontSize aDir) {
|
||||
MOZ_ASSERT(startNode);
|
||||
MOZ_ASSERT(endNode);
|
||||
if (startNode == endNode && startNode->IsText()) {
|
||||
nsresult rv = RelativeFontChangeOnTextNode(
|
||||
aDir, MOZ_KnownLive(*startNode->GetAsText()), range->StartOffset(),
|
||||
range->EndOffset());
|
||||
if (NS_FAILED(rv)) {
|
||||
CreateElementResult wrapWithBigOrSmallElementResult =
|
||||
RelativeFontChangeOnTextNode(
|
||||
aDir, MOZ_KnownLive(*startNode->GetAsText()),
|
||||
range->StartOffset(), range->EndOffset());
|
||||
if (wrapWithBigOrSmallElementResult.isErr()) {
|
||||
NS_WARNING("HTMLEditor::RelativeFontChangeOnTextNode() failed");
|
||||
return rv;
|
||||
return wrapWithBigOrSmallElementResult.unwrapErr();
|
||||
}
|
||||
// There is an AutoTransactionsConserveSelection instance so that we don't
|
||||
// need to update selection for this change.
|
||||
wrapWithBigOrSmallElementResult.IgnoreCaretPointSuggestion();
|
||||
} else {
|
||||
// Not the easy case. Range not contained in single text node. There
|
||||
// are up to three phases here. There are all the nodes reported by the
|
||||
@@ -2599,22 +2603,30 @@ nsresult HTMLEditor::RelativeFontChange(FontSize aDir) {
|
||||
// the subtree iterator works - it will not have reported them).
|
||||
if (startNode->IsText() && EditorUtils::IsEditableContent(
|
||||
*startNode->AsText(), EditorType::HTML)) {
|
||||
nsresult rv = RelativeFontChangeOnTextNode(
|
||||
aDir, MOZ_KnownLive(*startNode->AsText()), range->StartOffset(),
|
||||
startNode->Length());
|
||||
if (NS_FAILED(rv)) {
|
||||
CreateElementResult wrapWithBigOrSmallElementResult =
|
||||
RelativeFontChangeOnTextNode(
|
||||
aDir, MOZ_KnownLive(*startNode->AsText()), range->StartOffset(),
|
||||
startNode->Length());
|
||||
if (wrapWithBigOrSmallElementResult.isErr()) {
|
||||
NS_WARNING("HTMLEditor::RelativeFontChangeOnTextNode() failed");
|
||||
return rv;
|
||||
return wrapWithBigOrSmallElementResult.unwrapErr();
|
||||
}
|
||||
// There is an AutoTransactionsConserveSelection instance so that we
|
||||
// don't need to update selection for this change.
|
||||
wrapWithBigOrSmallElementResult.IgnoreCaretPointSuggestion();
|
||||
}
|
||||
if (endNode->IsText() && EditorUtils::IsEditableContent(
|
||||
*endNode->AsText(), EditorType::HTML)) {
|
||||
nsresult rv = RelativeFontChangeOnTextNode(
|
||||
aDir, MOZ_KnownLive(*endNode->AsText()), 0, range->EndOffset());
|
||||
if (NS_FAILED(rv)) {
|
||||
CreateElementResult wrapWithBigOrSmallElementResult =
|
||||
RelativeFontChangeOnTextNode(
|
||||
aDir, MOZ_KnownLive(*endNode->AsText()), 0, range->EndOffset());
|
||||
if (wrapWithBigOrSmallElementResult.isErr()) {
|
||||
NS_WARNING("HTMLEditor::RelativeFontChangeOnTextNode() failed");
|
||||
return rv;
|
||||
return wrapWithBigOrSmallElementResult.unwrapErr();
|
||||
}
|
||||
// There is an AutoTransactionsConserveSelection instance so that we
|
||||
// don't need to update selection for this change.
|
||||
wrapWithBigOrSmallElementResult.IgnoreCaretPointSuggestion();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2622,19 +2634,18 @@ nsresult HTMLEditor::RelativeFontChange(FontSize aDir) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult HTMLEditor::RelativeFontChangeOnTextNode(FontSize aDir,
|
||||
Text& aTextNode,
|
||||
uint32_t aStartOffset,
|
||||
uint32_t aEndOffset) {
|
||||
CreateElementResult HTMLEditor::RelativeFontChangeOnTextNode(
|
||||
FontSize aDir, Text& aTextNode, uint32_t aStartOffset,
|
||||
uint32_t aEndOffset) {
|
||||
// Don't need to do anything if no characters actually selected
|
||||
if (aStartOffset == aEndOffset) {
|
||||
return NS_OK;
|
||||
return CreateElementResult::NotHandled();
|
||||
}
|
||||
|
||||
if (!aTextNode.GetParentNode() ||
|
||||
!HTMLEditUtils::CanNodeContain(*aTextNode.GetParentNode(),
|
||||
*nsGkAtoms::big)) {
|
||||
return NS_OK;
|
||||
return CreateElementResult::NotHandled();
|
||||
}
|
||||
|
||||
aEndOffset = std::min(aTextNode.Length(), aEndOffset);
|
||||
@@ -2642,77 +2653,70 @@ nsresult HTMLEditor::RelativeFontChangeOnTextNode(FontSize aDir,
|
||||
// Make the range an independent node.
|
||||
RefPtr<Text> textNodeForTheRange = &aTextNode;
|
||||
|
||||
auto pointToPutCaretOrError =
|
||||
[&]() MOZ_CAN_RUN_SCRIPT -> Result<EditorDOMPoint, nsresult> {
|
||||
EditorDOMPoint pointToPutCaret;
|
||||
// Split at the end of the range.
|
||||
EditorDOMPoint atEnd(textNodeForTheRange, aEndOffset);
|
||||
if (!atEnd.IsEndOfContainer()) {
|
||||
// We need to split off back of text node
|
||||
SplitNodeResult splitAtEndResult = SplitNodeWithTransaction(atEnd);
|
||||
if (splitAtEndResult.isErr()) {
|
||||
NS_WARNING("HTMLEditor::SplitNodeWithTransaction() failed");
|
||||
return Err(splitAtEndResult.unwrapErr());
|
||||
EditorDOMPoint pointToPutCaret;
|
||||
{
|
||||
auto pointToPutCaretOrError =
|
||||
[&]() MOZ_CAN_RUN_SCRIPT -> Result<EditorDOMPoint, nsresult> {
|
||||
EditorDOMPoint pointToPutCaret;
|
||||
// Split at the end of the range.
|
||||
EditorDOMPoint atEnd(textNodeForTheRange, aEndOffset);
|
||||
if (!atEnd.IsEndOfContainer()) {
|
||||
// We need to split off back of text node
|
||||
SplitNodeResult splitAtEndResult = SplitNodeWithTransaction(atEnd);
|
||||
if (splitAtEndResult.isErr()) {
|
||||
NS_WARNING("HTMLEditor::SplitNodeWithTransaction() failed");
|
||||
return Err(splitAtEndResult.unwrapErr());
|
||||
}
|
||||
if (MOZ_UNLIKELY(!splitAtEndResult.HasCaretPointSuggestion())) {
|
||||
NS_WARNING(
|
||||
"HTMLEditor::SplitNodeWithTransaction() didn't suggest caret "
|
||||
"point");
|
||||
return Err(NS_ERROR_FAILURE);
|
||||
}
|
||||
splitAtEndResult.MoveCaretPointTo(pointToPutCaret, *this, {});
|
||||
MOZ_ASSERT_IF(AllowsTransactionsToChangeSelection(),
|
||||
pointToPutCaret.IsSet());
|
||||
textNodeForTheRange =
|
||||
Text::FromNodeOrNull(splitAtEndResult.GetPreviousContent());
|
||||
MOZ_DIAGNOSTIC_ASSERT(textNodeForTheRange);
|
||||
// When adding caret suggestion to SplitNodeResult, here didn't change
|
||||
// selection so that just ignore it.
|
||||
splitAtEndResult.IgnoreCaretPointSuggestion();
|
||||
}
|
||||
if (MOZ_UNLIKELY(!splitAtEndResult.HasCaretPointSuggestion())) {
|
||||
NS_WARNING(
|
||||
"HTMLEditor::SplitNodeWithTransaction() didn't suggest caret "
|
||||
"point");
|
||||
return Err(NS_ERROR_FAILURE);
|
||||
}
|
||||
splitAtEndResult.MoveCaretPointTo(
|
||||
pointToPutCaret, *this,
|
||||
{SuggestCaret::OnlyIfTransactionsAllowedToDoIt});
|
||||
MOZ_ASSERT_IF(AllowsTransactionsToChangeSelection(),
|
||||
pointToPutCaret.IsSet());
|
||||
textNodeForTheRange =
|
||||
Text::FromNodeOrNull(splitAtEndResult.GetPreviousContent());
|
||||
MOZ_DIAGNOSTIC_ASSERT(textNodeForTheRange);
|
||||
// When adding caret suggestion to SplitNodeResult, here didn't change
|
||||
// selection so that just ignore it.
|
||||
splitAtEndResult.IgnoreCaretPointSuggestion();
|
||||
}
|
||||
|
||||
// Split at the start of the range.
|
||||
EditorDOMPoint atStart(textNodeForTheRange, aStartOffset);
|
||||
if (!atStart.IsStartOfContainer()) {
|
||||
// We need to split off front of text node
|
||||
SplitNodeResult splitAtStartResult = SplitNodeWithTransaction(atStart);
|
||||
if (splitAtStartResult.isErr()) {
|
||||
NS_WARNING("HTMLEditor::SplitNodeWithTransaction() failed");
|
||||
return Err(splitAtStartResult.unwrapErr());
|
||||
// Split at the start of the range.
|
||||
EditorDOMPoint atStart(textNodeForTheRange, aStartOffset);
|
||||
if (!atStart.IsStartOfContainer()) {
|
||||
// We need to split off front of text node
|
||||
SplitNodeResult splitAtStartResult = SplitNodeWithTransaction(atStart);
|
||||
if (splitAtStartResult.isErr()) {
|
||||
NS_WARNING("HTMLEditor::SplitNodeWithTransaction() failed");
|
||||
return Err(splitAtStartResult.unwrapErr());
|
||||
}
|
||||
if (MOZ_UNLIKELY(!splitAtStartResult.HasCaretPointSuggestion())) {
|
||||
NS_WARNING(
|
||||
"HTMLEditor::SplitNodeWithTransaction() didn't suggest caret "
|
||||
"point");
|
||||
return Err(NS_ERROR_FAILURE);
|
||||
}
|
||||
splitAtStartResult.MoveCaretPointTo(pointToPutCaret, *this, {});
|
||||
MOZ_ASSERT_IF(AllowsTransactionsToChangeSelection(),
|
||||
pointToPutCaret.IsSet());
|
||||
textNodeForTheRange =
|
||||
Text::FromNodeOrNull(splitAtStartResult.GetNextContent());
|
||||
MOZ_DIAGNOSTIC_ASSERT(textNodeForTheRange);
|
||||
// When adding caret suggestion to SplitNodeResult, here didn't change
|
||||
// selection so that just ignore it.
|
||||
splitAtStartResult.IgnoreCaretPointSuggestion();
|
||||
}
|
||||
if (MOZ_UNLIKELY(!splitAtStartResult.HasCaretPointSuggestion())) {
|
||||
NS_WARNING(
|
||||
"HTMLEditor::SplitNodeWithTransaction() didn't suggest caret "
|
||||
"point");
|
||||
return Err(NS_ERROR_FAILURE);
|
||||
}
|
||||
splitAtStartResult.MoveCaretPointTo(
|
||||
pointToPutCaret, *this,
|
||||
{SuggestCaret::OnlyIfTransactionsAllowedToDoIt});
|
||||
MOZ_ASSERT_IF(AllowsTransactionsToChangeSelection(),
|
||||
pointToPutCaret.IsSet());
|
||||
textNodeForTheRange =
|
||||
Text::FromNodeOrNull(splitAtStartResult.GetNextContent());
|
||||
MOZ_DIAGNOSTIC_ASSERT(textNodeForTheRange);
|
||||
// When adding caret suggestion to SplitNodeResult, here didn't change
|
||||
// selection so that just ignore it.
|
||||
splitAtStartResult.IgnoreCaretPointSuggestion();
|
||||
}
|
||||
|
||||
return pointToPutCaret;
|
||||
}();
|
||||
if (MOZ_UNLIKELY(pointToPutCaretOrError.isErr())) {
|
||||
// Don't warn here since it should be done in the lambda.
|
||||
return pointToPutCaretOrError.unwrapErr();
|
||||
}
|
||||
if (pointToPutCaretOrError.inspect().IsSet()) {
|
||||
nsresult rv = CollapseSelectionTo(pointToPutCaretOrError.inspect());
|
||||
if (MOZ_UNLIKELY(NS_FAILED(rv))) {
|
||||
NS_WARNING("EditorBase::CollapseSelectionTo() failed");
|
||||
return rv;
|
||||
return pointToPutCaret;
|
||||
}();
|
||||
if (MOZ_UNLIKELY(pointToPutCaretOrError.isErr())) {
|
||||
// Don't warn here since it should be done in the lambda.
|
||||
return CreateElementResult(pointToPutCaretOrError.unwrapErr());
|
||||
}
|
||||
pointToPutCaret = pointToPutCaretOrError.unwrap();
|
||||
}
|
||||
|
||||
// Look for siblings that are correct type of node
|
||||
@@ -2722,70 +2726,46 @@ nsresult HTMLEditor::RelativeFontChangeOnTextNode(FontSize aDir,
|
||||
*textNodeForTheRange, {WalkTreeOption::IgnoreNonEditableNode});
|
||||
if (sibling && sibling->IsHTMLElement(bigOrSmallTagName)) {
|
||||
// Previous sib is already right kind of inline node; slide this over
|
||||
const MoveNodeResult moveTextNodeResult =
|
||||
MoveNodeResult moveTextNodeResult =
|
||||
MoveNodeToEndWithTransaction(*textNodeForTheRange, *sibling);
|
||||
if (moveTextNodeResult.isErr()) {
|
||||
NS_WARNING("HTMLEditor::MoveNodeToEndWithTransaction() failed");
|
||||
return moveTextNodeResult.unwrapErr();
|
||||
return CreateElementResult(moveTextNodeResult.unwrapErr());
|
||||
}
|
||||
nsresult rv = moveTextNodeResult.SuggestCaretPointTo(
|
||||
*this, {SuggestCaret::OnlyIfHasSuggestion,
|
||||
SuggestCaret::OnlyIfTransactionsAllowedToDoIt,
|
||||
SuggestCaret::AndIgnoreTrivialError});
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("MoveNodeResult::SuggestCaretPointTo() failed");
|
||||
return rv;
|
||||
}
|
||||
NS_WARNING_ASSERTION(
|
||||
rv != NS_SUCCESS_EDITOR_BUT_IGNORED_TRIVIAL_ERROR,
|
||||
"MoveNodeResult::SuggestCaretPointTo() failed, but ignored");
|
||||
return NS_OK;
|
||||
moveTextNodeResult.MoveCaretPointTo(pointToPutCaret, *this,
|
||||
{SuggestCaret::OnlyIfHasSuggestion});
|
||||
// XXX Should we return the new container?
|
||||
return CreateElementResult::NotHandled(std::move(pointToPutCaret));
|
||||
}
|
||||
sibling = HTMLEditUtils::GetNextSibling(
|
||||
*textNodeForTheRange, {WalkTreeOption::IgnoreNonEditableNode});
|
||||
if (sibling && sibling->IsHTMLElement(bigOrSmallTagName)) {
|
||||
// Following sib is already right kind of inline node; slide this over
|
||||
const MoveNodeResult moveTextNodeResult = MoveNodeWithTransaction(
|
||||
MoveNodeResult moveTextNodeResult = MoveNodeWithTransaction(
|
||||
*textNodeForTheRange, EditorDOMPoint(sibling, 0u));
|
||||
if (moveTextNodeResult.isErr()) {
|
||||
NS_WARNING("HTMLEditor::MoveNodeWithTransaction() failed");
|
||||
return moveTextNodeResult.unwrapErr();
|
||||
return CreateElementResult(moveTextNodeResult.unwrapErr());
|
||||
}
|
||||
nsresult rv = moveTextNodeResult.SuggestCaretPointTo(
|
||||
*this, {SuggestCaret::OnlyIfHasSuggestion,
|
||||
SuggestCaret::OnlyIfTransactionsAllowedToDoIt,
|
||||
SuggestCaret::AndIgnoreTrivialError});
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("MoveNodeResult::SuggestCaretPointTo() failed");
|
||||
return rv;
|
||||
}
|
||||
NS_WARNING_ASSERTION(
|
||||
rv != NS_SUCCESS_EDITOR_BUT_IGNORED_TRIVIAL_ERROR,
|
||||
"MoveNodeResult::SuggestCaretPointTo() failed, but ignored");
|
||||
return NS_OK;
|
||||
moveTextNodeResult.MoveCaretPointTo(pointToPutCaret, *this,
|
||||
{SuggestCaret::OnlyIfHasSuggestion});
|
||||
// XXX Should we return the new container?
|
||||
return CreateElementResult::NotHandled(std::move(pointToPutCaret));
|
||||
}
|
||||
|
||||
// Else wrap the node inside font node with appropriate relative size
|
||||
const CreateElementResult wrapTextWithBigOrSmallElementResult =
|
||||
CreateElementResult wrapTextWithBigOrSmallElementResult =
|
||||
InsertContainerWithTransaction(*textNodeForTheRange,
|
||||
MOZ_KnownLive(*bigOrSmallTagName));
|
||||
if (wrapTextWithBigOrSmallElementResult.isErr()) {
|
||||
NS_WARNING("HTMLEditor::InsertContainerWithTransaction() failed");
|
||||
return wrapTextWithBigOrSmallElementResult.inspectErr();
|
||||
return wrapTextWithBigOrSmallElementResult;
|
||||
}
|
||||
MOZ_ASSERT(wrapTextWithBigOrSmallElementResult.GetNewNode());
|
||||
nsresult rv = wrapTextWithBigOrSmallElementResult.SuggestCaretPointTo(
|
||||
*this, {SuggestCaret::OnlyIfHasSuggestion,
|
||||
SuggestCaret::OnlyIfTransactionsAllowedToDoIt,
|
||||
SuggestCaret::AndIgnoreTrivialError});
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("CreateElementResult::SuggestCaretPointTo() failed");
|
||||
return rv;
|
||||
}
|
||||
NS_WARNING_ASSERTION(
|
||||
rv != NS_SUCCESS_EDITOR_BUT_IGNORED_TRIVIAL_ERROR,
|
||||
"CreateElementResult::SuggestCaretPointTo() failed, but ignored");
|
||||
return rv;
|
||||
wrapTextWithBigOrSmallElementResult.MoveCaretPointTo(
|
||||
pointToPutCaret, {SuggestCaret::OnlyIfHasSuggestion});
|
||||
return CreateElementResult(
|
||||
wrapTextWithBigOrSmallElementResult.UnwrapNewNode(),
|
||||
std::move(pointToPutCaret));
|
||||
}
|
||||
|
||||
nsresult HTMLEditor::RelativeFontChangeHelper(int32_t aSizeChange,
|
||||
|
||||
Reference in New Issue
Block a user