Bug 1574852 - part 83: Move `HTMLEditRules::MakeSureElemStartsOrEndsOnCR()` to `HTMLEditor` r=m_kato

`HTMLEditRules::MakeSureElemStartsOrEndsOnCR()` is unclear what it does.
And fortunately, its job is simple if we split it to each mode.  Therefore,
this patch splits it to `EnsureHardLineBeginsWithFirstChildOf()` and
`EnsureHardLineEndsWithLastChildOf()`.  Finally, the batch caller of them,
`HTMLEditRules::MakeSureElemStartsAndEndsOnCR()` is removed since directly
calling both of them is clearer.

Differential Revision: https://phabricator.services.mozilla.com/D44787

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Masayuki Nakano 2019-09-09 10:47:08 +00:00
Родитель d87e610645
Коммит 2bc7658314
4 изменённых файлов: 108 добавлений и 89 удалений

Просмотреть файл

@ -553,16 +553,25 @@ nsresult HTMLEditor::SetPositionToStatic(Element& aElement) {
EmptyString());
}
if (aElement.IsHTMLElement(nsGkAtoms::div) &&
!HasStyleOrIdOrClass(&aElement)) {
RefPtr<HTMLEditRules> htmlRules = static_cast<HTMLEditRules*>(mRules.get());
NS_ENSURE_TRUE(htmlRules, NS_ERROR_FAILURE);
nsresult rv = htmlRules->MakeSureElemStartsAndEndsOnCR(aElement);
NS_ENSURE_SUCCESS(rv, rv);
rv = RemoveContainerWithTransaction(aElement);
NS_ENSURE_SUCCESS(rv, rv);
if (!aElement.IsHTMLElement(nsGkAtoms::div) ||
HasStyleOrIdOrClass(&aElement)) {
return NS_OK;
}
return NS_OK;
// Make sure the first fild and last child of aElement starts/ends hard
// line(s) even after removing `aElement`.
nsresult rv = EnsureHardLineBeginsWithFirstChildOf(aElement);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
rv = EnsureHardLineEndsWithLastChildOf(aElement);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
rv = RemoveContainerWithTransaction(aElement);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
"RemoveContainerWithTransaction() failed");
return rv;
}
NS_IMETHODIMP

Просмотреть файл

@ -10620,9 +10620,22 @@ nsresult HTMLEditRules::RemoveAlignment(nsINode& aNode,
return rv;
}
// we may have to insert BRs in first and last position of element's
// children if the nodes before/after are not blocks and not BRs
rv = MakeSureElemStartsAndEndsOnCR(*child);
// We may have to insert a `<br>` element before first child of the
// `<center>` element because it should be first element of a hard line
// even after removing the `<center>` element.
rv = MOZ_KnownLive(HTMLEditorRef())
.EnsureHardLineBeginsWithFirstChildOf(
MOZ_KnownLive(*child->AsElement()));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
// We may have to insert a `<br>` element after last child of the
// `<center>` element because it should be last element of a hard line
// even after removing the `<center>` element.
rv = MOZ_KnownLive(HTMLEditorRef())
.EnsureHardLineEndsWithLastChildOf(
MOZ_KnownLive(*child->AsElement()));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
@ -10690,68 +10703,76 @@ nsresult HTMLEditRules::RemoveAlignment(nsINode& aNode,
return NS_OK;
}
nsresult HTMLEditRules::MakeSureElemStartsOrEndsOnCR(nsINode& aNode,
bool aStarts) {
MOZ_ASSERT(IsEditorDataAvailable());
nsresult HTMLEditor::EnsureHardLineBeginsWithFirstChildOf(
Element& aRemovingContainerElement) {
MOZ_ASSERT(IsEditActionDataAvailable());
nsINode* child = aStarts ? HTMLEditorRef().GetFirstEditableChild(aNode)
: HTMLEditorRef().GetLastEditableChild(aNode);
if (NS_WARN_IF(!child)) {
nsIContent* firstEditableChild =
GetFirstEditableChild(aRemovingContainerElement);
if (!firstEditableChild) {
return NS_OK;
}
bool foundCR = false;
if (HTMLEditor::NodeIsBlockStatic(*child) ||
child->IsHTMLElement(nsGkAtoms::br)) {
foundCR = true;
} else {
nsINode* sibling = aStarts ? HTMLEditorRef().GetPriorHTMLSibling(&aNode)
: HTMLEditorRef().GetNextHTMLSibling(&aNode);
if (sibling) {
if (HTMLEditor::NodeIsBlockStatic(*sibling) ||
sibling->IsHTMLElement(nsGkAtoms::br)) {
foundCR = true;
}
} else {
foundCR = true;
}
if (HTMLEditor::NodeIsBlockStatic(*firstEditableChild) ||
firstEditableChild->IsHTMLElement(nsGkAtoms::br)) {
return NS_OK;
}
if (!foundCR) {
EditorDOMPoint pointToInsert;
if (!aStarts) {
pointToInsert.SetToEndOf(&aNode);
} else {
pointToInsert.Set(&aNode, 0);
}
RefPtr<Element> brElement =
MOZ_KnownLive(HTMLEditorRef())
.InsertBRElementWithTransaction(pointToInsert);
if (NS_WARN_IF(!CanHandleEditAction())) {
return NS_ERROR_EDITOR_DESTROYED;
}
if (NS_WARN_IF(!brElement)) {
return NS_ERROR_FAILURE;
}
nsIContent* previousEditableContent =
GetPriorHTMLSibling(&aRemovingContainerElement);
if (!previousEditableContent) {
return NS_OK;
}
if (HTMLEditor::NodeIsBlockStatic(*previousEditableContent) ||
previousEditableContent->IsHTMLElement(nsGkAtoms::br)) {
return NS_OK;
}
RefPtr<Element> brElement = InsertBRElementWithTransaction(
EditorDOMPoint(&aRemovingContainerElement, 0));
if (NS_WARN_IF(Destroyed())) {
return NS_ERROR_EDITOR_DESTROYED;
}
if (NS_WARN_IF(!brElement)) {
return NS_ERROR_FAILURE;
}
return NS_OK;
}
nsresult HTMLEditRules::MakeSureElemStartsAndEndsOnCR(nsINode& aNode) {
MOZ_ASSERT(IsEditorDataAvailable());
nsresult HTMLEditor::EnsureHardLineEndsWithLastChildOf(
Element& aRemovingContainerElement) {
MOZ_ASSERT(IsEditActionDataAvailable());
if (NS_WARN_IF(!CanHandleEditAction())) {
nsIContent* lastEditableChild =
GetLastEditableChild(aRemovingContainerElement);
if (!lastEditableChild) {
return NS_OK;
}
if (HTMLEditor::NodeIsBlockStatic(*lastEditableChild) ||
lastEditableChild->IsHTMLElement(nsGkAtoms::br)) {
return NS_OK;
}
nsIContent* nextEditableContent =
GetPriorHTMLSibling(&aRemovingContainerElement);
if (!nextEditableContent) {
return NS_OK;
}
if (HTMLEditor::NodeIsBlockStatic(*nextEditableContent) ||
nextEditableContent->IsHTMLElement(nsGkAtoms::br)) {
return NS_OK;
}
RefPtr<Element> brElement = InsertBRElementWithTransaction(
EditorDOMPoint::AtEndOf(aRemovingContainerElement));
if (NS_WARN_IF(Destroyed())) {
return NS_ERROR_EDITOR_DESTROYED;
}
AutoSafeEditorData setData(*this, *mHTMLEditor);
nsresult rv = MakeSureElemStartsOrEndsOnCR(aNode, false);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
rv = MakeSureElemStartsOrEndsOnCR(aNode, true);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
if (NS_WARN_IF(!brElement)) {
return NS_ERROR_FAILURE;
}
return NS_OK;
}

Просмотреть файл

@ -87,18 +87,6 @@ class HTMLEditRules : public TextEditRules {
MOZ_CAN_RUN_SCRIPT
nsresult GetParagraphState(bool* aMixed, nsAString& outFormat);
/**
* MakeSureElemStartsAndEndsOnCR() inserts <br> element at start (and/or end)
* of aNode if neither:
* - first (last) editable child of aNode is a block or a <br>,
* - previous (next) sibling of aNode is block or a <br>
* - nor no previous (next) sibling of aNode.
*
* @param aNode The node which may be inserted <br> elements.
*/
MOZ_CAN_RUN_SCRIPT
MOZ_MUST_USE nsresult MakeSureElemStartsAndEndsOnCR(nsINode& aNode);
void DidCreateNode(Element& aNewElement);
void DidInsertNode(nsIContent& aNode);
void WillDeleteNode(nsINode& aChild);
@ -327,21 +315,6 @@ class HTMLEditRules : public TextEditRules {
const nsAString& aAlignType,
bool aDescendantsOnly);
/**
* MakeSureElemStartsOrEndsOnCR() inserts <br> element at start (end) of
* aNode if neither:
* - first (last) editable child of aNode is a block or a <br>,
* - previous (next) sibling of aNode is block or a <br>
* - nor no previous (next) sibling of aNode.
*
* @param aNode The node which may be inserted <br> element.
* @param aStarts true for trying to insert <br> to the start.
* false for trying to insert <br> to the end.
*/
MOZ_CAN_RUN_SCRIPT
MOZ_MUST_USE nsresult MakeSureElemStartsOrEndsOnCR(nsINode& aNode,
bool aStarts);
/**
* AlignBlock() resets align attribute, text-align property, etc first.
* Then, aligns contents of aElement on aAlignType.

Просмотреть файл

@ -2462,6 +2462,22 @@ class HTMLEditor final : public TextEditor,
const nsTArray<OwningNonNull<nsINode>>& aNodeArray,
nsTArray<bool>& aTransitionArray);
/**
* EnsureHardLineBeginsWithFirstChildOf() inserts `<br>` element before
* first child of aRemovingContainerElement if it will not be start of a
* hard line after removing aRemovingContainerElement.
*/
MOZ_CAN_RUN_SCRIPT MOZ_MUST_USE nsresult
EnsureHardLineBeginsWithFirstChildOf(dom::Element& aRemovingContainerElement);
/**
* EnsureHardLineEndsWithLastChildOf() inserts `<br>` element after last
* child of aRemovingContainerElement if it will not be end of a hard line
* after removing aRemovingContainerElement.
*/
MOZ_CAN_RUN_SCRIPT MOZ_MUST_USE nsresult
EnsureHardLineEndsWithLastChildOf(dom::Element& aRemovingContainerElement);
protected: // Called by helper classes.
virtual void OnStartToHandleTopLevelEditSubAction(
EditSubAction aEditSubAction, nsIEditor::EDirection aDirection) override;