зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1720809 - part 2: Make `insertLineBreak` command handler in `HTMLEditor` insert a linefeed character instead of `<br>` element in same condition as Blink/WebKit r=m_kato
Similar to the previous patch, this patch makes `insertLineBreak` command handler of `HTMLEditor` may insert a linefeed character instead of `<br>` element for compatibility with Blink/WebKit. Note that for making same name rules as `insertParagraphSeparator` command handlers, this patch renames `HTMLEditor::InsertBRElementAtSelectionWithTransaction()` to `InsertLineBreakAsSubAction()` and moves `EditorBase::InsertLineBreakAsSubAction()` to `TextEditor` since it's used only by `TextEditor` instance. Depends on D124731 Differential Revision: https://phabricator.services.mozilla.com/D124732
This commit is contained in:
Родитель
2640b6cdc9
Коммит
153b43e7e2
|
@ -6026,52 +6026,7 @@ nsresult EditorBase::InsertTextAsSubAction(
|
|||
return result.Rv();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP EditorBase::InsertLineBreak() {
|
||||
AutoEditActionDataSetter editActionData(*this, EditAction::eInsertLineBreak);
|
||||
nsresult rv = editActionData.CanHandleAndMaybeDispatchBeforeInputEvent();
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING_ASSERTION(rv == NS_ERROR_EDITOR_ACTION_CANCELED,
|
||||
"CanHandleAndMaybeDispatchBeforeInputEvent() failed");
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
|
||||
if (NS_WARN_IF(IsSingleLineEditor())) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
AutoPlaceholderBatch treatAsOneTransaction(*this,
|
||||
ScrollSelectionIntoView::Yes);
|
||||
rv = InsertLineBreakAsSubAction();
|
||||
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
|
||||
"EditorBase::InsertLineBreakAsSubAction() failed");
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
|
||||
nsresult EditorBase::InsertLineBreakAsSubAction() {
|
||||
MOZ_ASSERT(IsEditActionDataAvailable());
|
||||
MOZ_ASSERT(IsTextEditor());
|
||||
|
||||
if (NS_WARN_IF(!mInitSucceeded)) {
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
IgnoredErrorResult ignoredError;
|
||||
AutoEditSubActionNotifier startToHandleEditSubAction(
|
||||
*this, EditSubAction::eInsertLineBreak, nsIEditor::eNext, ignoredError);
|
||||
if (NS_WARN_IF(ignoredError.ErrorCodeIs(NS_ERROR_EDITOR_DESTROYED))) {
|
||||
return ignoredError.StealNSResult();
|
||||
}
|
||||
NS_WARNING_ASSERTION(
|
||||
!ignoredError.Failed(),
|
||||
"TextEditor::OnStartToHandleTopLevelEditSubAction() failed, but ignored");
|
||||
|
||||
EditActionResult result =
|
||||
MOZ_KnownLive(AsTextEditor())->InsertLineFeedCharacterAtSelection();
|
||||
NS_WARNING_ASSERTION(
|
||||
result.Succeeded(),
|
||||
"TextEditor::InsertLineFeedCharacterAtSelection() failed, but ignored");
|
||||
return result.Rv();
|
||||
}
|
||||
NS_IMETHODIMP EditorBase::InsertLineBreak() { return NS_ERROR_NOT_IMPLEMENTED; }
|
||||
|
||||
/*****************************************************************************
|
||||
* mozilla::EditorBase::AutoEditActionDataSetter
|
||||
|
|
|
@ -2400,12 +2400,6 @@ class EditorBase : public nsIEditor,
|
|||
MOZ_CAN_RUN_SCRIPT void NotifyEditorObservers(
|
||||
NotificationForEditorObservers aNotification);
|
||||
|
||||
/**
|
||||
* InsertLineBreakAsSubAction() inserts a line break, i.e., \n if it's
|
||||
* TextEditor or <br> if it's HTMLEditor.
|
||||
*/
|
||||
[[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult InsertLineBreakAsSubAction();
|
||||
|
||||
/**
|
||||
* HowToHandleCollapsedRange indicates how collapsed range should be treated.
|
||||
*/
|
||||
|
|
|
@ -1308,6 +1308,136 @@ EditActionResult HTMLEditor::HandleInsertText(
|
|||
return EditActionHandled(rv);
|
||||
}
|
||||
|
||||
nsresult HTMLEditor::InsertLineBreakAsSubAction() {
|
||||
MOZ_ASSERT(IsEditActionDataAvailable());
|
||||
MOZ_ASSERT(!IsSelectionRangeContainerNotContent());
|
||||
|
||||
if (NS_WARN_IF(!mInitSucceeded)) {
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
EditActionResult result = CanHandleHTMLEditSubAction();
|
||||
if (result.Failed() || result.Canceled()) {
|
||||
NS_WARNING_ASSERTION(result.Succeeded(),
|
||||
"HTMLEditor::CanHandleHTMLEditSubAction() failed");
|
||||
return result.Rv();
|
||||
}
|
||||
|
||||
// XXX This may be called by execCommand() with "insertLineBreak".
|
||||
// In such case, naming the transaction "TypingTxnName" is odd.
|
||||
AutoPlaceholderBatch treatAsOneTransaction(*this, *nsGkAtoms::TypingTxnName,
|
||||
ScrollSelectionIntoView::Yes);
|
||||
|
||||
// calling it text insertion to trigger moz br treatment by rules
|
||||
// XXX Why do we use EditSubAction::eInsertText here? Looks like
|
||||
// EditSubAction::eInsertLineBreak or EditSubAction::eInsertNode
|
||||
// is better.
|
||||
IgnoredErrorResult ignoredError;
|
||||
AutoEditSubActionNotifier startToHandleEditSubAction(
|
||||
*this, EditSubAction::eInsertText, nsIEditor::eNext, ignoredError);
|
||||
if (NS_WARN_IF(ignoredError.ErrorCodeIs(NS_ERROR_EDITOR_DESTROYED))) {
|
||||
return ignoredError.StealNSResult();
|
||||
}
|
||||
NS_WARNING_ASSERTION(
|
||||
!ignoredError.Failed(),
|
||||
"HTMLEditor::OnStartToHandleTopLevelEditSubAction() failed, but ignored");
|
||||
|
||||
UndefineCaretBidiLevel();
|
||||
|
||||
// If the selection isn't collapsed, delete it.
|
||||
if (!SelectionRef().IsCollapsed()) {
|
||||
nsresult rv =
|
||||
DeleteSelectionAsSubAction(nsIEditor::eNone, nsIEditor::eStrip);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING(
|
||||
"EditorBase::DeleteSelectionAsSubAction(eNone, eStrip) failed");
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
const nsRange* firstRange = SelectionRef().GetRangeAt(0);
|
||||
if (NS_WARN_IF(!firstRange)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
EditorDOMPoint atStartOfSelection(firstRange->StartRef());
|
||||
if (NS_WARN_IF(!atStartOfSelection.IsSet())) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
MOZ_ASSERT(atStartOfSelection.IsSetAndValid());
|
||||
|
||||
RefPtr<Element> editingHost = GetActiveEditingHost();
|
||||
if (NS_WARN_IF(!editingHost)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// For backward compatibility, we should not insert a linefeed if
|
||||
// paragraph separator is set to "br" which is Gecko-specific mode.
|
||||
if (GetDefaultParagraphSeparator() == ParagraphSeparator::br ||
|
||||
!HTMLEditUtils::ShouldInsertLinefeedCharacter(atStartOfSelection,
|
||||
*editingHost)) {
|
||||
// InsertBRElementWithTransaction() will set selection after the new <br>
|
||||
// element.
|
||||
Result<RefPtr<Element>, nsresult> resultOfInsertingBRElement =
|
||||
InsertBRElementWithTransaction(atStartOfSelection, nsIEditor::eNext);
|
||||
if (resultOfInsertingBRElement.isErr()) {
|
||||
NS_WARNING("HTMLEditor::InsertBRElementWithTransaction() failed");
|
||||
return resultOfInsertingBRElement.unwrapErr();
|
||||
}
|
||||
MOZ_ASSERT(resultOfInsertingBRElement.inspect());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult rv = EnsureNoPaddingBRElementForEmptyEditor();
|
||||
if (NS_WARN_IF(rv == NS_ERROR_EDITOR_DESTROYED)) {
|
||||
return NS_ERROR_EDITOR_DESTROYED;
|
||||
}
|
||||
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
|
||||
"EditorBase::EnsureNoPaddingBRElementForEmptyEditor() "
|
||||
"failed, but ignored");
|
||||
|
||||
if (NS_SUCCEEDED(rv) && SelectionRef().IsCollapsed()) {
|
||||
nsresult rv = EnsureCaretNotAfterInvisibleBRElement();
|
||||
if (NS_WARN_IF(rv == NS_ERROR_EDITOR_DESTROYED)) {
|
||||
return NS_ERROR_EDITOR_DESTROYED;
|
||||
}
|
||||
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
|
||||
"HTMLEditor::EnsureCaretNotAfterInvisibleBRElement() "
|
||||
"failed, but ignored");
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsresult rv = PrepareInlineStylesForCaret();
|
||||
if (NS_WARN_IF(rv == NS_ERROR_EDITOR_DESTROYED)) {
|
||||
return NS_ERROR_EDITOR_DESTROYED;
|
||||
}
|
||||
NS_WARNING_ASSERTION(
|
||||
NS_SUCCEEDED(rv),
|
||||
"HTMLEditor::PrepareInlineStylesForCaret() failed, but ignored");
|
||||
}
|
||||
}
|
||||
|
||||
firstRange = SelectionRef().GetRangeAt(0);
|
||||
if (NS_WARN_IF(!firstRange)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
atStartOfSelection = EditorDOMPoint(firstRange->StartRef());
|
||||
if (NS_WARN_IF(!atStartOfSelection.IsSet())) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
MOZ_ASSERT(atStartOfSelection.IsSetAndValid());
|
||||
|
||||
// Do nothing if the node is read-only
|
||||
if (!HTMLEditUtils::IsSimplyEditableNode(
|
||||
*atStartOfSelection.GetContainer())) {
|
||||
return NS_SUCCESS_DOM_NO_OPERATION;
|
||||
}
|
||||
|
||||
rv = HandleInsertLinefeed(atStartOfSelection, *editingHost);
|
||||
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
|
||||
"HTMLEditor::HandleInsertLinefeed() failed");
|
||||
return rv;
|
||||
}
|
||||
|
||||
EditActionResult HTMLEditor::InsertParagraphSeparatorAsSubAction() {
|
||||
if (NS_WARN_IF(!mInitSucceeded)) {
|
||||
return EditActionIgnored(NS_ERROR_NOT_INITIALIZED);
|
||||
|
@ -1458,11 +1588,8 @@ EditActionResult HTMLEditor::InsertParagraphSeparatorAsSubAction() {
|
|||
insertLineBreak =
|
||||
separator == ParagraphSeparator::br ||
|
||||
!HTMLEditUtils::CanElementContainParagraph(*editingHost) ||
|
||||
(HTMLEditUtils::IsDisplayOutsideInline(*editingHost) &&
|
||||
EditorUtils::IsNewLinePreformatted(
|
||||
atStartOfSelection.IsInContentNode()
|
||||
? *atStartOfSelection.ContainerAsContent()
|
||||
: static_cast<nsIContent&>(*editingHost)));
|
||||
HTMLEditUtils::ShouldInsertLinefeedCharacter(atStartOfSelection,
|
||||
*editingHost);
|
||||
}
|
||||
// If the nearest block parent is a single-line container declared in
|
||||
// the execCommand spec and not the editing host, we should separate the
|
||||
|
@ -1488,17 +1615,10 @@ EditActionResult HTMLEditor::InsertParagraphSeparatorAsSubAction() {
|
|||
// a <br> element or a linefeed instead.
|
||||
if (insertLineBreak) {
|
||||
// For backward compatibility, we should not insert a linefeed if
|
||||
// paragraph separator is set to "br" which is Gecko-specific command.
|
||||
// paragraph separator is set to "br" which is Gecko-specific mode.
|
||||
if (separator != ParagraphSeparator::br &&
|
||||
// If and only if the nearest block is the editing host or its parent,
|
||||
(!editableBlockElement || editableBlockElement == editingHost) &&
|
||||
// and if the outside display value of the editing host is inline,
|
||||
HTMLEditUtils::IsDisplayOutsideInline(*editingHost) &&
|
||||
// and new line character is preformatted, we should insert a linefeed.
|
||||
EditorUtils::IsNewLinePreformatted(
|
||||
atStartOfSelection.IsInContentNode()
|
||||
? *atStartOfSelection.ContainerAsContent()
|
||||
: static_cast<nsIContent&>(*editingHost))) {
|
||||
HTMLEditUtils::ShouldInsertLinefeedCharacter(atStartOfSelection,
|
||||
*editingHost)) {
|
||||
nsresult rv = HandleInsertLinefeed(atStartOfSelection, *editingHost);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("HTMLEditor::HandleInsertLinefeed() failed");
|
||||
|
|
|
@ -676,6 +676,31 @@ bool HTMLEditUtils::IsEmptyNode(nsPresContext* aPresContext,
|
|||
return true;
|
||||
}
|
||||
|
||||
bool HTMLEditUtils::ShouldInsertLinefeedCharacter(
|
||||
EditorDOMPoint& aPointToInsert, const Element& aEditingHost) {
|
||||
MOZ_ASSERT(aPointToInsert.IsSetAndValid());
|
||||
|
||||
if (!aPointToInsert.IsInContentNode()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// closestEditableBlockElement can be nullptr if aEditingHost is an inline
|
||||
// element.
|
||||
Element* closestEditableBlockElement =
|
||||
HTMLEditUtils::GetInclusiveAncestorElement(
|
||||
*aPointToInsert.ContainerAsContent(),
|
||||
HTMLEditUtils::ClosestEditableBlockElement);
|
||||
|
||||
// If and only if the nearest block is the editing host or its parent,
|
||||
// and the outer display value of the editing host is inline, and new
|
||||
// line character is preformatted, we should insert a linefeed.
|
||||
return (!closestEditableBlockElement ||
|
||||
closestEditableBlockElement == &aEditingHost) &&
|
||||
HTMLEditUtils::IsDisplayOutsideInline(aEditingHost) &&
|
||||
EditorUtils::IsNewLinePreformatted(
|
||||
*aPointToInsert.ContainerAsContent());
|
||||
}
|
||||
|
||||
// We use bitmasks to test containment of elements. Elements are marked to be
|
||||
// in certain groups by setting the mGroup member of the `ElementInfo` struct
|
||||
// to the corresponding GROUP_ values (OR'ed together). Similarly, elements are
|
||||
|
|
|
@ -391,6 +391,13 @@ class HTMLEditUtils final {
|
|||
return !IsVisiblePreformattedNewLine(aPoint, aFollowingBlockElement);
|
||||
}
|
||||
|
||||
/**
|
||||
* ShouldInsertLinefeedCharacter() returns true if the caller should insert
|
||||
* a linefeed character instead of <br> element.
|
||||
*/
|
||||
static bool ShouldInsertLinefeedCharacter(EditorDOMPoint& aPointToInsert,
|
||||
const Element& aEditingHost);
|
||||
|
||||
/**
|
||||
* IsEmptyNode() returns false if aNode has some visible content nodes,
|
||||
* list elements or table elements.
|
||||
|
|
|
@ -1169,14 +1169,9 @@ nsresult HTMLEditor::InsertLineBreakAsAction(nsIPrincipal* aPrincipal) {
|
|||
return NS_SUCCESS_DOM_NO_OPERATION;
|
||||
}
|
||||
|
||||
// XXX This method may be called by "insertLineBreak" command. So, using
|
||||
// TypingTxnName here is odd in such case.
|
||||
AutoPlaceholderBatch treatAsOneTransaction(*this, *nsGkAtoms::TypingTxnName,
|
||||
ScrollSelectionIntoView::Yes);
|
||||
rv = InsertBRElementAtSelectionWithTransaction();
|
||||
NS_WARNING_ASSERTION(
|
||||
NS_SUCCEEDED(rv),
|
||||
"HTMLEditor::InsertBRElementAtSelectionWithTransaction() failed");
|
||||
rv = InsertLineBreakAsSubAction();
|
||||
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
|
||||
"HTMLEditor::InsertLineBreakAsSubAction() failed");
|
||||
// Don't return NS_SUCCESS_DOM_NO_OPERATION for compatibility of `execCommand`
|
||||
// result of Chrome.
|
||||
return NS_FAILED(rv) ? rv : NS_OK;
|
||||
|
@ -1318,50 +1313,6 @@ EditActionResult HTMLEditor::HandleTabKeyPressInTable(
|
|||
: NS_OK);
|
||||
}
|
||||
|
||||
nsresult HTMLEditor::InsertBRElementAtSelectionWithTransaction() {
|
||||
MOZ_ASSERT(IsEditActionDataAvailable());
|
||||
MOZ_ASSERT(!IsSelectionRangeContainerNotContent());
|
||||
|
||||
// calling it text insertion to trigger moz br treatment by rules
|
||||
// XXX Why do we use EditSubAction::eInsertText here? Looks like
|
||||
// EditSubAction::eInsertLineBreak or EditSubAction::eInsertNode
|
||||
// is better.
|
||||
IgnoredErrorResult ignoredError;
|
||||
AutoEditSubActionNotifier startToHandleEditSubAction(
|
||||
*this, EditSubAction::eInsertText, nsIEditor::eNext, ignoredError);
|
||||
if (NS_WARN_IF(ignoredError.ErrorCodeIs(NS_ERROR_EDITOR_DESTROYED))) {
|
||||
return ignoredError.StealNSResult();
|
||||
}
|
||||
NS_WARNING_ASSERTION(
|
||||
!ignoredError.Failed(),
|
||||
"HTMLEditor::OnStartToHandleTopLevelEditSubAction() failed, but ignored");
|
||||
|
||||
if (!SelectionRef().IsCollapsed()) {
|
||||
nsresult rv = DeleteSelectionAsSubAction(eNone, eStrip);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING(
|
||||
"EditorBase::DeleteSelectionAsSubAction(eNone, eStrip) failed");
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
EditorDOMPoint atStartOfSelection(EditorBase::GetStartPoint(SelectionRef()));
|
||||
if (NS_WARN_IF(!atStartOfSelection.IsSet())) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// InsertBRElementWithTransaction() will set selection after the new <br>
|
||||
// element.
|
||||
Result<RefPtr<Element>, nsresult> resultOfInsertingBRElement =
|
||||
InsertBRElementWithTransaction(atStartOfSelection, eNext);
|
||||
if (resultOfInsertingBRElement.isErr()) {
|
||||
NS_WARNING("HTMLEditor::InsertBRElementWithTransaction() failed");
|
||||
return resultOfInsertingBRElement.unwrapErr();
|
||||
}
|
||||
MOZ_ASSERT(resultOfInsertingBRElement.inspect());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void HTMLEditor::CollapseSelectionToDeepestNonTableFirstChild(nsINode* aNode) {
|
||||
MOZ_ASSERT(IsEditActionDataAvailable());
|
||||
|
||||
|
|
|
@ -1676,6 +1676,13 @@ class HTMLEditor final : public EditorBase,
|
|||
[[nodiscard]] MOZ_CAN_RUN_SCRIPT EditActionResult
|
||||
InsertParagraphSeparatorAsSubAction();
|
||||
|
||||
/**
|
||||
* InsertLineBreakAsSubAction() inserts a new <br> element or a linefeed
|
||||
* character at selection. If there is non-collapsed selection ranges, the
|
||||
* selected ranges is deleted first.
|
||||
*/
|
||||
[[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult InsertLineBreakAsSubAction();
|
||||
|
||||
/**
|
||||
* ChangeListElementType() replaces child list items of aListElement with
|
||||
* new list item element whose tag name is aNewListItemTag.
|
||||
|
@ -3289,13 +3296,6 @@ class HTMLEditor final : public EditorBase,
|
|||
nsIContent& aNode, const EditorDOMPoint& aPointToInsert,
|
||||
SplitAtEdges aSplitAtEdges);
|
||||
|
||||
/**
|
||||
* InsertBRElementAtSelectionWithTransaction() inserts a new <br> element at
|
||||
* selection. If there is non-collapsed selection ranges, the selected
|
||||
* ranges is deleted first.
|
||||
*/
|
||||
MOZ_CAN_RUN_SCRIPT nsresult InsertBRElementAtSelectionWithTransaction();
|
||||
|
||||
/**
|
||||
* InsertTextWithQuotationsInternal() replaces selection with new content.
|
||||
* First, this method splits aStringToInsert to multiple chunks which start
|
||||
|
|
|
@ -141,6 +141,30 @@ nsresult TextEditor::OnEndHandlingTopLevelEditSubAction() {
|
|||
return rv;
|
||||
}
|
||||
|
||||
nsresult TextEditor::InsertLineBreakAsSubAction() {
|
||||
MOZ_ASSERT(IsEditActionDataAvailable());
|
||||
|
||||
if (NS_WARN_IF(!mInitSucceeded)) {
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
IgnoredErrorResult ignoredError;
|
||||
AutoEditSubActionNotifier startToHandleEditSubAction(
|
||||
*this, EditSubAction::eInsertLineBreak, nsIEditor::eNext, ignoredError);
|
||||
if (NS_WARN_IF(ignoredError.ErrorCodeIs(NS_ERROR_EDITOR_DESTROYED))) {
|
||||
return ignoredError.StealNSResult();
|
||||
}
|
||||
NS_WARNING_ASSERTION(
|
||||
!ignoredError.Failed(),
|
||||
"TextEditor::OnStartToHandleTopLevelEditSubAction() failed, but ignored");
|
||||
|
||||
EditActionResult result = InsertLineFeedCharacterAtSelection();
|
||||
NS_WARNING_ASSERTION(
|
||||
result.Succeeded(),
|
||||
"TextEditor::InsertLineFeedCharacterAtSelection() failed, but ignored");
|
||||
return result.Rv();
|
||||
}
|
||||
|
||||
EditActionResult TextEditor::InsertLineFeedCharacterAtSelection() {
|
||||
MOZ_ASSERT(IsEditActionDataAvailable());
|
||||
MOZ_ASSERT(!IsSingleLineEditor());
|
||||
|
|
|
@ -269,6 +269,27 @@ nsresult TextEditor::HandleKeyPressEvent(WidgetKeyboardEvent* aKeyboardEvent) {
|
|||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP TextEditor::InsertLineBreak() {
|
||||
AutoEditActionDataSetter editActionData(*this, EditAction::eInsertLineBreak);
|
||||
nsresult rv = editActionData.CanHandleAndMaybeDispatchBeforeInputEvent();
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING_ASSERTION(rv == NS_ERROR_EDITOR_ACTION_CANCELED,
|
||||
"CanHandleAndMaybeDispatchBeforeInputEvent() failed");
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
|
||||
if (NS_WARN_IF(IsSingleLineEditor())) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
AutoPlaceholderBatch treatAsOneTransaction(*this,
|
||||
ScrollSelectionIntoView::Yes);
|
||||
rv = InsertLineBreakAsSubAction();
|
||||
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
|
||||
"TextEditor::InsertLineBreakAsSubAction() failed");
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
|
||||
nsresult TextEditor::InsertLineBreakAsAction(nsIPrincipal* aPrincipal) {
|
||||
AutoEditActionDataSetter editActionData(*this, EditAction::eInsertLineBreak,
|
||||
aPrincipal);
|
||||
|
|
|
@ -105,6 +105,7 @@ class TextEditor final : public EditorBase,
|
|||
NS_DECL_NSINAMED
|
||||
|
||||
// Overrides of nsIEditor
|
||||
MOZ_CAN_RUN_SCRIPT NS_IMETHOD InsertLineBreak() final;
|
||||
NS_IMETHOD GetTextLength(uint32_t* aCount) final;
|
||||
MOZ_CAN_RUN_SCRIPT NS_IMETHOD Paste(int32_t aClipboardType) final {
|
||||
const nsresult rv = TextEditor::PasteAsAction(aClipboardType, true);
|
||||
|
@ -263,6 +264,11 @@ class TextEditor final : public EditorBase,
|
|||
using EditorBase::RemoveAttributeOrEquivalent;
|
||||
using EditorBase::SetAttributeOrEquivalent;
|
||||
|
||||
/**
|
||||
* InsertLineBreakAsSubAction() inserts a line break.
|
||||
*/
|
||||
[[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult InsertLineBreakAsSubAction();
|
||||
|
||||
/**
|
||||
* Replace existed string with aString. Caller must guarantee that there
|
||||
* is a placeholder transaction which will have the transaction.
|
||||
|
|
|
@ -60,12 +60,10 @@ function test() {
|
|||
"insertLineBreak",
|
||||
"deleteContentBackward",
|
||||
"deleteContentBackward",
|
||||
], [
|
||||
// Blink does nothing in this case, but WebKit inserts `<br>` element.
|
||||
"insertLineBreak",
|
||||
"insertLineBreak",
|
||||
// XXX It's odd not to work with deleting the inserted `<br>` element.
|
||||
]]];
|
||||
],
|
||||
// Blink does nothing in this case, but WebKit inserts `<br>` element.
|
||||
[/* no input events for NOOP */]],
|
||||
];
|
||||
[
|
||||
["insertorderedlist", "insertOrderedList"],
|
||||
["insertunorderedlist", "insertUnorderedList"],
|
||||
|
|
|
@ -68,21 +68,9 @@
|
|||
[<div contenteditable><p style="display:block; white-space:pre-wrap">a[\]bc</p></div> (defaultparagraphseparator: div)]
|
||||
expected: FAIL
|
||||
|
||||
[<div contenteditable style="white-space:pre-wrap; display:inline">abc[\]</div> (defaultparagraphseparator: div)]
|
||||
expected: FAIL
|
||||
|
||||
[<div contenteditable style="white-space:pre-wrap; display:inline">[\]abc</div> (defaultparagraphseparator: div)]
|
||||
expected: FAIL
|
||||
|
||||
[<div contenteditable style="white-space:pre-wrap; display:inline">a[\]bc</div> (defaultparagraphseparator: div)]
|
||||
expected: FAIL
|
||||
|
||||
[<div contenteditable style="white-space:pre-wrap; display:inline">abc[\]</div> (defaultparagraphseparator: div) (preserving temporary inline style test)]
|
||||
expected: FAIL
|
||||
|
||||
[<div contenteditable style="white-space:pre-wrap; display:inline"><b>abc[\]</b></div> (defaultparagraphseparator: div) (preserving inline style test)]
|
||||
expected: FAIL
|
||||
|
||||
[<div contenteditable style="display:inline"><div style="white-space:pre-wrap">abc[\]</div></div> (defaultparagraphseparator: div)]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -137,21 +125,9 @@
|
|||
[<div contenteditable><p style="display:inline; white-space:pre-wrap">a[\]bc</p></div> (defaultparagraphseparator: div)]
|
||||
expected: FAIL
|
||||
|
||||
[<div contenteditable style="white-space:pre-wrap; display:inline-block">abc[\]</div> (defaultparagraphseparator: div)]
|
||||
expected: FAIL
|
||||
|
||||
[<div contenteditable style="white-space:pre-wrap; display:inline-block">[\]abc</div> (defaultparagraphseparator: div)]
|
||||
expected: FAIL
|
||||
|
||||
[<div contenteditable style="white-space:pre-wrap; display:inline-block">a[\]bc</div> (defaultparagraphseparator: div)]
|
||||
expected: FAIL
|
||||
|
||||
[<div contenteditable style="white-space:pre-wrap; display:inline-block">abc[\]</div> (defaultparagraphseparator: div) (preserving temporary inline style test)]
|
||||
expected: FAIL
|
||||
|
||||
[<div contenteditable style="white-space:pre-wrap; display:inline-block"><b>abc[\]</b></div> (defaultparagraphseparator: div) (preserving inline style test)]
|
||||
expected: FAIL
|
||||
|
||||
[<div contenteditable style="display:inline-block"><div style="white-space:pre-wrap">abc[\]</div></div> (defaultparagraphseparator: div)]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -275,21 +251,9 @@
|
|||
[<div contenteditable><p style="display:block; white-space:pre-wrap">a[\]bc</p></div> (defaultparagraphseparator: p)]
|
||||
expected: FAIL
|
||||
|
||||
[<div contenteditable style="white-space:pre-wrap; display:inline">abc[\]</div> (defaultparagraphseparator: p)]
|
||||
expected: FAIL
|
||||
|
||||
[<div contenteditable style="white-space:pre-wrap; display:inline">[\]abc</div> (defaultparagraphseparator: p)]
|
||||
expected: FAIL
|
||||
|
||||
[<div contenteditable style="white-space:pre-wrap; display:inline">a[\]bc</div> (defaultparagraphseparator: p)]
|
||||
expected: FAIL
|
||||
|
||||
[<div contenteditable style="white-space:pre-wrap; display:inline">abc[\]</div> (defaultparagraphseparator: p) (preserving temporary inline style test)]
|
||||
expected: FAIL
|
||||
|
||||
[<div contenteditable style="white-space:pre-wrap; display:inline"><b>abc[\]</b></div> (defaultparagraphseparator: p) (preserving inline style test)]
|
||||
expected: FAIL
|
||||
|
||||
[<div contenteditable style="display:inline"><div style="white-space:pre-wrap">abc[\]</div></div> (defaultparagraphseparator: p)]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -344,21 +308,9 @@
|
|||
[<div contenteditable><p style="display:inline; white-space:pre-wrap">a[\]bc</p></div> (defaultparagraphseparator: p)]
|
||||
expected: FAIL
|
||||
|
||||
[<div contenteditable style="white-space:pre-wrap; display:inline-block">abc[\]</div> (defaultparagraphseparator: p)]
|
||||
expected: FAIL
|
||||
|
||||
[<div contenteditable style="white-space:pre-wrap; display:inline-block">[\]abc</div> (defaultparagraphseparator: p)]
|
||||
expected: FAIL
|
||||
|
||||
[<div contenteditable style="white-space:pre-wrap; display:inline-block">a[\]bc</div> (defaultparagraphseparator: p)]
|
||||
expected: FAIL
|
||||
|
||||
[<div contenteditable style="white-space:pre-wrap; display:inline-block">abc[\]</div> (defaultparagraphseparator: p) (preserving temporary inline style test)]
|
||||
expected: FAIL
|
||||
|
||||
[<div contenteditable style="white-space:pre-wrap; display:inline-block"><b>abc[\]</b></div> (defaultparagraphseparator: p) (preserving inline style test)]
|
||||
expected: FAIL
|
||||
|
||||
[<div contenteditable style="display:inline-block"><div style="white-space:pre-wrap">abc[\]</div></div> (defaultparagraphseparator: p)]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -484,21 +436,9 @@
|
|||
[<div contenteditable><p style="display:block; white-space:pre">a[\]bc</p></div> (defaultparagraphseparator: div)]
|
||||
expected: FAIL
|
||||
|
||||
[<div contenteditable style="white-space:pre; display:inline">abc[\]</div> (defaultparagraphseparator: div)]
|
||||
expected: FAIL
|
||||
|
||||
[<div contenteditable style="white-space:pre; display:inline">[\]abc</div> (defaultparagraphseparator: div)]
|
||||
expected: FAIL
|
||||
|
||||
[<div contenteditable style="white-space:pre; display:inline">a[\]bc</div> (defaultparagraphseparator: div)]
|
||||
expected: FAIL
|
||||
|
||||
[<div contenteditable style="white-space:pre; display:inline">abc[\]</div> (defaultparagraphseparator: div) (preserving temporary inline style test)]
|
||||
expected: FAIL
|
||||
|
||||
[<div contenteditable style="white-space:pre; display:inline"><b>abc[\]</b></div> (defaultparagraphseparator: div) (preserving inline style test)]
|
||||
expected: FAIL
|
||||
|
||||
[<div contenteditable style="display:inline"><div style="white-space:pre">abc[\]</div></div> (defaultparagraphseparator: div)]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -553,21 +493,9 @@
|
|||
[<div contenteditable><p style="display:inline; white-space:pre">a[\]bc</p></div> (defaultparagraphseparator: div)]
|
||||
expected: FAIL
|
||||
|
||||
[<div contenteditable style="white-space:pre; display:inline-block">abc[\]</div> (defaultparagraphseparator: div)]
|
||||
expected: FAIL
|
||||
|
||||
[<div contenteditable style="white-space:pre; display:inline-block">[\]abc</div> (defaultparagraphseparator: div)]
|
||||
expected: FAIL
|
||||
|
||||
[<div contenteditable style="white-space:pre; display:inline-block">a[\]bc</div> (defaultparagraphseparator: div)]
|
||||
expected: FAIL
|
||||
|
||||
[<div contenteditable style="white-space:pre; display:inline-block">abc[\]</div> (defaultparagraphseparator: div) (preserving temporary inline style test)]
|
||||
expected: FAIL
|
||||
|
||||
[<div contenteditable style="white-space:pre; display:inline-block"><b>abc[\]</b></div> (defaultparagraphseparator: div) (preserving inline style test)]
|
||||
expected: FAIL
|
||||
|
||||
[<div contenteditable style="display:inline-block"><div style="white-space:pre">abc[\]</div></div> (defaultparagraphseparator: div)]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -691,21 +619,9 @@
|
|||
[<div contenteditable><p style="display:block; white-space:pre">a[\]bc</p></div> (defaultparagraphseparator: p)]
|
||||
expected: FAIL
|
||||
|
||||
[<div contenteditable style="white-space:pre; display:inline">abc[\]</div> (defaultparagraphseparator: p)]
|
||||
expected: FAIL
|
||||
|
||||
[<div contenteditable style="white-space:pre; display:inline">[\]abc</div> (defaultparagraphseparator: p)]
|
||||
expected: FAIL
|
||||
|
||||
[<div contenteditable style="white-space:pre; display:inline">a[\]bc</div> (defaultparagraphseparator: p)]
|
||||
expected: FAIL
|
||||
|
||||
[<div contenteditable style="white-space:pre; display:inline">abc[\]</div> (defaultparagraphseparator: p) (preserving temporary inline style test)]
|
||||
expected: FAIL
|
||||
|
||||
[<div contenteditable style="white-space:pre; display:inline"><b>abc[\]</b></div> (defaultparagraphseparator: p) (preserving inline style test)]
|
||||
expected: FAIL
|
||||
|
||||
[<div contenteditable style="display:inline"><div style="white-space:pre">abc[\]</div></div> (defaultparagraphseparator: p)]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -760,21 +676,9 @@
|
|||
[<div contenteditable><p style="display:inline; white-space:pre">a[\]bc</p></div> (defaultparagraphseparator: p)]
|
||||
expected: FAIL
|
||||
|
||||
[<div contenteditable style="white-space:pre; display:inline-block">abc[\]</div> (defaultparagraphseparator: p)]
|
||||
expected: FAIL
|
||||
|
||||
[<div contenteditable style="white-space:pre; display:inline-block">[\]abc</div> (defaultparagraphseparator: p)]
|
||||
expected: FAIL
|
||||
|
||||
[<div contenteditable style="white-space:pre; display:inline-block">a[\]bc</div> (defaultparagraphseparator: p)]
|
||||
expected: FAIL
|
||||
|
||||
[<div contenteditable style="white-space:pre; display:inline-block">abc[\]</div> (defaultparagraphseparator: p) (preserving temporary inline style test)]
|
||||
expected: FAIL
|
||||
|
||||
[<div contenteditable style="white-space:pre; display:inline-block"><b>abc[\]</b></div> (defaultparagraphseparator: p) (preserving inline style test)]
|
||||
expected: FAIL
|
||||
|
||||
[<div contenteditable style="display:inline-block"><div style="white-space:pre">abc[\]</div></div> (defaultparagraphseparator: p)]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -900,21 +804,9 @@
|
|||
[<div contenteditable><p style="display:block; white-space:pre-line">a[\]bc</p></div> (defaultparagraphseparator: div)]
|
||||
expected: FAIL
|
||||
|
||||
[<div contenteditable style="white-space:pre-line; display:inline">abc[\]</div> (defaultparagraphseparator: div)]
|
||||
expected: FAIL
|
||||
|
||||
[<div contenteditable style="white-space:pre-line; display:inline">[\]abc</div> (defaultparagraphseparator: div)]
|
||||
expected: FAIL
|
||||
|
||||
[<div contenteditable style="white-space:pre-line; display:inline">a[\]bc</div> (defaultparagraphseparator: div)]
|
||||
expected: FAIL
|
||||
|
||||
[<div contenteditable style="white-space:pre-line; display:inline">abc[\]</div> (defaultparagraphseparator: div) (preserving temporary inline style test)]
|
||||
expected: FAIL
|
||||
|
||||
[<div contenteditable style="white-space:pre-line; display:inline"><b>abc[\]</b></div> (defaultparagraphseparator: div) (preserving inline style test)]
|
||||
expected: FAIL
|
||||
|
||||
[<div contenteditable style="display:inline"><div style="white-space:pre-line">abc[\]</div></div> (defaultparagraphseparator: div)]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -969,21 +861,9 @@
|
|||
[<div contenteditable><p style="display:inline; white-space:pre-line">a[\]bc</p></div> (defaultparagraphseparator: div)]
|
||||
expected: FAIL
|
||||
|
||||
[<div contenteditable style="white-space:pre-line; display:inline-block">abc[\]</div> (defaultparagraphseparator: div)]
|
||||
expected: FAIL
|
||||
|
||||
[<div contenteditable style="white-space:pre-line; display:inline-block">[\]abc</div> (defaultparagraphseparator: div)]
|
||||
expected: FAIL
|
||||
|
||||
[<div contenteditable style="white-space:pre-line; display:inline-block">a[\]bc</div> (defaultparagraphseparator: div)]
|
||||
expected: FAIL
|
||||
|
||||
[<div contenteditable style="white-space:pre-line; display:inline-block">abc[\]</div> (defaultparagraphseparator: div) (preserving temporary inline style test)]
|
||||
expected: FAIL
|
||||
|
||||
[<div contenteditable style="white-space:pre-line; display:inline-block"><b>abc[\]</b></div> (defaultparagraphseparator: div) (preserving inline style test)]
|
||||
expected: FAIL
|
||||
|
||||
[<div contenteditable style="display:inline-block"><div style="white-space:pre-line">abc[\]</div></div> (defaultparagraphseparator: div)]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -1107,21 +987,9 @@
|
|||
[<div contenteditable><p style="display:block; white-space:pre-line">a[\]bc</p></div> (defaultparagraphseparator: p)]
|
||||
expected: FAIL
|
||||
|
||||
[<div contenteditable style="white-space:pre-line; display:inline">abc[\]</div> (defaultparagraphseparator: p)]
|
||||
expected: FAIL
|
||||
|
||||
[<div contenteditable style="white-space:pre-line; display:inline">[\]abc</div> (defaultparagraphseparator: p)]
|
||||
expected: FAIL
|
||||
|
||||
[<div contenteditable style="white-space:pre-line; display:inline">a[\]bc</div> (defaultparagraphseparator: p)]
|
||||
expected: FAIL
|
||||
|
||||
[<div contenteditable style="white-space:pre-line; display:inline">abc[\]</div> (defaultparagraphseparator: p) (preserving temporary inline style test)]
|
||||
expected: FAIL
|
||||
|
||||
[<div contenteditable style="white-space:pre-line; display:inline"><b>abc[\]</b></div> (defaultparagraphseparator: p) (preserving inline style test)]
|
||||
expected: FAIL
|
||||
|
||||
[<div contenteditable style="display:inline"><div style="white-space:pre-line">abc[\]</div></div> (defaultparagraphseparator: p)]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -1176,21 +1044,9 @@
|
|||
[<div contenteditable><p style="display:inline; white-space:pre-line">a[\]bc</p></div> (defaultparagraphseparator: p)]
|
||||
expected: FAIL
|
||||
|
||||
[<div contenteditable style="white-space:pre-line; display:inline-block">abc[\]</div> (defaultparagraphseparator: p)]
|
||||
expected: FAIL
|
||||
|
||||
[<div contenteditable style="white-space:pre-line; display:inline-block">[\]abc</div> (defaultparagraphseparator: p)]
|
||||
expected: FAIL
|
||||
|
||||
[<div contenteditable style="white-space:pre-line; display:inline-block">a[\]bc</div> (defaultparagraphseparator: p)]
|
||||
expected: FAIL
|
||||
|
||||
[<div contenteditable style="white-space:pre-line; display:inline-block">abc[\]</div> (defaultparagraphseparator: p) (preserving temporary inline style test)]
|
||||
expected: FAIL
|
||||
|
||||
[<div contenteditable style="white-space:pre-line; display:inline-block"><b>abc[\]</b></div> (defaultparagraphseparator: p) (preserving inline style test)]
|
||||
expected: FAIL
|
||||
|
||||
[<div contenteditable style="display:inline-block"><div style="white-space:pre-line">abc[\]</div></div> (defaultparagraphseparator: p)]
|
||||
expected: FAIL
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче