зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1770877 - part 15: Implement equivalent of `HTMLEditor::GetSelectionRangesExtendedToHardLineStartAndEnd` r=m_kato
It's always work with `Selection` ranges. Then, it should be treated within `AutoRangeArray` which can be initialized with `Selection` ranges automatically. Then, we can making `HTMLEditor` simpler. Note tha this tries to make it get editing host when the corresponding public method is called (after dispatched `beforeinput` event if handling a users' operation). However, as commented in `HTMLEditor::SetParagraphFormatAsAction`, it breaks a tricky crash test. Therefore, only the format block path computes it after the preparation. Differential Revision: https://phabricator.services.mozilla.com/D149079
This commit is contained in:
Родитель
4e0277fbf1
Коммит
c3b56cac82
|
@ -747,6 +747,56 @@ static EditorDOMPoint GetPointAfterFollowingLineBreakOrAtFollowingBlock(
|
|||
return point;
|
||||
}
|
||||
|
||||
void AutoRangeArray::ExtendRangesToWrapLinesToHandleBlockLevelEditAction(
|
||||
EditSubAction aEditSubAction, const Element& aEditingHost) {
|
||||
// FYI: This is originated in
|
||||
// https://searchfox.org/mozilla-central/rev/1739f1301d658c9bff544a0a095ab11fca2e549d/editor/libeditor/HTMLEditSubActionHandler.cpp#6712
|
||||
|
||||
bool removeSomeRanges = false;
|
||||
for (OwningNonNull<nsRange>& range : mRanges) {
|
||||
// Remove non-positioned ranges.
|
||||
if (MOZ_UNLIKELY(!range->IsPositioned())) {
|
||||
removeSomeRanges = true;
|
||||
continue;
|
||||
}
|
||||
// If the range is native anonymous subtrees, we must meet a bug of
|
||||
// `Selection` so that we need to hack here.
|
||||
if (MOZ_UNLIKELY(range->GetStartContainer()->IsInNativeAnonymousSubtree() ||
|
||||
range->GetEndContainer()->IsInNativeAnonymousSubtree())) {
|
||||
EditorRawDOMRange rawRange(range);
|
||||
if (!rawRange.EnsureNotInNativeAnonymousSubtree()) {
|
||||
range->Reset();
|
||||
removeSomeRanges = true;
|
||||
continue;
|
||||
}
|
||||
if (NS_FAILED(
|
||||
range->SetStartAndEnd(rawRange.StartRef().ToRawRangeBoundary(),
|
||||
rawRange.EndRef().ToRawRangeBoundary())) ||
|
||||
MOZ_UNLIKELY(!range->IsPositioned())) {
|
||||
range->Reset();
|
||||
removeSomeRanges = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// Finally, extend the range.
|
||||
if (NS_FAILED(ExtendRangeToWrapStartAndEndLinesContainingBoundaries(
|
||||
range, aEditSubAction, aEditingHost))) {
|
||||
// If we failed to extend the range, we should use the original range
|
||||
// as-is unless the range is broken at setting the range.
|
||||
if (NS_WARN_IF(!range->IsPositioned())) {
|
||||
removeSomeRanges = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (removeSomeRanges) {
|
||||
for (size_t i : Reversed(IntegerRange(mRanges.Length()))) {
|
||||
if (!mRanges[i]->IsPositioned()) {
|
||||
mRanges.RemoveElementAt(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
nsresult AutoRangeArray::ExtendRangeToWrapStartAndEndLinesContainingBoundaries(
|
||||
nsRange& aRange, EditSubAction aEditSubAction,
|
||||
|
|
|
@ -345,6 +345,13 @@ class MOZ_STACK_CLASS AutoRangeArray final {
|
|||
*/
|
||||
void EnsureRangesInTextNode(const dom::Text& aTextNode);
|
||||
|
||||
/**
|
||||
* Extend ranges to wrap lines to handle block level edit actions such as
|
||||
* updating the block parent or indent/outdent around the selection.
|
||||
*/
|
||||
void ExtendRangesToWrapLinesToHandleBlockLevelEditAction(
|
||||
EditSubAction aEditSubAction, const dom::Element& aEditingHost);
|
||||
|
||||
/**
|
||||
* Check whether the range is in aEditingHost and both containers of start and
|
||||
* end boundaries of the range are editable.
|
||||
|
|
|
@ -57,8 +57,13 @@ nsresult HTMLEditor::SetSelectionToAbsoluteOrStaticAsAction(
|
|||
return rv;
|
||||
}
|
||||
|
||||
const RefPtr<Element> editingHost = ComputeEditingHost();
|
||||
if (!editingHost) {
|
||||
return NS_SUCCESS_DOM_NO_OPERATION;
|
||||
}
|
||||
|
||||
if (aEnabled) {
|
||||
EditActionResult result = SetSelectionToAbsoluteAsSubAction();
|
||||
EditActionResult result = SetSelectionToAbsoluteAsSubAction(*editingHost);
|
||||
NS_WARNING_ASSERTION(
|
||||
result.Succeeded(),
|
||||
"HTMLEditor::SetSelectionToAbsoluteAsSubAction() failed");
|
||||
|
|
|
@ -1481,7 +1481,8 @@ nsresult HTMLEditor::InsertLineBreakAsSubAction() {
|
|||
return rv;
|
||||
}
|
||||
|
||||
EditActionResult HTMLEditor::InsertParagraphSeparatorAsSubAction() {
|
||||
EditActionResult HTMLEditor::InsertParagraphSeparatorAsSubAction(
|
||||
const Element& aEditingHost) {
|
||||
if (NS_WARN_IF(!mInitSucceeded)) {
|
||||
return EditActionIgnored(NS_ERROR_NOT_INITIALIZED);
|
||||
}
|
||||
|
@ -1550,11 +1551,6 @@ EditActionResult HTMLEditor::InsertParagraphSeparatorAsSubAction() {
|
|||
}
|
||||
}
|
||||
|
||||
RefPtr<Element> editingHost = ComputeEditingHost();
|
||||
if (NS_WARN_IF(!editingHost)) {
|
||||
return EditActionIgnored(NS_ERROR_FAILURE);
|
||||
}
|
||||
|
||||
if (IsMailEditor()) {
|
||||
const auto pointToSplit = GetFirstSelectionStartPoint<EditorDOMPoint>();
|
||||
if (NS_WARN_IF(!pointToSplit.IsInContentNode())) {
|
||||
|
@ -1567,7 +1563,7 @@ EditActionResult HTMLEditor::InsertParagraphSeparatorAsSubAction() {
|
|||
// table cell boundaries?
|
||||
Result<EditorDOMPoint, nsresult> atNewBRElementOrError =
|
||||
HandleInsertParagraphInMailCiteElement(*mailCiteElement, pointToSplit,
|
||||
*editingHost);
|
||||
aEditingHost);
|
||||
if (MOZ_UNLIKELY(atNewBRElementOrError.isErr())) {
|
||||
NS_WARNING(
|
||||
"HTMLEditor::HandleInsertParagraphInMailCiteElement() failed");
|
||||
|
@ -1612,11 +1608,11 @@ EditActionResult HTMLEditor::InsertParagraphSeparatorAsSubAction() {
|
|||
// insert new paragraph nor <br> element.
|
||||
// XXX Currently, we don't support editing outside <body> element, but Blink
|
||||
// does it.
|
||||
if (editingHost->GetParentElement() &&
|
||||
HTMLEditUtils::IsSimplyEditableNode(*editingHost->GetParentElement()) &&
|
||||
if (aEditingHost.GetParentElement() &&
|
||||
HTMLEditUtils::IsSimplyEditableNode(*aEditingHost.GetParentElement()) &&
|
||||
(!atStartOfSelection.IsInContentNode() ||
|
||||
!nsContentUtils::ContentIsFlattenedTreeDescendantOf(
|
||||
atStartOfSelection.ContainerAsContent(), editingHost))) {
|
||||
atStartOfSelection.ContainerAsContent(), &aEditingHost))) {
|
||||
return EditActionHandled(NS_ERROR_EDITOR_NO_EDITABLE_RANGE);
|
||||
}
|
||||
|
||||
|
@ -1644,9 +1640,9 @@ EditActionResult HTMLEditor::InsertParagraphSeparatorAsSubAction() {
|
|||
else if (!HTMLEditUtils::IsSplittableNode(*editableBlockElement)) {
|
||||
insertLineBreak =
|
||||
separator == ParagraphSeparator::br ||
|
||||
!HTMLEditUtils::CanElementContainParagraph(*editingHost) ||
|
||||
!HTMLEditUtils::CanElementContainParagraph(aEditingHost) ||
|
||||
HTMLEditUtils::ShouldInsertLinefeedCharacter(atStartOfSelection,
|
||||
*editingHost);
|
||||
aEditingHost);
|
||||
}
|
||||
// If the nearest block parent is a single-line container declared in
|
||||
// the execCommand spec and not the editing host, we should separate the
|
||||
|
@ -1675,8 +1671,8 @@ EditActionResult HTMLEditor::InsertParagraphSeparatorAsSubAction() {
|
|||
// paragraph separator is set to "br" which is Gecko-specific mode.
|
||||
if (separator != ParagraphSeparator::br &&
|
||||
HTMLEditUtils::ShouldInsertLinefeedCharacter(atStartOfSelection,
|
||||
*editingHost)) {
|
||||
nsresult rv = HandleInsertLinefeed(atStartOfSelection, *editingHost);
|
||||
aEditingHost)) {
|
||||
nsresult rv = HandleInsertLinefeed(atStartOfSelection, aEditingHost);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("HTMLEditor::HandleInsertLinefeed() failed");
|
||||
return EditActionResult(rv);
|
||||
|
@ -1685,7 +1681,7 @@ EditActionResult HTMLEditor::InsertParagraphSeparatorAsSubAction() {
|
|||
}
|
||||
|
||||
CreateElementResult insertBRElementResult =
|
||||
HandleInsertBRElement(atStartOfSelection, *editingHost);
|
||||
HandleInsertBRElement(atStartOfSelection, aEditingHost);
|
||||
if (insertBRElementResult.isErr()) {
|
||||
NS_WARNING("HTMLEditor::HandleInsertBRElement() failed");
|
||||
return EditActionHandled(insertBRElementResult.unwrapErr());
|
||||
|
@ -1707,7 +1703,8 @@ EditActionResult HTMLEditor::InsertParagraphSeparatorAsSubAction() {
|
|||
// Therefore, even if it returns NS_OK, editor might have been destroyed
|
||||
// at restoring Selection.
|
||||
nsresult rv = FormatBlockContainerWithTransaction(
|
||||
MOZ_KnownLive(HTMLEditor::ToParagraphSeparatorTagName(separator)));
|
||||
MOZ_KnownLive(HTMLEditor::ToParagraphSeparatorTagName(separator)),
|
||||
aEditingHost);
|
||||
if (NS_WARN_IF(rv == NS_ERROR_EDITOR_DESTROYED) ||
|
||||
NS_WARN_IF(Destroyed())) {
|
||||
return EditActionIgnored(NS_ERROR_EDITOR_DESTROYED);
|
||||
|
@ -1738,7 +1735,7 @@ EditActionResult HTMLEditor::InsertParagraphSeparatorAsSubAction() {
|
|||
if (NS_WARN_IF(!HTMLEditUtils::IsSplittableNode(*editableBlockElement))) {
|
||||
// Didn't create a new block for some reason, fall back to <br>
|
||||
CreateElementResult insertBRElementResult =
|
||||
HandleInsertBRElement(atStartOfSelection, *editingHost);
|
||||
HandleInsertBRElement(atStartOfSelection, aEditingHost);
|
||||
if (insertBRElementResult.isErr()) {
|
||||
NS_WARNING("HTMLEditor::HandleInsertBRElement() failed");
|
||||
return EditActionResult(insertBRElementResult.unwrapErr());
|
||||
|
@ -1793,12 +1790,12 @@ EditActionResult HTMLEditor::InsertParagraphSeparatorAsSubAction() {
|
|||
|
||||
RefPtr<Element> maybeNonEditableListItem =
|
||||
HTMLEditUtils::GetClosestAncestorListItemElement(*editableBlockElement,
|
||||
editingHost);
|
||||
&aEditingHost);
|
||||
if (maybeNonEditableListItem &&
|
||||
HTMLEditUtils::IsSplittableNode(*maybeNonEditableListItem)) {
|
||||
Result<EditorDOMPoint, nsresult> pointToPutCaretOrError =
|
||||
HandleInsertParagraphInListItemElement(
|
||||
*maybeNonEditableListItem, atStartOfSelection, *editingHost);
|
||||
*maybeNonEditableListItem, atStartOfSelection, aEditingHost);
|
||||
if (MOZ_UNLIKELY(pointToPutCaretOrError.isErr())) {
|
||||
if (NS_WARN_IF(pointToPutCaretOrError.unwrapErr() ==
|
||||
NS_ERROR_EDITOR_DESTROYED)) {
|
||||
|
@ -1884,7 +1881,7 @@ EditActionResult HTMLEditor::InsertParagraphSeparatorAsSubAction() {
|
|||
|
||||
// If nobody handles this edit action, let's insert new <br> at the selection.
|
||||
CreateElementResult insertBRElementResult =
|
||||
HandleInsertBRElement(atStartOfSelection, *editingHost);
|
||||
HandleInsertBRElement(atStartOfSelection, aEditingHost);
|
||||
if (insertBRElementResult.isErr()) {
|
||||
NS_WARNING("HTMLEditor::HandleInsertBRElement() failed");
|
||||
return EditActionIgnored(insertBRElementResult.unwrapErr());
|
||||
|
@ -1898,7 +1895,7 @@ EditActionResult HTMLEditor::InsertParagraphSeparatorAsSubAction() {
|
|||
}
|
||||
|
||||
CreateElementResult HTMLEditor::HandleInsertBRElement(
|
||||
const EditorDOMPoint& aPointToBreak, Element& aEditingHost) {
|
||||
const EditorDOMPoint& aPointToBreak, const Element& aEditingHost) {
|
||||
MOZ_ASSERT(aPointToBreak.IsSet());
|
||||
MOZ_ASSERT(IsEditActionDataAvailable());
|
||||
|
||||
|
@ -2052,7 +2049,7 @@ CreateElementResult HTMLEditor::HandleInsertBRElement(
|
|||
}
|
||||
|
||||
nsresult HTMLEditor::HandleInsertLinefeed(const EditorDOMPoint& aPointToBreak,
|
||||
Element& aEditingHost) {
|
||||
const Element& aEditingHost) {
|
||||
MOZ_ASSERT(IsEditActionDataAvailable());
|
||||
|
||||
if (NS_WARN_IF(!aPointToBreak.IsSet())) {
|
||||
|
@ -2194,7 +2191,7 @@ nsresult HTMLEditor::HandleInsertLinefeed(const EditorDOMPoint& aPointToBreak,
|
|||
Result<EditorDOMPoint, nsresult>
|
||||
HTMLEditor::HandleInsertParagraphInMailCiteElement(
|
||||
Element& aMailCiteElement, const EditorDOMPoint& aPointToSplit,
|
||||
Element& aEditingHost) {
|
||||
const Element& aEditingHost) {
|
||||
MOZ_ASSERT(IsEditActionDataAvailable());
|
||||
MOZ_ASSERT(aPointToSplit.IsSet());
|
||||
NS_ASSERTION(!HTMLEditUtils::IsEmptyNode(aMailCiteElement),
|
||||
|
@ -3037,9 +3034,13 @@ EditActionResult HTMLEditor::MakeOrChangeListAndListItemAsSubAction(
|
|||
// ChangeSelectedHardLinesToList() creates AutoSelectionRestorer.
|
||||
// Therefore, even if it returns NS_OK, editor might have been destroyed
|
||||
// at restoring Selection.
|
||||
result = ChangeSelectedHardLinesToList(MOZ_KnownLive(*listTagName),
|
||||
MOZ_KnownLive(*listItemTagName),
|
||||
aBulletType, aSelectAllOfCurrentList);
|
||||
const RefPtr<Element> editingHost = ComputeEditingHost();
|
||||
if (MOZ_UNLIKELY(!editingHost)) {
|
||||
return EditActionIgnored(NS_SUCCESS_DOM_NO_OPERATION);
|
||||
}
|
||||
result = ChangeSelectedHardLinesToList(
|
||||
MOZ_KnownLive(*listTagName), MOZ_KnownLive(*listItemTagName), aBulletType,
|
||||
aSelectAllOfCurrentList, *editingHost);
|
||||
if (NS_WARN_IF(Destroyed())) {
|
||||
return EditActionResult(NS_ERROR_EDITOR_DESTROYED);
|
||||
}
|
||||
|
@ -3051,15 +3052,11 @@ EditActionResult HTMLEditor::MakeOrChangeListAndListItemAsSubAction(
|
|||
EditActionResult HTMLEditor::ChangeSelectedHardLinesToList(
|
||||
nsAtom& aListElementTagName, nsAtom& aListItemElementTagName,
|
||||
const nsAString& aBulletType,
|
||||
SelectAllOfCurrentList aSelectAllOfCurrentList) {
|
||||
SelectAllOfCurrentList aSelectAllOfCurrentList,
|
||||
const Element& aEditingHost) {
|
||||
MOZ_ASSERT(IsTopLevelEditSubActionDataAvailable());
|
||||
MOZ_ASSERT(!IsSelectionRangeContainerNotContent());
|
||||
|
||||
RefPtr<Element> editingHost = ComputeEditingHost();
|
||||
if (MOZ_UNLIKELY(NS_WARN_IF(!editingHost))) {
|
||||
return EditActionResult(NS_ERROR_FAILURE);
|
||||
}
|
||||
|
||||
AutoSelectionRestorer restoreSelectionLater(*this);
|
||||
|
||||
AutoTArray<OwningNonNull<nsIContent>, 64> arrayOfContents;
|
||||
|
@ -3073,11 +3070,11 @@ EditActionResult HTMLEditor::ChangeSelectedHardLinesToList(
|
|||
} else {
|
||||
AutoTransactionsConserveSelection dontChangeMySelection(*this);
|
||||
|
||||
AutoTArray<OwningNonNull<nsRange>, 4> extendedSelectionRanges;
|
||||
GetSelectionRangesExtendedToHardLineStartAndEnd(
|
||||
extendedSelectionRanges, EditSubAction::eCreateOrChangeList);
|
||||
AutoRangeArray extendedSelectionRanges(SelectionRef());
|
||||
extendedSelectionRanges.ExtendRangesToWrapLinesToHandleBlockLevelEditAction(
|
||||
EditSubAction::eCreateOrChangeList, aEditingHost);
|
||||
nsresult rv = SplitInlinesAndCollectEditTargetNodes(
|
||||
extendedSelectionRanges, arrayOfContents,
|
||||
extendedSelectionRanges.Ranges(), arrayOfContents,
|
||||
EditSubAction::eCreateOrChangeList, CollectNonEditableNodes::No);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING(
|
||||
|
@ -3134,7 +3131,7 @@ EditActionResult HTMLEditor::ChangeSelectedHardLinesToList(
|
|||
CreateElementResult createNewListElementResult =
|
||||
InsertElementWithSplittingAncestorsWithTransaction(
|
||||
aListElementTagName, atStartOfSelection,
|
||||
BRElementNextToSplitPoint::Keep, *editingHost,
|
||||
BRElementNextToSplitPoint::Keep, aEditingHost,
|
||||
// MOZ_CAN_RUN_SCRIPT_BOUNDARY due to bug 1758868
|
||||
[&newListItemElement, &aListItemElementTagName](
|
||||
HTMLEditor& aHTMLEditor, Element& aListElement,
|
||||
|
@ -3531,7 +3528,7 @@ EditActionResult HTMLEditor::ChangeSelectedHardLinesToList(
|
|||
CreateElementResult createNewListElementResult =
|
||||
InsertElementWithSplittingAncestorsWithTransaction(
|
||||
aListElementTagName, atContent, BRElementNextToSplitPoint::Keep,
|
||||
*editingHost);
|
||||
aEditingHost);
|
||||
if (createNewListElementResult.isErr()) {
|
||||
NS_WARNING(
|
||||
nsPrintfCString(
|
||||
|
@ -3661,7 +3658,8 @@ EditActionResult HTMLEditor::ChangeSelectedHardLinesToList(
|
|||
return EditActionHandled();
|
||||
}
|
||||
|
||||
nsresult HTMLEditor::RemoveListAtSelectionAsSubAction() {
|
||||
nsresult HTMLEditor::RemoveListAtSelectionAsSubAction(
|
||||
const Element& aEditingHost) {
|
||||
MOZ_ASSERT(IsEditActionDataAvailable());
|
||||
|
||||
EditActionResult result = CanHandleHTMLEditSubAction();
|
||||
|
@ -3699,11 +3697,11 @@ nsresult HTMLEditor::RemoveListAtSelectionAsSubAction() {
|
|||
{
|
||||
AutoTransactionsConserveSelection dontChangeMySelection(*this);
|
||||
|
||||
AutoTArray<OwningNonNull<nsRange>, 4> extendedSelectionRanges;
|
||||
GetSelectionRangesExtendedToHardLineStartAndEnd(
|
||||
extendedSelectionRanges, EditSubAction::eCreateOrChangeList);
|
||||
AutoRangeArray extendedSelectionRanges(SelectionRef());
|
||||
extendedSelectionRanges.ExtendRangesToWrapLinesToHandleBlockLevelEditAction(
|
||||
EditSubAction::eCreateOrChangeList, aEditingHost);
|
||||
nsresult rv = SplitInlinesAndCollectEditTargetNodes(
|
||||
extendedSelectionRanges, arrayOfContents,
|
||||
extendedSelectionRanges.Ranges(), arrayOfContents,
|
||||
EditSubAction::eCreateOrChangeList, CollectNonEditableNodes::No);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING(
|
||||
|
@ -3752,14 +3750,10 @@ nsresult HTMLEditor::RemoveListAtSelectionAsSubAction() {
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult HTMLEditor::FormatBlockContainerWithTransaction(nsAtom& blockType) {
|
||||
nsresult HTMLEditor::FormatBlockContainerWithTransaction(
|
||||
nsAtom& blockType, const Element& aEditingHost) {
|
||||
MOZ_ASSERT(IsTopLevelEditSubActionDataAvailable());
|
||||
|
||||
const RefPtr<Element> editingHost = ComputeEditingHost();
|
||||
if (MOZ_UNLIKELY(NS_WARN_IF(!editingHost))) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (!SelectionRef().IsCollapsed()) {
|
||||
nsresult rv = MaybeExtendSelectionToHardLineEdgesForBlockEditAction();
|
||||
if (NS_FAILED(rv)) {
|
||||
|
@ -3775,11 +3769,11 @@ nsresult HTMLEditor::FormatBlockContainerWithTransaction(nsAtom& blockType) {
|
|||
|
||||
AutoTArray<OwningNonNull<nsIContent>, 64> arrayOfContents;
|
||||
{
|
||||
AutoTArray<OwningNonNull<nsRange>, 4> extendedSelectionRanges;
|
||||
GetSelectionRangesExtendedToHardLineStartAndEnd(
|
||||
extendedSelectionRanges, EditSubAction::eCreateOrRemoveBlock);
|
||||
AutoRangeArray extendedSelectionRanges(SelectionRef());
|
||||
extendedSelectionRanges.ExtendRangesToWrapLinesToHandleBlockLevelEditAction(
|
||||
EditSubAction::eCreateOrRemoveBlock, aEditingHost);
|
||||
nsresult rv = SplitInlinesAndCollectEditTargetNodes(
|
||||
extendedSelectionRanges, arrayOfContents,
|
||||
extendedSelectionRanges.Ranges(), arrayOfContents,
|
||||
EditSubAction::eCreateOrRemoveBlock, CollectNonEditableNodes::Yes);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING(
|
||||
|
@ -3826,7 +3820,7 @@ nsresult HTMLEditor::FormatBlockContainerWithTransaction(nsAtom& blockType) {
|
|||
// which is visually bad.
|
||||
if (nsCOMPtr<nsIContent> brContent = HTMLEditUtils::GetNextContent(
|
||||
pointToInsertBlock, {WalkTreeOption::IgnoreNonEditableNode},
|
||||
editingHost)) {
|
||||
&aEditingHost)) {
|
||||
if (brContent && brContent->IsHTMLElement(nsGkAtoms::br)) {
|
||||
AutoEditorDOMPointChildInvalidator lockOffset(pointToInsertBlock);
|
||||
nsresult rv = DeleteNodeWithTransaction(*brContent);
|
||||
|
@ -3868,7 +3862,7 @@ nsresult HTMLEditor::FormatBlockContainerWithTransaction(nsAtom& blockType) {
|
|||
pointToInsertBlock,
|
||||
{WalkTreeOption::IgnoreNonEditableNode,
|
||||
WalkTreeOption::StopAtBlockBoundary},
|
||||
editingHost)) {
|
||||
&aEditingHost)) {
|
||||
if (maybeBRContent->IsHTMLElement(nsGkAtoms::br)) {
|
||||
AutoEditorDOMPointChildInvalidator lockOffset(pointToInsertBlock);
|
||||
nsresult rv = DeleteNodeWithTransaction(*maybeBRContent);
|
||||
|
@ -3884,7 +3878,7 @@ nsresult HTMLEditor::FormatBlockContainerWithTransaction(nsAtom& blockType) {
|
|||
CreateElementResult createNewBlockElementResult =
|
||||
InsertElementWithSplittingAncestorsWithTransaction(
|
||||
blockType, pointToInsertBlock, BRElementNextToSplitPoint::Keep,
|
||||
*editingHost);
|
||||
aEditingHost);
|
||||
if (createNewBlockElementResult.isErr()) {
|
||||
NS_WARNING(
|
||||
nsPrintfCString(
|
||||
|
@ -3932,7 +3926,7 @@ nsresult HTMLEditor::FormatBlockContainerWithTransaction(nsAtom& blockType) {
|
|||
if (&blockType == nsGkAtoms::blockquote) {
|
||||
Result<EditorDOMPoint, nsresult> wrapContentsInBlockquoteElementsResult =
|
||||
WrapContentsInBlockquoteElementsWithTransaction(arrayOfContents,
|
||||
*editingHost);
|
||||
aEditingHost);
|
||||
if (wrapContentsInBlockquoteElementsResult.isErr()) {
|
||||
NS_WARNING(
|
||||
"HTMLEditor::WrapContentsInBlockquoteElementsWithTransaction() "
|
||||
|
@ -3957,7 +3951,7 @@ nsresult HTMLEditor::FormatBlockContainerWithTransaction(nsAtom& blockType) {
|
|||
}
|
||||
Result<EditorDOMPoint, nsresult> wrapContentsInBlockElementResult =
|
||||
CreateOrChangeBlockContainerElement(arrayOfContents, blockType,
|
||||
*editingHost);
|
||||
aEditingHost);
|
||||
if (MOZ_UNLIKELY(wrapContentsInBlockElementResult.isErr())) {
|
||||
NS_WARNING("HTMLEditor::CreateOrChangeBlockContainerElement() failed");
|
||||
return wrapContentsInBlockElementResult.unwrapErr();
|
||||
|
@ -3996,7 +3990,7 @@ nsresult HTMLEditor::MaybeInsertPaddingBRElementForEmptyLastLineAtSelection() {
|
|||
return rv;
|
||||
}
|
||||
|
||||
EditActionResult HTMLEditor::IndentAsSubAction() {
|
||||
EditActionResult HTMLEditor::IndentAsSubAction(const Element& aEditingHost) {
|
||||
MOZ_ASSERT(IsEditActionDataAvailable());
|
||||
|
||||
AutoPlaceholderBatch treatAsOneTransaction(
|
||||
|
@ -4023,7 +4017,7 @@ EditActionResult HTMLEditor::IndentAsSubAction() {
|
|||
return EditActionIgnored();
|
||||
}
|
||||
|
||||
result |= HandleIndentAtSelection();
|
||||
result |= HandleIndentAtSelection(aEditingHost);
|
||||
if (result.Failed() || result.Canceled()) {
|
||||
NS_WARNING_ASSERTION(result.Succeeded(),
|
||||
"HTMLEditor::HandleIndentAtSelection() failed");
|
||||
|
@ -4182,7 +4176,8 @@ nsresult HTMLEditor::IndentListChild(RefPtr<Element>* aCurList,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
EditActionResult HTMLEditor::HandleIndentAtSelection() {
|
||||
EditActionResult HTMLEditor::HandleIndentAtSelection(
|
||||
const Element& aEditingHost) {
|
||||
MOZ_ASSERT(IsEditActionDataAvailable());
|
||||
MOZ_ASSERT(!IsSelectionRangeContainerNotContent());
|
||||
|
||||
|
@ -4219,18 +4214,18 @@ EditActionResult HTMLEditor::HandleIndentAtSelection() {
|
|||
}
|
||||
|
||||
if (IsCSSEnabled()) {
|
||||
nsresult rv = HandleCSSIndentAtSelection();
|
||||
nsresult rv = HandleCSSIndentAtSelection(aEditingHost);
|
||||
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
|
||||
"HTMLEditor::HandleCSSIndentAtSelection() failed");
|
||||
return EditActionHandled(rv);
|
||||
}
|
||||
rv = HandleHTMLIndentAtSelection();
|
||||
rv = HandleHTMLIndentAtSelection(aEditingHost);
|
||||
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
|
||||
"HTMLEditor::HandleHTMLIndent() failed");
|
||||
return EditActionHandled(rv);
|
||||
}
|
||||
|
||||
nsresult HTMLEditor::HandleCSSIndentAtSelection() {
|
||||
nsresult HTMLEditor::HandleCSSIndentAtSelection(const Element& aEditingHost) {
|
||||
MOZ_ASSERT(IsEditActionDataAvailable());
|
||||
MOZ_ASSERT(!IsSelectionRangeContainerNotContent());
|
||||
|
||||
|
@ -4247,7 +4242,7 @@ nsresult HTMLEditor::HandleCSSIndentAtSelection() {
|
|||
// HandleCSSIndentAtSelectionInternal() creates AutoSelectionRestorer.
|
||||
// Therefore, even if it returns NS_OK, editor might have been destroyed
|
||||
// at restoring Selection.
|
||||
nsresult rv = HandleCSSIndentAtSelectionInternal();
|
||||
nsresult rv = HandleCSSIndentAtSelectionInternal(aEditingHost);
|
||||
if (NS_WARN_IF(Destroyed())) {
|
||||
return NS_ERROR_EDITOR_DESTROYED;
|
||||
}
|
||||
|
@ -4257,15 +4252,11 @@ nsresult HTMLEditor::HandleCSSIndentAtSelection() {
|
|||
return rv;
|
||||
}
|
||||
|
||||
nsresult HTMLEditor::HandleCSSIndentAtSelectionInternal() {
|
||||
nsresult HTMLEditor::HandleCSSIndentAtSelectionInternal(
|
||||
const Element& aEditingHost) {
|
||||
MOZ_ASSERT(IsTopLevelEditSubActionDataAvailable());
|
||||
MOZ_ASSERT(!IsSelectionRangeContainerNotContent());
|
||||
|
||||
RefPtr<Element> editingHost = ComputeEditingHost();
|
||||
if (MOZ_UNLIKELY(NS_WARN_IF(!editingHost))) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
AutoSelectionRestorer restoreSelectionLater(*this);
|
||||
AutoTArray<OwningNonNull<nsIContent>, 64> arrayOfContents;
|
||||
|
||||
|
@ -4289,12 +4280,12 @@ nsresult HTMLEditor::HandleCSSIndentAtSelectionInternal() {
|
|||
}
|
||||
|
||||
if (arrayOfContents.IsEmpty()) {
|
||||
AutoTArray<OwningNonNull<nsRange>, 4> extendedSelectionRanges;
|
||||
GetSelectionRangesExtendedToHardLineStartAndEnd(extendedSelectionRanges,
|
||||
EditSubAction::eIndent);
|
||||
AutoRangeArray extendedSelectionRanges(SelectionRef());
|
||||
extendedSelectionRanges.ExtendRangesToWrapLinesToHandleBlockLevelEditAction(
|
||||
EditSubAction::eIndent, aEditingHost);
|
||||
nsresult rv = SplitInlinesAndCollectEditTargetNodes(
|
||||
extendedSelectionRanges, arrayOfContents, EditSubAction::eIndent,
|
||||
CollectNonEditableNodes::Yes);
|
||||
extendedSelectionRanges.Ranges(), arrayOfContents,
|
||||
EditSubAction::eIndent, CollectNonEditableNodes::Yes);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING(
|
||||
"SplitInlinesAndCollectEditTargetNodes(EditSubAction::eIndent, "
|
||||
|
@ -4322,7 +4313,7 @@ nsresult HTMLEditor::HandleCSSIndentAtSelectionInternal() {
|
|||
CreateElementResult createNewDivElementResult =
|
||||
InsertElementWithSplittingAncestorsWithTransaction(
|
||||
*nsGkAtoms::div, atStartOfSelection,
|
||||
BRElementNextToSplitPoint::Keep, *editingHost);
|
||||
BRElementNextToSplitPoint::Keep, aEditingHost);
|
||||
if (createNewDivElementResult.isErr()) {
|
||||
NS_WARNING(
|
||||
"HTMLEditor::InsertElementWithSplittingAncestorsWithTransaction("
|
||||
|
@ -4418,7 +4409,7 @@ nsresult HTMLEditor::HandleCSSIndentAtSelectionInternal() {
|
|||
CreateElementResult createNewDivElementResult =
|
||||
InsertElementWithSplittingAncestorsWithTransaction(
|
||||
*nsGkAtoms::div, atContent, BRElementNextToSplitPoint::Keep,
|
||||
*editingHost);
|
||||
aEditingHost);
|
||||
if (createNewDivElementResult.isErr()) {
|
||||
NS_WARNING(
|
||||
"HTMLEditor::InsertElementWithSplittingAncestorsWithTransaction("
|
||||
|
@ -4471,7 +4462,7 @@ nsresult HTMLEditor::HandleCSSIndentAtSelectionInternal() {
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult HTMLEditor::HandleHTMLIndentAtSelection() {
|
||||
nsresult HTMLEditor::HandleHTMLIndentAtSelection(const Element& aEditingHost) {
|
||||
MOZ_ASSERT(IsEditActionDataAvailable());
|
||||
MOZ_ASSERT(!IsSelectionRangeContainerNotContent());
|
||||
|
||||
|
@ -4488,7 +4479,7 @@ nsresult HTMLEditor::HandleHTMLIndentAtSelection() {
|
|||
// HandleHTMLIndentAtSelectionInternal() creates AutoSelectionRestorer.
|
||||
// Therefore, even if it returns NS_OK, editor might have been destroyed
|
||||
// at restoring Selection.
|
||||
nsresult rv = HandleHTMLIndentAtSelectionInternal();
|
||||
nsresult rv = HandleHTMLIndentAtSelectionInternal(aEditingHost);
|
||||
if (NS_WARN_IF(Destroyed())) {
|
||||
return NS_ERROR_EDITOR_DESTROYED;
|
||||
}
|
||||
|
@ -4498,14 +4489,10 @@ nsresult HTMLEditor::HandleHTMLIndentAtSelection() {
|
|||
return rv;
|
||||
}
|
||||
|
||||
nsresult HTMLEditor::HandleHTMLIndentAtSelectionInternal() {
|
||||
nsresult HTMLEditor::HandleHTMLIndentAtSelectionInternal(
|
||||
const Element& aEditingHost) {
|
||||
MOZ_ASSERT(IsTopLevelEditSubActionDataAvailable());
|
||||
|
||||
RefPtr<Element> editingHost = ComputeEditingHost();
|
||||
if (MOZ_UNLIKELY(NS_WARN_IF(!editingHost))) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
AutoSelectionRestorer restoreSelectionLater(*this);
|
||||
|
||||
// convert the selection ranges into "promoted" selection ranges:
|
||||
|
@ -4513,14 +4500,14 @@ nsresult HTMLEditor::HandleHTMLIndentAtSelectionInternal() {
|
|||
// block parent, and then further expands to include any ancestors
|
||||
// whose children are all in the range
|
||||
|
||||
AutoTArray<OwningNonNull<nsRange>, 4> arrayOfRanges;
|
||||
GetSelectionRangesExtendedToHardLineStartAndEnd(arrayOfRanges,
|
||||
EditSubAction::eIndent);
|
||||
AutoRangeArray extendedSelectionRanges(SelectionRef());
|
||||
extendedSelectionRanges.ExtendRangesToWrapLinesToHandleBlockLevelEditAction(
|
||||
EditSubAction::eIndent, aEditingHost);
|
||||
|
||||
// use these ranges to construct a list of nodes to act on.
|
||||
AutoTArray<OwningNonNull<nsIContent>, 64> arrayOfContents;
|
||||
nsresult rv = SplitInlinesAndCollectEditTargetNodes(
|
||||
arrayOfRanges, arrayOfContents, EditSubAction::eIndent,
|
||||
extendedSelectionRanges.Ranges(), arrayOfContents, EditSubAction::eIndent,
|
||||
CollectNonEditableNodes::Yes);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING(
|
||||
|
@ -4547,7 +4534,7 @@ nsresult HTMLEditor::HandleHTMLIndentAtSelectionInternal() {
|
|||
CreateElementResult createNewBlockQuoteElementResult =
|
||||
InsertElementWithSplittingAncestorsWithTransaction(
|
||||
*nsGkAtoms::blockquote, atStartOfSelection,
|
||||
BRElementNextToSplitPoint::Keep, *editingHost);
|
||||
BRElementNextToSplitPoint::Keep, aEditingHost);
|
||||
if (createNewBlockQuoteElementResult.isErr()) {
|
||||
NS_WARNING(
|
||||
"HTMLEditor::InsertElementWithSplittingAncestorsWithTransaction("
|
||||
|
@ -4622,7 +4609,7 @@ nsresult HTMLEditor::HandleHTMLIndentAtSelectionInternal() {
|
|||
// to act on that is still inside the same li.
|
||||
if (RefPtr<Element> listItem =
|
||||
HTMLEditUtils::GetClosestAncestorListItemElement(content,
|
||||
editingHost)) {
|
||||
&aEditingHost)) {
|
||||
if (indentedLI == listItem) {
|
||||
// already indented this list item
|
||||
continue;
|
||||
|
@ -4645,7 +4632,7 @@ nsresult HTMLEditor::HandleHTMLIndentAtSelectionInternal() {
|
|||
CreateElementResult createNewListElementResult =
|
||||
InsertElementWithSplittingAncestorsWithTransaction(
|
||||
MOZ_KnownLive(*containerName), atListItem,
|
||||
BRElementNextToSplitPoint::Keep, *editingHost);
|
||||
BRElementNextToSplitPoint::Keep, aEditingHost);
|
||||
if (createNewListElementResult.isErr()) {
|
||||
NS_WARNING(nsPrintfCString("HTMLEditor::"
|
||||
"InsertElementWithSplittingAncestorsWithTr"
|
||||
|
@ -4709,7 +4696,7 @@ nsresult HTMLEditor::HandleHTMLIndentAtSelectionInternal() {
|
|||
CreateElementResult createNewBlockQuoteElementResult =
|
||||
InsertElementWithSplittingAncestorsWithTransaction(
|
||||
*nsGkAtoms::blockquote, atContent,
|
||||
BRElementNextToSplitPoint::Keep, *editingHost);
|
||||
BRElementNextToSplitPoint::Keep, aEditingHost);
|
||||
if (createNewBlockQuoteElementResult.isErr()) {
|
||||
NS_WARNING(
|
||||
"HTMLEditor::InsertElementWithSplittingAncestorsWithTransaction("
|
||||
|
@ -4759,7 +4746,7 @@ nsresult HTMLEditor::HandleHTMLIndentAtSelectionInternal() {
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
EditActionResult HTMLEditor::OutdentAsSubAction() {
|
||||
EditActionResult HTMLEditor::OutdentAsSubAction(const Element& aEditingHost) {
|
||||
MOZ_ASSERT(IsEditActionDataAvailable());
|
||||
|
||||
AutoPlaceholderBatch treatAsOneTransaction(
|
||||
|
@ -4786,7 +4773,7 @@ EditActionResult HTMLEditor::OutdentAsSubAction() {
|
|||
return EditActionIgnored();
|
||||
}
|
||||
|
||||
result |= HandleOutdentAtSelection();
|
||||
result |= HandleOutdentAtSelection(aEditingHost);
|
||||
if (result.Failed() || result.Canceled()) {
|
||||
NS_WARNING_ASSERTION(result.Succeeded(),
|
||||
"HTMLEditor::HandleOutdentAtSelection() failed");
|
||||
|
@ -4806,7 +4793,8 @@ EditActionResult HTMLEditor::OutdentAsSubAction() {
|
|||
return result.SetResult(rv);
|
||||
}
|
||||
|
||||
EditActionResult HTMLEditor::HandleOutdentAtSelection() {
|
||||
EditActionResult HTMLEditor::HandleOutdentAtSelection(
|
||||
const Element& aEditingHost) {
|
||||
MOZ_ASSERT(IsEditActionDataAvailable());
|
||||
MOZ_ASSERT(!IsSelectionRangeContainerNotContent());
|
||||
|
||||
|
@ -4821,7 +4809,7 @@ EditActionResult HTMLEditor::HandleOutdentAtSelection() {
|
|||
// Therefore, even if it returns NS_OK, the editor might have been destroyed
|
||||
// at restoring Selection.
|
||||
SplitRangeOffFromNodeResult outdentResult =
|
||||
HandleOutdentAtSelectionInternal();
|
||||
HandleOutdentAtSelectionInternal(aEditingHost);
|
||||
if (NS_WARN_IF(Destroyed())) {
|
||||
return EditActionHandled(NS_ERROR_EDITOR_DESTROYED);
|
||||
}
|
||||
|
@ -4900,7 +4888,8 @@ EditActionResult HTMLEditor::HandleOutdentAtSelection() {
|
|||
return EditActionHandled();
|
||||
}
|
||||
|
||||
SplitRangeOffFromNodeResult HTMLEditor::HandleOutdentAtSelectionInternal() {
|
||||
SplitRangeOffFromNodeResult HTMLEditor::HandleOutdentAtSelectionInternal(
|
||||
const Element& aEditingHost) {
|
||||
MOZ_ASSERT(IsEditActionDataAvailable());
|
||||
|
||||
AutoSelectionRestorer restoreSelectionLater(*this);
|
||||
|
@ -4913,12 +4902,12 @@ SplitRangeOffFromNodeResult HTMLEditor::HandleOutdentAtSelectionInternal() {
|
|||
// in the range
|
||||
AutoTArray<OwningNonNull<nsIContent>, 64> arrayOfContents;
|
||||
{
|
||||
AutoTArray<OwningNonNull<nsRange>, 4> extendedSelectionRanges;
|
||||
GetSelectionRangesExtendedToHardLineStartAndEnd(extendedSelectionRanges,
|
||||
EditSubAction::eOutdent);
|
||||
AutoRangeArray extendedSelectionRanges(SelectionRef());
|
||||
extendedSelectionRanges.ExtendRangesToWrapLinesToHandleBlockLevelEditAction(
|
||||
EditSubAction::eOutdent, aEditingHost);
|
||||
nsresult rv = SplitInlinesAndCollectEditTargetNodes(
|
||||
extendedSelectionRanges, arrayOfContents, EditSubAction::eOutdent,
|
||||
CollectNonEditableNodes::Yes);
|
||||
extendedSelectionRanges.Ranges(), arrayOfContents,
|
||||
EditSubAction::eOutdent, CollectNonEditableNodes::Yes);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING(
|
||||
"HTMLEditor::SplitInlinesAndCollectEditTargetNodes(EditSubAction::"
|
||||
|
@ -5622,7 +5611,8 @@ nsresult HTMLEditor::CreateStyleForInsertText(
|
|||
return rv;
|
||||
}
|
||||
|
||||
EditActionResult HTMLEditor::AlignAsSubAction(const nsAString& aAlignType) {
|
||||
EditActionResult HTMLEditor::AlignAsSubAction(const nsAString& aAlignType,
|
||||
const Element& aEditingHost) {
|
||||
MOZ_ASSERT(IsEditActionDataAvailable());
|
||||
|
||||
AutoPlaceholderBatch treatAsOneTransaction(
|
||||
|
@ -5695,7 +5685,7 @@ EditActionResult HTMLEditor::AlignAsSubAction(const nsAString& aAlignType) {
|
|||
// AlignContentsAtSelection() creates AutoSelectionRestorer. Therefore,
|
||||
// we need to check whether we've been destroyed or not even if it returns
|
||||
// NS_OK.
|
||||
rv = AlignContentsAtSelection(aAlignType);
|
||||
rv = AlignContentsAtSelection(aAlignType, aEditingHost);
|
||||
if (NS_WARN_IF(Destroyed())) {
|
||||
return EditActionHandled(NS_ERROR_EDITOR_DESTROYED);
|
||||
}
|
||||
|
@ -5717,7 +5707,8 @@ EditActionResult HTMLEditor::AlignAsSubAction(const nsAString& aAlignType) {
|
|||
return EditActionHandled(rv);
|
||||
}
|
||||
|
||||
nsresult HTMLEditor::AlignContentsAtSelection(const nsAString& aAlignType) {
|
||||
nsresult HTMLEditor::AlignContentsAtSelection(const nsAString& aAlignType,
|
||||
const Element& aEditingHost) {
|
||||
MOZ_ASSERT(IsEditActionDataAvailable());
|
||||
MOZ_ASSERT(!IsSelectionRangeContainerNotContent());
|
||||
|
||||
|
@ -5729,11 +5720,11 @@ nsresult HTMLEditor::AlignContentsAtSelection(const nsAString& aAlignType) {
|
|||
// in the range
|
||||
AutoTArray<OwningNonNull<nsIContent>, 64> arrayOfContents;
|
||||
{
|
||||
AutoTArray<OwningNonNull<nsRange>, 4> extendedSelectionRanges;
|
||||
GetSelectionRangesExtendedToHardLineStartAndEnd(
|
||||
extendedSelectionRanges, EditSubAction::eSetOrClearAlignment);
|
||||
AutoRangeArray extendedSelectionRanges(SelectionRef());
|
||||
extendedSelectionRanges.ExtendRangesToWrapLinesToHandleBlockLevelEditAction(
|
||||
EditSubAction::eSetOrClearAlignment, aEditingHost);
|
||||
nsresult rv = SplitInlinesAndCollectEditTargetNodes(
|
||||
extendedSelectionRanges, arrayOfContents,
|
||||
extendedSelectionRanges.Ranges(), arrayOfContents,
|
||||
EditSubAction::eSetOrClearAlignment, CollectNonEditableNodes::Yes);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING(
|
||||
|
@ -6396,42 +6387,6 @@ nsresult HTMLEditor::MaybeExtendSelectionToHardLineEdgesForBlockEditAction() {
|
|||
return error.StealNSResult();
|
||||
}
|
||||
|
||||
void HTMLEditor::GetSelectionRangesExtendedToHardLineStartAndEnd(
|
||||
nsTArray<OwningNonNull<nsRange>>& aOutArrayOfRanges,
|
||||
EditSubAction aEditSubAction) {
|
||||
MOZ_ASSERT(IsEditActionDataAvailable());
|
||||
MOZ_ASSERT(aOutArrayOfRanges.IsEmpty());
|
||||
|
||||
Element* editingHost = ComputeEditingHost();
|
||||
|
||||
const uint32_t rangeCount = SelectionRef().RangeCount();
|
||||
aOutArrayOfRanges.SetCapacity(rangeCount);
|
||||
for (const uint32_t i : IntegerRange(rangeCount)) {
|
||||
MOZ_ASSERT(SelectionRef().RangeCount() == rangeCount);
|
||||
// Make a new adjusted range to represent the appropriate block content.
|
||||
// The basic idea is to push out the range endpoints to truly enclose the
|
||||
// blocks that we will affect. This call alters opRange.
|
||||
nsRange* selectionRange = SelectionRef().GetRangeAt(i);
|
||||
MOZ_ASSERT(selectionRange);
|
||||
EditorDOMRange editorRange(*selectionRange);
|
||||
if (!editorRange.IsPositioned() ||
|
||||
!editorRange.EnsureNotInNativeAnonymousSubtree()) {
|
||||
continue; // ignore ranges which are in orphan fragment which were
|
||||
// disconnected from native anonymous subtrees
|
||||
}
|
||||
RefPtr<nsRange> extendedRange;
|
||||
if (editingHost) {
|
||||
extendedRange = AutoRangeArray::
|
||||
CreateRangeWrappingStartAndEndLinesContainingBoundaries(
|
||||
editorRange, aEditSubAction, *editingHost);
|
||||
}
|
||||
if (!extendedRange) {
|
||||
extendedRange = selectionRange->CloneRange();
|
||||
}
|
||||
aOutArrayOfRanges.AppendElement(std::move(extendedRange));
|
||||
}
|
||||
}
|
||||
|
||||
template <typename EditorDOMRangeType>
|
||||
already_AddRefed<nsRange> HTMLEditor::CreateRangeIncludingAdjuscentWhiteSpaces(
|
||||
const EditorDOMRangeType& aRange) {
|
||||
|
@ -7573,7 +7528,7 @@ nsresult HTMLEditor::SplitParagraph(Element& aParentDivOrP,
|
|||
Result<EditorDOMPoint, nsresult>
|
||||
HTMLEditor::HandleInsertParagraphInListItemElement(
|
||||
Element& aListItemElement, const EditorDOMPoint& aPointToSplit,
|
||||
Element& aEditingHost) {
|
||||
const Element& aEditingHost) {
|
||||
MOZ_ASSERT(IsEditActionDataAvailable());
|
||||
MOZ_ASSERT(HTMLEditUtils::IsListItem(&aListItemElement));
|
||||
|
||||
|
@ -10044,7 +9999,8 @@ nsresult HTMLEditor::ChangeMarginStart(Element& aElement,
|
|||
return rv;
|
||||
}
|
||||
|
||||
EditActionResult HTMLEditor::SetSelectionToAbsoluteAsSubAction() {
|
||||
EditActionResult HTMLEditor::SetSelectionToAbsoluteAsSubAction(
|
||||
const Element& aEditingHost) {
|
||||
MOZ_ASSERT(IsTopLevelEditSubActionDataAvailable());
|
||||
|
||||
AutoPlaceholderBatch treatAsOneTransaction(
|
||||
|
@ -10115,7 +10071,7 @@ EditActionResult HTMLEditor::SetSelectionToAbsoluteAsSubAction() {
|
|||
|
||||
RefPtr<Element> divElement;
|
||||
rv = MoveSelectedContentsToDivElementToMakeItAbsolutePosition(
|
||||
address_of(divElement));
|
||||
address_of(divElement), aEditingHost);
|
||||
// MoveSelectedContentsToDivElementToMakeItAbsolutePosition() may restore
|
||||
// selection with AutoSelectionRestorer. Therefore, the editor might have
|
||||
// already been destroyed now.
|
||||
|
@ -10155,26 +10111,21 @@ EditActionResult HTMLEditor::SetSelectionToAbsoluteAsSubAction() {
|
|||
}
|
||||
|
||||
nsresult HTMLEditor::MoveSelectedContentsToDivElementToMakeItAbsolutePosition(
|
||||
RefPtr<Element>* aTargetElement) {
|
||||
RefPtr<Element>* aTargetElement, const Element& aEditingHost) {
|
||||
MOZ_ASSERT(IsEditActionDataAvailable());
|
||||
MOZ_ASSERT(aTargetElement);
|
||||
|
||||
RefPtr<Element> editingHost = ComputeEditingHost();
|
||||
if (MOZ_UNLIKELY(NS_WARN_IF(!editingHost))) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
AutoSelectionRestorer restoreSelectionLater(*this);
|
||||
|
||||
AutoTArray<OwningNonNull<nsRange>, 4> arrayOfRanges;
|
||||
GetSelectionRangesExtendedToHardLineStartAndEnd(
|
||||
arrayOfRanges, EditSubAction::eSetPositionToAbsolute);
|
||||
AutoRangeArray extendedSelectionRanges(SelectionRef());
|
||||
extendedSelectionRanges.ExtendRangesToWrapLinesToHandleBlockLevelEditAction(
|
||||
EditSubAction::eSetPositionToAbsolute, aEditingHost);
|
||||
|
||||
// Use these ranges to construct a list of nodes to act on.
|
||||
AutoTArray<OwningNonNull<nsIContent>, 64> arrayOfContents;
|
||||
nsresult rv = SplitInlinesAndCollectEditTargetNodes(
|
||||
arrayOfRanges, arrayOfContents, EditSubAction::eSetPositionToAbsolute,
|
||||
CollectNonEditableNodes::Yes);
|
||||
extendedSelectionRanges.Ranges(), arrayOfContents,
|
||||
EditSubAction::eSetPositionToAbsolute, CollectNonEditableNodes::Yes);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING(
|
||||
"HTMLEditor::SplitInlinesAndCollectEditTargetNodes("
|
||||
|
@ -10200,7 +10151,7 @@ nsresult HTMLEditor::MoveSelectedContentsToDivElementToMakeItAbsolutePosition(
|
|||
CreateElementResult createNewDivElementResult =
|
||||
InsertElementWithSplittingAncestorsWithTransaction(
|
||||
*nsGkAtoms::div, atCaret, BRElementNextToSplitPoint::Keep,
|
||||
*editingHost);
|
||||
aEditingHost);
|
||||
if (createNewDivElementResult.isErr()) {
|
||||
NS_WARNING(
|
||||
"HTMLEditor::InsertElementWithSplittingAncestorsWithTransaction("
|
||||
|
@ -10292,7 +10243,7 @@ nsresult HTMLEditor::MoveSelectedContentsToDivElementToMakeItAbsolutePosition(
|
|||
CreateElementResult createNewDivElementResult =
|
||||
InsertElementWithSplittingAncestorsWithTransaction(
|
||||
*nsGkAtoms::div, atContent, BRElementNextToSplitPoint::Keep,
|
||||
*editingHost);
|
||||
aEditingHost);
|
||||
if (createNewDivElementResult.isErr()) {
|
||||
NS_WARNING(
|
||||
"HTMLEditor::"
|
||||
|
@ -10358,7 +10309,7 @@ nsresult HTMLEditor::MoveSelectedContentsToDivElementToMakeItAbsolutePosition(
|
|||
// because we want to keep indent level of the contents.
|
||||
if (RefPtr<Element> listItemElement =
|
||||
HTMLEditUtils::GetClosestAncestorListItemElement(content,
|
||||
editingHost)) {
|
||||
&aEditingHost)) {
|
||||
if (handledListItemElement == listItemElement) {
|
||||
// Current node has already been moved into the `<div>` element.
|
||||
continue;
|
||||
|
@ -10402,7 +10353,7 @@ nsresult HTMLEditor::MoveSelectedContentsToDivElementToMakeItAbsolutePosition(
|
|||
CreateElementResult createNewDivElementResult =
|
||||
InsertElementWithSplittingAncestorsWithTransaction(
|
||||
*nsGkAtoms::div, atContent, BRElementNextToSplitPoint::Keep,
|
||||
*editingHost);
|
||||
aEditingHost);
|
||||
if (createNewDivElementResult.isErr()) {
|
||||
NS_WARNING(
|
||||
"HTMLEditor::"
|
||||
|
@ -10481,7 +10432,7 @@ nsresult HTMLEditor::MoveSelectedContentsToDivElementToMakeItAbsolutePosition(
|
|||
CreateElementResult createNewDivElementResult =
|
||||
InsertElementWithSplittingAncestorsWithTransaction(
|
||||
*nsGkAtoms::div, atContent, BRElementNextToSplitPoint::Keep,
|
||||
*editingHost);
|
||||
aEditingHost);
|
||||
if (createNewDivElementResult.isErr()) {
|
||||
NS_WARNING(
|
||||
"HTMLEditor::InsertElementWithSplittingAncestorsWithTransaction("
|
||||
|
|
|
@ -1257,7 +1257,12 @@ NS_IMETHODIMP HTMLEditor::InsertLineBreak() {
|
|||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
|
||||
EditActionResult result = InsertParagraphSeparatorAsSubAction();
|
||||
const RefPtr<Element> editingHost = ComputeEditingHost();
|
||||
if (!editingHost) {
|
||||
return NS_SUCCESS_DOM_NO_OPERATION;
|
||||
}
|
||||
|
||||
EditActionResult result = InsertParagraphSeparatorAsSubAction(*editingHost);
|
||||
NS_WARNING_ASSERTION(
|
||||
result.Succeeded(),
|
||||
"HTMLEditor::InsertParagraphSeparatorAsSubAction() failed");
|
||||
|
@ -1297,7 +1302,12 @@ nsresult HTMLEditor::InsertParagraphSeparatorAsAction(
|
|||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
|
||||
EditActionResult result = InsertParagraphSeparatorAsSubAction();
|
||||
const RefPtr<Element> editingHost = ComputeEditingHost();
|
||||
if (!editingHost) {
|
||||
return NS_SUCCESS_DOM_NO_OPERATION;
|
||||
}
|
||||
|
||||
EditActionResult result = InsertParagraphSeparatorAsSubAction(*editingHost);
|
||||
NS_WARNING_ASSERTION(
|
||||
result.Succeeded(),
|
||||
"HTMLEditor::InsertParagraphSeparatorAsSubAction() failed");
|
||||
|
@ -2153,6 +2163,12 @@ nsresult HTMLEditor::SetParagraphFormatAsAction(
|
|||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
|
||||
// TODO: Computing the editing host here makes the `execCommand` in
|
||||
// docshell/base/crashtests/file_432114-2.xhtml cannot run
|
||||
// `DOMNodeRemoved` event listener with deleting the bogus <br> element.
|
||||
// So that it should be rewritten with different mutation event listener
|
||||
// since we'd like to stop using it.
|
||||
|
||||
nsAutoString lowerCaseTagName(aParagraphFormat);
|
||||
ToLowerCase(lowerCaseTagName);
|
||||
RefPtr<nsAtom> tagName = NS_Atomize(lowerCaseTagName);
|
||||
|
@ -2165,6 +2181,7 @@ nsresult HTMLEditor::SetParagraphFormatAsAction(
|
|||
"SelectAllOfCurrentList::No) failed");
|
||||
return EditorBase::ToGenericNSResult(result.Rv());
|
||||
}
|
||||
|
||||
rv = FormatBlockContainerAsSubAction(*tagName);
|
||||
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
|
||||
"HTMLEditor::FormatBlockContainerAsSubAction() failed");
|
||||
|
@ -2573,7 +2590,12 @@ nsresult HTMLEditor::RemoveListAsAction(const nsAString& aListType,
|
|||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
|
||||
rv = RemoveListAtSelectionAsSubAction();
|
||||
const RefPtr<Element> editingHost = ComputeEditingHost();
|
||||
if (!editingHost) {
|
||||
return NS_SUCCESS_DOM_NO_OPERATION;
|
||||
}
|
||||
|
||||
rv = RemoveListAtSelectionAsSubAction(*editingHost);
|
||||
NS_WARNING_ASSERTION(NS_FAILED(rv),
|
||||
"HTMLEditor::RemoveListAtSelectionAsSubAction() failed");
|
||||
return rv;
|
||||
|
@ -2642,7 +2664,11 @@ nsresult HTMLEditor::FormatBlockContainerAsSubAction(nsAtom& aTagName) {
|
|||
// FormatBlockContainerWithTransaction() creates AutoSelectionRestorer.
|
||||
// Therefore, even if it returns NS_OK, editor might have been destroyed
|
||||
// at restoring Selection.
|
||||
rv = FormatBlockContainerWithTransaction(aTagName);
|
||||
const RefPtr<Element> editingHost = ComputeEditingHost();
|
||||
if (MOZ_UNLIKELY(!editingHost)) {
|
||||
return NS_SUCCESS_DOM_NO_OPERATION;
|
||||
}
|
||||
rv = FormatBlockContainerWithTransaction(aTagName, *editingHost);
|
||||
if (NS_WARN_IF(Destroyed())) {
|
||||
return NS_ERROR_EDITOR_DESTROYED;
|
||||
}
|
||||
|
@ -2673,7 +2699,12 @@ nsresult HTMLEditor::IndentAsAction(nsIPrincipal* aPrincipal) {
|
|||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
|
||||
EditActionResult result = IndentAsSubAction();
|
||||
const RefPtr<Element> editingHost = ComputeEditingHost();
|
||||
if (!editingHost) {
|
||||
return NS_SUCCESS_DOM_NO_OPERATION;
|
||||
}
|
||||
|
||||
EditActionResult result = IndentAsSubAction(*editingHost);
|
||||
NS_WARNING_ASSERTION(result.Succeeded(),
|
||||
"HTMLEditor::IndentAsSubAction() failed");
|
||||
return EditorBase::ToGenericNSResult(result.Rv());
|
||||
|
@ -2693,7 +2724,12 @@ nsresult HTMLEditor::OutdentAsAction(nsIPrincipal* aPrincipal) {
|
|||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
|
||||
EditActionResult result = OutdentAsSubAction();
|
||||
const RefPtr<Element> editingHost = ComputeEditingHost();
|
||||
if (!editingHost) {
|
||||
return NS_SUCCESS_DOM_NO_OPERATION;
|
||||
}
|
||||
|
||||
EditActionResult result = OutdentAsSubAction(*editingHost);
|
||||
NS_WARNING_ASSERTION(result.Succeeded(),
|
||||
"HTMLEditor::OutdentAsSubAction() failed");
|
||||
return EditorBase::ToGenericNSResult(result.Rv());
|
||||
|
@ -2712,7 +2748,12 @@ nsresult HTMLEditor::AlignAsAction(const nsAString& aAlignType,
|
|||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
|
||||
EditActionResult result = AlignAsSubAction(aAlignType);
|
||||
const RefPtr<Element> editingHost = ComputeEditingHost();
|
||||
if (!editingHost) {
|
||||
return NS_SUCCESS_DOM_NO_OPERATION;
|
||||
}
|
||||
|
||||
EditActionResult result = AlignAsSubAction(aAlignType, *editingHost);
|
||||
NS_WARNING_ASSERTION(result.Succeeded(),
|
||||
"HTMLEditor::AlignAsSubAction() failed");
|
||||
return EditorBase::ToGenericNSResult(result.Rv());
|
||||
|
@ -5860,9 +5901,8 @@ nsresult HTMLEditor::SetBackgroundColorAsAction(const nsAString& aColor,
|
|||
}
|
||||
|
||||
Result<EditorDOMPoint, nsresult>
|
||||
HTMLEditor::CopyLastEditableChildStylesWithTransaction(Element& aPreviousBlock,
|
||||
Element& aNewBlock,
|
||||
Element& aEditingHost) {
|
||||
HTMLEditor::CopyLastEditableChildStylesWithTransaction(
|
||||
Element& aPreviousBlock, Element& aNewBlock, const Element& aEditingHost) {
|
||||
MOZ_ASSERT(IsEditActionDataAvailable());
|
||||
|
||||
// First, clear out aNewBlock. Contract is that we want only the styles
|
||||
|
|
|
@ -758,14 +758,14 @@ class HTMLEditor final : public EditorBase,
|
|||
* are cloned to aNewBlock.
|
||||
* @param aNewBlock New block container element. All children of
|
||||
* this is deleted first.
|
||||
* @param aEditingHost Current editing host.
|
||||
* @param aEditingHost The editing host.
|
||||
* @return If succeeded, returns a suggesting point to put
|
||||
* caret.
|
||||
*/
|
||||
[[nodiscard]] MOZ_CAN_RUN_SCRIPT Result<EditorDOMPoint, nsresult>
|
||||
CopyLastEditableChildStylesWithTransaction(Element& aPreviousBlock,
|
||||
Element& aNewBlock,
|
||||
Element& aEditingHost);
|
||||
const Element& aEditingHost);
|
||||
|
||||
/**
|
||||
* RemoveBlockContainerWithTransaction() removes aElement from the DOM tree
|
||||
|
@ -1087,14 +1087,14 @@ class HTMLEditor final : public EditorBase,
|
|||
*
|
||||
* @param aMailCiteElement The mail-cite element which should be split.
|
||||
* @param aPointToSplit The point to split.
|
||||
* @param aEditingHost Current editing host element.
|
||||
* @param aEditingHost The editing host.
|
||||
* @return Candidate caret position where is at inserted
|
||||
* <br> element into the split point.
|
||||
*/
|
||||
[[nodiscard]] MOZ_CAN_RUN_SCRIPT Result<EditorDOMPoint, nsresult>
|
||||
HandleInsertParagraphInMailCiteElement(Element& aMailCiteElement,
|
||||
const EditorDOMPoint& aPointToSplit,
|
||||
Element& aEditingHost);
|
||||
const Element& aEditingHost);
|
||||
|
||||
/**
|
||||
* HandleInsertBRElement() inserts a <br> element into aInsertToBreak.
|
||||
|
@ -1108,7 +1108,7 @@ class HTMLEditor final : public EditorBase,
|
|||
* candidate caret point.
|
||||
*/
|
||||
[[nodiscard]] MOZ_CAN_RUN_SCRIPT CreateElementResult HandleInsertBRElement(
|
||||
const EditorDOMPoint& aInsertToBreak, Element& aEditingHost);
|
||||
const EditorDOMPoint& aInsertToBreak, const Element& aEditingHost);
|
||||
|
||||
/**
|
||||
* HandleInsertLinefeed() inserts a linefeed character into aInsertToBreak.
|
||||
|
@ -1118,7 +1118,7 @@ class HTMLEditor final : public EditorBase,
|
|||
* @param aEditingHost Current active editing host.
|
||||
*/
|
||||
[[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult HandleInsertLinefeed(
|
||||
const EditorDOMPoint& aInsertToBreak, Element& aEditingHost);
|
||||
const EditorDOMPoint& aInsertToBreak, const Element& aEditingHost);
|
||||
|
||||
/**
|
||||
* SplitParentInlineElementsAtRangeEdges() splits parent inline nodes at both
|
||||
|
@ -1243,19 +1243,6 @@ class HTMLEditor final : public EditorBase,
|
|||
const EditorDOMPointType1& aStartPoint,
|
||||
const EditorDOMPointType2& aEndPoint);
|
||||
|
||||
/**
|
||||
* GetSelectionRangesExtendedToHardLineStartAndEnd() collects selection ranges
|
||||
* with extending to start/end of hard line from each range start and end.
|
||||
* XXX This means that same range may be included in the result.
|
||||
*
|
||||
* @param aOutArrayOfRanges [out] Always appended same number of ranges
|
||||
* as Selection::RangeCount(). Must be empty
|
||||
* when you call this.
|
||||
*/
|
||||
void GetSelectionRangesExtendedToHardLineStartAndEnd(
|
||||
nsTArray<OwningNonNull<nsRange>>& aOutArrayOfRanges,
|
||||
EditSubAction aEditSubAction);
|
||||
|
||||
/**
|
||||
* GetChildNodesOf() returns all child nodes of aParent with an array.
|
||||
*/
|
||||
|
@ -1497,9 +1484,10 @@ class HTMLEditor final : public EditorBase,
|
|||
* be called.
|
||||
* Otherwise, CreateOrChangeBlockContainerElement() will be
|
||||
* called.
|
||||
* @param aEditingHost The editing host.
|
||||
*/
|
||||
[[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult
|
||||
FormatBlockContainerWithTransaction(nsAtom& aBlockType);
|
||||
[[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult FormatBlockContainerWithTransaction(
|
||||
nsAtom& aBlockType, const Element& aEditingHost);
|
||||
|
||||
/**
|
||||
* InsertBRElementIfHardLineIsEmptyAndEndsWithBlockBoundary() determines if
|
||||
|
@ -1583,20 +1571,22 @@ class HTMLEditor final : public EditorBase,
|
|||
*
|
||||
* @param aListItemElement The list item which has the following point.
|
||||
* @param aPointToSplit The point to split aListItemElement.
|
||||
* @param aEditingHost The editing host for aListItemElement
|
||||
* @param aEditingHost The editing host.
|
||||
* @return A candidate position to put caret.
|
||||
*/
|
||||
[[nodiscard]] MOZ_CAN_RUN_SCRIPT Result<EditorDOMPoint, nsresult>
|
||||
HandleInsertParagraphInListItemElement(Element& aListItemElement,
|
||||
const EditorDOMPoint& aPointToSplit,
|
||||
Element& aEditingHost);
|
||||
const Element& aEditingHost);
|
||||
|
||||
/**
|
||||
* InsertParagraphSeparatorAsSubAction() handles insertPargraph commad
|
||||
* (i.e., handling Enter key press) with the above helper methods.
|
||||
*
|
||||
* @param aEditingHost The editing host.
|
||||
*/
|
||||
[[nodiscard]] MOZ_CAN_RUN_SCRIPT EditActionResult
|
||||
InsertParagraphSeparatorAsSubAction();
|
||||
InsertParagraphSeparatorAsSubAction(const Element& aEditingHost);
|
||||
|
||||
/**
|
||||
* InsertLineBreakAsSubAction() inserts a new <br> element or a linefeed
|
||||
|
@ -1641,12 +1631,14 @@ class HTMLEditor final : public EditorBase,
|
|||
* attributes will be removed.
|
||||
* @param aSelectAllOfCurrentList Yes if this should treat all of
|
||||
* ancestor list element at selection.
|
||||
* @param aEditingHost The editing host.
|
||||
*/
|
||||
[[nodiscard]] MOZ_CAN_RUN_SCRIPT EditActionResult
|
||||
ChangeSelectedHardLinesToList(nsAtom& aListElementTagName,
|
||||
nsAtom& aListItemElementTagName,
|
||||
const nsAString& aBulletType,
|
||||
SelectAllOfCurrentList aSelectAllOfCurrentList);
|
||||
SelectAllOfCurrentList aSelectAllOfCurrentList,
|
||||
const Element& aEditingHost);
|
||||
|
||||
/**
|
||||
* MakeOrChangeListAndListItemAsSubAction() handles create list commands with
|
||||
|
@ -2318,8 +2310,11 @@ class HTMLEditor final : public EditorBase,
|
|||
* RemoveListAtSelectionAsSubAction() removes list elements and list item
|
||||
* elements at Selection. And move contents in them where the removed list
|
||||
* was.
|
||||
*
|
||||
* @param aEditingHost The editing host.
|
||||
*/
|
||||
[[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult RemoveListAtSelectionAsSubAction();
|
||||
[[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult
|
||||
RemoveListAtSelectionAsSubAction(const Element& aEditingHost);
|
||||
|
||||
/**
|
||||
* ChangeMarginStart() changes margin of aElement to indent or outdent.
|
||||
|
@ -2336,9 +2331,11 @@ class HTMLEditor final : public EditorBase,
|
|||
* need to check if the editor is still available even if this returns
|
||||
* NS_OK.
|
||||
* NOTE: Use HandleCSSIndentAtSelection() instead.
|
||||
*
|
||||
* @param aEditingHost The editing host.
|
||||
*/
|
||||
[[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult
|
||||
HandleCSSIndentAtSelectionInternal();
|
||||
HandleCSSIndentAtSelectionInternal(const Element& aEditingHost);
|
||||
|
||||
/**
|
||||
* HandleHTMLIndentAtSelectionInternal() indents around Selection with HTML.
|
||||
|
@ -2346,30 +2343,41 @@ class HTMLEditor final : public EditorBase,
|
|||
* need to check if the editor is still available even if this returns
|
||||
* NS_OK.
|
||||
* NOTE: Use HandleHTMLIndentAtSelection() instead.
|
||||
*
|
||||
* @param aEditingHost The editing host.
|
||||
*/
|
||||
[[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult
|
||||
HandleHTMLIndentAtSelectionInternal();
|
||||
HandleHTMLIndentAtSelectionInternal(const Element& aEditingHost);
|
||||
|
||||
/**
|
||||
* HandleCSSIndentAtSelection() indents around Selection with CSS.
|
||||
* NOTE: This is a helper method of `HandleIndentAtSelection()`. If you
|
||||
* want to call this directly, you should check whether you need
|
||||
* do do something which `HandleIndentAtSelection()` does.
|
||||
*
|
||||
* @param aEditingHost The editing host.
|
||||
*/
|
||||
[[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult HandleCSSIndentAtSelection();
|
||||
[[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult
|
||||
HandleCSSIndentAtSelection(const Element& aEditingHost);
|
||||
|
||||
/**
|
||||
* HandleHTMLIndentAtSelection() indents around Selection with HTML.
|
||||
* NOTE: This is a helper method of `HandleIndentAtSelection()`. If you
|
||||
* want to call this directly, you should check whether you need
|
||||
* do do something which `HandleIndentAtSelection()` does.
|
||||
*
|
||||
* @param aEditingHost The editing host.
|
||||
*/
|
||||
[[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult HandleHTMLIndentAtSelection();
|
||||
[[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult
|
||||
HandleHTMLIndentAtSelection(const Element& aEditingHost);
|
||||
|
||||
/**
|
||||
* HandleIndentAtSelection() indents around Selection with HTML or CSS.
|
||||
*
|
||||
* @param aEditingHost The editing host.
|
||||
*/
|
||||
[[nodiscard]] MOZ_CAN_RUN_SCRIPT EditActionResult HandleIndentAtSelection();
|
||||
[[nodiscard]] MOZ_CAN_RUN_SCRIPT EditActionResult
|
||||
HandleIndentAtSelection(const Element& aEditingHost);
|
||||
|
||||
/**
|
||||
* OutdentPartOfBlock() outdents the nodes between aStartOfOutdent and
|
||||
|
@ -2407,6 +2415,7 @@ class HTMLEditor final : public EditorBase,
|
|||
* NS_OK.
|
||||
* NOTE: Call `HandleOutdentAtSelection()` instead.
|
||||
*
|
||||
* @param aEditingHost The editing host.
|
||||
* @return The left content is left content of last
|
||||
* outdented element.
|
||||
* The right content is right content of last
|
||||
|
@ -2415,12 +2424,15 @@ class HTMLEditor final : public EditorBase,
|
|||
* outdented element.
|
||||
*/
|
||||
[[nodiscard]] MOZ_CAN_RUN_SCRIPT SplitRangeOffFromNodeResult
|
||||
HandleOutdentAtSelectionInternal();
|
||||
HandleOutdentAtSelectionInternal(const Element& aEditingHost);
|
||||
|
||||
/**
|
||||
* HandleOutdentAtSelection() outdents contents around Selection.
|
||||
*
|
||||
* @param aEditingHost The editing host.
|
||||
*/
|
||||
[[nodiscard]] MOZ_CAN_RUN_SCRIPT EditActionResult HandleOutdentAtSelection();
|
||||
[[nodiscard]] MOZ_CAN_RUN_SCRIPT EditActionResult
|
||||
HandleOutdentAtSelection(const Element& aEditingHost);
|
||||
|
||||
/**
|
||||
* AlignBlockContentsWithDivElement() sets align attribute of <div> element
|
||||
|
@ -2555,18 +2567,20 @@ class HTMLEditor final : public EditorBase,
|
|||
*
|
||||
* @param aAlignType New align attribute value where the contents
|
||||
* should be aligned to.
|
||||
* @param aEditingHost The editing host.
|
||||
*/
|
||||
[[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult
|
||||
AlignContentsAtSelection(const nsAString& aAlignType);
|
||||
[[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult AlignContentsAtSelection(
|
||||
const nsAString& aAlignType, const Element& aEditingHost);
|
||||
|
||||
/**
|
||||
* AlignAsSubAction() handles "align" command with `Selection`.
|
||||
*
|
||||
* @param aAlignType New align attribute value where the contents
|
||||
* should be aligned to.
|
||||
* @param aEditingHost The editing host.
|
||||
*/
|
||||
[[nodiscard]] MOZ_CAN_RUN_SCRIPT EditActionResult
|
||||
AlignAsSubAction(const nsAString& aAlignType);
|
||||
AlignAsSubAction(const nsAString& aAlignType, const Element& aEditingHost);
|
||||
|
||||
/**
|
||||
* AdjustCaretPositionAndEnsurePaddingBRElement() may adjust caret
|
||||
|
@ -2642,10 +2656,12 @@ class HTMLEditor final : public EditorBase,
|
|||
*
|
||||
* @param aTargetElement Returns target `<div>` element which should be
|
||||
* changed to absolute positioned.
|
||||
* @param aEditingHost The editing host.
|
||||
*/
|
||||
// TODO: Rewrite this with `Result<RefPtr<Element>, nsresult>`.
|
||||
[[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult
|
||||
MoveSelectedContentsToDivElementToMakeItAbsolutePosition(
|
||||
RefPtr<Element>* aTargetElement);
|
||||
RefPtr<Element>* aTargetElement, const Element& aEditingHost);
|
||||
|
||||
/**
|
||||
* SetSelectionToAbsoluteAsSubAction() move selected contents to first
|
||||
|
@ -2653,9 +2669,11 @@ class HTMLEditor final : public EditorBase,
|
|||
* the `<div>` element positioned absolutely.
|
||||
* mNewBlockElement of TopLevelEditSubActionData will be set to the `<div>`
|
||||
* element.
|
||||
*
|
||||
* @param aEditingHost The editing host.
|
||||
*/
|
||||
[[nodiscard]] MOZ_CAN_RUN_SCRIPT EditActionResult
|
||||
SetSelectionToAbsoluteAsSubAction();
|
||||
SetSelectionToAbsoluteAsSubAction(const Element& aEditingHost);
|
||||
|
||||
/**
|
||||
* SetSelectionToStaticAsSubAction() sets the `position` property of a
|
||||
|
@ -3275,13 +3293,19 @@ class HTMLEditor final : public EditorBase,
|
|||
|
||||
/**
|
||||
* IndentAsSubAction() indents the content around Selection.
|
||||
*
|
||||
* @param aEditingHost The editing host.
|
||||
*/
|
||||
[[nodiscard]] MOZ_CAN_RUN_SCRIPT EditActionResult IndentAsSubAction();
|
||||
[[nodiscard]] MOZ_CAN_RUN_SCRIPT EditActionResult
|
||||
IndentAsSubAction(const Element& aEditingHost);
|
||||
|
||||
/**
|
||||
* OutdentAsSubAction() outdents the content around Selection.
|
||||
*
|
||||
* @param aEditingHost The editing host.
|
||||
*/
|
||||
[[nodiscard]] MOZ_CAN_RUN_SCRIPT EditActionResult OutdentAsSubAction();
|
||||
[[nodiscard]] MOZ_CAN_RUN_SCRIPT EditActionResult
|
||||
OutdentAsSubAction(const Element& aEditingHost);
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT nsresult LoadHTML(const nsAString& aInputString);
|
||||
|
||||
|
@ -4486,10 +4510,8 @@ class HTMLEditor final : public EditorBase,
|
|||
|
||||
ParagraphSeparator mDefaultParagraphSeparator;
|
||||
|
||||
friend class
|
||||
AlignStateAtSelection; // CollectEditableTargetNodes,
|
||||
// CollectNonEditableNodes,
|
||||
// GetSelectionRangesExtendedToHardLineStartAndEnd
|
||||
friend class AlignStateAtSelection; // CollectEditableTargetNodes,
|
||||
// CollectNonEditableNodes
|
||||
friend class AutoSelectionSetterAfterTableEdit; // SetSelectionAfterEdit
|
||||
friend class
|
||||
AutoSetTemporaryAncestorLimiter; // InitializeSelectionAncestorLimit
|
||||
|
@ -4503,29 +4525,23 @@ class HTMLEditor final : public EditorBase,
|
|||
// ReflectPaddingBRElementForEmptyEditor,
|
||||
// RefreshEditingUI,
|
||||
// RemoveEmptyInclusiveAncestorInlineElements,
|
||||
// mComposerUpdater, mHasBeforeINputBeenCancelded
|
||||
// mComposerUpdater, mHasBeforeInputBeenCanceled
|
||||
friend class JoinNodesTransaction; // DidJoinNodesTransaction, DoJoinNodes,
|
||||
// DoSplitNode, RangeUpdaterRef
|
||||
friend class
|
||||
ListElementSelectionState; // CollectEditTargetNodes,
|
||||
// CollectNonEditableNodes,
|
||||
// GetSelectionRangesExtendedToHardLineStartAndEnd
|
||||
friend class
|
||||
ListItemElementSelectionState; // CollectEditTargetNodes,
|
||||
// CollectNonEditableNodes,
|
||||
// GetSelectionRangesExtendedToHardLineStartAndEnd
|
||||
friend class ListElementSelectionState; // CollectEditTargetNodes,
|
||||
// CollectNonEditableNodes
|
||||
friend class ListItemElementSelectionState; // CollectEditTargetNodes,
|
||||
// CollectNonEditableNodes
|
||||
friend class MoveNodeResult; // AllowsTransactionsToChangeSelection,
|
||||
// CollapseSelectionTo
|
||||
friend class MoveNodeTransaction; // AllowsTransactionsToChangeSelection,
|
||||
// CollapseSelectionTo, MarkElementDirty,
|
||||
// RangeUpdaterRef
|
||||
friend class
|
||||
ParagraphStateAtSelection; // CollectChildren,
|
||||
// CollectEditTargetNodes,
|
||||
// CollectListChildren,
|
||||
// CollectNonEditableNodes,
|
||||
// CollectTableChildren,
|
||||
// GetSelectionRangesExtendedToHardLineStartAndEnd
|
||||
friend class ParagraphStateAtSelection; // CollectChildren,
|
||||
// CollectEditTargetNodes,
|
||||
// CollectListChildren,
|
||||
// CollectNonEditableNodes,
|
||||
// CollectTableChildren
|
||||
friend class SlurpBlobEventListener; // BlobReader
|
||||
friend class SplitNodeResult; // CollapseSelectionTo
|
||||
friend class SplitNodeTransaction; // DoJoinNodes, DoSplitNode
|
||||
|
@ -4662,13 +4678,13 @@ class MOZ_STACK_CLASS ParagraphStateAtSelection final {
|
|||
/**
|
||||
* CollectEditableFormatNodesInSelection() collects only editable nodes
|
||||
* around selection ranges (with
|
||||
* `HTMLEditor::GetSelectionRangesExtendedToHardLineStartAndEnd()` and
|
||||
* `AutoRangeArray::ExtendRangesToWrapLinesToHandleBlockLevelEditAction()` and
|
||||
* `HTMLEditor::CollectEditTargetNodes()`, see its document for the detail).
|
||||
* If it includes list, list item or table related elements, they will be
|
||||
* replaced their children.
|
||||
*/
|
||||
static nsresult CollectEditableFormatNodesInSelection(
|
||||
HTMLEditor& aHTMLEditor,
|
||||
HTMLEditor& aHTMLEditor, const dom::Element& aEditingHost,
|
||||
nsTArray<OwningNonNull<nsIContent>>& aArrayOfContents);
|
||||
|
||||
RefPtr<nsAtom> mFirstParagraphState;
|
||||
|
|
|
@ -64,13 +64,23 @@ ListElementSelectionState::ListElementSelectionState(HTMLEditor& aHTMLEditor,
|
|||
return;
|
||||
}
|
||||
|
||||
Element* editingHostOrRoot = aHTMLEditor.ComputeEditingHost();
|
||||
if (!editingHostOrRoot) {
|
||||
// This is not a handler of editing command so that if there is no active
|
||||
// editing host, let's use the <body> or document element instead.
|
||||
editingHostOrRoot = aHTMLEditor.GetRoot();
|
||||
if (!editingHostOrRoot) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
AutoTArray<OwningNonNull<nsIContent>, 64> arrayOfContents;
|
||||
{
|
||||
AutoTArray<OwningNonNull<nsRange>, 4> extendedSelectionRanges;
|
||||
aHTMLEditor.GetSelectionRangesExtendedToHardLineStartAndEnd(
|
||||
extendedSelectionRanges, EditSubAction::eCreateOrChangeList);
|
||||
AutoRangeArray extendedSelectionRanges(aHTMLEditor.SelectionRef());
|
||||
extendedSelectionRanges.ExtendRangesToWrapLinesToHandleBlockLevelEditAction(
|
||||
EditSubAction::eCreateOrChangeList, *editingHostOrRoot);
|
||||
nsresult rv = aHTMLEditor.CollectEditTargetNodes(
|
||||
extendedSelectionRanges, arrayOfContents,
|
||||
extendedSelectionRanges.Ranges(), arrayOfContents,
|
||||
EditSubAction::eCreateOrChangeList,
|
||||
HTMLEditor::CollectNonEditableNodes::No);
|
||||
if (NS_FAILED(rv)) {
|
||||
|
@ -135,13 +145,23 @@ ListItemElementSelectionState::ListItemElementSelectionState(
|
|||
return;
|
||||
}
|
||||
|
||||
Element* editingHostOrRoot = aHTMLEditor.ComputeEditingHost();
|
||||
if (!editingHostOrRoot) {
|
||||
// This is not a handler of editing command so that if there is no active
|
||||
// editing host, let's use the <body> or document element instead.
|
||||
editingHostOrRoot = aHTMLEditor.GetRoot();
|
||||
if (!editingHostOrRoot) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
AutoTArray<OwningNonNull<nsIContent>, 64> arrayOfContents;
|
||||
{
|
||||
AutoTArray<OwningNonNull<nsRange>, 4> extendedSelectionRanges;
|
||||
aHTMLEditor.GetSelectionRangesExtendedToHardLineStartAndEnd(
|
||||
extendedSelectionRanges, EditSubAction::eCreateOrChangeList);
|
||||
AutoRangeArray extendedSelectionRanges(aHTMLEditor.SelectionRef());
|
||||
extendedSelectionRanges.ExtendRangesToWrapLinesToHandleBlockLevelEditAction(
|
||||
EditSubAction::eCreateOrChangeList, *editingHostOrRoot);
|
||||
nsresult rv = aHTMLEditor.CollectEditTargetNodes(
|
||||
extendedSelectionRanges, arrayOfContents,
|
||||
extendedSelectionRanges.Ranges(), arrayOfContents,
|
||||
EditSubAction::eCreateOrChangeList,
|
||||
HTMLEditor::CollectNonEditableNodes::No);
|
||||
if (NS_FAILED(rv)) {
|
||||
|
@ -274,13 +294,23 @@ AlignStateAtSelection::AlignStateAtSelection(HTMLEditor& aHTMLEditor,
|
|||
// ranges. `HTMLEditor` should have
|
||||
// `GetFirstSelectionRangeExtendedToHardLineStartAndEnd()`.
|
||||
else {
|
||||
AutoTArray<OwningNonNull<nsRange>, 4> arrayOfRanges;
|
||||
aHTMLEditor.GetSelectionRangesExtendedToHardLineStartAndEnd(
|
||||
arrayOfRanges, EditSubAction::eSetOrClearAlignment);
|
||||
Element* editingHostOrRoot = aHTMLEditor.ComputeEditingHost();
|
||||
if (!editingHostOrRoot) {
|
||||
// This is not a handler of editing command so that if there is no active
|
||||
// editing host, let's use the <body> or document element instead.
|
||||
editingHostOrRoot = aHTMLEditor.GetRoot();
|
||||
if (!editingHostOrRoot) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
AutoRangeArray extendedSelectionRanges(aHTMLEditor.SelectionRef());
|
||||
extendedSelectionRanges.ExtendRangesToWrapLinesToHandleBlockLevelEditAction(
|
||||
EditSubAction::eSetOrClearAlignment, *editingHostOrRoot);
|
||||
|
||||
AutoTArray<OwningNonNull<nsIContent>, 64> arrayOfContents;
|
||||
nsresult rv = aHTMLEditor.CollectEditTargetNodes(
|
||||
arrayOfRanges, arrayOfContents, EditSubAction::eSetOrClearAlignment,
|
||||
extendedSelectionRanges.Ranges(), arrayOfContents,
|
||||
EditSubAction::eSetOrClearAlignment,
|
||||
HTMLEditor::CollectNonEditableNodes::Yes);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING(
|
||||
|
@ -440,9 +470,19 @@ ParagraphStateAtSelection::ParagraphStateAtSelection(HTMLEditor& aHTMLEditor,
|
|||
return;
|
||||
}
|
||||
|
||||
Element* editingHostOrRoot = aHTMLEditor.ComputeEditingHost();
|
||||
if (!editingHostOrRoot) {
|
||||
// This is not a handler of editing command so that if there is no active
|
||||
// editing host, let's use the <body> or document element instead.
|
||||
editingHostOrRoot = aHTMLEditor.GetRoot();
|
||||
if (!editingHostOrRoot) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
AutoTArray<OwningNonNull<nsIContent>, 64> arrayOfContents;
|
||||
nsresult rv =
|
||||
CollectEditableFormatNodesInSelection(aHTMLEditor, arrayOfContents);
|
||||
nsresult rv = CollectEditableFormatNodesInSelection(
|
||||
aHTMLEditor, *editingHostOrRoot, arrayOfContents);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING(
|
||||
"ParagraphStateAtSelection::CollectEditableFormatNodesInSelection() "
|
||||
|
@ -581,14 +621,14 @@ void ParagraphStateAtSelection::AppendDescendantFormatNodesAndFirstInlineNode(
|
|||
|
||||
// static
|
||||
nsresult ParagraphStateAtSelection::CollectEditableFormatNodesInSelection(
|
||||
HTMLEditor& aHTMLEditor,
|
||||
HTMLEditor& aHTMLEditor, const Element& aEditingHost,
|
||||
nsTArray<OwningNonNull<nsIContent>>& aArrayOfContents) {
|
||||
{
|
||||
AutoTArray<OwningNonNull<nsRange>, 4> extendedSelectionRanges;
|
||||
aHTMLEditor.GetSelectionRangesExtendedToHardLineStartAndEnd(
|
||||
extendedSelectionRanges, EditSubAction::eCreateOrRemoveBlock);
|
||||
AutoRangeArray extendedSelectionRanges(aHTMLEditor.SelectionRef());
|
||||
extendedSelectionRanges.ExtendRangesToWrapLinesToHandleBlockLevelEditAction(
|
||||
EditSubAction::eCreateOrRemoveBlock, aEditingHost);
|
||||
nsresult rv = aHTMLEditor.CollectEditTargetNodes(
|
||||
extendedSelectionRanges, aArrayOfContents,
|
||||
extendedSelectionRanges.Ranges(), aArrayOfContents,
|
||||
EditSubAction::eCreateOrRemoveBlock,
|
||||
HTMLEditor::CollectNonEditableNodes::Yes);
|
||||
if (NS_FAILED(rv)) {
|
||||
|
|
|
@ -717,7 +717,7 @@ EditActionResult WhiteSpaceVisibilityKeeper::
|
|||
// static
|
||||
CreateElementResult WhiteSpaceVisibilityKeeper::InsertBRElement(
|
||||
HTMLEditor& aHTMLEditor, const EditorDOMPoint& aPointToInsert,
|
||||
Element& aEditingHost) {
|
||||
const Element& aEditingHost) {
|
||||
if (MOZ_UNLIKELY(NS_WARN_IF(!aPointToInsert.IsSet()))) {
|
||||
return CreateElementResult(NS_ERROR_INVALID_ARG);
|
||||
}
|
||||
|
|
|
@ -1471,7 +1471,7 @@ class WhiteSpaceVisibilityKeeper final {
|
|||
*/
|
||||
[[nodiscard]] MOZ_CAN_RUN_SCRIPT static CreateElementResult InsertBRElement(
|
||||
HTMLEditor& aHTMLEditor, const EditorDOMPoint& aPointToInsert,
|
||||
Element& aEditingHost);
|
||||
const Element& aEditingHost);
|
||||
|
||||
/**
|
||||
* InsertText() inserts aStringToInsert to aPointToInsert and makes any needed
|
||||
|
|
Загрузка…
Ссылка в новой задаче