Backed out 5 changesets (bug 1926483) for causing failures at WSRunScanner.h. CLOSED TREE
Backed out changeset fa4c36cef1c5 (bug 1926483) Backed out changeset 24bdcd7af3e0 (bug 1926483) Backed out changeset 1df51ca968f8 (bug 1926483) Backed out changeset 7aceecb585e4 (bug 1926483) Backed out changeset 41b040b374a2 (bug 1926483)
This commit is contained in:
@@ -245,7 +245,7 @@ AutoClonedRangeArray::ShrinkRangesIfStartFromOrEndAfterAtomicContent(
|
||||
"Changing range in selection may cause running script");
|
||||
Result<bool, nsresult> result =
|
||||
WSRunScanner::ShrinkRangeIfStartsFromOrEndsAfterAtomicContent(
|
||||
WSRunScanner::Scan::EditableNodes, range);
|
||||
aHTMLEditor, range);
|
||||
if (result.isErr()) {
|
||||
NS_WARNING(
|
||||
"WSRunScanner::ShrinkRangeIfStartsFromOrEndsAfterAtomicContent() "
|
||||
|
||||
@@ -284,11 +284,6 @@ class EditorDOMPointBase final {
|
||||
*/
|
||||
bool IsContainerElement() const { return mParent && mParent->IsElement(); }
|
||||
|
||||
/**
|
||||
* Returns true if the container node is an editing host.
|
||||
*/
|
||||
[[nodiscard]] bool IsContainerEditableRoot() const;
|
||||
|
||||
/**
|
||||
* IsContainerHTMLElement() returns true if the container node is an HTML
|
||||
* element node and its node name is aTag.
|
||||
|
||||
@@ -352,15 +352,6 @@ bool EditorDOMPointBase<
|
||||
EditorUtils::IsOnlyNewLinePreformatted(*ContainerAs<Text>());
|
||||
}
|
||||
|
||||
template <typename PT, typename CT>
|
||||
bool EditorDOMPointBase<PT, CT>::IsContainerEditableRoot() const {
|
||||
if (MOZ_UNLIKELY(!mParent) || MOZ_UNLIKELY(!mParent->IsEditable()) ||
|
||||
NS_WARN_IF(mParent->IsInNativeAnonymousSubtree())) {
|
||||
return false;
|
||||
}
|
||||
return HTMLEditUtils::ElementIsEditableRoot(*mParent);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* mozilla::EditorDOMRangeBase
|
||||
*****************************************************************************/
|
||||
|
||||
@@ -486,26 +486,29 @@ nsresult HTMLEditor::OnEndHandlingTopLevelEditSubActionInternal() {
|
||||
NS_WARNING("There was no selection range");
|
||||
return NS_ERROR_EDITOR_UNEXPECTED_DOM_TREE;
|
||||
}
|
||||
Result<CreateLineBreakResult, nsresult>
|
||||
insertPaddingBRElementResultOrError =
|
||||
InsertPaddingBRElementToMakeEmptyLineVisibleIfNeeded(
|
||||
newCaretPosition);
|
||||
if (MOZ_UNLIKELY(insertPaddingBRElementResultOrError.isErr())) {
|
||||
NS_WARNING(
|
||||
"HTMLEditor::"
|
||||
"InsertPaddingBRElementToMakeEmptyLineVisibleIfNeeded() failed");
|
||||
return insertPaddingBRElementResultOrError.unwrapErr();
|
||||
if (const RefPtr<Element> editingHost =
|
||||
ComputeEditingHost(LimitInBodyElement::No)) {
|
||||
Result<CreateLineBreakResult, nsresult>
|
||||
insertPaddingBRElementResultOrError =
|
||||
InsertPaddingBRElementToMakeEmptyLineVisibleIfNeeded(
|
||||
newCaretPosition, *editingHost);
|
||||
if (MOZ_UNLIKELY(insertPaddingBRElementResultOrError.isErr())) {
|
||||
NS_WARNING(
|
||||
"HTMLEditor::"
|
||||
"InsertPaddingBRElementToMakeEmptyLineVisibleIfNeeded() failed");
|
||||
return insertPaddingBRElementResultOrError.unwrapErr();
|
||||
}
|
||||
nsresult rv =
|
||||
insertPaddingBRElementResultOrError.unwrap().SuggestCaretPointTo(
|
||||
*this, {SuggestCaret::OnlyIfHasSuggestion});
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("CaretPoint::SuggestCaretPointTo() failed");
|
||||
return rv;
|
||||
}
|
||||
NS_WARNING_ASSERTION(
|
||||
rv != NS_SUCCESS_EDITOR_BUT_IGNORED_TRIVIAL_ERROR,
|
||||
"CaretPoint::SuggestCaretPointTo() failed, but ignored");
|
||||
}
|
||||
nsresult rv =
|
||||
insertPaddingBRElementResultOrError.unwrap().SuggestCaretPointTo(
|
||||
*this, {SuggestCaret::OnlyIfHasSuggestion});
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("CaretPoint::SuggestCaretPointTo() failed");
|
||||
return rv;
|
||||
}
|
||||
NS_WARNING_ASSERTION(
|
||||
rv != NS_SUCCESS_EDITOR_BUT_IGNORED_TRIVIAL_ERROR,
|
||||
"CaretPoint::SuggestCaretPointTo() failed, but ignored");
|
||||
}
|
||||
|
||||
// add in any needed <br>s, and remove any unneeded ones.
|
||||
@@ -1205,7 +1208,7 @@ Result<EditActionResult, nsresult> HTMLEditor::HandleInsertText(
|
||||
const InsertTextResult insertEmptyTextResult =
|
||||
insertEmptyTextResultOrError.unwrap();
|
||||
nsresult rv = EnsureNoFollowingUnnecessaryLineBreak(
|
||||
insertEmptyTextResult.EndOfInsertedTextRef());
|
||||
insertEmptyTextResult.EndOfInsertedTextRef(), *editingHost);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING(
|
||||
"HTMLEditor::EnsureNoFollowingUnnecessaryLineBreak() failed");
|
||||
@@ -1254,7 +1257,7 @@ Result<EditActionResult, nsresult> HTMLEditor::HandleInsertText(
|
||||
}
|
||||
InsertTextResult unwrappedReplacedTextResult = replaceTextResult.unwrap();
|
||||
nsresult rv = EnsureNoFollowingUnnecessaryLineBreak(
|
||||
unwrappedReplacedTextResult.EndOfInsertedTextRef());
|
||||
unwrappedReplacedTextResult.EndOfInsertedTextRef(), *editingHost);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("HTMLEditor::EnsureNoFollowingUnnecessaryLineBreak() failed");
|
||||
return Err(rv);
|
||||
@@ -1529,7 +1532,8 @@ Result<EditActionResult, nsresult> HTMLEditor::HandleInsertText(
|
||||
mLastCollapsibleWhiteSpaceAppendedTextNode =
|
||||
currentPoint.ContainerAs<Text>();
|
||||
}
|
||||
nsresult rv = EnsureNoFollowingUnnecessaryLineBreak(currentPoint);
|
||||
nsresult rv =
|
||||
EnsureNoFollowingUnnecessaryLineBreak(currentPoint, *editingHost);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("HTMLEditor::EnsureNoFollowingUnnecessaryLineBreak() failed");
|
||||
return Err(rv);
|
||||
@@ -1657,8 +1661,7 @@ nsresult HTMLEditor::InsertLineBreakAsSubAction() {
|
||||
}
|
||||
const WSScanResult backwardScanFromBeforeBRElementResult =
|
||||
WSRunScanner::ScanPreviousVisibleNodeOrBlockBoundary(
|
||||
WSRunScanner::Scan::EditableNodes,
|
||||
insertLineBreakResult.AtLineBreak<EditorDOMPoint>(),
|
||||
editingHost, insertLineBreakResult.AtLineBreak<EditorDOMPoint>(),
|
||||
BlockInlineCheck::UseComputedDisplayStyle);
|
||||
if (MOZ_UNLIKELY(backwardScanFromBeforeBRElementResult.Failed())) {
|
||||
NS_WARNING(
|
||||
@@ -1668,7 +1671,7 @@ nsresult HTMLEditor::InsertLineBreakAsSubAction() {
|
||||
|
||||
const WSScanResult forwardScanFromAfterBRElementResult =
|
||||
WSRunScanner::ScanInclusiveNextVisibleNodeOrBlockBoundary(
|
||||
WSRunScanner::Scan::EditableNodes, pointToPutCaret,
|
||||
editingHost, pointToPutCaret,
|
||||
BlockInlineCheck::UseComputedDisplayStyle);
|
||||
if (MOZ_UNLIKELY(forwardScanFromAfterBRElementResult.Failed())) {
|
||||
NS_WARNING("WSRunScanner::ScanNextVisibleNodeOrBlockBoundary() failed");
|
||||
@@ -1898,7 +1901,7 @@ HTMLEditor::InsertParagraphSeparatorAsSubAction(const Element& aEditingHost) {
|
||||
// table cell boundaries?
|
||||
Result<CaretPoint, nsresult> caretPointOrError =
|
||||
HandleInsertParagraphInMailCiteElement(*mailCiteElement,
|
||||
pointToInsert);
|
||||
pointToInsert, aEditingHost);
|
||||
if (MOZ_UNLIKELY(caretPointOrError.isErr())) {
|
||||
NS_WARNING(
|
||||
"HTMLEditor::HandleInsertParagraphInMailCiteElement() failed");
|
||||
@@ -2320,9 +2323,8 @@ Result<CreateElementResult, nsresult> HTMLEditor::HandleInsertBRElement(
|
||||
|
||||
const bool editingHostIsEmpty = HTMLEditUtils::IsEmptyNode(
|
||||
aEditingHost, {EmptyCheckOption::TreatNonEditableContentAsInvisible});
|
||||
const WSRunScanner wsRunScanner(WSRunScanner::Scan::EditableNodes,
|
||||
aPointToBreak,
|
||||
BlockInlineCheck::UseComputedDisplayStyle);
|
||||
WSRunScanner wsRunScanner(&aEditingHost, aPointToBreak,
|
||||
BlockInlineCheck::UseComputedDisplayStyle);
|
||||
const WSScanResult backwardScanResult =
|
||||
wsRunScanner.ScanPreviousVisibleNodeOrBlockBoundaryFrom(aPointToBreak);
|
||||
if (MOZ_UNLIKELY(backwardScanResult.Failed())) {
|
||||
@@ -2469,7 +2471,7 @@ Result<CreateElementResult, nsresult> HTMLEditor::HandleInsertBRElement(
|
||||
|
||||
const WSScanResult forwardScanFromAfterBRElementResult =
|
||||
WSRunScanner::ScanInclusiveNextVisibleNodeOrBlockBoundary(
|
||||
WSRunScanner::Scan::EditableNodes, afterBRElement,
|
||||
&aEditingHost, afterBRElement,
|
||||
BlockInlineCheck::UseComputedDisplayStyle);
|
||||
if (MOZ_UNLIKELY(forwardScanFromAfterBRElementResult.Failed())) {
|
||||
NS_WARNING("WSRunScanner::ScanNextVisibleNodeOrBlockBoundary() failed");
|
||||
@@ -2617,9 +2619,8 @@ Result<EditorDOMPoint, nsresult> HTMLEditor::HandleInsertLinefeed(
|
||||
// boundary. Note that it should always be <br> for avoiding padding line
|
||||
// breaks appear in `.textContent` value.
|
||||
if (pointToPutCaret.IsInContentNode() && pointToPutCaret.IsEndOfContainer()) {
|
||||
const WSRunScanner wsScannerAtCaret(
|
||||
WSRunScanner::Scan::EditableNodes, pointToPutCaret,
|
||||
BlockInlineCheck::UseComputedDisplayStyle);
|
||||
WSRunScanner wsScannerAtCaret(&aEditingHost, pointToPutCaret,
|
||||
BlockInlineCheck::UseComputedDisplayStyle);
|
||||
if (wsScannerAtCaret.StartsFromPreformattedLineBreak() &&
|
||||
(wsScannerAtCaret.EndsByBlockBoundary() ||
|
||||
wsScannerAtCaret.EndsByInlineEditingHostBoundary()) &&
|
||||
@@ -2684,7 +2685,8 @@ Result<EditorDOMPoint, nsresult> HTMLEditor::HandleInsertLinefeed(
|
||||
}
|
||||
|
||||
Result<CaretPoint, nsresult> HTMLEditor::HandleInsertParagraphInMailCiteElement(
|
||||
Element& aMailCiteElement, const EditorDOMPoint& aPointToSplit) {
|
||||
Element& aMailCiteElement, const EditorDOMPoint& aPointToSplit,
|
||||
const Element& aEditingHost) {
|
||||
MOZ_ASSERT(IsEditActionDataAvailable());
|
||||
MOZ_ASSERT(aPointToSplit.IsSet());
|
||||
NS_ASSERTION(!HTMLEditUtils::IsEmptyNode(
|
||||
@@ -2707,8 +2709,7 @@ Result<CaretPoint, nsresult> HTMLEditor::HandleInsertParagraphInMailCiteElement(
|
||||
// mailquote may affect wrapping behavior, or font color, etc.
|
||||
const WSScanResult forwardScanFromPointToSplitResult =
|
||||
WSRunScanner::ScanInclusiveNextVisibleNodeOrBlockBoundary(
|
||||
WSRunScanner::Scan::EditableNodes, pointToSplit,
|
||||
BlockInlineCheck::UseHTMLDefaultStyle);
|
||||
&aEditingHost, pointToSplit, BlockInlineCheck::UseHTMLDefaultStyle);
|
||||
if (forwardScanFromPointToSplitResult.Failed()) {
|
||||
return Err(NS_ERROR_FAILURE);
|
||||
}
|
||||
@@ -2828,7 +2829,7 @@ Result<CaretPoint, nsresult> HTMLEditor::HandleInsertParagraphInMailCiteElement(
|
||||
// resultOfInsertingBRElement.inspect()?
|
||||
const WSScanResult backwardScanFromPointToCreateNewBRElementResult =
|
||||
WSRunScanner::ScanPreviousVisibleNodeOrBlockBoundary(
|
||||
WSRunScanner::Scan::EditableNodes, pointToCreateNewBRElement,
|
||||
&aEditingHost, pointToCreateNewBRElement,
|
||||
BlockInlineCheck::UseHTMLDefaultStyle);
|
||||
if (MOZ_UNLIKELY(
|
||||
backwardScanFromPointToCreateNewBRElementResult.Failed())) {
|
||||
@@ -2845,7 +2846,7 @@ Result<CaretPoint, nsresult> HTMLEditor::HandleInsertParagraphInMailCiteElement(
|
||||
}
|
||||
const WSScanResult forwardScanFromPointAfterNewBRElementResult =
|
||||
WSRunScanner::ScanInclusiveNextVisibleNodeOrBlockBoundary(
|
||||
WSRunScanner::Scan::EditableNodes,
|
||||
&aEditingHost,
|
||||
EditorRawDOMPoint::After(pointToCreateNewBRElement),
|
||||
BlockInlineCheck::UseHTMLDefaultStyle);
|
||||
if (MOZ_UNLIKELY(forwardScanFromPointAfterNewBRElementResult.Failed())) {
|
||||
@@ -2930,8 +2931,8 @@ HTMLEditor::GetPreviousCharPointDataForNormalizingWhiteSpaces(
|
||||
HTMLEditor::GetPreviousCharPointType(aPoint));
|
||||
}
|
||||
const auto previousCharPoint =
|
||||
WSRunScanner::GetPreviousCharPoint<EditorRawDOMPointInText>(
|
||||
WSRunScanner::Scan::EditableNodes, aPoint,
|
||||
WSRunScanner::GetPreviousEditableCharPoint<EditorRawDOMPointInText>(
|
||||
ComputeEditingHost(), aPoint,
|
||||
BlockInlineCheck::UseComputedDisplayStyle);
|
||||
if (!previousCharPoint.IsSet()) {
|
||||
return CharPointData::InDifferentTextNode(CharPointType::TextEnd);
|
||||
@@ -2949,8 +2950,8 @@ HTMLEditor::GetInclusiveNextCharPointDataForNormalizingWhiteSpaces(
|
||||
return CharPointData::InSameTextNode(HTMLEditor::GetCharPointType(aPoint));
|
||||
}
|
||||
const auto nextCharPoint =
|
||||
WSRunScanner::GetInclusiveNextCharPoint<EditorRawDOMPointInText>(
|
||||
WSRunScanner::Scan::EditableNodes, aPoint,
|
||||
WSRunScanner::GetInclusiveNextEditableCharPoint<EditorRawDOMPointInText>(
|
||||
ComputeEditingHost(), aPoint,
|
||||
BlockInlineCheck::UseComputedDisplayStyle);
|
||||
if (!nextCharPoint.IsSet()) {
|
||||
return CharPointData::InDifferentTextNode(CharPointType::TextEnd);
|
||||
@@ -3048,14 +3049,14 @@ void HTMLEditor::ExtendRangeToDeleteWithNormalizingWhiteSpaces(
|
||||
// are, check whether they are collapsible or not. Note that we shouldn't
|
||||
// touch white-spaces in different text nodes for performance, but we need
|
||||
// adjacent text node's first or last character information in some cases.
|
||||
const auto precedingCharPoint =
|
||||
WSRunScanner::GetPreviousCharPoint<EditorDOMPointInText>(
|
||||
WSRunScanner::Scan::EditableNodes, aStartToDelete,
|
||||
BlockInlineCheck::UseComputedDisplayStyle);
|
||||
const auto followingCharPoint =
|
||||
WSRunScanner::GetInclusiveNextCharPoint<EditorDOMPointInText>(
|
||||
WSRunScanner::Scan::EditableNodes, aEndToDelete,
|
||||
Element* editingHost = ComputeEditingHost();
|
||||
const EditorDOMPointInText precedingCharPoint =
|
||||
WSRunScanner::GetPreviousEditableCharPoint(
|
||||
editingHost, aStartToDelete,
|
||||
BlockInlineCheck::UseComputedDisplayStyle);
|
||||
const EditorDOMPointInText followingCharPoint =
|
||||
WSRunScanner::GetInclusiveNextEditableCharPoint(
|
||||
editingHost, aEndToDelete, BlockInlineCheck::UseComputedDisplayStyle);
|
||||
// Blink-compat: Normalize white-spaces in first node only when not removing
|
||||
// its last character or no text nodes follow the first node.
|
||||
// If removing last character of first node and there are
|
||||
@@ -3404,7 +3405,8 @@ HTMLEditor::DeleteTextAndNormalizeSurroundingWhiteSpaces(
|
||||
{
|
||||
AutoTrackDOMPoint trackPointToPutCaret(RangeUpdaterRef(),
|
||||
&newCaretPosition);
|
||||
nsresult rv = EnsureNoFollowingUnnecessaryLineBreak(newCaretPosition);
|
||||
nsresult rv =
|
||||
EnsureNoFollowingUnnecessaryLineBreak(newCaretPosition, aEditingHost);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("HTMLEditor::EnsureNoFollowingUnnecessaryLineBreak() failed");
|
||||
return Err(rv);
|
||||
@@ -3460,7 +3462,7 @@ bool HTMLEditor::CanInsertLineBreak(LineBreakType aLineBreakType,
|
||||
|
||||
Result<CreateLineBreakResult, nsresult>
|
||||
HTMLEditor::InsertPaddingBRElementToMakeEmptyLineVisibleIfNeeded(
|
||||
const EditorDOMPoint& aPointToInsert) {
|
||||
const EditorDOMPoint& aPointToInsert, const Element& aEditingHost) {
|
||||
MOZ_ASSERT(IsEditActionDataAvailable());
|
||||
MOZ_ASSERT(aPointToInsert.IsSet());
|
||||
|
||||
@@ -3483,7 +3485,7 @@ HTMLEditor::InsertPaddingBRElementToMakeEmptyLineVisibleIfNeeded(
|
||||
// here.
|
||||
const WSScanResult previousThing =
|
||||
WSRunScanner::ScanPreviousVisibleNodeOrBlockBoundary(
|
||||
WSRunScanner::Scan::EditableNodes, aPointToInsert,
|
||||
&aEditingHost, aPointToInsert,
|
||||
BlockInlineCheck::UseComputedDisplayStyle);
|
||||
if (!previousThing.ReachedLineBoundary()) {
|
||||
return CreateLineBreakResult::NotHandled();
|
||||
@@ -3493,7 +3495,7 @@ HTMLEditor::InsertPaddingBRElementToMakeEmptyLineVisibleIfNeeded(
|
||||
// line break here.
|
||||
const WSScanResult nextThing =
|
||||
WSRunScanner::ScanInclusiveNextVisibleNodeOrBlockBoundary(
|
||||
WSRunScanner::Scan::EditableNodes, aPointToInsert,
|
||||
&aEditingHost, aPointToInsert,
|
||||
BlockInlineCheck::UseComputedDisplayStyle);
|
||||
if (!nextThing.ReachedBlockBoundary()) {
|
||||
return CreateLineBreakResult::NotHandled();
|
||||
@@ -7039,7 +7041,8 @@ Result<EditorDOMPoint, nsresult> HTMLEditor::CreateStyleForInsertText(
|
||||
NS_WARNING("AutoClonedRangeArray::AutoClonedRangeArray() failed");
|
||||
return Err(NS_ERROR_FAILURE);
|
||||
}
|
||||
nsresult rv = SetInlinePropertiesAroundRanges(ranges, stylesToSet);
|
||||
nsresult rv =
|
||||
SetInlinePropertiesAroundRanges(ranges, stylesToSet, aEditingHost);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("HTMLEditor::SetInlinePropertiesAroundRanges() failed");
|
||||
return Err(rv);
|
||||
@@ -7818,8 +7821,8 @@ HTMLEditor::GetRangeExtendedToHardLineEdgesForBlockEditAction(
|
||||
|
||||
// Is there any intervening visible white-space? If so we can't push
|
||||
// selection past that, it would visibly change meaning of users selection.
|
||||
const WSRunScanner wsScannerAtEnd(
|
||||
WSRunScanner::Scan::EditableNodes, endPoint,
|
||||
WSRunScanner wsScannerAtEnd(
|
||||
&aEditingHost, endPoint,
|
||||
// We should refer only the default style of HTML because we need to wrap
|
||||
// any elements with a specific HTML element. So we should not refer
|
||||
// actual style. For example, we want to reformat parent HTML block
|
||||
@@ -7863,9 +7866,8 @@ HTMLEditor::GetRangeExtendedToHardLineEdgesForBlockEditAction(
|
||||
|
||||
// Is there any intervening visible white-space? If so we can't push
|
||||
// selection past that, it would visibly change meaning of users selection.
|
||||
const WSRunScanner wsScannerAtStart(WSRunScanner::Scan::EditableNodes,
|
||||
startPoint,
|
||||
BlockInlineCheck::UseHTMLDefaultStyle);
|
||||
WSRunScanner wsScannerAtStart(&aEditingHost, startPoint,
|
||||
BlockInlineCheck::UseHTMLDefaultStyle);
|
||||
const WSScanResult scanResultAtStart =
|
||||
wsScannerAtStart.ScanInclusiveNextVisibleNodeOrBlockBoundaryFrom(
|
||||
startPoint);
|
||||
@@ -9172,8 +9174,7 @@ HTMLEditor::HandleInsertParagraphInListItemElement(
|
||||
// the element is proper position.
|
||||
const WSScanResult forwardScanFromStartOfListItemResult =
|
||||
WSRunScanner::ScanInclusiveNextVisibleNodeOrBlockBoundary(
|
||||
WSRunScanner::Scan::EditableNodes,
|
||||
EditorRawDOMPoint(&rightListItemElement, 0u),
|
||||
&aEditingHost, EditorRawDOMPoint(&rightListItemElement, 0u),
|
||||
BlockInlineCheck::UseComputedDisplayStyle);
|
||||
if (MOZ_UNLIKELY(forwardScanFromStartOfListItemResult.Failed())) {
|
||||
NS_WARNING("WSRunScanner::ScanNextVisibleNodeOrBlockBoundary() failed");
|
||||
@@ -11208,7 +11209,7 @@ HTMLEditor::InsertPaddingBRElementIfNeeded(
|
||||
if (IsPlaintextMailComposer()) {
|
||||
const WSScanResult nextVisibleThing =
|
||||
WSRunScanner::ScanInclusiveNextVisibleNodeOrBlockBoundary(
|
||||
WSRunScanner::Scan::EditableNodes, aPoint,
|
||||
&aEditingHost, aPoint,
|
||||
BlockInlineCheck::UseComputedDisplayOutsideStyle);
|
||||
if (nextVisibleThing.ReachedBlockBoundary() &&
|
||||
HTMLEditUtils::IsMailCite(*nextVisibleThing.ElementPtr()) &&
|
||||
|
||||
@@ -41,7 +41,6 @@
|
||||
#include "nsError.h" // for NS_SUCCEEDED
|
||||
#include "nsGkAtoms.h" // for nsGkAtoms, nsGkAtoms::a, etc.
|
||||
#include "nsHTMLTags.h"
|
||||
#include "nsIContentInlines.h" // for nsIContent::IsInDesignMode(), etc.
|
||||
#include "nsIFrameInlines.h" // for nsIFrame::IsFlexOrGridItem()
|
||||
#include "nsLiteralString.h" // for NS_LITERAL_STRING
|
||||
#include "nsNameSpaceManager.h" // for kNameSpaceID_None
|
||||
@@ -115,24 +114,26 @@ template nsIContent* HTMLEditUtils::GetContentToPreserveInlineStyles(
|
||||
const EditorRawDOMPoint& aPoint, const Element& aEditingHost);
|
||||
|
||||
template EditorDOMPoint HTMLEditUtils::GetBetterInsertionPointFor(
|
||||
const nsIContent& aContentToInsert, const EditorDOMPoint& aPointToInsert);
|
||||
const nsIContent& aContentToInsert, const EditorDOMPoint& aPointToInsert,
|
||||
const Element& aEditingHost);
|
||||
template EditorRawDOMPoint HTMLEditUtils::GetBetterInsertionPointFor(
|
||||
const nsIContent& aContentToInsert,
|
||||
const EditorRawDOMPoint& aPointToInsert);
|
||||
const nsIContent& aContentToInsert, const EditorRawDOMPoint& aPointToInsert,
|
||||
const Element& aEditingHost);
|
||||
template EditorDOMPoint HTMLEditUtils::GetBetterInsertionPointFor(
|
||||
const nsIContent& aContentToInsert,
|
||||
const EditorRawDOMPoint& aPointToInsert);
|
||||
const nsIContent& aContentToInsert, const EditorRawDOMPoint& aPointToInsert,
|
||||
const Element& aEditingHost);
|
||||
template EditorRawDOMPoint HTMLEditUtils::GetBetterInsertionPointFor(
|
||||
const nsIContent& aContentToInsert, const EditorDOMPoint& aPointToInsert);
|
||||
const nsIContent& aContentToInsert, const EditorDOMPoint& aPointToInsert,
|
||||
const Element& aEditingHost);
|
||||
|
||||
template EditorDOMPoint HTMLEditUtils::GetBetterCaretPositionToInsertText(
|
||||
const EditorDOMPoint& aPoint);
|
||||
const EditorDOMPoint& aPoint, const Element& aEditingHost);
|
||||
template EditorDOMPoint HTMLEditUtils::GetBetterCaretPositionToInsertText(
|
||||
const EditorRawDOMPoint& aPoint);
|
||||
const EditorRawDOMPoint& aPoint, const Element& aEditingHost);
|
||||
template EditorRawDOMPoint HTMLEditUtils::GetBetterCaretPositionToInsertText(
|
||||
const EditorDOMPoint& aPoint);
|
||||
const EditorDOMPoint& aPoint, const Element& aEditingHost);
|
||||
template EditorRawDOMPoint HTMLEditUtils::GetBetterCaretPositionToInsertText(
|
||||
const EditorRawDOMPoint& aPoint);
|
||||
const EditorRawDOMPoint& aPoint, const Element& aEditingHost);
|
||||
|
||||
template Result<EditorDOMPoint, nsresult>
|
||||
HTMLEditUtils::ComputePointToPutCaretInElementIfOutside(
|
||||
@@ -153,54 +154,48 @@ template bool HTMLEditUtils::IsSameCSSColorValue(const nsACString& aColorA,
|
||||
const nsACString& aColorB);
|
||||
|
||||
template Maybe<EditorLineBreak> HTMLEditUtils::GetFollowingUnnecessaryLineBreak(
|
||||
const EditorDOMPoint& aPoint);
|
||||
const EditorDOMPoint& aPoint, const Element& aEditingHost);
|
||||
template Maybe<EditorLineBreak> HTMLEditUtils::GetFollowingUnnecessaryLineBreak(
|
||||
const EditorRawDOMPoint& aPoint);
|
||||
const EditorRawDOMPoint& aPoint, const Element& aEditingHost);
|
||||
template Maybe<EditorLineBreak> HTMLEditUtils::GetFollowingUnnecessaryLineBreak(
|
||||
const EditorDOMPointInText& aPoint);
|
||||
const EditorDOMPointInText& aPoint, const Element& aEditingHost);
|
||||
template Maybe<EditorLineBreak> HTMLEditUtils::GetFollowingUnnecessaryLineBreak(
|
||||
const EditorRawDOMPointInText& aPoint);
|
||||
const EditorRawDOMPointInText& aPoint, const Element& aEditingHost);
|
||||
template Maybe<EditorRawLineBreak>
|
||||
HTMLEditUtils::GetFollowingUnnecessaryLineBreak(const EditorDOMPoint& aPoint);
|
||||
HTMLEditUtils::GetFollowingUnnecessaryLineBreak(const EditorDOMPoint& aPoint,
|
||||
const Element& aEditingHost);
|
||||
template Maybe<EditorRawLineBreak>
|
||||
HTMLEditUtils::GetFollowingUnnecessaryLineBreak(const EditorRawDOMPoint& aPoint,
|
||||
const Element& aEditingHost);
|
||||
template Maybe<EditorRawLineBreak>
|
||||
HTMLEditUtils::GetFollowingUnnecessaryLineBreak(
|
||||
const EditorRawDOMPoint& aPoint);
|
||||
const EditorDOMPointInText& aPoint, const Element& aEditingHost);
|
||||
template Maybe<EditorRawLineBreak>
|
||||
HTMLEditUtils::GetFollowingUnnecessaryLineBreak(
|
||||
const EditorDOMPointInText& aPoint);
|
||||
template Maybe<EditorRawLineBreak>
|
||||
HTMLEditUtils::GetFollowingUnnecessaryLineBreak(
|
||||
const EditorRawDOMPointInText& aPoint);
|
||||
const EditorRawDOMPointInText& aPoint, const Element& aEditingHost);
|
||||
|
||||
template bool HTMLEditUtils::PointIsImmediatelyBeforeCurrentBlockBoundary(
|
||||
const EditorDOMPoint& aPoint,
|
||||
IgnoreInvisibleLineBreak aIgnoreInvisibleLineBreak);
|
||||
IgnoreInvisibleLineBreak aIgnoreInvisibleLineBreak,
|
||||
const Element& aEditingHost);
|
||||
template bool HTMLEditUtils::PointIsImmediatelyBeforeCurrentBlockBoundary(
|
||||
const EditorRawDOMPoint& aPoint,
|
||||
IgnoreInvisibleLineBreak aIgnoreInvisibleLineBreak);
|
||||
IgnoreInvisibleLineBreak aIgnoreInvisibleLineBreak,
|
||||
const Element& aEditingHost);
|
||||
template bool HTMLEditUtils::PointIsImmediatelyBeforeCurrentBlockBoundary(
|
||||
const EditorDOMPointInText& aPoint,
|
||||
IgnoreInvisibleLineBreak aIgnoreInvisibleLineBreak);
|
||||
IgnoreInvisibleLineBreak aIgnoreInvisibleLineBreak,
|
||||
const Element& aEditingHost);
|
||||
template bool HTMLEditUtils::PointIsImmediatelyBeforeCurrentBlockBoundary(
|
||||
const EditorRawDOMPointInText& aPoint,
|
||||
IgnoreInvisibleLineBreak aIgnoreInvisibleLineBreak);
|
||||
IgnoreInvisibleLineBreak aIgnoreInvisibleLineBreak,
|
||||
const Element& aEditingHost);
|
||||
|
||||
template Maybe<EditorLineBreak> HTMLEditUtils::GetUnnecessaryLineBreak(
|
||||
const Element& aBlockElement, ScanLineBreak aScanLineBreak);
|
||||
template Maybe<EditorRawLineBreak> HTMLEditUtils::GetUnnecessaryLineBreak(
|
||||
const Element& aBlockElement, ScanLineBreak aScanLineBreak);
|
||||
|
||||
bool HTMLEditUtils::ElementIsEditableRoot(const Element& aElement) {
|
||||
MOZ_ASSERT(!aElement.IsInNativeAnonymousSubtree());
|
||||
if (NS_WARN_IF(!aElement.IsEditable()) ||
|
||||
NS_WARN_IF(!aElement.IsInComposedDoc())) {
|
||||
return false;
|
||||
}
|
||||
return !aElement.GetParent() || // root element
|
||||
!aElement.GetParent()->IsEditable() || // editing host
|
||||
aElement.OwnerDoc()->GetBody() == &aElement; // the <body>
|
||||
}
|
||||
|
||||
bool HTMLEditUtils::CanContentsBeJoined(const nsIContent& aLeftContent,
|
||||
const nsIContent& aRightContent) {
|
||||
if (aLeftContent.NodeInfo()->NameAtom() !=
|
||||
@@ -816,7 +811,7 @@ EditorDOMPoint HTMLEditUtils::LineRequiresPaddingLineBreakToBeVisible(
|
||||
}
|
||||
const WSScanResult nextThing =
|
||||
WSRunScanner::ScanInclusiveNextVisibleNodeOrBlockBoundary(
|
||||
WSRunScanner::Scan::EditableNodes, point,
|
||||
&aEditingHost, point,
|
||||
BlockInlineCheck::UseComputedDisplayOutsideStyle);
|
||||
if (nextThing.ReachedBlockBoundary()) {
|
||||
if (nextThing.ReachedCurrentBlockBoundary()) {
|
||||
@@ -838,7 +833,7 @@ EditorDOMPoint HTMLEditUtils::LineRequiresPaddingLineBreakToBeVisible(
|
||||
}
|
||||
const WSScanResult previousThing =
|
||||
WSRunScanner::ScanPreviousVisibleNodeOrBlockBoundary(
|
||||
WSRunScanner::Scan::EditableNodes, preferredPaddingLineBreakPoint,
|
||||
&aEditingHost, preferredPaddingLineBreakPoint,
|
||||
BlockInlineCheck::UseComputedDisplayOutsideStyle);
|
||||
if (previousThing.ContentIsText()) {
|
||||
if (MOZ_UNLIKELY(!previousThing.TextPtr()->TextDataLength())) {
|
||||
@@ -989,15 +984,16 @@ Element* HTMLEditUtils::GetElementOfImmediateBlockBoundary(
|
||||
template <typename PT, typename CT>
|
||||
bool HTMLEditUtils::PointIsImmediatelyBeforeCurrentBlockBoundary(
|
||||
const EditorDOMPointBase<PT, CT>& aPoint,
|
||||
IgnoreInvisibleLineBreak aIgnoreInvisibleLineBreak) {
|
||||
IgnoreInvisibleLineBreak aIgnoreInvisibleLineBreak,
|
||||
const Element& aEditingHost) {
|
||||
MOZ_ASSERT(aPoint.IsSetAndValidInComposedDoc());
|
||||
|
||||
if (MOZ_UNLIKELY(!aPoint.IsInContentNode())) {
|
||||
return false;
|
||||
}
|
||||
const WSScanResult nextThing =
|
||||
WSScanResult nextThing =
|
||||
WSRunScanner::ScanInclusiveNextVisibleNodeOrBlockBoundary(
|
||||
WSRunScanner::Scan::EditableNodes, aPoint,
|
||||
&aEditingHost, aPoint,
|
||||
BlockInlineCheck::UseComputedDisplayOutsideStyle);
|
||||
if (nextThing.ReachedCurrentBlockBoundary()) {
|
||||
return true;
|
||||
@@ -1006,9 +1002,9 @@ bool HTMLEditUtils::PointIsImmediatelyBeforeCurrentBlockBoundary(
|
||||
if (aIgnoreInvisibleLineBreak == IgnoreInvisibleLineBreak::No) {
|
||||
return false;
|
||||
}
|
||||
const WSScanResult afterInvisibleBRThing =
|
||||
WSScanResult afterInvisibleBRThing =
|
||||
WSRunScanner::ScanInclusiveNextVisibleNodeOrBlockBoundary(
|
||||
WSRunScanner::Scan::EditableNodes,
|
||||
&aEditingHost,
|
||||
nextThing.PointAfterReachedContent<EditorRawDOMPoint>(),
|
||||
BlockInlineCheck::UseComputedDisplayOutsideStyle);
|
||||
return afterInvisibleBRThing.ReachedCurrentBlockBoundary();
|
||||
@@ -1017,9 +1013,9 @@ bool HTMLEditUtils::PointIsImmediatelyBeforeCurrentBlockBoundary(
|
||||
if (aIgnoreInvisibleLineBreak == IgnoreInvisibleLineBreak::No) {
|
||||
return false;
|
||||
}
|
||||
const WSScanResult afterPreformattedLineBreakThing =
|
||||
WSScanResult afterPreformattedLineBreakThing =
|
||||
WSRunScanner::ScanInclusiveNextVisibleNodeOrBlockBoundary(
|
||||
WSRunScanner::Scan::EditableNodes,
|
||||
&aEditingHost,
|
||||
nextThing.PointAfterReachedContent<EditorRawDOMPoint>(),
|
||||
BlockInlineCheck::UseComputedDisplayOutsideStyle);
|
||||
return afterPreformattedLineBreakThing.ReachedCurrentBlockBoundary();
|
||||
@@ -1198,23 +1194,22 @@ Maybe<EditorLineBreakType> HTMLEditUtils::GetUnnecessaryLineBreak(
|
||||
|
||||
template <typename EditorLineBreakType, typename EditorDOMPointType>
|
||||
Maybe<EditorLineBreakType> HTMLEditUtils::GetFollowingUnnecessaryLineBreak(
|
||||
const EditorDOMPointType& aPoint) {
|
||||
const EditorDOMPointType& aPoint, const Element& aEditingHost) {
|
||||
MOZ_ASSERT(aPoint.IsSetAndValid());
|
||||
MOZ_ASSERT(aPoint.IsInContentNode());
|
||||
|
||||
const WSScanResult nextThing =
|
||||
WSScanResult nextThing =
|
||||
WSRunScanner::ScanInclusiveNextVisibleNodeOrBlockBoundary(
|
||||
WSRunScanner::Scan::EditableNodes, aPoint,
|
||||
BlockInlineCheck::UseComputedDisplayStyle);
|
||||
&aEditingHost, aPoint, BlockInlineCheck::UseComputedDisplayStyle);
|
||||
if (!nextThing.ReachedBRElement() &&
|
||||
!(nextThing.ReachedPreformattedLineBreak() &&
|
||||
nextThing.PointAtReachedContent<EditorRawDOMPoint>()
|
||||
.IsAtLastContent())) {
|
||||
return Nothing(); // no line break next to aPoint
|
||||
}
|
||||
const WSScanResult nextThingOfLineBreak =
|
||||
WSScanResult nextThingOfLineBreak =
|
||||
WSRunScanner::ScanInclusiveNextVisibleNodeOrBlockBoundary(
|
||||
WSRunScanner::Scan::EditableNodes,
|
||||
&aEditingHost,
|
||||
nextThing.PointAfterReachedContent<EditorRawDOMPoint>(),
|
||||
BlockInlineCheck::UseComputedDisplayStyle);
|
||||
const Element* const blockElement =
|
||||
@@ -2098,7 +2093,7 @@ EditorDOMPointType HTMLEditUtils::GetPreviousEditablePoint(
|
||||
// There may be invisible trailing white-spaces which should be
|
||||
// ignored. Let's scan its start.
|
||||
return WSRunScanner::GetAfterLastVisiblePoint<EditorDOMPointType>(
|
||||
WSRunScanner::Scan::EditableNodes, *textNode);
|
||||
*textNode);
|
||||
}
|
||||
|
||||
// If it's a container element, return end of it. Otherwise, return
|
||||
@@ -2209,8 +2204,7 @@ EditorDOMPointType HTMLEditUtils::GetNextEditablePoint(
|
||||
}
|
||||
// There may be invisible leading white-spaces which should be
|
||||
// ignored. Let's scan its start.
|
||||
return WSRunScanner::GetFirstVisiblePoint<EditorDOMPointType>(
|
||||
WSRunScanner::Scan::EditableNodes, *textNode);
|
||||
return WSRunScanner::GetFirstVisiblePoint<EditorDOMPointType>(*textNode);
|
||||
}
|
||||
|
||||
// If it's a container element, return start of it. Otherwise, return
|
||||
@@ -2547,14 +2541,11 @@ nsIContent* HTMLEditUtils::GetContentToPreserveInlineStyles(
|
||||
for (auto point = aPoint.template To<EditorRawDOMPoint>(); point.IsSet();) {
|
||||
const WSScanResult nextVisibleThing =
|
||||
WSRunScanner::ScanInclusiveNextVisibleNodeOrBlockBoundary(
|
||||
WSRunScanner::Scan::EditableNodes, point,
|
||||
&aEditingHost, point,
|
||||
BlockInlineCheck::UseComputedDisplayOutsideStyle);
|
||||
if (nextVisibleThing.InVisibleOrCollapsibleCharacters()) {
|
||||
return nextVisibleThing.TextPtr();
|
||||
}
|
||||
if (nextVisibleThing.IsContentEditableRoot()) {
|
||||
break;
|
||||
}
|
||||
// Ignore empty inline container elements because it's not visible for
|
||||
// users so that using the style will appear suddenly from point of
|
||||
// view of users.
|
||||
@@ -2575,16 +2566,18 @@ nsIContent* HTMLEditUtils::GetContentToPreserveInlineStyles(
|
||||
template <typename EditorDOMPointType, typename EditorDOMPointTypeInput>
|
||||
EditorDOMPointType HTMLEditUtils::GetBetterInsertionPointFor(
|
||||
const nsIContent& aContentToInsert,
|
||||
const EditorDOMPointTypeInput& aPointToInsert) {
|
||||
const EditorDOMPointTypeInput& aPointToInsert,
|
||||
const Element& aEditingHost) {
|
||||
if (NS_WARN_IF(!aPointToInsert.IsSet())) {
|
||||
return EditorDOMPointType();
|
||||
}
|
||||
|
||||
auto pointToInsert =
|
||||
aPointToInsert.template GetNonAnonymousSubtreePoint<EditorDOMPointType>();
|
||||
if (NS_WARN_IF(!pointToInsert.IsSet()) ||
|
||||
NS_WARN_IF(!HTMLEditUtils::IsSimplyEditableNode(
|
||||
*pointToInsert.GetContainer()))) {
|
||||
if (MOZ_UNLIKELY(
|
||||
NS_WARN_IF(!pointToInsert.IsSet()) ||
|
||||
NS_WARN_IF(!pointToInsert.GetContainer()->IsInclusiveDescendantOf(
|
||||
&aEditingHost)))) {
|
||||
// Cannot insert aContentToInsert into this DOM tree.
|
||||
return EditorDOMPointType();
|
||||
}
|
||||
@@ -2596,8 +2589,8 @@ EditorDOMPointType HTMLEditUtils::GetBetterInsertionPointFor(
|
||||
return pointToInsert;
|
||||
}
|
||||
|
||||
const WSRunScanner wsScannerForPointToInsert(
|
||||
WSRunScanner::Scan::EditableNodes, pointToInsert,
|
||||
WSRunScanner wsScannerForPointToInsert(
|
||||
const_cast<Element*>(&aEditingHost), pointToInsert,
|
||||
BlockInlineCheck::UseComputedDisplayStyle);
|
||||
|
||||
// If the insertion position is after the last visible item in a line,
|
||||
@@ -2638,9 +2631,10 @@ EditorDOMPointType HTMLEditUtils::GetBetterInsertionPointFor(
|
||||
// static
|
||||
template <typename EditorDOMPointType, typename EditorDOMPointTypeInput>
|
||||
EditorDOMPointType HTMLEditUtils::GetBetterCaretPositionToInsertText(
|
||||
const EditorDOMPointTypeInput& aPoint) {
|
||||
const EditorDOMPointTypeInput& aPoint, const Element& aEditingHost) {
|
||||
MOZ_ASSERT(aPoint.IsSetAndValid());
|
||||
MOZ_ASSERT(HTMLEditUtils::IsSimplyEditableNode(*aPoint.GetContainer()));
|
||||
MOZ_ASSERT(
|
||||
aPoint.GetContainer()->IsInclusiveFlatTreeDescendantOf(&aEditingHost));
|
||||
|
||||
if (aPoint.IsInTextNode()) {
|
||||
return aPoint.template To<EditorDOMPointType>();
|
||||
@@ -2650,10 +2644,10 @@ EditorDOMPointType HTMLEditUtils::GetBetterCaretPositionToInsertText(
|
||||
return EditorDOMPointType(aPoint.GetChild(), 0u);
|
||||
}
|
||||
if (aPoint.IsEndOfContainer()) {
|
||||
WSRunScanner scanner(&aEditingHost, aPoint,
|
||||
BlockInlineCheck::UseComputedDisplayStyle);
|
||||
const WSScanResult previousThing =
|
||||
WSRunScanner::ScanPreviousVisibleNodeOrBlockBoundary(
|
||||
WSRunScanner::Scan::EditableNodes, aPoint,
|
||||
BlockInlineCheck::UseComputedDisplayStyle);
|
||||
scanner.ScanPreviousVisibleNodeOrBlockBoundaryFrom(aPoint);
|
||||
if (previousThing.InVisibleOrCollapsibleCharacters()) {
|
||||
return EditorDOMPointType::AtEndOf(*previousThing.TextPtr());
|
||||
}
|
||||
@@ -2662,7 +2656,7 @@ EditorDOMPointType HTMLEditUtils::GetBetterCaretPositionToInsertText(
|
||||
*nsGkAtoms::textTagName)) {
|
||||
return aPoint.template To<EditorDOMPointType>();
|
||||
}
|
||||
if (MOZ_UNLIKELY(aPoint.GetContainer()->IsEditingHost() ||
|
||||
if (MOZ_UNLIKELY(aPoint.GetContainer() == &aEditingHost ||
|
||||
!aPoint.template GetContainerParentAs<nsIContent>() ||
|
||||
!HTMLEditUtils::CanNodeContain(
|
||||
*aPoint.template ContainerParentAs<nsIContent>(),
|
||||
|
||||
@@ -76,14 +76,6 @@ class HTMLEditUtils final {
|
||||
return aNode.IsEditable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if aElement is an editing host which is either:
|
||||
* - the root element
|
||||
* - parent is not editable
|
||||
* - the <body> element of the document
|
||||
*/
|
||||
[[nodiscard]] static bool ElementIsEditableRoot(const Element& aElement);
|
||||
|
||||
/**
|
||||
* Return true if inclusive flat tree ancestor has `inert` state.
|
||||
*/
|
||||
@@ -548,7 +540,8 @@ class HTMLEditUtils final {
|
||||
template <typename PT, typename CT>
|
||||
[[nodiscard]] static bool PointIsImmediatelyBeforeCurrentBlockBoundary(
|
||||
const EditorDOMPointBase<PT, CT>& aPoint,
|
||||
IgnoreInvisibleLineBreak aIgnoreInvisibleLineBreak);
|
||||
IgnoreInvisibleLineBreak aIgnoreInvisibleLineBreak,
|
||||
const Element& aEditingHost);
|
||||
|
||||
/**
|
||||
* Return true if aRange crosses the inclusive ancestor block element at
|
||||
@@ -1645,8 +1638,6 @@ class HTMLEditUtils final {
|
||||
AncestorType::ClosestBlockElement};
|
||||
constexpr static AncestorTypes ClosestEditableBlockElement = {
|
||||
AncestorType::ClosestBlockElement, AncestorType::EditableElement};
|
||||
constexpr static AncestorTypes ClosestBlockElementExceptHRElement = {
|
||||
AncestorType::ClosestBlockElement, AncestorType::IgnoreHRElement};
|
||||
constexpr static AncestorTypes ClosestEditableBlockElementExceptHRElement = {
|
||||
AncestorType::ClosestBlockElement, AncestorType::IgnoreHRElement,
|
||||
AncestorType::EditableElement};
|
||||
@@ -2078,7 +2069,8 @@ class HTMLEditUtils final {
|
||||
*/
|
||||
template <typename EditorLineBreakType, typename EditorDOMPointType>
|
||||
[[nodiscard]] static Maybe<EditorLineBreakType>
|
||||
GetFollowingUnnecessaryLineBreak(const EditorDOMPointType& aPoint);
|
||||
GetFollowingUnnecessaryLineBreak(const EditorDOMPointType& aPoint,
|
||||
const Element& aEditingHost);
|
||||
|
||||
/**
|
||||
* IsInTableCellSelectionMode() returns true when Gecko's editor thinks that
|
||||
@@ -2372,6 +2364,7 @@ class HTMLEditUtils final {
|
||||
*
|
||||
* @param aContentToInsert The content to insert.
|
||||
* @param aPointToInsert A candidate point to insert the node.
|
||||
* @param aEditingHost The editing host containing aPointToInsert.
|
||||
* @return Better insertion point if next visible node
|
||||
* is a <br> element and previous visible node
|
||||
* is neither none, another <br> element nor
|
||||
@@ -2380,7 +2373,8 @@ class HTMLEditUtils final {
|
||||
template <typename EditorDOMPointType, typename EditorDOMPointTypeInput>
|
||||
static EditorDOMPointType GetBetterInsertionPointFor(
|
||||
const nsIContent& aContentToInsert,
|
||||
const EditorDOMPointTypeInput& aPointToInsert);
|
||||
const EditorDOMPointTypeInput& aPointToInsert,
|
||||
const Element& aEditingHost);
|
||||
|
||||
/**
|
||||
* GetBetterCaretPositionToInsertText() returns better point to put caret
|
||||
@@ -2388,7 +2382,7 @@ class HTMLEditUtils final {
|
||||
*/
|
||||
template <typename EditorDOMPointType, typename EditorDOMPointTypeInput>
|
||||
static EditorDOMPointType GetBetterCaretPositionToInsertText(
|
||||
const EditorDOMPointTypeInput& aPoint);
|
||||
const EditorDOMPointTypeInput& aPoint, const Element& aEditingHost);
|
||||
|
||||
/**
|
||||
* ComputePointToPutCaretInElementIfOutside() returns a good point in aElement
|
||||
|
||||
@@ -1194,7 +1194,7 @@ nsresult HTMLEditor::MaybeCollapseSelectionAtFirstEditableNode(
|
||||
// the visible character.
|
||||
const WSScanResult scanResultInTextNode =
|
||||
WSRunScanner::ScanInclusiveNextVisibleNodeOrBlockBoundary(
|
||||
WSRunScanner::Scan::EditableNodes, EditorRawDOMPoint(text, 0),
|
||||
editingHost, EditorRawDOMPoint(text, 0),
|
||||
BlockInlineCheck::UseComputedDisplayStyle);
|
||||
if ((scanResultInTextNode.InVisibleOrCollapsibleCharacters() ||
|
||||
scanResultInTextNode.ReachedPreformattedLineBreak()) &&
|
||||
@@ -2244,16 +2244,12 @@ nsresult HTMLEditor::InsertElementAtSelectionAsAction(
|
||||
if (!SelectionRef().GetAnchorNode()) {
|
||||
return NS_OK;
|
||||
}
|
||||
if (NS_WARN_IF(!SelectionRef().GetAnchorNode()->IsInclusiveDescendantOf(
|
||||
editingHost))) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
EditorRawDOMPoint atAnchor(SelectionRef().AnchorRef());
|
||||
// Adjust position based on the node we are going to insert.
|
||||
EditorDOMPoint pointToInsert =
|
||||
HTMLEditUtils::GetBetterInsertionPointFor<EditorDOMPoint>(*aElement,
|
||||
atAnchor);
|
||||
HTMLEditUtils::GetBetterInsertionPointFor<EditorDOMPoint>(
|
||||
*aElement, atAnchor, *editingHost);
|
||||
if (!pointToInsert.IsSet()) {
|
||||
NS_WARNING("HTMLEditUtils::GetBetterInsertionPointFor() failed");
|
||||
return NS_ERROR_FAILURE;
|
||||
@@ -2295,7 +2291,8 @@ nsresult HTMLEditor::InsertElementAtSelectionAsAction(
|
||||
if (MOZ_LIKELY(aElement->IsInComposedDoc())) {
|
||||
const auto afterElement = EditorDOMPoint::After(*aElement);
|
||||
if (MOZ_LIKELY(afterElement.IsInContentNode())) {
|
||||
nsresult rv = EnsureNoFollowingUnnecessaryLineBreak(afterElement);
|
||||
nsresult rv =
|
||||
EnsureNoFollowingUnnecessaryLineBreak(afterElement, *editingHost);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING(
|
||||
"HTMLEditor::EnsureNoFollowingUnnecessaryLineBreak() failed");
|
||||
@@ -4518,7 +4515,8 @@ Result<CreateLineBreakResult, nsresult> HTMLEditor::InsertLineBreak(
|
||||
}
|
||||
|
||||
nsresult HTMLEditor::EnsureNoFollowingUnnecessaryLineBreak(
|
||||
const EditorDOMPoint& aNextOrAfterModifiedPoint) {
|
||||
const EditorDOMPoint& aNextOrAfterModifiedPoint,
|
||||
const Element& aEditingHost) {
|
||||
MOZ_ASSERT(aNextOrAfterModifiedPoint.IsInContentNode());
|
||||
|
||||
// If the point is in a mailcite in plaintext mail composer (it is a <span>
|
||||
@@ -4546,7 +4544,7 @@ nsresult HTMLEditor::EnsureNoFollowingUnnecessaryLineBreak(
|
||||
|
||||
const Maybe<EditorLineBreak> unnecessaryLineBreak =
|
||||
HTMLEditUtils::GetFollowingUnnecessaryLineBreak<EditorLineBreak>(
|
||||
aNextOrAfterModifiedPoint);
|
||||
aNextOrAfterModifiedPoint, aEditingHost);
|
||||
if (MOZ_LIKELY(unnecessaryLineBreak.isNothing())) {
|
||||
return NS_OK;
|
||||
}
|
||||
@@ -7845,7 +7843,7 @@ nsresult HTMLEditor::OnModifyDocument(const DocumentModifiedEvent& aRunner) {
|
||||
}
|
||||
const WSScanResult nextThing =
|
||||
WSRunScanner::ScanInclusiveNextVisibleNodeOrBlockBoundary(
|
||||
WSRunScanner::Scan::EditableNodes,
|
||||
editingHost,
|
||||
atCollapsibleWhiteSpace.AfterContainer<EditorRawDOMPoint>(),
|
||||
BlockInlineCheck::UseComputedDisplayStyle);
|
||||
if (!nextThing.ReachedBlockBoundary()) {
|
||||
@@ -7907,18 +7905,21 @@ void HTMLEditor::DocumentModifiedEvent::MaybeAppendNewInvisibleWhiteSpace(
|
||||
!aContentWillBeRemoved->IsHTMLElement(nsGkAtoms::br)) {
|
||||
return;
|
||||
}
|
||||
const Element* const editingHost =
|
||||
const_cast<nsIContent*>(aContentWillBeRemoved)->GetEditingHost();
|
||||
if (MOZ_UNLIKELY(!editingHost)) {
|
||||
return;
|
||||
}
|
||||
const WSScanResult nextThing =
|
||||
WSRunScanner::ScanInclusiveNextVisibleNodeOrBlockBoundary(
|
||||
WSRunScanner::Scan::EditableNodes,
|
||||
EditorRawDOMPoint::After(*aContentWillBeRemoved),
|
||||
editingHost, EditorRawDOMPoint::After(*aContentWillBeRemoved),
|
||||
BlockInlineCheck::UseComputedDisplayStyle);
|
||||
if (!nextThing.ReachedBlockBoundary()) {
|
||||
return;
|
||||
}
|
||||
const WSScanResult previousThing =
|
||||
WSRunScanner::ScanPreviousVisibleNodeOrBlockBoundary(
|
||||
WSRunScanner::Scan::EditableNodes,
|
||||
EditorRawDOMPoint(aContentWillBeRemoved),
|
||||
editingHost, EditorRawDOMPoint(aContentWillBeRemoved),
|
||||
BlockInlineCheck::UseComputedDisplayOutsideStyle);
|
||||
if (!previousThing.ContentIsText() || !previousThing.IsContentEditable()) {
|
||||
return;
|
||||
|
||||
@@ -1213,12 +1213,14 @@ class HTMLEditor final : public EditorBase,
|
||||
*
|
||||
* @param aMailCiteElement The mail-cite element which should be split.
|
||||
* @param aPointToSplit The point to split.
|
||||
* @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<CaretPoint, nsresult>
|
||||
HandleInsertParagraphInMailCiteElement(Element& aMailCiteElement,
|
||||
const EditorDOMPoint& aPointToSplit);
|
||||
const EditorDOMPoint& aPointToSplit,
|
||||
const Element& aEditingHost);
|
||||
|
||||
/**
|
||||
* HandleInsertBRElement() inserts a <br> element into aPointToBreak.
|
||||
@@ -1655,7 +1657,7 @@ class HTMLEditor final : public EditorBase,
|
||||
*/
|
||||
[[nodiscard]] MOZ_CAN_RUN_SCRIPT Result<CreateLineBreakResult, nsresult>
|
||||
InsertPaddingBRElementToMakeEmptyLineVisibleIfNeeded(
|
||||
const EditorDOMPoint& aPointToInsert);
|
||||
const EditorDOMPoint& aPointToInsert, const Element& aEditingHost);
|
||||
|
||||
/**
|
||||
* Insert a padding <br> if aPoint is in an empty block.
|
||||
@@ -3398,10 +3400,12 @@ class HTMLEditor final : public EditorBase,
|
||||
* content.
|
||||
* If you deleted something, this should be
|
||||
* end of the deleted range.
|
||||
* @param aEditingHost The editing host.
|
||||
*/
|
||||
[[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult
|
||||
EnsureNoFollowingUnnecessaryLineBreak(
|
||||
const EditorDOMPoint& aNextOrAfterModifiedPoint);
|
||||
const EditorDOMPoint& aNextOrAfterModifiedPoint,
|
||||
const Element& aEditingHost);
|
||||
|
||||
/**
|
||||
* IndentAsSubAction() indents the content around Selection.
|
||||
@@ -3451,7 +3455,8 @@ class HTMLEditor final : public EditorBase,
|
||||
template <size_t N>
|
||||
[[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult SetInlinePropertiesAroundRanges(
|
||||
AutoClonedRangeArray& aRanges,
|
||||
const AutoTArray<EditorInlineStyleAndValue, N>& aStylesToSet);
|
||||
const AutoTArray<EditorInlineStyleAndValue, N>& aStylesToSet,
|
||||
const Element& aEditingHost);
|
||||
|
||||
/**
|
||||
* RemoveInlinePropertiesAsSubAction() removes specified styles from
|
||||
|
||||
@@ -501,8 +501,8 @@ HTMLEditor::HTMLWithContextInserter::FragmentFromPasteCreator final {
|
||||
HTMLBRElement*
|
||||
HTMLEditor::HTMLWithContextInserter::GetInvisibleBRElementAtPoint(
|
||||
const EditorDOMPoint& aPointToInsert) const {
|
||||
const WSRunScanner wsRunScannerAtInsertionPoint(
|
||||
WSRunScanner::Scan::EditableNodes, aPointToInsert,
|
||||
WSRunScanner wsRunScannerAtInsertionPoint(
|
||||
mHTMLEditor.ComputeEditingHost(), aPointToInsert,
|
||||
BlockInlineCheck::UseComputedDisplayStyle);
|
||||
if (wsRunScannerAtInsertionPoint.EndsByInvisibleBRElement()) {
|
||||
return wsRunScannerAtInsertionPoint.EndReasonBRElementPtr();
|
||||
@@ -563,14 +563,14 @@ HTMLEditor::HTMLWithContextInserter::GetNewCaretPointAfterInsertingHTML(
|
||||
|
||||
// Make sure we don't end up with selection collapsed after an invisible
|
||||
// `<br>` element.
|
||||
const WSRunScanner wsRunScannerAtCaret(
|
||||
WSRunScanner::Scan::EditableNodes, pointToPutCaret,
|
||||
BlockInlineCheck::UseComputedDisplayStyle);
|
||||
Element* editingHost = mHTMLEditor.ComputeEditingHost();
|
||||
WSRunScanner wsRunScannerAtCaret(editingHost, pointToPutCaret,
|
||||
BlockInlineCheck::UseComputedDisplayStyle);
|
||||
if (wsRunScannerAtCaret
|
||||
.ScanPreviousVisibleNodeOrBlockBoundaryFrom(pointToPutCaret)
|
||||
.ReachedInvisibleBRElement()) {
|
||||
const WSRunScanner wsRunScannerAtStartReason(
|
||||
WSRunScanner::Scan::EditableNodes,
|
||||
WSRunScanner wsRunScannerAtStartReason(
|
||||
editingHost,
|
||||
EditorDOMPoint(wsRunScannerAtCaret.GetStartReasonContent()),
|
||||
BlockInlineCheck::UseComputedDisplayStyle);
|
||||
const WSScanResult backwardScanFromPointToCaretResult =
|
||||
@@ -830,18 +830,11 @@ Result<EditActionResult, nsresult> HTMLEditor::HTMLWithContextInserter::Run(
|
||||
}
|
||||
|
||||
// Adjust position based on the first node we are going to insert.
|
||||
const auto candidatePointToInsert =
|
||||
mHTMLEditor.GetFirstSelectionStartPoint<EditorRawDOMPoint>();
|
||||
if (NS_WARN_IF(!candidatePointToInsert.IsSet()) ||
|
||||
NS_WARN_IF(
|
||||
!candidatePointToInsert.GetContainer()->IsInclusiveDescendantOf(
|
||||
&mEditingHost))) {
|
||||
return Err(NS_ERROR_FAILURE);
|
||||
}
|
||||
EditorDOMPoint pointToInsert =
|
||||
HTMLEditUtils::GetBetterInsertionPointFor<EditorDOMPoint>(
|
||||
arrayOfTopMostChildContents[0],
|
||||
mHTMLEditor.GetFirstSelectionStartPoint<EditorRawDOMPoint>());
|
||||
mHTMLEditor.GetFirstSelectionStartPoint<EditorRawDOMPoint>(),
|
||||
mEditingHost);
|
||||
if (!pointToInsert.IsSet()) {
|
||||
NS_WARNING("HTMLEditor::GetBetterInsertionPointFor() failed");
|
||||
return Err(NS_ERROR_FAILURE);
|
||||
@@ -903,7 +896,7 @@ Result<EditActionResult, nsresult> HTMLEditor::HTMLWithContextInserter::Run(
|
||||
lastInsertedPoint.inspect().NextPointOrAfterContainer();
|
||||
if (MOZ_LIKELY(afterLastInsertedContent.IsInContentNode())) {
|
||||
nsresult rv = mHTMLEditor.EnsureNoFollowingUnnecessaryLineBreak(
|
||||
afterLastInsertedContent);
|
||||
afterLastInsertedContent, mEditingHost);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING(
|
||||
"HTMLEditor::EnsureNoFollowingUnnecessaryLineBreak() failed");
|
||||
|
||||
@@ -1517,8 +1517,8 @@ nsresult HTMLEditor::AutoDeleteRangesHandler::ComputeRangesToDelete(
|
||||
EditorType::HTML)) {
|
||||
return NS_SUCCESS_DOM_NO_OPERATION;
|
||||
}
|
||||
const WSRunScanner wsRunScannerAtCaret(
|
||||
WSRunScanner::Scan::EditableNodes, caretPoint,
|
||||
WSRunScanner wsRunScannerAtCaret(
|
||||
&aEditingHost, caretPoint,
|
||||
BlockInlineCheck::UseComputedDisplayOutsideStyle);
|
||||
const WSScanResult scanFromCaretPointResult =
|
||||
aDirectionAndAmount == nsIEditor::eNext
|
||||
@@ -1535,7 +1535,8 @@ nsresult HTMLEditor::AutoDeleteRangesHandler::ComputeRangesToDelete(
|
||||
MOZ_ASSERT(scanFromCaretPointResult.GetContent());
|
||||
|
||||
if (scanFromCaretPointResult.ReachedBRElement()) {
|
||||
if (scanFromCaretPointResult.BRElementPtr() == &aEditingHost) {
|
||||
if (scanFromCaretPointResult.BRElementPtr() ==
|
||||
wsRunScannerAtCaret.GetEditingHost()) {
|
||||
return NS_OK;
|
||||
}
|
||||
if (!scanFromCaretPointResult.IsContentEditable()) {
|
||||
@@ -1811,8 +1812,8 @@ Result<EditActionResult, nsresult> HTMLEditor::AutoDeleteRangesHandler::Run(
|
||||
*caretPoint.ref().ContainerAs<nsIContent>(), EditorType::HTML)) {
|
||||
return EditActionResult::CanceledResult();
|
||||
}
|
||||
const WSRunScanner wsRunScannerAtCaret(
|
||||
WSRunScanner::Scan::EditableNodes, caretPoint.ref(),
|
||||
WSRunScanner wsRunScannerAtCaret(
|
||||
&aEditingHost, caretPoint.ref(),
|
||||
BlockInlineCheck::UseComputedDisplayOutsideStyle);
|
||||
const WSScanResult scanFromCaretPointResult =
|
||||
aDirectionAndAmount == nsIEditor::eNext
|
||||
@@ -1871,8 +1872,8 @@ Result<EditActionResult, nsresult> HTMLEditor::AutoDeleteRangesHandler::Run(
|
||||
NS_EVENT_BITS_MUTATION_NODEREMOVEDFROMDOCUMENT)) {
|
||||
// Let's check whether there is new invisible `<br>` element
|
||||
// for avoiding infinite recursive calls.
|
||||
const WSRunScanner wsRunScannerAtCaret(
|
||||
WSRunScanner::Scan::EditableNodes, caretPoint.ref(),
|
||||
WSRunScanner wsRunScannerAtCaret(
|
||||
&aEditingHost, caretPoint.ref(),
|
||||
BlockInlineCheck::UseComputedDisplayOutsideStyle);
|
||||
const WSScanResult scanFromCaretPointResult =
|
||||
aDirectionAndAmount == nsIEditor::eNext
|
||||
@@ -1955,7 +1956,8 @@ HTMLEditor::AutoDeleteRangesHandler::ComputeRangesToDeleteAroundCollapsedRanges(
|
||||
aScanFromCaretPointResult.ReachedBRElement() ||
|
||||
aScanFromCaretPointResult.ReachedHRElement() ||
|
||||
aScanFromCaretPointResult.ReachedNonEditableOtherBlockElement()) {
|
||||
if (aScanFromCaretPointResult.GetContent() == &aEditingHost) {
|
||||
if (aScanFromCaretPointResult.GetContent() ==
|
||||
aWSRunScannerAtCaret.GetEditingHost()) {
|
||||
return NS_OK;
|
||||
}
|
||||
nsIContent* atomicContent = GetAtomicContentToDelete(
|
||||
@@ -2255,8 +2257,7 @@ nsresult HTMLEditor::AutoDeleteRangesHandler::
|
||||
EditorDOMRangeInTexts rangeToDelete;
|
||||
if (aDirectionAndAmount == nsIEditor::eNext) {
|
||||
Result<EditorDOMRangeInTexts, nsresult> result =
|
||||
WSRunScanner::GetRangeInTextNodesToForwardDeleteFrom(
|
||||
WSRunScanner::Scan::EditableNodes, caretPosition);
|
||||
WSRunScanner::GetRangeInTextNodesToForwardDeleteFrom(caretPosition);
|
||||
if (result.isErr()) {
|
||||
NS_WARNING(
|
||||
"WSRunScanner::GetRangeInTextNodesToForwardDeleteFrom() failed");
|
||||
@@ -2268,8 +2269,7 @@ nsresult HTMLEditor::AutoDeleteRangesHandler::
|
||||
}
|
||||
} else {
|
||||
Result<EditorDOMRangeInTexts, nsresult> result =
|
||||
WSRunScanner::GetRangeInTextNodesToBackspaceFrom(
|
||||
WSRunScanner::Scan::EditableNodes, caretPosition);
|
||||
WSRunScanner::GetRangeInTextNodesToBackspaceFrom(caretPosition);
|
||||
if (result.isErr()) {
|
||||
NS_WARNING("WSRunScanner::GetRangeInTextNodesToBackspaceFrom() failed");
|
||||
return result.unwrapErr();
|
||||
@@ -2373,8 +2373,8 @@ Result<CaretPoint, nsresult> HTMLEditor::AutoDeleteRangesHandler::
|
||||
if (MOZ_LIKELY(pointToPutCaret.IsInContentNode())) {
|
||||
AutoTrackDOMPoint trackPointToPutCaret(aHTMLEditor.RangeUpdaterRef(),
|
||||
&pointToPutCaret);
|
||||
nsresult rv =
|
||||
aHTMLEditor.EnsureNoFollowingUnnecessaryLineBreak(pointToPutCaret);
|
||||
nsresult rv = aHTMLEditor.EnsureNoFollowingUnnecessaryLineBreak(
|
||||
pointToPutCaret, aEditingHost);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("HTMLEditor::EnsureNoFollowingUnnecessaryLineBreak() failed");
|
||||
return Err(rv);
|
||||
@@ -2581,8 +2581,8 @@ Result<CaretPoint, nsresult> HTMLEditor::AutoDeleteRangesHandler::
|
||||
if (MOZ_LIKELY(pointToPutCaret.IsInContentNode())) {
|
||||
AutoTrackDOMPoint trackPointToPutCaret(aHTMLEditor.RangeUpdaterRef(),
|
||||
&pointToPutCaret);
|
||||
nsresult rv =
|
||||
aHTMLEditor.EnsureNoFollowingUnnecessaryLineBreak(pointToPutCaret);
|
||||
nsresult rv = aHTMLEditor.EnsureNoFollowingUnnecessaryLineBreak(
|
||||
pointToPutCaret, aEditingHost);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("HTMLEditor::EnsureNoFollowingUnnecessaryLineBreak() failed");
|
||||
return Err(rv);
|
||||
@@ -2704,8 +2704,7 @@ HTMLEditor::AutoDeleteRangesHandler::ComputeRangesToDeleteAtomicContent(
|
||||
const nsIContent& aAtomicContent,
|
||||
AutoClonedSelectionRangeArray& aRangesToDelete) const {
|
||||
EditorDOMRange rangeToDelete =
|
||||
WSRunScanner::GetRangesForDeletingAtomicContent(
|
||||
WSRunScanner::Scan::EditableNodes, aAtomicContent);
|
||||
WSRunScanner::GetRangesForDeletingAtomicContent(aAtomicContent);
|
||||
if (!rangeToDelete.IsPositioned()) {
|
||||
NS_WARNING("WSRunScanner::GetRangeForDeleteAContentNode() failed");
|
||||
return NS_ERROR_FAILURE;
|
||||
@@ -2728,7 +2727,7 @@ HTMLEditor::AutoDeleteRangesHandler::HandleDeleteAtomicContent(
|
||||
const Element& aEditingHost) {
|
||||
MOZ_ASSERT(aHTMLEditor.IsEditActionDataAvailable());
|
||||
MOZ_ASSERT(!HTMLEditUtils::IsInvisibleBRElement(aAtomicContent));
|
||||
MOZ_ASSERT(!aAtomicContent.IsEditingHost());
|
||||
MOZ_ASSERT(&aAtomicContent != aWSRunScannerAtCaret.GetEditingHost());
|
||||
|
||||
EditorDOMPoint pointToPutCaret = aCaretPoint;
|
||||
{
|
||||
@@ -2756,8 +2755,8 @@ HTMLEditor::AutoDeleteRangesHandler::HandleDeleteAtomicContent(
|
||||
if (MOZ_LIKELY(pointToPutCaret.IsInContentNode())) {
|
||||
AutoTrackDOMPoint trackPointToPutCaret(aHTMLEditor.RangeUpdaterRef(),
|
||||
&pointToPutCaret);
|
||||
nsresult rv =
|
||||
aHTMLEditor.EnsureNoFollowingUnnecessaryLineBreak(pointToPutCaret);
|
||||
nsresult rv = aHTMLEditor.EnsureNoFollowingUnnecessaryLineBreak(
|
||||
pointToPutCaret, aEditingHost);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("HTMLEditor::EnsureNoFollowingUnnecessaryLineBreak() failed");
|
||||
return Err(rv);
|
||||
@@ -3085,9 +3084,8 @@ Result<EditActionResult, nsresult> HTMLEditor::AutoDeleteRangesHandler::
|
||||
aHTMLEditor.GetEditAction())) {
|
||||
return EditorDOMPoint();
|
||||
}
|
||||
const WSRunScanner scanner(
|
||||
WSRunScanner::Scan::EditableNodes, EditorRawDOMPoint(mBRElement),
|
||||
BlockInlineCheck::UseComputedDisplayOutsideStyle);
|
||||
WSRunScanner scanner(&aEditingHost, EditorRawDOMPoint(mBRElement),
|
||||
BlockInlineCheck::UseComputedDisplayOutsideStyle);
|
||||
const WSScanResult maybePreviousText =
|
||||
scanner.ScanPreviousVisibleNodeOrBlockBoundaryFrom(
|
||||
EditorRawDOMPoint(mBRElement));
|
||||
@@ -3586,7 +3584,7 @@ bool HTMLEditor::AutoDeleteRangesHandler::AutoBlockElementsJoiner::
|
||||
}
|
||||
const WSScanResult prevVisibleThingBeforeCurrentBlock =
|
||||
WSRunScanner::ScanPreviousVisibleNodeOrBlockBoundary(
|
||||
WSRunScanner::Scan::EditableNodes,
|
||||
&aEditingHost,
|
||||
EditorRawDOMPoint(
|
||||
inclusiveAncestorOfRightChildBlockOrError.inspect()),
|
||||
BlockInlineCheck::UseComputedDisplayOutsideStyle);
|
||||
@@ -3605,7 +3603,7 @@ bool HTMLEditor::AutoDeleteRangesHandler::AutoBlockElementsJoiner::
|
||||
MOZ_ASSERT(atPrecedingLineBreak.IsSet());
|
||||
const WSScanResult prevVisibleThingBeforeLineBreak =
|
||||
WSRunScanner::ScanPreviousVisibleNodeOrBlockBoundary(
|
||||
WSRunScanner::Scan::EditableNodes, atPrecedingLineBreak,
|
||||
&aEditingHost, atPrecedingLineBreak,
|
||||
BlockInlineCheck::UseComputedDisplayOutsideStyle);
|
||||
if (prevVisibleThingBeforeLineBreak.ReachedBRElement() ||
|
||||
prevVisibleThingBeforeLineBreak.ReachedPreformattedLineBreak() ||
|
||||
@@ -3898,7 +3896,6 @@ HTMLEditor::AutoDeleteRangesHandler::ComputeRangesToDeleteNonCollapsedRanges(
|
||||
EditorDOMRange firstRange(aRangesToDelete.FirstRangeRef());
|
||||
EditorDOMRange extendedRange =
|
||||
WSRunScanner::GetRangeContainingInvisibleWhiteSpacesAtRangeBoundaries(
|
||||
WSRunScanner::Scan::EditableNodes,
|
||||
EditorDOMRange(aRangesToDelete.FirstRangeRef()));
|
||||
if (firstRange != extendedRange) {
|
||||
nsresult rv = aRangesToDelete.FirstRangeRef()->SetStartAndEnd(
|
||||
@@ -4214,8 +4211,7 @@ bool HTMLEditor::AutoDeleteRangesHandler::AutoBlockElementsJoiner::
|
||||
// rough check.
|
||||
const WSScanResult nextVisibleThingOfEndBoundary =
|
||||
WSRunScanner::ScanInclusiveNextVisibleNodeOrBlockBoundary(
|
||||
WSRunScanner::Scan::EditableNodes,
|
||||
EditorRawDOMPoint(aRangeToDelete.EndRef()),
|
||||
&aEditingHost, EditorRawDOMPoint(aRangeToDelete.EndRef()),
|
||||
BlockInlineCheck::UseComputedDisplayOutsideStyle);
|
||||
if (!nextVisibleThingOfEndBoundary.ReachedCurrentBlockBoundary()) {
|
||||
MOZ_ASSERT(mLeftContent->IsElement());
|
||||
@@ -4228,8 +4224,7 @@ bool HTMLEditor::AutoDeleteRangesHandler::AutoBlockElementsJoiner::
|
||||
if (MOZ_LIKELY(mostDistantBlockOrError.inspect())) {
|
||||
const WSScanResult prevVisibleThingOfStartBoundary =
|
||||
WSRunScanner::ScanPreviousVisibleNodeOrBlockBoundary(
|
||||
WSRunScanner::Scan::EditableNodes,
|
||||
EditorRawDOMPoint(aRangeToDelete.StartRef()),
|
||||
&aEditingHost, EditorRawDOMPoint(aRangeToDelete.StartRef()),
|
||||
BlockInlineCheck::UseComputedDisplayOutsideStyle);
|
||||
if (prevVisibleThingOfStartBoundary.ReachedBRElement()) {
|
||||
// If the range start after a <br> followed by the block boundary,
|
||||
@@ -4237,7 +4232,7 @@ bool HTMLEditor::AutoDeleteRangesHandler::AutoBlockElementsJoiner::
|
||||
// not a part of empty line like `<div>abc<br>{<div>]def`.
|
||||
const WSScanResult nextVisibleThingOfBR =
|
||||
WSRunScanner::ScanInclusiveNextVisibleNodeOrBlockBoundary(
|
||||
WSRunScanner::Scan::EditableNodes,
|
||||
&aEditingHost,
|
||||
EditorRawDOMPoint::After(
|
||||
*prevVisibleThingOfStartBoundary.GetContent()),
|
||||
BlockInlineCheck::UseComputedDisplayOutsideStyle);
|
||||
@@ -4251,7 +4246,7 @@ bool HTMLEditor::AutoDeleteRangesHandler::AutoBlockElementsJoiner::
|
||||
}
|
||||
const WSScanResult prevVisibleThingOfBR =
|
||||
WSRunScanner::ScanPreviousVisibleNodeOrBlockBoundary(
|
||||
WSRunScanner::Scan::EditableNodes,
|
||||
&aEditingHost,
|
||||
EditorRawDOMPoint(
|
||||
prevVisibleThingOfStartBoundary.GetContent()),
|
||||
BlockInlineCheck::UseComputedDisplayOutsideStyle);
|
||||
@@ -4266,7 +4261,7 @@ bool HTMLEditor::AutoDeleteRangesHandler::AutoBlockElementsJoiner::
|
||||
.ReachedPreformattedLineBreak()) {
|
||||
const WSScanResult nextVisibleThingOfLineBreak =
|
||||
WSRunScanner::ScanInclusiveNextVisibleNodeOrBlockBoundary(
|
||||
WSRunScanner::Scan::EditableNodes,
|
||||
&aEditingHost,
|
||||
prevVisibleThingOfStartBoundary
|
||||
.PointAfterReachedContent<EditorRawDOMPoint>(),
|
||||
BlockInlineCheck::UseComputedDisplayOutsideStyle);
|
||||
@@ -4281,7 +4276,7 @@ bool HTMLEditor::AutoDeleteRangesHandler::AutoBlockElementsJoiner::
|
||||
}
|
||||
const WSScanResult prevVisibleThingOfLineBreak =
|
||||
WSRunScanner::ScanPreviousVisibleNodeOrBlockBoundary(
|
||||
WSRunScanner::Scan::EditableNodes,
|
||||
&aEditingHost,
|
||||
prevVisibleThingOfStartBoundary
|
||||
.PointAtReachedContent<EditorRawDOMPoint>(),
|
||||
BlockInlineCheck::UseComputedDisplayOutsideStyle);
|
||||
@@ -4298,7 +4293,7 @@ bool HTMLEditor::AutoDeleteRangesHandler::AutoBlockElementsJoiner::
|
||||
mLeftContent);
|
||||
const WSScanResult firstVisibleThingInBlock =
|
||||
WSRunScanner::ScanInclusiveNextVisibleNodeOrBlockBoundary(
|
||||
WSRunScanner::Scan::EditableNodes,
|
||||
&aEditingHost,
|
||||
EditorRawDOMPoint(
|
||||
prevVisibleThingOfStartBoundary.ElementPtr(), 0),
|
||||
BlockInlineCheck::UseComputedDisplayOutsideStyle);
|
||||
@@ -4311,7 +4306,7 @@ bool HTMLEditor::AutoDeleteRangesHandler::AutoBlockElementsJoiner::
|
||||
} else if (prevVisibleThingOfStartBoundary.ReachedOtherBlockElement()) {
|
||||
const WSScanResult firstVisibleThingAfterBlock =
|
||||
WSRunScanner::ScanInclusiveNextVisibleNodeOrBlockBoundary(
|
||||
WSRunScanner::Scan::EditableNodes,
|
||||
&aEditingHost,
|
||||
EditorRawDOMPoint::After(
|
||||
*prevVisibleThingOfStartBoundary.ElementPtr()),
|
||||
BlockInlineCheck::UseComputedDisplayOutsideStyle);
|
||||
@@ -4559,9 +4554,8 @@ Result<EditActionResult, nsresult> HTMLEditor::AutoDeleteRangesHandler::
|
||||
// node because the other browsers insert following inputs into there.
|
||||
if (MayEditActionDeleteAroundCollapsedSelection(
|
||||
aHTMLEditor.GetEditAction())) {
|
||||
const WSRunScanner scanner(
|
||||
WSRunScanner::Scan::EditableNodes, startOfRightContent,
|
||||
BlockInlineCheck::UseComputedDisplayOutsideStyle);
|
||||
WSRunScanner scanner(&aEditingHost, startOfRightContent,
|
||||
BlockInlineCheck::UseComputedDisplayOutsideStyle);
|
||||
const WSScanResult maybePreviousText =
|
||||
scanner.ScanPreviousVisibleNodeOrBlockBoundaryFrom(startOfRightContent);
|
||||
if (maybePreviousText.IsContentEditable() &&
|
||||
@@ -4905,8 +4899,8 @@ Result<Element*, nsresult> HTMLEditor::AutoDeleteRangesHandler::
|
||||
|
||||
const WSScanResult prevVisibleThing =
|
||||
WSRunScanner::ScanPreviousVisibleNodeOrBlockBoundary(
|
||||
WSRunScanner::Scan::EditableNodes, aPoint,
|
||||
BlockInlineCheck::UseComputedDisplayOutsideStyle, aAncestorLimiter);
|
||||
aAncestorLimiter, aPoint,
|
||||
BlockInlineCheck::UseComputedDisplayOutsideStyle);
|
||||
if (!ReachedCurrentBlockBoundaryWhichWeCanCross(prevVisibleThing)) {
|
||||
return nullptr;
|
||||
}
|
||||
@@ -4916,8 +4910,8 @@ Result<Element*, nsresult> HTMLEditor::AutoDeleteRangesHandler::
|
||||
for (Element* ancestorBlock = prevVisibleThing.ElementPtr(); ancestorBlock;) {
|
||||
const WSScanResult prevVisibleThing =
|
||||
WSRunScanner::ScanPreviousVisibleNodeOrBlockBoundary(
|
||||
WSRunScanner::Scan::EditableNodes, EditorRawDOMPoint(ancestorBlock),
|
||||
BlockInlineCheck::UseComputedDisplayOutsideStyle, aAncestorLimiter);
|
||||
aAncestorLimiter, EditorRawDOMPoint(ancestorBlock),
|
||||
BlockInlineCheck::UseComputedDisplayOutsideStyle);
|
||||
if (!ReachedCurrentBlockBoundaryWhichWeCanCross(prevVisibleThing)) {
|
||||
return ancestorBlock;
|
||||
}
|
||||
@@ -4983,8 +4977,7 @@ void HTMLEditor::AutoDeleteRangesHandler::AutoBlockElementsJoiner::
|
||||
|
||||
const WSScanResult prevVisibleThingOfStartBoundary =
|
||||
WSRunScanner::ScanPreviousVisibleNodeOrBlockBoundary(
|
||||
WSRunScanner::Scan::EditableNodes,
|
||||
EditorRawDOMPoint(aRangeToDelete.StartRef()),
|
||||
&aEditingHost, EditorRawDOMPoint(aRangeToDelete.StartRef()),
|
||||
BlockInlineCheck::UseComputedDisplayOutsideStyle);
|
||||
// If the range starts after an invisible <br> of empty line immediately
|
||||
// before the most distant inclusive ancestor of the right block like
|
||||
@@ -4994,13 +4987,13 @@ void HTMLEditor::AutoDeleteRangesHandler::AutoBlockElementsJoiner::
|
||||
prevVisibleThingOfStartBoundary.ReachedPreformattedLineBreak()) {
|
||||
const WSScanResult prevVisibleThingOfPreviousLineBreak =
|
||||
WSRunScanner::ScanPreviousVisibleNodeOrBlockBoundary(
|
||||
WSRunScanner::Scan::EditableNodes,
|
||||
&aEditingHost,
|
||||
prevVisibleThingOfStartBoundary
|
||||
.PointAtReachedContent<EditorRawDOMPoint>(),
|
||||
BlockInlineCheck::UseComputedDisplayOutsideStyle);
|
||||
const WSScanResult nextVisibleThingOfPreviousBR =
|
||||
WSRunScanner::ScanInclusiveNextVisibleNodeOrBlockBoundary(
|
||||
WSRunScanner::Scan::EditableNodes,
|
||||
&aEditingHost,
|
||||
prevVisibleThingOfStartBoundary
|
||||
.PointAfterReachedContent<EditorRawDOMPoint>(),
|
||||
BlockInlineCheck::UseComputedDisplayOutsideStyle);
|
||||
@@ -5031,9 +5024,8 @@ void HTMLEditor::AutoDeleteRangesHandler::AutoBlockElementsJoiner::
|
||||
while (true) {
|
||||
WSScanResult scanResult =
|
||||
WSRunScanner::ScanInclusiveNextVisibleNodeOrBlockBoundary(
|
||||
WSRunScanner::Scan::EditableNodes, scanStartPoint,
|
||||
BlockInlineCheck::UseComputedDisplayOutsideStyle,
|
||||
mLeftContent->AsElement());
|
||||
mLeftContent->AsElement(), scanStartPoint,
|
||||
BlockInlineCheck::UseComputedDisplayOutsideStyle);
|
||||
if (scanResult.ReachedBlockBoundary() ||
|
||||
scanResult.ReachedInlineEditingHostBoundary()) {
|
||||
return lastScanResult;
|
||||
@@ -5185,7 +5177,7 @@ Result<EditActionResult, nsresult> HTMLEditor::AutoDeleteRangesHandler::
|
||||
mMode != Mode::DeletePrecedingLinesAndContentInRange &&
|
||||
HTMLEditUtils::PointIsImmediatelyBeforeCurrentBlockBoundary(
|
||||
EditorRawDOMPoint(aRangeToDelete.StartRef()),
|
||||
HTMLEditUtils::IgnoreInvisibleLineBreak::Yes);
|
||||
HTMLEditUtils::IgnoreInvisibleLineBreak::Yes, aEditingHost);
|
||||
const PutCaretTo putCaretTo = [&]() {
|
||||
// When we delete only preceding lines of the right child block, we should
|
||||
// put caret into start of the right block.
|
||||
@@ -5409,8 +5401,8 @@ Result<EditActionResult, nsresult> HTMLEditor::AutoDeleteRangesHandler::
|
||||
aHTMLEditor.RangeUpdaterRef(), &moveFirstLineResult);
|
||||
AutoTrackDOMPoint trackPointToPutCaret(
|
||||
aHTMLEditor.RangeUpdaterRef(), &pointToPutCaret);
|
||||
nsresult rv =
|
||||
aHTMLEditor.EnsureNoFollowingUnnecessaryLineBreak(aPoint);
|
||||
nsresult rv = aHTMLEditor.EnsureNoFollowingUnnecessaryLineBreak(
|
||||
aPoint, aEditingHost);
|
||||
NS_WARNING_ASSERTION(
|
||||
NS_SUCCEEDED(rv),
|
||||
"HTMLEditor::EnsureNoFollowingUnnecessaryLineBreak() failed");
|
||||
@@ -5500,7 +5492,7 @@ Result<EditActionResult, nsresult> HTMLEditor::AutoDeleteRangesHandler::
|
||||
}
|
||||
WSScanResult nextThing =
|
||||
WSRunScanner::ScanInclusiveNextVisibleNodeOrBlockBoundary(
|
||||
WSRunScanner::Scan::EditableNodes,
|
||||
&aEditingHost,
|
||||
deleteContentResult.DeleteRangeRef().EndRef(),
|
||||
BlockInlineCheck::UseComputedDisplayOutsideStyle);
|
||||
return nextThing.ReachedBRElement() ||
|
||||
@@ -5649,8 +5641,8 @@ nsresult HTMLEditor::AutoDeleteRangesHandler::DeleteUnnecessaryNodes(
|
||||
|
||||
if (MOZ_LIKELY(range.EndRef().IsInContentNode())) {
|
||||
AutoTrackDOMRange trackRange(aHTMLEditor.RangeUpdaterRef(), &range);
|
||||
nsresult rv =
|
||||
aHTMLEditor.EnsureNoFollowingUnnecessaryLineBreak(range.EndRef());
|
||||
nsresult rv = aHTMLEditor.EnsureNoFollowingUnnecessaryLineBreak(
|
||||
range.EndRef(), aEditingHost);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("HTMLEditor::EnsureNoFollowingUnnecessaryLineBreak() failed");
|
||||
return Err(rv);
|
||||
@@ -5692,9 +5684,8 @@ HTMLEditor::AutoDeleteRangesHandler::DeleteParentBlocksWithTransactionIfEmpty(
|
||||
|
||||
// First, check there is visible contents before the point in current block.
|
||||
RefPtr<Element> editingHost = aHTMLEditor.ComputeEditingHost();
|
||||
const WSRunScanner wsScannerForPoint(
|
||||
WSRunScanner::Scan::EditableNodes, aPoint,
|
||||
BlockInlineCheck::UseComputedDisplayOutsideStyle);
|
||||
WSRunScanner wsScannerForPoint(
|
||||
editingHost, aPoint, BlockInlineCheck::UseComputedDisplayOutsideStyle);
|
||||
if (!wsScannerForPoint.StartsFromCurrentBlockBoundary() &&
|
||||
!wsScannerForPoint.StartsFromInlineEditingHostBoundary()) {
|
||||
// If there is visible node before the point, we shouldn't remove the
|
||||
@@ -5741,7 +5732,7 @@ HTMLEditor::AutoDeleteRangesHandler::DeleteParentBlocksWithTransactionIfEmpty(
|
||||
if (wsScannerForPoint.GetEndReasonContent()->GetNextSibling()) {
|
||||
const WSScanResult scanResult =
|
||||
WSRunScanner::ScanInclusiveNextVisibleNodeOrBlockBoundary(
|
||||
WSRunScanner::Scan::EditableNodes,
|
||||
editingHost,
|
||||
EditorRawDOMPoint::After(
|
||||
*wsScannerForPoint.GetEndReasonContent()),
|
||||
BlockInlineCheck::UseComputedDisplayOutsideStyle);
|
||||
@@ -6293,7 +6284,7 @@ Result<bool, nsresult> HTMLEditor::AutoDeleteRangesHandler::
|
||||
mRightBlockElement) {
|
||||
mPrecedingInvisibleBRElement =
|
||||
WSRunScanner::GetPrecedingBRElementUnlessVisibleContentFound(
|
||||
WSRunScanner::Scan::EditableNodes,
|
||||
aHTMLEditor.ComputeEditingHost(),
|
||||
EditorDOMPoint::AtEndOf(mLeftBlockElement),
|
||||
BlockInlineCheck::UseComputedDisplayOutsideStyle);
|
||||
// `WhiteSpaceVisibilityKeeper::
|
||||
@@ -6324,7 +6315,7 @@ Result<bool, nsresult> HTMLEditor::AutoDeleteRangesHandler::
|
||||
mLeftBlockElement) {
|
||||
mPrecedingInvisibleBRElement =
|
||||
WSRunScanner::GetPrecedingBRElementUnlessVisibleContentFound(
|
||||
WSRunScanner::Scan::EditableNodes,
|
||||
aHTMLEditor.ComputeEditingHost(),
|
||||
mPointContainingTheOtherBlockElement,
|
||||
BlockInlineCheck::UseComputedDisplayOutsideStyle);
|
||||
// `WhiteSpaceVisibilityKeeper::
|
||||
@@ -6360,7 +6351,7 @@ Result<bool, nsresult> HTMLEditor::AutoDeleteRangesHandler::
|
||||
} else {
|
||||
mPrecedingInvisibleBRElement =
|
||||
WSRunScanner::GetPrecedingBRElementUnlessVisibleContentFound(
|
||||
WSRunScanner::Scan::EditableNodes,
|
||||
aHTMLEditor.ComputeEditingHost(),
|
||||
EditorDOMPoint::AtEndOf(mLeftBlockElement),
|
||||
BlockInlineCheck::UseComputedDisplayOutsideStyle);
|
||||
// `WhiteSpaceVisibilityKeeper::
|
||||
@@ -6397,8 +6388,8 @@ nsresult HTMLEditor::AutoDeleteRangesHandler::AutoBlockElementsJoiner::
|
||||
}
|
||||
EditorDOMRange range =
|
||||
WSRunScanner::GetRangeForDeletingBlockElementBoundaries(
|
||||
WSRunScanner::Scan::EditableNodes, *mLeftBlockElement,
|
||||
*mRightBlockElement, pointContainingTheOtherBlock);
|
||||
aHTMLEditor, *mLeftBlockElement, *mRightBlockElement,
|
||||
pointContainingTheOtherBlock);
|
||||
if (!range.IsPositioned()) {
|
||||
NS_WARNING(
|
||||
"WSRunScanner::GetRangeForDeletingBlockElementBoundaries() failed");
|
||||
@@ -6486,9 +6477,8 @@ Result<DeleteRangeResult, nsresult> HTMLEditor::AutoDeleteRangesHandler::
|
||||
// We should put caret to end of preceding text node if there is.
|
||||
// Then, users can type text into it like the other browsers.
|
||||
auto pointToPutCaret = [&]() -> EditorDOMPoint {
|
||||
const WSRunScanner scanner(WSRunScanner::Scan::EditableNodes,
|
||||
maybeDeepStartOfRightContent,
|
||||
BlockInlineCheck::UseComputedDisplayStyle);
|
||||
WSRunScanner scanner(&aEditingHost, maybeDeepStartOfRightContent,
|
||||
BlockInlineCheck::UseComputedDisplayStyle);
|
||||
const WSScanResult maybePreviousText =
|
||||
scanner.ScanPreviousVisibleNodeOrBlockBoundaryFrom(
|
||||
maybeDeepStartOfRightContent);
|
||||
@@ -8353,15 +8343,14 @@ HTMLEditor::AutoDeleteRangesHandler::ExtendOrShrinkRangeToDelete(
|
||||
for (;;) {
|
||||
const WSScanResult backwardScanFromStartResult =
|
||||
WSRunScanner::ScanPreviousVisibleNodeOrBlockBoundary(
|
||||
WSRunScanner::Scan::EditableNodes, rangeToDelete.StartRef(),
|
||||
closestEditingHost, rangeToDelete.StartRef(),
|
||||
BlockInlineCheck::UseComputedDisplayOutsideStyle);
|
||||
if (!backwardScanFromStartResult.ReachedCurrentBlockBoundary() &&
|
||||
!backwardScanFromStartResult.ReachedInlineEditingHostBoundary()) {
|
||||
break;
|
||||
}
|
||||
MOZ_ASSERT(backwardScanFromStartResult.GetContent() ==
|
||||
WSRunScanner(WSRunScanner::Scan::EditableNodes,
|
||||
rangeToDelete.StartRef(),
|
||||
WSRunScanner(closestEditingHost, rangeToDelete.StartRef(),
|
||||
BlockInlineCheck::UseComputedDisplayOutsideStyle)
|
||||
.GetStartReasonContent());
|
||||
// We want to keep looking up. But stop if we are crossing table
|
||||
@@ -8407,8 +8396,8 @@ HTMLEditor::AutoDeleteRangesHandler::ExtendOrShrinkRangeToDelete(
|
||||
if (rangeToDelete.EndRef().GetContainer() !=
|
||||
closestBlockAncestorOrInlineEditingHost) {
|
||||
for (;;) {
|
||||
const WSRunScanner wsScannerAtEnd(
|
||||
WSRunScanner::Scan::EditableNodes, rangeToDelete.EndRef(),
|
||||
WSRunScanner wsScannerAtEnd(
|
||||
closestEditingHost, rangeToDelete.EndRef(),
|
||||
BlockInlineCheck::UseComputedDisplayOutsideStyle);
|
||||
const WSScanResult forwardScanFromEndResult =
|
||||
wsScannerAtEnd.ScanInclusiveNextVisibleNodeOrBlockBoundaryFrom(
|
||||
|
||||
@@ -78,7 +78,8 @@ class MOZ_STACK_CLASS HTMLEditor::AutoInlineStyleSetter final
|
||||
* See comments in the definition what this does.
|
||||
*/
|
||||
Result<EditorRawDOMRange, nsresult> ExtendOrShrinkRangeToApplyTheStyle(
|
||||
const HTMLEditor& aHTMLEditor, const EditorDOMRange& aRange) const;
|
||||
const HTMLEditor& aHTMLEditor, const EditorDOMRange& aRange,
|
||||
const Element& aEditingHost) const;
|
||||
|
||||
/**
|
||||
* Returns next/previous sibling of aContent or an ancestor of it if it's
|
||||
@@ -103,6 +104,7 @@ class MOZ_STACK_CLASS HTMLEditor::AutoInlineStyleSetter final
|
||||
* @param aHTMLEditor The editor.
|
||||
* @param aCandidatePointToInsert The point where the caller wants to
|
||||
* insert new text.
|
||||
* @param aEditingHost The editing host.
|
||||
* @return If this creates new empty text node returns it.
|
||||
* If this couldn't create new empty text node due to
|
||||
* the point or aEditingHost cannot have text node,
|
||||
@@ -110,8 +112,9 @@ class MOZ_STACK_CLASS HTMLEditor::AutoInlineStyleSetter final
|
||||
* Otherwise, returns error.
|
||||
*/
|
||||
[[nodiscard]] MOZ_CAN_RUN_SCRIPT static Result<RefPtr<Text>, nsresult>
|
||||
GetEmptyTextNodeToApplyNewStyle(
|
||||
HTMLEditor& aHTMLEditor, const EditorDOMPoint& aCandidatePointToInsert);
|
||||
GetEmptyTextNodeToApplyNewStyle(HTMLEditor& aHTMLEditor,
|
||||
const EditorDOMPoint& aCandidatePointToInsert,
|
||||
const Element& aEditingHost);
|
||||
|
||||
private:
|
||||
[[nodiscard]] MOZ_CAN_RUN_SCRIPT Result<CaretPoint, nsresult> ApplyStyle(
|
||||
|
||||
@@ -75,10 +75,12 @@ template nsresult HTMLEditor::SetInlinePropertiesAsSubAction(
|
||||
|
||||
template nsresult HTMLEditor::SetInlinePropertiesAroundRanges(
|
||||
AutoClonedRangeArray& aRanges,
|
||||
const AutoTArray<EditorInlineStyleAndValue, 1>& aStylesToSet);
|
||||
const AutoTArray<EditorInlineStyleAndValue, 1>& aStylesToSet,
|
||||
const Element& aEditingHost);
|
||||
template nsresult HTMLEditor::SetInlinePropertiesAroundRanges(
|
||||
AutoClonedRangeArray& aRanges,
|
||||
const AutoTArray<EditorInlineStyleAndValue, 32>& aStylesToSet);
|
||||
const AutoTArray<EditorInlineStyleAndValue, 32>& aStylesToSet,
|
||||
const Element& aEditingHost);
|
||||
|
||||
nsresult HTMLEditor::SetInlinePropertyAsAction(nsStaticAtom& aProperty,
|
||||
nsStaticAtom* aAttribute,
|
||||
@@ -308,7 +310,8 @@ nsresult HTMLEditor::SetInlinePropertiesAsSubAction(
|
||||
AutoTransactionsConserveSelection dontChangeMySelection(*this);
|
||||
|
||||
AutoClonedSelectionRangeArray selectionRanges(SelectionRef());
|
||||
nsresult rv = SetInlinePropertiesAroundRanges(selectionRanges, aStylesToSet);
|
||||
nsresult rv = SetInlinePropertiesAroundRanges(selectionRanges, aStylesToSet,
|
||||
aEditingHost);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("HTMLEditor::SetInlinePropertiesAroundRanges() failed");
|
||||
return rv;
|
||||
@@ -326,7 +329,8 @@ nsresult HTMLEditor::SetInlinePropertiesAsSubAction(
|
||||
template <size_t N>
|
||||
nsresult HTMLEditor::SetInlinePropertiesAroundRanges(
|
||||
AutoClonedRangeArray& aRanges,
|
||||
const AutoTArray<EditorInlineStyleAndValue, N>& aStylesToSet) {
|
||||
const AutoTArray<EditorInlineStyleAndValue, N>& aStylesToSet,
|
||||
const Element& aEditingHost) {
|
||||
MOZ_ASSERT(!aRanges.HasSavedRanges());
|
||||
for (const EditorInlineStyleAndValue& styleToSet : aStylesToSet) {
|
||||
AutoInlineStyleSetter inlineStyleSetter(styleToSet);
|
||||
@@ -367,7 +371,8 @@ nsresult HTMLEditor::SetInlinePropertiesAroundRanges(
|
||||
}
|
||||
}
|
||||
Result<EditorRawDOMRange, nsresult> rangeOrError =
|
||||
inlineStyleSetter.ExtendOrShrinkRangeToApplyTheStyle(*this, range);
|
||||
inlineStyleSetter.ExtendOrShrinkRangeToApplyTheStyle(*this, range,
|
||||
aEditingHost);
|
||||
if (MOZ_UNLIKELY(rangeOrError.isErr())) {
|
||||
NS_WARNING(
|
||||
"HTMLEditor::ExtendOrShrinkRangeToApplyTheStyle() failed, but "
|
||||
@@ -389,7 +394,7 @@ nsresult HTMLEditor::SetInlinePropertiesAroundRanges(
|
||||
if (range.Collapsed()) {
|
||||
Result<RefPtr<Text>, nsresult> emptyTextNodeOrError =
|
||||
AutoInlineStyleSetter::GetEmptyTextNodeToApplyNewStyle(
|
||||
*this, range.StartRef());
|
||||
*this, range.StartRef(), aEditingHost);
|
||||
if (MOZ_UNLIKELY(emptyTextNodeOrError.isErr())) {
|
||||
NS_WARNING(
|
||||
"AutoInlineStyleSetter::GetEmptyTextNodeToApplyNewStyle() "
|
||||
@@ -574,10 +579,11 @@ nsresult HTMLEditor::SetInlinePropertiesAroundRanges(
|
||||
// static
|
||||
Result<RefPtr<Text>, nsresult>
|
||||
HTMLEditor::AutoInlineStyleSetter::GetEmptyTextNodeToApplyNewStyle(
|
||||
HTMLEditor& aHTMLEditor, const EditorDOMPoint& aCandidatePointToInsert) {
|
||||
HTMLEditor& aHTMLEditor, const EditorDOMPoint& aCandidatePointToInsert,
|
||||
const Element& aEditingHost) {
|
||||
auto pointToInsertNewText =
|
||||
HTMLEditUtils::GetBetterCaretPositionToInsertText<EditorDOMPoint>(
|
||||
aCandidatePointToInsert);
|
||||
aCandidatePointToInsert, aEditingHost);
|
||||
if (MOZ_UNLIKELY(!pointToInsertNewText.IsSet())) {
|
||||
return RefPtr<Text>(); // cannot insert text there
|
||||
}
|
||||
@@ -1919,7 +1925,8 @@ EditorRawDOMRange HTMLEditor::AutoInlineStyleSetter::
|
||||
|
||||
Result<EditorRawDOMRange, nsresult>
|
||||
HTMLEditor::AutoInlineStyleSetter::ExtendOrShrinkRangeToApplyTheStyle(
|
||||
const HTMLEditor& aHTMLEditor, const EditorDOMRange& aRange) const {
|
||||
const HTMLEditor& aHTMLEditor, const EditorDOMRange& aRange,
|
||||
const Element& aEditingHost) const {
|
||||
if (NS_WARN_IF(!aRange.IsPositioned())) {
|
||||
return Err(NS_ERROR_FAILURE);
|
||||
}
|
||||
@@ -1938,7 +1945,7 @@ HTMLEditor::AutoInlineStyleSetter::ExtendOrShrinkRangeToApplyTheStyle(
|
||||
if (range.EndRef().IsInContentNode()) {
|
||||
const WSScanResult nextContentData =
|
||||
WSRunScanner::ScanInclusiveNextVisibleNodeOrBlockBoundary(
|
||||
WSRunScanner::Scan::EditableNodes, range.EndRef(),
|
||||
&aEditingHost, range.EndRef(),
|
||||
BlockInlineCheck::UseComputedDisplayOutsideStyle);
|
||||
if (nextContentData.ReachedInvisibleBRElement() &&
|
||||
nextContentData.BRElementPtr()->GetParentElement() &&
|
||||
|
||||
@@ -24,87 +24,6 @@ namespace mozilla {
|
||||
|
||||
using namespace dom;
|
||||
|
||||
/******************************************************************************
|
||||
* mozilla::WSScanResult
|
||||
******************************************************************************/
|
||||
|
||||
void WSScanResult::AssertIfInvalidData(const WSRunScanner& aScanner) const {
|
||||
#ifdef DEBUG
|
||||
MOZ_ASSERT(mReason == WSType::UnexpectedError ||
|
||||
mReason == WSType::InUncomposedDoc ||
|
||||
mReason == WSType::NonCollapsibleCharacters ||
|
||||
mReason == WSType::CollapsibleWhiteSpaces ||
|
||||
mReason == WSType::BRElement ||
|
||||
mReason == WSType::PreformattedLineBreak ||
|
||||
mReason == WSType::SpecialContent ||
|
||||
mReason == WSType::CurrentBlockBoundary ||
|
||||
mReason == WSType::OtherBlockBoundary ||
|
||||
mReason == WSType::InlineEditingHostBoundary);
|
||||
MOZ_ASSERT_IF(mReason == WSType::UnexpectedError, !mContent);
|
||||
MOZ_ASSERT_IF(mReason != WSType::UnexpectedError, mContent);
|
||||
MOZ_ASSERT_IF(mReason == WSType::InUncomposedDoc,
|
||||
!mContent->IsInComposedDoc());
|
||||
MOZ_ASSERT_IF(mContent && !mContent->IsInComposedDoc(),
|
||||
mReason == WSType::InUncomposedDoc);
|
||||
MOZ_ASSERT_IF(mReason == WSType::NonCollapsibleCharacters ||
|
||||
mReason == WSType::CollapsibleWhiteSpaces ||
|
||||
mReason == WSType::PreformattedLineBreak,
|
||||
mContent->IsText());
|
||||
MOZ_ASSERT_IF(mReason == WSType::NonCollapsibleCharacters ||
|
||||
mReason == WSType::CollapsibleWhiteSpaces ||
|
||||
mReason == WSType::PreformattedLineBreak,
|
||||
mOffset.isSome());
|
||||
MOZ_ASSERT_IF(mReason == WSType::NonCollapsibleCharacters ||
|
||||
mReason == WSType::CollapsibleWhiteSpaces ||
|
||||
mReason == WSType::PreformattedLineBreak,
|
||||
mContent->AsText()->TextDataLength() > 0);
|
||||
MOZ_ASSERT_IF(mDirection == ScanDirection::Backward &&
|
||||
(mReason == WSType::NonCollapsibleCharacters ||
|
||||
mReason == WSType::CollapsibleWhiteSpaces ||
|
||||
mReason == WSType::PreformattedLineBreak),
|
||||
*mOffset > 0);
|
||||
MOZ_ASSERT_IF(mDirection == ScanDirection::Forward &&
|
||||
(mReason == WSType::NonCollapsibleCharacters ||
|
||||
mReason == WSType::CollapsibleWhiteSpaces ||
|
||||
mReason == WSType::PreformattedLineBreak),
|
||||
*mOffset < mContent->AsText()->TextDataLength());
|
||||
MOZ_ASSERT_IF(mReason == WSType::BRElement,
|
||||
mContent->IsHTMLElement(nsGkAtoms::br));
|
||||
MOZ_ASSERT_IF(mReason == WSType::PreformattedLineBreak,
|
||||
EditorUtils::IsNewLinePreformatted(*mContent));
|
||||
MOZ_ASSERT_IF(mReason == WSType::SpecialContent,
|
||||
(mContent->IsText() && !mContent->IsEditable()) ||
|
||||
(!mContent->IsHTMLElement(nsGkAtoms::br) &&
|
||||
!HTMLEditUtils::IsBlockElement(
|
||||
*mContent, aScanner.mBlockInlineCheck)));
|
||||
MOZ_ASSERT_IF(
|
||||
mReason == WSType::OtherBlockBoundary,
|
||||
HTMLEditUtils::IsBlockElement(*mContent, aScanner.mBlockInlineCheck));
|
||||
MOZ_ASSERT_IF(mReason == WSType::CurrentBlockBoundary, mContent->IsElement());
|
||||
MOZ_ASSERT_IF(mReason == WSType::CurrentBlockBoundary &&
|
||||
aScanner.mScanMode == WSRunScanner::Scan::EditableNodes,
|
||||
mContent->IsEditable());
|
||||
MOZ_ASSERT_IF(
|
||||
mReason == WSType::CurrentBlockBoundary,
|
||||
HTMLEditUtils::IsBlockElement(*mContent, aScanner.mBlockInlineCheck));
|
||||
MOZ_ASSERT_IF(mReason == WSType::InlineEditingHostBoundary,
|
||||
mContent->IsElement());
|
||||
MOZ_ASSERT_IF(mReason == WSType::InlineEditingHostBoundary &&
|
||||
aScanner.mScanMode == WSRunScanner::Scan::EditableNodes,
|
||||
mContent->IsEditable());
|
||||
MOZ_ASSERT_IF(
|
||||
mReason == WSType::InlineEditingHostBoundary,
|
||||
!HTMLEditUtils::IsBlockElement(*mContent, aScanner.mBlockInlineCheck));
|
||||
MOZ_ASSERT_IF(mReason == WSType::InlineEditingHostBoundary,
|
||||
!mContent->GetParentElement() ||
|
||||
!mContent->GetParentElement()->IsEditable());
|
||||
#endif // #ifdef DEBUG
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* mozilla::WSRunScanner
|
||||
******************************************************************************/
|
||||
|
||||
template WSScanResult WSRunScanner::ScanPreviousVisibleNodeOrBlockBoundaryFrom(
|
||||
const EditorDOMPoint& aPoint) const;
|
||||
template WSScanResult WSRunScanner::ScanPreviousVisibleNodeOrBlockBoundaryFrom(
|
||||
@@ -125,14 +44,11 @@ WSRunScanner::ScanInclusiveNextVisibleNodeOrBlockBoundaryFrom(
|
||||
template WSScanResult
|
||||
WSRunScanner::ScanInclusiveNextVisibleNodeOrBlockBoundaryFrom(
|
||||
const EditorRawDOMPointInText& aPoint) const;
|
||||
template EditorDOMPoint WSRunScanner::GetAfterLastVisiblePoint(
|
||||
Scan aScanMode, Text& aTextNode, const Element* aAncestorLimiter);
|
||||
template EditorDOMPoint WSRunScanner::GetAfterLastVisiblePoint(Text& aTextNode);
|
||||
template EditorRawDOMPoint WSRunScanner::GetAfterLastVisiblePoint(
|
||||
Scan aScanMode, Text& aTextNode, const Element* aAncestorLimiter);
|
||||
template EditorDOMPoint WSRunScanner::GetFirstVisiblePoint(
|
||||
Scan aScanMode, Text& aTextNode, const Element* aAncestorLimiter);
|
||||
template EditorRawDOMPoint WSRunScanner::GetFirstVisiblePoint(
|
||||
Scan aScanMode, Text& aTextNode, const Element* aAncestorLimiter);
|
||||
Text& aTextNode);
|
||||
template EditorDOMPoint WSRunScanner::GetFirstVisiblePoint(Text& aTextNode);
|
||||
template EditorRawDOMPoint WSRunScanner::GetFirstVisiblePoint(Text& aTextNode);
|
||||
|
||||
template <typename PT, typename CT>
|
||||
WSScanResult WSRunScanner::ScanPreviousVisibleNodeOrBlockBoundaryFrom(
|
||||
@@ -149,9 +65,9 @@ WSScanResult WSRunScanner::ScanPreviousVisibleNodeOrBlockBoundaryFrom(
|
||||
// removed from the tree, they are not editable unless nested contenteditable
|
||||
// attribute is set to "true".
|
||||
if (MOZ_UNLIKELY(!aPoint.IsInComposedDoc())) {
|
||||
return WSScanResult(*this, WSScanResult::ScanDirection::Backward,
|
||||
return WSScanResult(WSScanResult::ScanDirection::Backward,
|
||||
*aPoint.template ContainerAs<nsIContent>(),
|
||||
WSType::InUncomposedDoc);
|
||||
WSType::InUncomposedDoc, mBlockInlineCheck);
|
||||
}
|
||||
|
||||
if (!TextFragmentDataAtStartRef().IsInitialized()) {
|
||||
@@ -167,23 +83,24 @@ WSScanResult WSRunScanner::ScanPreviousVisibleNodeOrBlockBoundaryFrom(
|
||||
// If the visible things are not editable, we shouldn't scan "editable"
|
||||
// things now. Whether keep scanning editable things or not should be
|
||||
// considered by the caller.
|
||||
if (mScanMode == Scan::EditableNodes && aPoint.GetChild() &&
|
||||
!HTMLEditUtils::IsSimplyEditableNode((*aPoint.GetChild()))) {
|
||||
return WSScanResult(*this, WSScanResult::ScanDirection::Backward,
|
||||
*aPoint.GetChild(), WSType::SpecialContent);
|
||||
if (aPoint.GetChild() && !aPoint.GetChild()->IsEditable()) {
|
||||
return WSScanResult(WSScanResult::ScanDirection::Backward,
|
||||
*aPoint.GetChild(), WSType::SpecialContent,
|
||||
mBlockInlineCheck);
|
||||
}
|
||||
const auto atPreviousChar =
|
||||
GetPreviousCharPoint<EditorRawDOMPointInText>(aPoint);
|
||||
GetPreviousEditableCharPoint<EditorRawDOMPointInText>(aPoint);
|
||||
// When it's a non-empty text node, return it.
|
||||
if (atPreviousChar.IsSet() && !atPreviousChar.IsContainerEmpty()) {
|
||||
MOZ_ASSERT(!atPreviousChar.IsEndOfContainer());
|
||||
return WSScanResult(*this, WSScanResult::ScanDirection::Backward,
|
||||
return WSScanResult(WSScanResult::ScanDirection::Backward,
|
||||
atPreviousChar.template NextPoint<EditorDOMPoint>(),
|
||||
atPreviousChar.IsCharCollapsibleASCIISpaceOrNBSP()
|
||||
? WSType::CollapsibleWhiteSpaces
|
||||
: atPreviousChar.IsCharPreformattedNewLine()
|
||||
? WSType::PreformattedLineBreak
|
||||
: WSType::NonCollapsibleCharacters);
|
||||
: WSType::NonCollapsibleCharacters,
|
||||
mBlockInlineCheck);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -200,9 +117,10 @@ WSScanResult WSRunScanner::ScanPreviousVisibleNodeOrBlockBoundaryFrom(
|
||||
// XXX: If we find the character at last of a text node and we started
|
||||
// scanning from following text node of it, some callers may work with the
|
||||
// point in the following text node instead of end of the found text node.
|
||||
return WSScanResult(*this, WSScanResult::ScanDirection::Backward,
|
||||
return WSScanResult(WSScanResult::ScanDirection::Backward,
|
||||
TextFragmentDataAtStartRef().StartRef(),
|
||||
TextFragmentDataAtStartRef().StartRawReason());
|
||||
TextFragmentDataAtStartRef().StartRawReason(),
|
||||
mBlockInlineCheck);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -215,16 +133,18 @@ WSScanResult WSRunScanner::ScanPreviousVisibleNodeOrBlockBoundaryFrom(
|
||||
}
|
||||
// In this case, TextFragmentDataAtStartRef().StartRef().Offset() is not
|
||||
// meaningful.
|
||||
return WSScanResult(*this, WSScanResult::ScanDirection::Backward,
|
||||
return WSScanResult(WSScanResult::ScanDirection::Backward,
|
||||
*TextFragmentDataAtStartRef().GetStartReasonContent(),
|
||||
TextFragmentDataAtStartRef().StartRawReason());
|
||||
TextFragmentDataAtStartRef().StartRawReason(),
|
||||
mBlockInlineCheck);
|
||||
}
|
||||
if (NS_WARN_IF(!TextFragmentDataAtStartRef().StartRef().IsSet())) {
|
||||
return WSScanResult::Error();
|
||||
}
|
||||
return WSScanResult(*this, WSScanResult::ScanDirection::Backward,
|
||||
return WSScanResult(WSScanResult::ScanDirection::Backward,
|
||||
TextFragmentDataAtStartRef().StartRef(),
|
||||
TextFragmentDataAtStartRef().StartRawReason());
|
||||
TextFragmentDataAtStartRef().StartRawReason(),
|
||||
mBlockInlineCheck);
|
||||
}
|
||||
|
||||
template <typename PT, typename CT>
|
||||
@@ -242,9 +162,9 @@ WSScanResult WSRunScanner::ScanInclusiveNextVisibleNodeOrBlockBoundaryFrom(
|
||||
// removed from the tree, they are not editable unless nested contenteditable
|
||||
// attribute is set to "true".
|
||||
if (MOZ_UNLIKELY(!aPoint.IsInComposedDoc())) {
|
||||
return WSScanResult(*this, WSScanResult::ScanDirection::Forward,
|
||||
return WSScanResult(WSScanResult::ScanDirection::Forward,
|
||||
*aPoint.template ContainerAs<nsIContent>(),
|
||||
WSType::InUncomposedDoc);
|
||||
WSType::InUncomposedDoc, mBlockInlineCheck);
|
||||
}
|
||||
|
||||
if (!TextFragmentDataAtStartRef().IsInitialized()) {
|
||||
@@ -260,23 +180,24 @@ WSScanResult WSRunScanner::ScanInclusiveNextVisibleNodeOrBlockBoundaryFrom(
|
||||
// If the visible things are not editable, we shouldn't scan "editable"
|
||||
// things now. Whether keep scanning editable things or not should be
|
||||
// considered by the caller.
|
||||
if (mScanMode == Scan::EditableNodes && aPoint.GetChild() &&
|
||||
!HTMLEditUtils::IsSimplyEditableNode(*aPoint.GetChild())) {
|
||||
return WSScanResult(*this, WSScanResult::ScanDirection::Forward,
|
||||
*aPoint.GetChild(), WSType::SpecialContent);
|
||||
if (aPoint.GetChild() && !aPoint.GetChild()->IsEditable()) {
|
||||
return WSScanResult(WSScanResult::ScanDirection::Forward,
|
||||
*aPoint.GetChild(), WSType::SpecialContent,
|
||||
mBlockInlineCheck);
|
||||
}
|
||||
const auto atNextChar = GetInclusiveNextCharPoint<EditorDOMPoint>(aPoint);
|
||||
const auto atNextChar =
|
||||
GetInclusiveNextEditableCharPoint<EditorDOMPoint>(aPoint);
|
||||
// When it's a non-empty text node, return it.
|
||||
if (atNextChar.IsSet() && !atNextChar.IsContainerEmpty()) {
|
||||
return WSScanResult(*this, WSScanResult::ScanDirection::Forward,
|
||||
atNextChar,
|
||||
return WSScanResult(WSScanResult::ScanDirection::Forward, atNextChar,
|
||||
!atNextChar.IsEndOfContainer() &&
|
||||
atNextChar.IsCharCollapsibleASCIISpaceOrNBSP()
|
||||
? WSType::CollapsibleWhiteSpaces
|
||||
: !atNextChar.IsEndOfContainer() &&
|
||||
atNextChar.IsCharPreformattedNewLine()
|
||||
? WSType::PreformattedLineBreak
|
||||
: WSType::NonCollapsibleCharacters);
|
||||
: WSType::NonCollapsibleCharacters,
|
||||
mBlockInlineCheck);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -294,9 +215,10 @@ WSScanResult WSRunScanner::ScanInclusiveNextVisibleNodeOrBlockBoundaryFrom(
|
||||
// started scanning from preceding text node of it, some callers may want
|
||||
// to work with the point at end of the preceding text node instead of
|
||||
// start of the found text node.
|
||||
return WSScanResult(*this, WSScanResult::ScanDirection::Forward,
|
||||
return WSScanResult(WSScanResult::ScanDirection::Forward,
|
||||
TextFragmentDataAtStartRef().EndRef(),
|
||||
TextFragmentDataAtStartRef().EndRawReason());
|
||||
TextFragmentDataAtStartRef().EndRawReason(),
|
||||
mBlockInlineCheck);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -309,23 +231,23 @@ WSScanResult WSRunScanner::ScanInclusiveNextVisibleNodeOrBlockBoundaryFrom(
|
||||
}
|
||||
// In this case, TextFragmentDataAtStartRef().EndRef().Offset() is not
|
||||
// meaningful.
|
||||
return WSScanResult(*this, WSScanResult::ScanDirection::Forward,
|
||||
return WSScanResult(WSScanResult::ScanDirection::Forward,
|
||||
*TextFragmentDataAtStartRef().GetEndReasonContent(),
|
||||
TextFragmentDataAtStartRef().EndRawReason());
|
||||
TextFragmentDataAtStartRef().EndRawReason(),
|
||||
mBlockInlineCheck);
|
||||
}
|
||||
if (NS_WARN_IF(!TextFragmentDataAtStartRef().EndRef().IsSet())) {
|
||||
return WSScanResult::Error();
|
||||
}
|
||||
return WSScanResult(*this, WSScanResult::ScanDirection::Forward,
|
||||
return WSScanResult(WSScanResult::ScanDirection::Forward,
|
||||
TextFragmentDataAtStartRef().EndRef(),
|
||||
TextFragmentDataAtStartRef().EndRawReason());
|
||||
TextFragmentDataAtStartRef().EndRawReason(),
|
||||
mBlockInlineCheck);
|
||||
}
|
||||
|
||||
// static
|
||||
template <typename EditorDOMPointType>
|
||||
EditorDOMPointType WSRunScanner::GetAfterLastVisiblePoint(
|
||||
Scan aScanMode, Text& aTextNode,
|
||||
const Element* aAncestorLimiter /* = nullptr */) {
|
||||
EditorDOMPointType WSRunScanner::GetAfterLastVisiblePoint(Text& aTextNode) {
|
||||
EditorDOMPoint atLastCharOfTextNode(
|
||||
&aTextNode, AssertedCast<uint32_t>(std::max<int64_t>(
|
||||
static_cast<int64_t>(aTextNode.Length()) - 1, 0)));
|
||||
@@ -334,8 +256,8 @@ EditorDOMPointType WSRunScanner::GetAfterLastVisiblePoint(
|
||||
return EditorDOMPointType::AtEndOf(aTextNode);
|
||||
}
|
||||
const TextFragmentData textFragmentData(
|
||||
aScanMode, atLastCharOfTextNode,
|
||||
BlockInlineCheck::UseComputedDisplayStyle, aAncestorLimiter);
|
||||
Scan::EditableNodes, atLastCharOfTextNode,
|
||||
BlockInlineCheck::UseComputedDisplayStyle);
|
||||
if (NS_WARN_IF(!textFragmentData.IsInitialized())) {
|
||||
return EditorDOMPointType(); // TODO: Make here return error with Err.
|
||||
}
|
||||
@@ -350,17 +272,15 @@ EditorDOMPointType WSRunScanner::GetAfterLastVisiblePoint(
|
||||
|
||||
// static
|
||||
template <typename EditorDOMPointType>
|
||||
EditorDOMPointType WSRunScanner::GetFirstVisiblePoint(
|
||||
Scan aScanMode, Text& aTextNode,
|
||||
const Element* aAncestorLimiter /* = nullptr */) {
|
||||
EditorDOMPointType WSRunScanner::GetFirstVisiblePoint(Text& aTextNode) {
|
||||
EditorDOMPoint atStartOfTextNode(&aTextNode, 0);
|
||||
if (!atStartOfTextNode.IsContainerEmpty() &&
|
||||
atStartOfTextNode.IsCharCollapsibleASCIISpace()) {
|
||||
return atStartOfTextNode.To<EditorDOMPointType>();
|
||||
}
|
||||
const TextFragmentData textFragmentData(
|
||||
aScanMode, atStartOfTextNode, BlockInlineCheck::UseComputedDisplayStyle,
|
||||
aAncestorLimiter);
|
||||
Scan::EditableNodes, atStartOfTextNode,
|
||||
BlockInlineCheck::UseComputedDisplayStyle);
|
||||
if (NS_WARN_IF(!textFragmentData.IsInitialized())) {
|
||||
return EditorDOMPointType(); // TODO: Make here return error with Err.
|
||||
}
|
||||
@@ -373,6 +293,15 @@ EditorDOMPointType WSRunScanner::GetFirstVisiblePoint(
|
||||
return invisibleWhiteSpaceRange.EndRef().To<EditorDOMPointType>();
|
||||
}
|
||||
|
||||
char16_t WSRunScanner::GetCharAt(Text* aTextNode, uint32_t aOffset) const {
|
||||
// return 0 if we can't get a char, for whatever reason
|
||||
if (NS_WARN_IF(!aTextNode) ||
|
||||
NS_WARN_IF(aOffset >= aTextNode->TextDataLength())) {
|
||||
return 0;
|
||||
}
|
||||
return aTextNode->TextFragment().CharAt(aOffset);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Implementation for new white-space normalizer
|
||||
*****************************************************************************/
|
||||
@@ -381,8 +310,6 @@ EditorDOMPointType WSRunScanner::GetFirstVisiblePoint(
|
||||
EditorDOMRangeInTexts
|
||||
WSRunScanner::ComputeRangeInTextNodesContainingInvisibleWhiteSpaces(
|
||||
const TextFragmentData& aStart, const TextFragmentData& aEnd) {
|
||||
MOZ_ASSERT(aStart.ScanMode() == aEnd.ScanMode());
|
||||
|
||||
// Corresponding to handling invisible white-spaces part of
|
||||
// `TextFragmentData::GetReplaceRangeDataAtEndOfDeletionRange()` and
|
||||
// `TextFragmentData::GetReplaceRangeDataAtStartOfDeletionRange()`
|
||||
@@ -443,13 +370,10 @@ WSRunScanner::ComputeRangeInTextNodesContainingInvisibleWhiteSpaces(
|
||||
const auto atFirstInvisibleWhiteSpace =
|
||||
hasInvisibleLeadingWhiteSpaces
|
||||
? aStart.GetInclusiveNextCharPoint<EditorDOMPointInText>(
|
||||
aroundFirstInvisibleWhiteSpace,
|
||||
ShouldIgnoreNonEditableSiblingsOrDescendants(
|
||||
aStart.ScanMode()))
|
||||
aroundFirstInvisibleWhiteSpace, IgnoreNonEditableNodes::Yes)
|
||||
: aEnd.GetInclusiveNextCharPoint<EditorDOMPointInText>(
|
||||
aroundFirstInvisibleWhiteSpace,
|
||||
ShouldIgnoreNonEditableSiblingsOrDescendants(
|
||||
aEnd.ScanMode()));
|
||||
IgnoreNonEditableNodes::Yes);
|
||||
MOZ_ASSERT(atFirstInvisibleWhiteSpace.IsSet());
|
||||
MOZ_ASSERT(
|
||||
atFirstInvisibleWhiteSpace.EqualsOrIsBefore(result.StartRef()));
|
||||
@@ -477,12 +401,9 @@ WSRunScanner::ComputeRangeInTextNodesContainingInvisibleWhiteSpaces(
|
||||
const auto atLastInvisibleWhiteSpace =
|
||||
hasInvisibleTrailingWhiteSpaces
|
||||
? aEnd.GetPreviousCharPoint<EditorDOMPointInText>(
|
||||
afterLastInvisibleWhiteSpace,
|
||||
ShouldIgnoreNonEditableSiblingsOrDescendants(aEnd.ScanMode()))
|
||||
afterLastInvisibleWhiteSpace, IgnoreNonEditableNodes::Yes)
|
||||
: aStart.GetPreviousCharPoint<EditorDOMPointInText>(
|
||||
afterLastInvisibleWhiteSpace,
|
||||
ShouldIgnoreNonEditableSiblingsOrDescendants(
|
||||
aStart.ScanMode()));
|
||||
afterLastInvisibleWhiteSpace, IgnoreNonEditableNodes::Yes);
|
||||
MOZ_ASSERT(atLastInvisibleWhiteSpace.IsSet());
|
||||
MOZ_ASSERT(atLastInvisibleWhiteSpace.IsContainerEmpty() ||
|
||||
atLastInvisibleWhiteSpace.IsAtLastContent());
|
||||
@@ -496,22 +417,19 @@ WSRunScanner::ComputeRangeInTextNodesContainingInvisibleWhiteSpaces(
|
||||
|
||||
// static
|
||||
Result<EditorDOMRangeInTexts, nsresult>
|
||||
WSRunScanner::GetRangeInTextNodesToBackspaceFrom(
|
||||
Scan aScanMode, const EditorDOMPoint& aPoint,
|
||||
const Element* aAncestorLimiter /* = nullptr */) {
|
||||
WSRunScanner::GetRangeInTextNodesToBackspaceFrom(const EditorDOMPoint& aPoint) {
|
||||
// Corresponding to computing delete range part of
|
||||
// `WhiteSpaceVisibilityKeeper::DeletePreviousWhiteSpace()`
|
||||
MOZ_ASSERT(aPoint.IsSetAndValid());
|
||||
|
||||
const TextFragmentData textFragmentDataAtCaret(
|
||||
aScanMode, aPoint, BlockInlineCheck::UseComputedDisplayStyle,
|
||||
aAncestorLimiter);
|
||||
Scan::EditableNodes, aPoint, BlockInlineCheck::UseComputedDisplayStyle);
|
||||
if (NS_WARN_IF(!textFragmentDataAtCaret.IsInitialized())) {
|
||||
return Err(NS_ERROR_FAILURE);
|
||||
}
|
||||
auto atPreviousChar =
|
||||
textFragmentDataAtCaret.GetPreviousCharPoint<EditorDOMPointInText>(
|
||||
aPoint, ShouldIgnoreNonEditableSiblingsOrDescendants(aScanMode));
|
||||
aPoint, IgnoreNonEditableNodes::Yes);
|
||||
if (!atPreviousChar.IsSet()) {
|
||||
return EditorDOMRangeInTexts(); // There is no content in the block.
|
||||
}
|
||||
@@ -546,7 +464,7 @@ WSRunScanner::GetRangeInTextNodesToBackspaceFrom(
|
||||
textFragmentDataAtCaret
|
||||
.GetFirstASCIIWhiteSpacePointCollapsedTo<EditorDOMPointInText>(
|
||||
atPreviousChar, nsIEditor::ePrevious,
|
||||
ShouldIgnoreNonEditableSiblingsOrDescendants(aScanMode));
|
||||
IgnoreNonEditableNodes::Yes);
|
||||
if (!startToDelete.IsSet()) {
|
||||
NS_WARNING(
|
||||
"WSRunScanner::GetFirstASCIIWhiteSpacePointCollapsedTo() failed");
|
||||
@@ -556,7 +474,7 @@ WSRunScanner::GetRangeInTextNodesToBackspaceFrom(
|
||||
textFragmentDataAtCaret
|
||||
.GetEndOfCollapsibleASCIIWhiteSpaces<EditorDOMPointInText>(
|
||||
atPreviousChar, nsIEditor::ePrevious,
|
||||
ShouldIgnoreNonEditableSiblingsOrDescendants(aScanMode));
|
||||
IgnoreNonEditableNodes::Yes);
|
||||
if (!endToDelete.IsSet()) {
|
||||
NS_WARNING("WSRunScanner::GetEndOfCollapsibleASCIIWhiteSpaces() failed");
|
||||
return Err(NS_ERROR_FAILURE);
|
||||
@@ -576,15 +494,13 @@ WSRunScanner::GetRangeInTextNodesToBackspaceFrom(
|
||||
// And also delete invisible white-spaces if they become visible.
|
||||
const TextFragmentData textFragmentDataAtStart =
|
||||
rangeToDelete.StartRef() != aPoint
|
||||
? TextFragmentData(aScanMode, rangeToDelete.StartRef(),
|
||||
BlockInlineCheck::UseComputedDisplayStyle,
|
||||
aAncestorLimiter)
|
||||
? TextFragmentData(Scan::EditableNodes, rangeToDelete.StartRef(),
|
||||
BlockInlineCheck::UseComputedDisplayStyle)
|
||||
: textFragmentDataAtCaret;
|
||||
const TextFragmentData textFragmentDataAtEnd =
|
||||
rangeToDelete.EndRef() != aPoint
|
||||
? TextFragmentData(aScanMode, rangeToDelete.EndRef(),
|
||||
BlockInlineCheck::UseComputedDisplayStyle,
|
||||
aAncestorLimiter)
|
||||
? TextFragmentData(Scan::EditableNodes, rangeToDelete.EndRef(),
|
||||
BlockInlineCheck::UseComputedDisplayStyle)
|
||||
: textFragmentDataAtCaret;
|
||||
if (NS_WARN_IF(!textFragmentDataAtStart.IsInitialized()) ||
|
||||
NS_WARN_IF(!textFragmentDataAtEnd.IsInitialized())) {
|
||||
@@ -601,21 +517,19 @@ WSRunScanner::GetRangeInTextNodesToBackspaceFrom(
|
||||
// static
|
||||
Result<EditorDOMRangeInTexts, nsresult>
|
||||
WSRunScanner::GetRangeInTextNodesToForwardDeleteFrom(
|
||||
Scan aScanMode, const EditorDOMPoint& aPoint,
|
||||
const Element* aAncestorLimiter /* = nullptr */) {
|
||||
const EditorDOMPoint& aPoint) {
|
||||
// Corresponding to computing delete range part of
|
||||
// `WhiteSpaceVisibilityKeeper::DeleteInclusiveNextWhiteSpace()`
|
||||
MOZ_ASSERT(aPoint.IsSetAndValid());
|
||||
|
||||
const TextFragmentData textFragmentDataAtCaret(
|
||||
aScanMode, aPoint, BlockInlineCheck::UseComputedDisplayStyle,
|
||||
aAncestorLimiter);
|
||||
TextFragmentData textFragmentDataAtCaret(
|
||||
Scan::EditableNodes, aPoint, BlockInlineCheck::UseComputedDisplayStyle);
|
||||
if (NS_WARN_IF(!textFragmentDataAtCaret.IsInitialized())) {
|
||||
return Err(NS_ERROR_FAILURE);
|
||||
}
|
||||
auto atCaret =
|
||||
textFragmentDataAtCaret.GetInclusiveNextCharPoint<EditorDOMPointInText>(
|
||||
aPoint, ShouldIgnoreNonEditableSiblingsOrDescendants(aScanMode));
|
||||
aPoint, IgnoreNonEditableNodes::Yes);
|
||||
if (!atCaret.IsSet()) {
|
||||
return EditorDOMRangeInTexts(); // There is no content in the block.
|
||||
}
|
||||
@@ -648,8 +562,7 @@ WSRunScanner::GetRangeInTextNodesToForwardDeleteFrom(
|
||||
const auto startToDelete =
|
||||
textFragmentDataAtCaret
|
||||
.GetFirstASCIIWhiteSpacePointCollapsedTo<EditorDOMPointInText>(
|
||||
atCaret, nsIEditor::eNext,
|
||||
ShouldIgnoreNonEditableSiblingsOrDescendants(aScanMode));
|
||||
atCaret, nsIEditor::eNext, IgnoreNonEditableNodes::Yes);
|
||||
if (!startToDelete.IsSet()) {
|
||||
NS_WARNING(
|
||||
"WSRunScanner::GetFirstASCIIWhiteSpacePointCollapsedTo() failed");
|
||||
@@ -658,8 +571,7 @@ WSRunScanner::GetRangeInTextNodesToForwardDeleteFrom(
|
||||
const EditorDOMPointInText endToDelete =
|
||||
textFragmentDataAtCaret
|
||||
.GetEndOfCollapsibleASCIIWhiteSpaces<EditorDOMPointInText>(
|
||||
atCaret, nsIEditor::eNext,
|
||||
ShouldIgnoreNonEditableSiblingsOrDescendants(aScanMode));
|
||||
atCaret, nsIEditor::eNext, IgnoreNonEditableNodes::Yes);
|
||||
if (!endToDelete.IsSet()) {
|
||||
NS_WARNING("WSRunScanner::GetEndOfCollapsibleASCIIWhiteSpaces() failed");
|
||||
return Err(NS_ERROR_FAILURE);
|
||||
@@ -679,15 +591,13 @@ WSRunScanner::GetRangeInTextNodesToForwardDeleteFrom(
|
||||
// And also delete invisible white-spaces if they become visible.
|
||||
const TextFragmentData textFragmentDataAtStart =
|
||||
rangeToDelete.StartRef() != aPoint
|
||||
? TextFragmentData(aScanMode, rangeToDelete.StartRef(),
|
||||
BlockInlineCheck::UseComputedDisplayStyle,
|
||||
aAncestorLimiter)
|
||||
? TextFragmentData(Scan::EditableNodes, rangeToDelete.StartRef(),
|
||||
BlockInlineCheck::UseComputedDisplayStyle)
|
||||
: textFragmentDataAtCaret;
|
||||
const TextFragmentData textFragmentDataAtEnd =
|
||||
rangeToDelete.EndRef() != aPoint
|
||||
? TextFragmentData(aScanMode, rangeToDelete.EndRef(),
|
||||
BlockInlineCheck::UseComputedDisplayStyle,
|
||||
aAncestorLimiter)
|
||||
? TextFragmentData(Scan::EditableNodes, rangeToDelete.EndRef(),
|
||||
BlockInlineCheck::UseComputedDisplayStyle)
|
||||
: textFragmentDataAtCaret;
|
||||
if (NS_WARN_IF(!textFragmentDataAtStart.IsInitialized()) ||
|
||||
NS_WARN_IF(!textFragmentDataAtEnd.IsInitialized())) {
|
||||
@@ -703,14 +613,13 @@ WSRunScanner::GetRangeInTextNodesToForwardDeleteFrom(
|
||||
|
||||
// static
|
||||
EditorDOMRange WSRunScanner::GetRangesForDeletingAtomicContent(
|
||||
Scan aScanMode, const nsIContent& aAtomicContent,
|
||||
const Element* aAncestorLimiter /* = nullptr */) {
|
||||
const nsIContent& aAtomicContent) {
|
||||
if (aAtomicContent.IsHTMLElement(nsGkAtoms::br)) {
|
||||
// Preceding white-spaces should be preserved, but the following
|
||||
// white-spaces should be invisible around `<br>` element.
|
||||
const TextFragmentData textFragmentDataAfterBRElement(
|
||||
aScanMode, EditorDOMPoint::After(aAtomicContent),
|
||||
BlockInlineCheck::UseComputedDisplayStyle, aAncestorLimiter);
|
||||
Scan::EditableNodes, EditorDOMPoint::After(aAtomicContent),
|
||||
BlockInlineCheck::UseComputedDisplayStyle);
|
||||
if (NS_WARN_IF(!textFragmentDataAfterBRElement.IsInitialized())) {
|
||||
return EditorDOMRange(); // TODO: Make here return error with Err.
|
||||
}
|
||||
@@ -740,8 +649,9 @@ EditorDOMRange WSRunScanner::GetRangesForDeletingAtomicContent(
|
||||
// Both preceding and following white-spaces can be invisible around a
|
||||
// block element.
|
||||
const TextFragmentData textFragmentDataBeforeAtomicContent(
|
||||
aScanMode, EditorDOMPoint(const_cast<nsIContent*>(&aAtomicContent)),
|
||||
BlockInlineCheck::UseComputedDisplayStyle, aAncestorLimiter);
|
||||
Scan::EditableNodes,
|
||||
EditorDOMPoint(const_cast<nsIContent*>(&aAtomicContent)),
|
||||
BlockInlineCheck::UseComputedDisplayStyle);
|
||||
if (NS_WARN_IF(!textFragmentDataBeforeAtomicContent.IsInitialized())) {
|
||||
return EditorDOMRange(); // TODO: Make here return error with Err.
|
||||
}
|
||||
@@ -750,8 +660,8 @@ EditorDOMRange WSRunScanner::GetRangesForDeletingAtomicContent(
|
||||
textFragmentDataBeforeAtomicContent
|
||||
.InvisibleTrailingWhiteSpaceRangeRef());
|
||||
const TextFragmentData textFragmentDataAfterAtomicContent(
|
||||
aScanMode, EditorDOMPoint::After(aAtomicContent),
|
||||
BlockInlineCheck::UseComputedDisplayStyle, aAncestorLimiter);
|
||||
Scan::EditableNodes, EditorDOMPoint::After(aAtomicContent),
|
||||
BlockInlineCheck::UseComputedDisplayStyle);
|
||||
if (NS_WARN_IF(!textFragmentDataAfterAtomicContent.IsInitialized())) {
|
||||
return EditorDOMRange(); // TODO: Make here return error with Err.
|
||||
}
|
||||
@@ -780,10 +690,9 @@ EditorDOMRange WSRunScanner::GetRangesForDeletingAtomicContent(
|
||||
|
||||
// static
|
||||
EditorDOMRange WSRunScanner::GetRangeForDeletingBlockElementBoundaries(
|
||||
Scan aScanMode, const Element& aLeftBlockElement,
|
||||
const HTMLEditor& aHTMLEditor, const Element& aLeftBlockElement,
|
||||
const Element& aRightBlockElement,
|
||||
const EditorDOMPoint& aPointContainingTheOtherBlock,
|
||||
const Element* aAncestorLimiter /* = nullptr */) {
|
||||
const EditorDOMPoint& aPointContainingTheOtherBlock) {
|
||||
MOZ_ASSERT(&aLeftBlockElement != &aRightBlockElement);
|
||||
MOZ_ASSERT_IF(
|
||||
aPointContainingTheOtherBlock.IsSet(),
|
||||
@@ -807,22 +716,15 @@ EditorDOMRange WSRunScanner::GetRangeForDeletingBlockElementBoundaries(
|
||||
EditorRawDOMPoint(const_cast<Element*>(&aLeftBlockElement))
|
||||
.IsBefore(EditorRawDOMPoint(
|
||||
const_cast<Element*>(&aRightBlockElement))));
|
||||
MOZ_ASSERT_IF(aAncestorLimiter,
|
||||
aLeftBlockElement.IsInclusiveDescendantOf(aAncestorLimiter));
|
||||
MOZ_ASSERT_IF(aAncestorLimiter,
|
||||
aRightBlockElement.IsInclusiveDescendantOf(aAncestorLimiter));
|
||||
MOZ_ASSERT_IF(aScanMode == Scan::EditableNodes,
|
||||
const_cast<Element&>(aLeftBlockElement).GetEditingHost() ==
|
||||
const_cast<Element&>(aRightBlockElement).GetEditingHost());
|
||||
|
||||
EditorDOMRange range;
|
||||
// Include trailing invisible white-spaces in aLeftBlockElement.
|
||||
const TextFragmentData textFragmentDataAtEndOfLeftBlockElement(
|
||||
aScanMode,
|
||||
Scan::EditableNodes,
|
||||
aPointContainingTheOtherBlock.GetContainer() == &aLeftBlockElement
|
||||
? aPointContainingTheOtherBlock
|
||||
: EditorDOMPoint::AtEndOf(const_cast<Element&>(aLeftBlockElement)),
|
||||
BlockInlineCheck::UseComputedDisplayOutsideStyle, aAncestorLimiter);
|
||||
BlockInlineCheck::UseComputedDisplayOutsideStyle);
|
||||
if (NS_WARN_IF(!textFragmentDataAtEndOfLeftBlockElement.IsInitialized())) {
|
||||
return EditorDOMRange(); // TODO: Make here return error with Err.
|
||||
}
|
||||
@@ -845,12 +747,12 @@ EditorDOMRange WSRunScanner::GetRangeForDeletingBlockElementBoundaries(
|
||||
}
|
||||
// Include leading invisible white-spaces in aRightBlockElement.
|
||||
const TextFragmentData textFragmentDataAtStartOfRightBlockElement(
|
||||
aScanMode,
|
||||
Scan::EditableNodes,
|
||||
aPointContainingTheOtherBlock.GetContainer() == &aRightBlockElement &&
|
||||
!aPointContainingTheOtherBlock.IsEndOfContainer()
|
||||
? aPointContainingTheOtherBlock.NextPoint()
|
||||
: EditorDOMPoint(const_cast<Element*>(&aRightBlockElement), 0u),
|
||||
BlockInlineCheck::UseComputedDisplayOutsideStyle, aAncestorLimiter);
|
||||
BlockInlineCheck::UseComputedDisplayOutsideStyle);
|
||||
if (NS_WARN_IF(!textFragmentDataAtStartOfRightBlockElement.IsInitialized())) {
|
||||
return EditorDOMRange(); // TODO: Make here return error with Err.
|
||||
}
|
||||
@@ -868,16 +770,15 @@ EditorDOMRange WSRunScanner::GetRangeForDeletingBlockElementBoundaries(
|
||||
// static
|
||||
EditorDOMRange
|
||||
WSRunScanner::GetRangeContainingInvisibleWhiteSpacesAtRangeBoundaries(
|
||||
Scan aScanMode, const EditorDOMRange& aRange,
|
||||
const Element* aAncestorLimiter /* = nullptr */) {
|
||||
const EditorDOMRange& aRange) {
|
||||
MOZ_ASSERT(aRange.IsPositionedAndValid());
|
||||
MOZ_ASSERT(aRange.EndRef().IsSetAndValid());
|
||||
MOZ_ASSERT(aRange.StartRef().IsSetAndValid());
|
||||
|
||||
EditorDOMRange result;
|
||||
const TextFragmentData textFragmentDataAtStart(
|
||||
aScanMode, aRange.StartRef(), BlockInlineCheck::UseComputedDisplayStyle,
|
||||
aAncestorLimiter);
|
||||
Scan::EditableNodes, aRange.StartRef(),
|
||||
BlockInlineCheck::UseComputedDisplayStyle);
|
||||
if (NS_WARN_IF(!textFragmentDataAtStart.IsInitialized())) {
|
||||
return EditorDOMRange(); // TODO: Make here return error with Err.
|
||||
}
|
||||
@@ -912,8 +813,8 @@ WSRunScanner::GetRangeContainingInvisibleWhiteSpacesAtRangeBoundaries(
|
||||
}
|
||||
|
||||
const TextFragmentData textFragmentDataAtEnd(
|
||||
aScanMode, aRange.EndRef(), BlockInlineCheck::UseComputedDisplayStyle,
|
||||
aAncestorLimiter);
|
||||
Scan::EditableNodes, aRange.EndRef(),
|
||||
BlockInlineCheck::UseComputedDisplayStyle);
|
||||
if (NS_WARN_IF(!textFragmentDataAtEnd.IsInitialized())) {
|
||||
return EditorDOMRange(); // TODO: Make here return error with Err.
|
||||
}
|
||||
@@ -957,8 +858,7 @@ WSRunScanner::GetRangeContainingInvisibleWhiteSpacesAtRangeBoundaries(
|
||||
// static
|
||||
Result<bool, nsresult>
|
||||
WSRunScanner::ShrinkRangeIfStartsFromOrEndsAfterAtomicContent(
|
||||
Scan aScanMode, nsRange& aRange,
|
||||
const Element* aAncestorLimiter /* = nullptr */) {
|
||||
const HTMLEditor& aHTMLEditor, nsRange& aRange) {
|
||||
MOZ_ASSERT(aRange.IsPositioned());
|
||||
MOZ_ASSERT(!aRange.IsInAnySelection(),
|
||||
"Changing range in selection may cause running script");
|
||||
@@ -978,15 +878,11 @@ WSRunScanner::ShrinkRangeIfStartsFromOrEndsAfterAtomicContent(
|
||||
// joining the blocks.
|
||||
if (HTMLEditUtils::GetInclusiveAncestorElement(
|
||||
*aRange.GetStartContainer()->AsContent(),
|
||||
aScanMode == Scan::EditableNodes
|
||||
? HTMLEditUtils::ClosestEditableBlockElementExceptHRElement
|
||||
: HTMLEditUtils::ClosestBlockElementExceptHRElement,
|
||||
HTMLEditUtils::ClosestEditableBlockElementExceptHRElement,
|
||||
BlockInlineCheck::UseComputedDisplayStyle) !=
|
||||
HTMLEditUtils::GetInclusiveAncestorElement(
|
||||
*aRange.GetEndContainer()->AsContent(),
|
||||
aScanMode == Scan::EditableNodes
|
||||
? HTMLEditUtils::ClosestEditableBlockElementExceptHRElement
|
||||
: HTMLEditUtils::ClosestBlockElementExceptHRElement,
|
||||
HTMLEditUtils::ClosestEditableBlockElementExceptHRElement,
|
||||
BlockInlineCheck::UseComputedDisplayStyle)) {
|
||||
return false;
|
||||
}
|
||||
@@ -998,8 +894,8 @@ WSRunScanner::ShrinkRangeIfStartsFromOrEndsAfterAtomicContent(
|
||||
// (e.g., `<img>`, non-editable text node, etc) or a block level void
|
||||
// element like `<hr>`, the range should start with it.
|
||||
const TextFragmentData textFragmentDataAtStart(
|
||||
aScanMode, EditorRawDOMPoint(aRange.StartRef()),
|
||||
BlockInlineCheck::UseComputedDisplayStyle, aAncestorLimiter);
|
||||
Scan::EditableNodes, EditorRawDOMPoint(aRange.StartRef()),
|
||||
BlockInlineCheck::UseComputedDisplayStyle);
|
||||
if (NS_WARN_IF(!textFragmentDataAtStart.IsInitialized())) {
|
||||
return Err(NS_ERROR_FAILURE);
|
||||
}
|
||||
@@ -1021,8 +917,8 @@ WSRunScanner::ShrinkRangeIfStartsFromOrEndsAfterAtomicContent(
|
||||
// (e.g., `<img>`, non-editable text node, etc) or a block level void
|
||||
// element like `<hr>`, the range should end after it.
|
||||
const TextFragmentData textFragmentDataAtEnd(
|
||||
aScanMode, EditorRawDOMPoint(aRange.EndRef()),
|
||||
BlockInlineCheck::UseComputedDisplayStyle, aAncestorLimiter);
|
||||
Scan::EditableNodes, EditorRawDOMPoint(aRange.EndRef()),
|
||||
BlockInlineCheck::UseComputedDisplayStyle);
|
||||
if (NS_WARN_IF(!textFragmentDataAtEnd.IsInitialized())) {
|
||||
return Err(NS_ERROR_FAILURE);
|
||||
}
|
||||
|
||||
@@ -106,26 +106,97 @@ class MOZ_STACK_CLASS WSScanResult final {
|
||||
public:
|
||||
WSScanResult() = delete;
|
||||
enum class ScanDirection : bool { Backward, Forward };
|
||||
WSScanResult(const WSRunScanner& aScanner, ScanDirection aScanDirection,
|
||||
nsIContent& aContent, WSType aReason)
|
||||
MOZ_NEVER_INLINE_DEBUG WSScanResult(ScanDirection aScanDirection,
|
||||
nsIContent& aContent, WSType aReason,
|
||||
BlockInlineCheck aBlockInlineCheck)
|
||||
: mContent(&aContent), mReason(aReason), mDirection(aScanDirection) {
|
||||
MOZ_ASSERT(aReason != WSType::CollapsibleWhiteSpaces &&
|
||||
aReason != WSType::NonCollapsibleCharacters &&
|
||||
aReason != WSType::PreformattedLineBreak);
|
||||
AssertIfInvalidData(aScanner);
|
||||
AssertIfInvalidData(aBlockInlineCheck);
|
||||
}
|
||||
WSScanResult(const WSRunScanner& aScanner, ScanDirection aScanDirection,
|
||||
const EditorDOMPoint& aPoint, WSType aReason)
|
||||
MOZ_NEVER_INLINE_DEBUG WSScanResult(ScanDirection aScanDirection,
|
||||
const EditorDOMPoint& aPoint,
|
||||
WSType aReason,
|
||||
BlockInlineCheck aBlockInlineCheck)
|
||||
: mContent(aPoint.GetContainerAs<nsIContent>()),
|
||||
mOffset(Some(aPoint.Offset())),
|
||||
mReason(aReason),
|
||||
mDirection(aScanDirection) {
|
||||
AssertIfInvalidData(aScanner);
|
||||
AssertIfInvalidData(aBlockInlineCheck);
|
||||
}
|
||||
|
||||
static WSScanResult Error() { return WSScanResult(WSType::UnexpectedError); }
|
||||
|
||||
void AssertIfInvalidData(const WSRunScanner& aScanner) const;
|
||||
MOZ_NEVER_INLINE_DEBUG void AssertIfInvalidData(
|
||||
BlockInlineCheck aBlockInlineCheck) const {
|
||||
#ifdef DEBUG
|
||||
MOZ_ASSERT(mReason == WSType::UnexpectedError ||
|
||||
mReason == WSType::InUncomposedDoc ||
|
||||
mReason == WSType::NonCollapsibleCharacters ||
|
||||
mReason == WSType::CollapsibleWhiteSpaces ||
|
||||
mReason == WSType::BRElement ||
|
||||
mReason == WSType::PreformattedLineBreak ||
|
||||
mReason == WSType::SpecialContent ||
|
||||
mReason == WSType::CurrentBlockBoundary ||
|
||||
mReason == WSType::OtherBlockBoundary ||
|
||||
mReason == WSType::InlineEditingHostBoundary);
|
||||
MOZ_ASSERT_IF(mReason == WSType::UnexpectedError, !mContent);
|
||||
MOZ_ASSERT_IF(mReason != WSType::UnexpectedError, mContent);
|
||||
MOZ_ASSERT_IF(mReason == WSType::InUncomposedDoc,
|
||||
!mContent->IsInComposedDoc());
|
||||
MOZ_ASSERT_IF(mContent && !mContent->IsInComposedDoc(),
|
||||
mReason == WSType::InUncomposedDoc);
|
||||
MOZ_ASSERT_IF(mReason == WSType::NonCollapsibleCharacters ||
|
||||
mReason == WSType::CollapsibleWhiteSpaces ||
|
||||
mReason == WSType::PreformattedLineBreak,
|
||||
mContent->IsText());
|
||||
MOZ_ASSERT_IF(mReason == WSType::NonCollapsibleCharacters ||
|
||||
mReason == WSType::CollapsibleWhiteSpaces ||
|
||||
mReason == WSType::PreformattedLineBreak,
|
||||
mOffset.isSome());
|
||||
MOZ_ASSERT_IF(mReason == WSType::NonCollapsibleCharacters ||
|
||||
mReason == WSType::CollapsibleWhiteSpaces ||
|
||||
mReason == WSType::PreformattedLineBreak,
|
||||
mContent->AsText()->TextDataLength() > 0);
|
||||
MOZ_ASSERT_IF(mDirection == ScanDirection::Backward &&
|
||||
(mReason == WSType::NonCollapsibleCharacters ||
|
||||
mReason == WSType::CollapsibleWhiteSpaces ||
|
||||
mReason == WSType::PreformattedLineBreak),
|
||||
*mOffset > 0);
|
||||
MOZ_ASSERT_IF(mDirection == ScanDirection::Forward &&
|
||||
(mReason == WSType::NonCollapsibleCharacters ||
|
||||
mReason == WSType::CollapsibleWhiteSpaces ||
|
||||
mReason == WSType::PreformattedLineBreak),
|
||||
*mOffset < mContent->AsText()->TextDataLength());
|
||||
MOZ_ASSERT_IF(mReason == WSType::BRElement,
|
||||
mContent->IsHTMLElement(nsGkAtoms::br));
|
||||
MOZ_ASSERT_IF(mReason == WSType::PreformattedLineBreak,
|
||||
EditorUtils::IsNewLinePreformatted(*mContent));
|
||||
MOZ_ASSERT_IF(
|
||||
mReason == WSType::SpecialContent,
|
||||
(mContent->IsText() && !mContent->IsEditable()) ||
|
||||
(!mContent->IsHTMLElement(nsGkAtoms::br) &&
|
||||
!HTMLEditUtils::IsBlockElement(*mContent, aBlockInlineCheck)));
|
||||
MOZ_ASSERT_IF(mReason == WSType::OtherBlockBoundary,
|
||||
HTMLEditUtils::IsBlockElement(*mContent, aBlockInlineCheck));
|
||||
MOZ_ASSERT_IF(mReason == WSType::CurrentBlockBoundary,
|
||||
mContent->IsElement());
|
||||
MOZ_ASSERT_IF(mReason == WSType::CurrentBlockBoundary,
|
||||
mContent->IsEditable());
|
||||
MOZ_ASSERT_IF(mReason == WSType::CurrentBlockBoundary,
|
||||
HTMLEditUtils::IsBlockElement(*mContent, aBlockInlineCheck));
|
||||
MOZ_ASSERT_IF(mReason == WSType::InlineEditingHostBoundary,
|
||||
mContent->IsElement());
|
||||
MOZ_ASSERT_IF(mReason == WSType::InlineEditingHostBoundary,
|
||||
mContent->IsEditable());
|
||||
MOZ_ASSERT_IF(mReason == WSType::InlineEditingHostBoundary,
|
||||
!HTMLEditUtils::IsBlockElement(*mContent, aBlockInlineCheck));
|
||||
MOZ_ASSERT_IF(mReason == WSType::InlineEditingHostBoundary,
|
||||
!mContent->GetParentElement() ||
|
||||
!mContent->GetParentElement()->IsEditable());
|
||||
#endif // #ifdef DEBUG
|
||||
}
|
||||
|
||||
bool Failed() const {
|
||||
return mReason == WSType::NotInitialized ||
|
||||
@@ -167,11 +238,6 @@ class MOZ_STACK_CLASS WSScanResult final {
|
||||
*/
|
||||
bool IsContentEditable() const { return mContent && mContent->IsEditable(); }
|
||||
|
||||
[[nodiscard]] bool IsContentEditableRoot() const {
|
||||
return mContent && mContent->IsElement() &&
|
||||
HTMLEditUtils::ElementIsEditableRoot(*mContent->AsElement());
|
||||
}
|
||||
|
||||
/**
|
||||
* Offset_Deprecated() returns meaningful value only when
|
||||
* InVisibleOrCollapsibleCharacters() returns true or the scanner reached to
|
||||
@@ -369,14 +435,14 @@ class MOZ_STACK_CLASS WSRunScanner final {
|
||||
}
|
||||
|
||||
template <typename EditorDOMPointType>
|
||||
WSRunScanner(Scan aScanMode, const EditorDOMPointType& aScanStartPoint,
|
||||
BlockInlineCheck aBlockInlineCheck,
|
||||
const Element* aAncestorLimiter = nullptr)
|
||||
WSRunScanner(const Element* aEditingHost,
|
||||
const EditorDOMPointType& aScanStartPoint,
|
||||
BlockInlineCheck aBlockInlineCheck)
|
||||
: mScanStartPoint(aScanStartPoint.template To<EditorDOMPoint>()),
|
||||
mTextFragmentDataAtStart(aScanMode, mScanStartPoint, aBlockInlineCheck,
|
||||
aAncestorLimiter),
|
||||
mBlockInlineCheck(aBlockInlineCheck),
|
||||
mScanMode(aScanMode) {}
|
||||
mEditingHost(const_cast<Element*>(aEditingHost)),
|
||||
mTextFragmentDataAtStart(Scan::EditableNodes, mScanStartPoint,
|
||||
aBlockInlineCheck),
|
||||
mBlockInlineCheck(aBlockInlineCheck) {}
|
||||
|
||||
// ScanInclusiveNextVisibleNodeOrBlockBoundaryFrom() returns the first visible
|
||||
// node at or after aPoint. If there is no visible nodes after aPoint,
|
||||
@@ -389,10 +455,9 @@ class MOZ_STACK_CLASS WSRunScanner final {
|
||||
const EditorDOMPointBase<PT, CT>& aPoint) const;
|
||||
template <typename PT, typename CT>
|
||||
static WSScanResult ScanInclusiveNextVisibleNodeOrBlockBoundary(
|
||||
Scan aScanMode, const EditorDOMPointBase<PT, CT>& aPoint,
|
||||
BlockInlineCheck aBlockInlineCheck,
|
||||
const Element* aAncestorLimiter = nullptr) {
|
||||
return WSRunScanner(aScanMode, aPoint, aBlockInlineCheck, aAncestorLimiter)
|
||||
const Element* aEditingHost, const EditorDOMPointBase<PT, CT>& aPoint,
|
||||
BlockInlineCheck aBlockInlineCheck) {
|
||||
return WSRunScanner(aEditingHost, aPoint, aBlockInlineCheck)
|
||||
.ScanInclusiveNextVisibleNodeOrBlockBoundaryFrom(aPoint);
|
||||
}
|
||||
|
||||
@@ -407,50 +472,49 @@ class MOZ_STACK_CLASS WSRunScanner final {
|
||||
const EditorDOMPointBase<PT, CT>& aPoint) const;
|
||||
template <typename PT, typename CT>
|
||||
static WSScanResult ScanPreviousVisibleNodeOrBlockBoundary(
|
||||
Scan aScanMode, const EditorDOMPointBase<PT, CT>& aPoint,
|
||||
BlockInlineCheck aBlockInlineCheck,
|
||||
const Element* aAncestorLimiter = nullptr) {
|
||||
return WSRunScanner(aScanMode, aPoint, aBlockInlineCheck, aAncestorLimiter)
|
||||
const Element* aEditingHost, const EditorDOMPointBase<PT, CT>& aPoint,
|
||||
BlockInlineCheck aBlockInlineCheck) {
|
||||
return WSRunScanner(aEditingHost, aPoint, aBlockInlineCheck)
|
||||
.ScanPreviousVisibleNodeOrBlockBoundaryFrom(aPoint);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a point in a `Text` node which is at current character or next
|
||||
* character if aPoint does not points a character or end of a `Text` node.
|
||||
* GetInclusiveNextEditableCharPoint() returns a point in a text node which
|
||||
* is at current editable character or next editable character if aPoint
|
||||
* does not points an editable character.
|
||||
*/
|
||||
template <typename EditorDOMPointType, typename PT, typename CT>
|
||||
static EditorDOMPointType GetInclusiveNextCharPoint(
|
||||
Scan aScanMode, const EditorDOMPointBase<PT, CT>& aPoint,
|
||||
BlockInlineCheck aBlockInlineCheck,
|
||||
const Element* aAncestorLimiter = nullptr) {
|
||||
template <typename EditorDOMPointType = EditorDOMPointInText, typename PT,
|
||||
typename CT>
|
||||
static EditorDOMPointType GetInclusiveNextEditableCharPoint(
|
||||
Element* aEditingHost, const EditorDOMPointBase<PT, CT>& aPoint,
|
||||
BlockInlineCheck aBlockInlineCheck) {
|
||||
if (aPoint.IsInTextNode() && !aPoint.IsEndOfContainer() &&
|
||||
(aScanMode != Scan::EditableNodes ||
|
||||
HTMLEditUtils::IsSimplyEditableNode(
|
||||
*aPoint.template ContainerAs<Text>()))) {
|
||||
HTMLEditUtils::IsSimplyEditableNode(
|
||||
*aPoint.template ContainerAs<Text>())) {
|
||||
return EditorDOMPointType(aPoint.template ContainerAs<Text>(),
|
||||
aPoint.Offset());
|
||||
}
|
||||
return WSRunScanner(aScanMode, aPoint, aBlockInlineCheck, aAncestorLimiter)
|
||||
.GetInclusiveNextCharPoint<EditorDOMPointType>(aPoint);
|
||||
return WSRunScanner(aEditingHost, aPoint, aBlockInlineCheck)
|
||||
.GetInclusiveNextEditableCharPoint<EditorDOMPointType>(aPoint);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a point in a `Text` node which is before aPoint.
|
||||
* GetPreviousEditableCharPoint() returns a point in a text node which
|
||||
* is at previous editable character.
|
||||
*/
|
||||
template <typename EditorDOMPointType, typename PT, typename CT>
|
||||
static EditorDOMPointType GetPreviousCharPoint(
|
||||
Scan aScanMode, const EditorDOMPointBase<PT, CT>& aPoint,
|
||||
BlockInlineCheck aBlockInlineCheck,
|
||||
const Element* aAncestorLimiter = nullptr) {
|
||||
template <typename EditorDOMPointType = EditorDOMPointInText, typename PT,
|
||||
typename CT>
|
||||
static EditorDOMPointType GetPreviousEditableCharPoint(
|
||||
Element* aEditingHost, const EditorDOMPointBase<PT, CT>& aPoint,
|
||||
BlockInlineCheck aBlockInlineCheck) {
|
||||
if (aPoint.IsInTextNode() && !aPoint.IsStartOfContainer() &&
|
||||
(aScanMode != Scan::EditableNodes ||
|
||||
HTMLEditUtils::IsSimplyEditableNode(
|
||||
*aPoint.template ContainerAs<Text>()))) {
|
||||
HTMLEditUtils::IsSimplyEditableNode(
|
||||
*aPoint.template ContainerAs<Text>())) {
|
||||
return EditorDOMPointType(aPoint.template ContainerAs<Text>(),
|
||||
aPoint.Offset() - 1);
|
||||
}
|
||||
return WSRunScanner(aScanMode, aPoint, aBlockInlineCheck, aAncestorLimiter)
|
||||
.GetPreviousCharPoint<EditorDOMPointType>(aPoint);
|
||||
return WSRunScanner(aEditingHost, aPoint, aBlockInlineCheck)
|
||||
.GetPreviousEditableCharPoint<EditorDOMPointType>(aPoint);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -462,31 +526,23 @@ class MOZ_STACK_CLASS WSRunScanner final {
|
||||
* only invisible white-spaces and there is previous or next text node.
|
||||
*/
|
||||
template <typename EditorDOMPointType>
|
||||
static EditorDOMPointType GetAfterLastVisiblePoint(
|
||||
Scan aScanMode, Text& aTextNode,
|
||||
const Element* aAncestorLimiter = nullptr);
|
||||
static EditorDOMPointType GetAfterLastVisiblePoint(Text& aTextNode);
|
||||
template <typename EditorDOMPointType>
|
||||
static EditorDOMPointType GetFirstVisiblePoint(
|
||||
Scan aScanMode, Text& aTextNode,
|
||||
const Element* aAncestorLimiter = nullptr);
|
||||
static EditorDOMPointType GetFirstVisiblePoint(Text& aTextNode);
|
||||
|
||||
/**
|
||||
* GetRangeInTextNodesToForwardDeleteFrom() returns the range to remove
|
||||
* text when caret is at aPoint.
|
||||
*/
|
||||
static Result<EditorDOMRangeInTexts, nsresult>
|
||||
GetRangeInTextNodesToForwardDeleteFrom(
|
||||
Scan aScanMode, const EditorDOMPoint& aPoint,
|
||||
const Element* aAncestorLimiter = nullptr);
|
||||
GetRangeInTextNodesToForwardDeleteFrom(const EditorDOMPoint& aPoint);
|
||||
|
||||
/**
|
||||
* GetRangeInTextNodesToBackspaceFrom() returns the range to remove text
|
||||
* when caret is at aPoint.
|
||||
*/
|
||||
static Result<EditorDOMRangeInTexts, nsresult>
|
||||
GetRangeInTextNodesToBackspaceFrom(Scan aScanMode,
|
||||
const EditorDOMPoint& aPoint,
|
||||
const Element* aAncestorLimiter = nullptr);
|
||||
GetRangeInTextNodesToBackspaceFrom(const EditorDOMPoint& aPoint);
|
||||
|
||||
/**
|
||||
* GetRangesForDeletingAtomicContent() returns the range to delete
|
||||
@@ -494,14 +550,14 @@ class MOZ_STACK_CLASS WSRunScanner final {
|
||||
* be included into the range.
|
||||
*/
|
||||
static EditorDOMRange GetRangesForDeletingAtomicContent(
|
||||
Scan aScanMode, const nsIContent& aAtomicContent,
|
||||
const Element* aAncestorLimiter = nullptr);
|
||||
const nsIContent& aAtomicContent);
|
||||
|
||||
/**
|
||||
* GetRangeForDeleteBlockElementBoundaries() returns a range starting from end
|
||||
* of aLeftBlockElement to start of aRightBlockElement and extend invisible
|
||||
* white-spaces around them.
|
||||
*
|
||||
* @param aHTMLEditor The HTML editor.
|
||||
* @param aLeftBlockElement The block element which will be joined with
|
||||
* aRightBlockElement.
|
||||
* @param aRightBlockElement The block element which will be joined with
|
||||
@@ -517,10 +573,9 @@ class MOZ_STACK_CLASS WSRunScanner final {
|
||||
* Otherwise, must not be set.
|
||||
*/
|
||||
static EditorDOMRange GetRangeForDeletingBlockElementBoundaries(
|
||||
Scan aScanMode, const Element& aLeftBlockElement,
|
||||
const HTMLEditor& aHTMLEditor, const Element& aLeftBlockElement,
|
||||
const Element& aRightBlockElement,
|
||||
const EditorDOMPoint& aPointContainingTheOtherBlock,
|
||||
const Element* aAncestorLimiter = nullptr);
|
||||
const EditorDOMPoint& aPointContainingTheOtherBlock);
|
||||
|
||||
/**
|
||||
* ShrinkRangeIfStartsFromOrEndsAfterAtomicContent() may shrink aRange if it
|
||||
@@ -528,16 +583,14 @@ class MOZ_STACK_CLASS WSRunScanner final {
|
||||
* is in adjacent text nodes. Returns true if this modifies the range.
|
||||
*/
|
||||
static Result<bool, nsresult> ShrinkRangeIfStartsFromOrEndsAfterAtomicContent(
|
||||
Scan aScanMode, nsRange& aRange,
|
||||
const Element* aAncestorLimiter = nullptr);
|
||||
const HTMLEditor& aHTMLEditor, nsRange& aRange);
|
||||
|
||||
/**
|
||||
* GetRangeContainingInvisibleWhiteSpacesAtRangeBoundaries() returns
|
||||
* extended range if range boundaries of aRange are in invisible white-spaces.
|
||||
*/
|
||||
static EditorDOMRange GetRangeContainingInvisibleWhiteSpacesAtRangeBoundaries(
|
||||
Scan aScanMode, const EditorDOMRange& aRange,
|
||||
const Element* aAncestorLimiter = nullptr);
|
||||
const EditorDOMRange& aRange);
|
||||
|
||||
/**
|
||||
* GetPrecedingBRElementUnlessVisibleContentFound() scans a `<br>` element
|
||||
@@ -548,9 +601,8 @@ class MOZ_STACK_CLASS WSRunScanner final {
|
||||
template <typename EditorDOMPointType>
|
||||
MOZ_NEVER_INLINE_DEBUG static HTMLBRElement*
|
||||
GetPrecedingBRElementUnlessVisibleContentFound(
|
||||
Scan aScanMode, const EditorDOMPointType& aPoint,
|
||||
BlockInlineCheck aBlockInlineCheck,
|
||||
const Element* aAncestorLimiter = nullptr) {
|
||||
const Element* aEditingHost, const EditorDOMPointType& aPoint,
|
||||
BlockInlineCheck aBlockInlineCheck) {
|
||||
MOZ_ASSERT(aPoint.IsSetAndValid());
|
||||
// XXX This method behaves differently even in similar point.
|
||||
// If aPoint is in a text node following `<br>` element, reaches the
|
||||
@@ -564,8 +616,8 @@ class MOZ_STACK_CLASS WSRunScanner final {
|
||||
}
|
||||
// TODO: Scan for end boundary is redundant in this case, we should optimize
|
||||
// it.
|
||||
TextFragmentData textFragmentData(aScanMode, aPoint, aBlockInlineCheck,
|
||||
aAncestorLimiter);
|
||||
TextFragmentData textFragmentData(Scan::EditableNodes, aPoint,
|
||||
aBlockInlineCheck, aEditingHost);
|
||||
return textFragmentData.StartsFromBRElement()
|
||||
? textFragmentData.StartReasonBRElementPtr()
|
||||
: nullptr;
|
||||
@@ -667,6 +719,11 @@ class MOZ_STACK_CLASS WSRunScanner final {
|
||||
return TextFragmentDataAtStartRef().EndReasonBRElementPtr();
|
||||
}
|
||||
|
||||
/**
|
||||
* Active editing host when this instance is created.
|
||||
*/
|
||||
Element* GetEditingHost() const { return mEditingHost; }
|
||||
|
||||
protected:
|
||||
using EditorType = EditorBase::EditorType;
|
||||
|
||||
@@ -788,32 +845,34 @@ class MOZ_STACK_CLASS WSRunScanner final {
|
||||
using PointPosition = VisibleWhiteSpacesData::PointPosition;
|
||||
|
||||
/**
|
||||
* Return aPoint if it points a character in a `Text` node, or start of next
|
||||
* `Text` node otherwise.
|
||||
* FYI: For the performance, this does not check whether given container is
|
||||
* not after mStart.mReasonContent or not.
|
||||
* GetInclusiveNextEditableCharPoint() returns aPoint if it points a character
|
||||
* in an editable text node, or start of next editable text node otherwise.
|
||||
* FYI: For the performance, this does not check whether given container
|
||||
* is not after mStart.mReasonContent or not.
|
||||
*/
|
||||
template <typename EditorDOMPointType, typename PT, typename CT>
|
||||
EditorDOMPointType GetInclusiveNextCharPoint(
|
||||
template <typename EditorDOMPointType = EditorDOMPointInText, typename PT,
|
||||
typename CT>
|
||||
EditorDOMPointType GetInclusiveNextEditableCharPoint(
|
||||
const EditorDOMPointBase<PT, CT>& aPoint) const {
|
||||
return TextFragmentDataAtStartRef()
|
||||
.GetInclusiveNextCharPoint<EditorDOMPointType>(
|
||||
aPoint, ShouldIgnoreNonEditableSiblingsOrDescendants(mScanMode));
|
||||
aPoint, IgnoreNonEditableNodes::Yes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the previous editable point in a `Text` node. Note that this
|
||||
* returns the last character point when it meets non-empty text node,
|
||||
* otherwise, returns a point in an empty text node.
|
||||
* FYI: For the performance, this does not check whether given container is
|
||||
* not before mEnd.mReasonContent or not.
|
||||
* GetPreviousEditableCharPoint() returns previous editable point in a
|
||||
* text node. Note that this returns last character point when it meets
|
||||
* non-empty text node, otherwise, returns a point in an empty text node.
|
||||
* FYI: For the performance, this does not check whether given container
|
||||
* is not before mEnd.mReasonContent or not.
|
||||
*/
|
||||
template <typename EditorDOMPointType, typename PT, typename CT>
|
||||
EditorDOMPointType GetPreviousCharPoint(
|
||||
template <typename EditorDOMPointType = EditorDOMPointInText, typename PT,
|
||||
typename CT>
|
||||
EditorDOMPointType GetPreviousEditableCharPoint(
|
||||
const EditorDOMPointBase<PT, CT>& aPoint) const {
|
||||
return TextFragmentDataAtStartRef()
|
||||
.GetPreviousCharPoint<EditorDOMPointType>(
|
||||
aPoint, ShouldIgnoreNonEditableSiblingsOrDescendants(mScanMode));
|
||||
.GetPreviousCharPoint<EditorDOMPointType>(aPoint,
|
||||
IgnoreNonEditableNodes::Yes);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -823,7 +882,7 @@ class MOZ_STACK_CLASS WSRunScanner final {
|
||||
* Note that this may return different text node from the container of
|
||||
* aPointAtASCIIWhiteSpace.
|
||||
*/
|
||||
template <typename EditorDOMPointType>
|
||||
template <typename EditorDOMPointType = EditorDOMPointInText>
|
||||
EditorDOMPointType GetEndOfCollapsibleASCIIWhiteSpaces(
|
||||
const EditorDOMPointInText& aPointAtASCIIWhiteSpace,
|
||||
nsIEditor::EDirection aDirectionToDelete) const {
|
||||
@@ -843,7 +902,7 @@ class MOZ_STACK_CLASS WSRunScanner final {
|
||||
* Note that this may return different text node from the container of
|
||||
* aPointAtASCIIWhiteSpace.
|
||||
*/
|
||||
template <typename EditorDOMPointType>
|
||||
template <typename EditorDOMPointType = EditorDOMPointInText>
|
||||
EditorDOMPointType GetFirstASCIIWhiteSpacePointCollapsedTo(
|
||||
const EditorDOMPointInText& aPointAtASCIIWhiteSpace,
|
||||
nsIEditor::EDirection aDirectionToDelete) const {
|
||||
@@ -855,6 +914,11 @@ class MOZ_STACK_CLASS WSRunScanner final {
|
||||
aPointAtASCIIWhiteSpace, aDirectionToDelete);
|
||||
}
|
||||
|
||||
EditorDOMPointInText GetPreviousCharPointFromPointInText(
|
||||
const EditorDOMPointInText& aPoint) const;
|
||||
|
||||
char16_t GetCharAt(Text* aTextNode, uint32_t aOffset) const;
|
||||
|
||||
/**
|
||||
* TextFragmentData stores the information of white-space sequence which
|
||||
* contains `aPoint` of the constructor.
|
||||
@@ -879,8 +943,8 @@ class MOZ_STACK_CLASS WSRunScanner final {
|
||||
*/
|
||||
template <typename EditorDOMPointType>
|
||||
static BoundaryData ScanCollapsibleWhiteSpaceStartFrom(
|
||||
Scan aScanMode, const EditorDOMPointType& aPoint,
|
||||
NoBreakingSpaceData* aNBSPData, BlockInlineCheck aBlockInlineCheck,
|
||||
const EditorDOMPointType& aPoint, NoBreakingSpaceData* aNBSPData,
|
||||
BlockInlineCheck aBlockInlineCheck,
|
||||
StopAtNonEditableNode aStopAtNonEditableNode,
|
||||
const Element& aAncestorLimiter);
|
||||
|
||||
@@ -896,8 +960,8 @@ class MOZ_STACK_CLASS WSRunScanner final {
|
||||
*/
|
||||
template <typename EditorDOMPointType>
|
||||
static BoundaryData ScanCollapsibleWhiteSpaceEndFrom(
|
||||
Scan aScanMode, const EditorDOMPointType& aPoint,
|
||||
NoBreakingSpaceData* aNBSPData, BlockInlineCheck aBlockInlineCheck,
|
||||
const EditorDOMPointType& aPoint, NoBreakingSpaceData* aNBSPData,
|
||||
BlockInlineCheck aBlockInlineCheck,
|
||||
StopAtNonEditableNode aStopAtNonEditableNode,
|
||||
const Element& aAncestorLimiter);
|
||||
|
||||
@@ -1021,8 +1085,6 @@ class MOZ_STACK_CLASS WSRunScanner final {
|
||||
return mStart.Initialized() && mEnd.Initialized();
|
||||
}
|
||||
|
||||
constexpr Scan ScanMode() const { return mScanMode; }
|
||||
|
||||
nsIContent* GetStartReasonContent() const {
|
||||
return mStart.GetReasonContent();
|
||||
}
|
||||
@@ -1462,6 +1524,9 @@ class MOZ_STACK_CLASS WSRunScanner final {
|
||||
// Together, the above represent the point at which we are building up ws
|
||||
// info.
|
||||
|
||||
// The editing host when the instance is created.
|
||||
RefPtr<Element> mEditingHost;
|
||||
|
||||
private:
|
||||
/**
|
||||
* ComputeRangeInTextNodesContainingInvisibleWhiteSpaces() returns range
|
||||
@@ -1480,10 +1545,8 @@ class MOZ_STACK_CLASS WSRunScanner final {
|
||||
TextFragmentData mTextFragmentDataAtStart;
|
||||
|
||||
const BlockInlineCheck mBlockInlineCheck;
|
||||
const Scan mScanMode;
|
||||
|
||||
friend class WhiteSpaceVisibilityKeeper;
|
||||
friend class WSScanResult;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
@@ -147,7 +147,7 @@ WSRunScanner::TextFragmentData::TextFragmentData(
|
||||
return;
|
||||
}
|
||||
mStart = BoundaryData::ScanCollapsibleWhiteSpaceStartFrom(
|
||||
aScanMode, mScanStartPoint, &mNBSPData, aBlockInlineCheck,
|
||||
mScanStartPoint, &mNBSPData, aBlockInlineCheck,
|
||||
ShouldStopAtNonEditableNode(aScanMode),
|
||||
*editableBlockElementOrInlineEditingHostOrNonEditableRootElement);
|
||||
MOZ_ASSERT_IF(mStart.IsNonCollapsibleCharacters(),
|
||||
@@ -155,7 +155,7 @@ WSRunScanner::TextFragmentData::TextFragmentData(
|
||||
MOZ_ASSERT_IF(mStart.IsPreformattedLineBreak(),
|
||||
mStart.PointRef().IsPreviousCharPreformattedNewLine());
|
||||
mEnd = BoundaryData::ScanCollapsibleWhiteSpaceEndFrom(
|
||||
aScanMode, mScanStartPoint, &mNBSPData, aBlockInlineCheck,
|
||||
mScanStartPoint, &mNBSPData, aBlockInlineCheck,
|
||||
ShouldStopAtNonEditableNode(aScanMode),
|
||||
*editableBlockElementOrInlineEditingHostOrNonEditableRootElement);
|
||||
MOZ_ASSERT_IF(mEnd.IsNonCollapsibleCharacters(),
|
||||
@@ -230,15 +230,13 @@ Maybe<WSRunScanner::TextFragmentData::BoundaryData> WSRunScanner::
|
||||
template <typename EditorDOMPointType>
|
||||
WSRunScanner::TextFragmentData::BoundaryData WSRunScanner::TextFragmentData::
|
||||
BoundaryData::ScanCollapsibleWhiteSpaceStartFrom(
|
||||
Scan aScanMode, const EditorDOMPointType& aPoint,
|
||||
NoBreakingSpaceData* aNBSPData, BlockInlineCheck aBlockInlineCheck,
|
||||
const EditorDOMPointType& aPoint, NoBreakingSpaceData* aNBSPData,
|
||||
BlockInlineCheck aBlockInlineCheck,
|
||||
StopAtNonEditableNode aStopAtNonEditableNode,
|
||||
const Element& aAncestorLimiter) {
|
||||
MOZ_ASSERT(aPoint.IsSetAndValid());
|
||||
MOZ_ASSERT_IF(aScanMode == Scan::EditableNodes,
|
||||
// FIXME: Both values should be true here.
|
||||
HTMLEditUtils::IsSimplyEditableNode(*aPoint.GetContainer()) ==
|
||||
HTMLEditUtils::IsSimplyEditableNode(aAncestorLimiter));
|
||||
MOZ_ASSERT(HTMLEditUtils::IsSimplyEditableNode(*aPoint.GetContainer()) ==
|
||||
HTMLEditUtils::IsSimplyEditableNode(aAncestorLimiter));
|
||||
|
||||
if (aPoint.IsInTextNode() && !aPoint.IsStartOfContainer()) {
|
||||
Maybe<BoundaryData> startInTextNode =
|
||||
@@ -250,8 +248,8 @@ WSRunScanner::TextFragmentData::BoundaryData WSRunScanner::TextFragmentData::
|
||||
// The text node does not have visible character, let's keep scanning
|
||||
// preceding nodes.
|
||||
return BoundaryData::ScanCollapsibleWhiteSpaceStartFrom(
|
||||
aScanMode, EditorDOMPoint(aPoint.template ContainerAs<Text>(), 0),
|
||||
aNBSPData, aBlockInlineCheck, aStopAtNonEditableNode, aAncestorLimiter);
|
||||
EditorDOMPoint(aPoint.template ContainerAs<Text>(), 0), aNBSPData,
|
||||
aBlockInlineCheck, aStopAtNonEditableNode, aAncestorLimiter);
|
||||
}
|
||||
|
||||
// Then, we need to check previous leaf node.
|
||||
@@ -294,7 +292,6 @@ WSRunScanner::TextFragmentData::BoundaryData WSRunScanner::TextFragmentData::
|
||||
// Note that even if the empty text node is preformatted, we should keep
|
||||
// looking for the previous one.
|
||||
return BoundaryData::ScanCollapsibleWhiteSpaceStartFrom(
|
||||
aScanMode,
|
||||
EditorDOMPointInText(previousLeafContentOrBlock->AsText(), 0),
|
||||
aNBSPData, aBlockInlineCheck, aStopAtNonEditableNode, aAncestorLimiter);
|
||||
}
|
||||
@@ -310,8 +307,8 @@ WSRunScanner::TextFragmentData::BoundaryData WSRunScanner::TextFragmentData::
|
||||
// The text node does not have visible character, let's keep scanning
|
||||
// preceding nodes.
|
||||
return BoundaryData::ScanCollapsibleWhiteSpaceStartFrom(
|
||||
aScanMode, EditorDOMPointInText(previousLeafContentOrBlock->AsText(), 0),
|
||||
aNBSPData, aBlockInlineCheck, aStopAtNonEditableNode, aAncestorLimiter);
|
||||
EditorDOMPointInText(previousLeafContentOrBlock->AsText(), 0), aNBSPData,
|
||||
aBlockInlineCheck, aStopAtNonEditableNode, aAncestorLimiter);
|
||||
}
|
||||
|
||||
// static
|
||||
@@ -378,15 +375,13 @@ Maybe<WSRunScanner::TextFragmentData::BoundaryData> WSRunScanner::
|
||||
template <typename EditorDOMPointType>
|
||||
WSRunScanner::TextFragmentData::BoundaryData
|
||||
WSRunScanner::TextFragmentData::BoundaryData::ScanCollapsibleWhiteSpaceEndFrom(
|
||||
Scan aScanMode, const EditorDOMPointType& aPoint,
|
||||
NoBreakingSpaceData* aNBSPData, BlockInlineCheck aBlockInlineCheck,
|
||||
const EditorDOMPointType& aPoint, NoBreakingSpaceData* aNBSPData,
|
||||
BlockInlineCheck aBlockInlineCheck,
|
||||
StopAtNonEditableNode aStopAtNonEditableNode,
|
||||
const Element& aAncestorLimiter) {
|
||||
MOZ_ASSERT(aPoint.IsSetAndValid());
|
||||
MOZ_ASSERT_IF(aScanMode == Scan::EditableNodes,
|
||||
// FIXME: Both values should be true here.
|
||||
HTMLEditUtils::IsSimplyEditableNode(*aPoint.GetContainer()) ==
|
||||
HTMLEditUtils::IsSimplyEditableNode(aAncestorLimiter));
|
||||
MOZ_ASSERT(HTMLEditUtils::IsSimplyEditableNode(*aPoint.GetContainer()) ==
|
||||
HTMLEditUtils::IsSimplyEditableNode(aAncestorLimiter));
|
||||
|
||||
if (aPoint.IsInTextNode() && !aPoint.IsEndOfContainer()) {
|
||||
Maybe<BoundaryData> endInTextNode =
|
||||
@@ -398,7 +393,6 @@ WSRunScanner::TextFragmentData::BoundaryData::ScanCollapsibleWhiteSpaceEndFrom(
|
||||
// The text node does not have visible character, let's keep scanning
|
||||
// following nodes.
|
||||
return BoundaryData::ScanCollapsibleWhiteSpaceEndFrom(
|
||||
aScanMode,
|
||||
EditorDOMPointInText::AtEndOf(*aPoint.template ContainerAs<Text>()),
|
||||
aNBSPData, aBlockInlineCheck, aStopAtNonEditableNode, aAncestorLimiter);
|
||||
}
|
||||
@@ -446,8 +440,8 @@ WSRunScanner::TextFragmentData::BoundaryData::ScanCollapsibleWhiteSpaceEndFrom(
|
||||
// Note that even if the empty text node is preformatted, we should keep
|
||||
// looking for the next one.
|
||||
return BoundaryData::ScanCollapsibleWhiteSpaceEndFrom(
|
||||
aScanMode, EditorDOMPointInText(nextLeafContentOrBlock->AsText(), 0),
|
||||
aNBSPData, aBlockInlineCheck, aStopAtNonEditableNode, aAncestorLimiter);
|
||||
EditorDOMPointInText(nextLeafContentOrBlock->AsText(), 0), aNBSPData,
|
||||
aBlockInlineCheck, aStopAtNonEditableNode, aAncestorLimiter);
|
||||
}
|
||||
|
||||
Maybe<BoundaryData> endInTextNode =
|
||||
@@ -461,7 +455,6 @@ WSRunScanner::TextFragmentData::BoundaryData::ScanCollapsibleWhiteSpaceEndFrom(
|
||||
// The text node does not have visible character, let's keep scanning
|
||||
// following nodes.
|
||||
return BoundaryData::ScanCollapsibleWhiteSpaceEndFrom(
|
||||
aScanMode,
|
||||
EditorDOMPointInText::AtEndOf(*nextLeafContentOrBlock->AsText()),
|
||||
aNBSPData, aBlockInlineCheck, aStopAtNonEditableNode, aAncestorLimiter);
|
||||
}
|
||||
|
||||
@@ -209,7 +209,7 @@ Result<MoveNodeResult, nsresult> WhiteSpaceVisibilityKeeper::
|
||||
// MoveNodeResult at last.
|
||||
const RefPtr<HTMLBRElement> invisibleBRElementAtEndOfLeftBlockElement =
|
||||
WSRunScanner::GetPrecedingBRElementUnlessVisibleContentFound(
|
||||
WSRunScanner::Scan::EditableNodes,
|
||||
aHTMLEditor.ComputeEditingHost(),
|
||||
EditorDOMPoint::AtEndOf(aLeftBlockElement),
|
||||
BlockInlineCheck::UseComputedDisplayStyle);
|
||||
NS_ASSERTION(
|
||||
@@ -434,7 +434,7 @@ Result<MoveNodeResult, nsresult> WhiteSpaceVisibilityKeeper::
|
||||
// MoveNodeResult at last.
|
||||
const RefPtr<HTMLBRElement> invisibleBRElementBeforeLeftBlockElement =
|
||||
WSRunScanner::GetPrecedingBRElementUnlessVisibleContentFound(
|
||||
WSRunScanner::Scan::EditableNodes, atLeftBlockChild,
|
||||
aHTMLEditor.ComputeEditingHost(), atLeftBlockChild,
|
||||
BlockInlineCheck::UseComputedDisplayStyle);
|
||||
NS_ASSERTION(
|
||||
aPrecedingInvisibleBRElement == invisibleBRElementBeforeLeftBlockElement,
|
||||
@@ -689,7 +689,7 @@ Result<MoveNodeResult, nsresult> WhiteSpaceVisibilityKeeper::
|
||||
// MoveNodeResult at last.
|
||||
const RefPtr<HTMLBRElement> invisibleBRElementAtEndOfLeftBlockElement =
|
||||
WSRunScanner::GetPrecedingBRElementUnlessVisibleContentFound(
|
||||
WSRunScanner::Scan::EditableNodes,
|
||||
aHTMLEditor.ComputeEditingHost(),
|
||||
EditorDOMPoint::AtEndOf(aLeftBlockElement),
|
||||
BlockInlineCheck::UseComputedDisplayStyle);
|
||||
NS_ASSERTION(
|
||||
|
||||
Reference in New Issue
Block a user