Bug 1716728 - Part 3: Move MaybeCreatePaddingBRElementForEmptyEditor to HTMLEditor r=masayuki

Differential Revision: https://phabricator.services.mozilla.com/D118065
This commit is contained in:
Kagami Sascha Rosylight 2021-06-21 01:48:59 +00:00
Родитель 5dc38e6e2f
Коммит 24eb2dca60
4 изменённых файлов: 98 добавлений и 97 удалений

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

@ -364,13 +364,14 @@ nsresult EditorBase::InitEditorContentAndSelection() {
if (IsTextEditor()) {
MOZ_TRY(EnsureEmptyTextFirstChild());
}
nsresult rv = MaybeCreatePaddingBRElementForEmptyEditor();
if (NS_FAILED(rv)) {
NS_WARNING(
"EditorBase::MaybeCreatePaddingBRElementForEmptyEditor() failed");
return rv;
} else {
nsresult rv = MOZ_KnownLive(AsHTMLEditor())
->MaybeCreatePaddingBRElementForEmptyEditor();
if (NS_FAILED(rv)) {
NS_WARNING(
"HTMLEditor::MaybeCreatePaddingBRElementForEmptyEditor() failed");
return rv;
}
}
// If the selection hasn't been set up yet, set it up collapsed to the end of
@ -3609,89 +3610,6 @@ nsresult EditorBase::EnsureNoPaddingBRElementForEmptyEditor() {
return rv;
}
nsresult EditorBase::MaybeCreatePaddingBRElementForEmptyEditor() {
MOZ_ASSERT(IsEditActionDataAvailable());
if (mPaddingBRElementForEmptyEditor) {
return NS_OK;
}
IgnoredErrorResult ignoredError;
AutoEditSubActionNotifier startToHandleEditSubAction(
*this, EditSubAction::eCreatePaddingBRElementForEmptyEditor,
nsIEditor::eNone, ignoredError);
if (NS_WARN_IF(ignoredError.ErrorCodeIs(NS_ERROR_EDITOR_DESTROYED))) {
return ignoredError.StealNSResult();
}
NS_WARNING_ASSERTION(
!ignoredError.Failed(),
"TextEditor::OnStartToHandleTopLevelEditSubAction() failed, but ignored");
ignoredError.SuppressException();
RefPtr<Element> rootElement = GetRoot();
if (!rootElement) {
return NS_OK;
}
// Now we've got the body element. Iterate over the body element's children,
// looking for editable content. If no editable content is found, insert the
// padding <br> element.
EditorType editorType = GetEditorType();
bool isRootEditable =
EditorUtils::IsEditableContent(*rootElement, editorType);
for (nsIContent* rootChild = rootElement->GetFirstChild(); rootChild;
rootChild = rootChild->GetNextSibling()) {
if (EditorUtils::IsPaddingBRElementForEmptyEditor(*rootChild) ||
!isRootEditable ||
EditorUtils::IsEditableContent(*rootChild, editorType) ||
HTMLEditUtils::IsBlockElement(*rootChild)) {
return NS_OK;
}
}
// Skip adding the padding <br> element for empty editor if body
// is read-only.
if (IsHTMLEditor() && !HTMLEditUtils::IsSimplyEditableNode(*rootElement)) {
return NS_OK;
}
// Create a br.
RefPtr<Element> newBRElement = CreateHTMLContent(nsGkAtoms::br);
if (NS_WARN_IF(Destroyed())) {
return NS_ERROR_EDITOR_DESTROYED;
}
if (NS_WARN_IF(!newBRElement)) {
return NS_ERROR_FAILURE;
}
mPaddingBRElementForEmptyEditor =
static_cast<HTMLBRElement*>(newBRElement.get());
// Give it a special attribute.
newBRElement->SetFlags(NS_PADDING_FOR_EMPTY_EDITOR);
// Put the node in the document.
nsresult rv =
InsertNodeWithTransaction(*newBRElement, EditorDOMPoint(rootElement, 0));
if (NS_WARN_IF(Destroyed())) {
return NS_ERROR_EDITOR_DESTROYED;
}
if (NS_FAILED(rv)) {
NS_WARNING("EditorBase::InsertNodeWithTransaction() failed");
return rv;
}
// Set selection.
SelectionRef().CollapseInLimiter(EditorRawDOMPoint(rootElement, 0),
ignoredError);
if (NS_WARN_IF(Destroyed())) {
return NS_ERROR_EDITOR_DESTROYED;
}
NS_WARNING_ASSERTION(!ignoredError.Failed(),
"Selection::CollapseInLimiter() failed, but ignored");
return NS_OK;
}
void EditorBase::BeginUpdateViewBatch() {
MOZ_ASSERT(IsEditActionDataAvailable());
MOZ_ASSERT(mUpdateCount >= 0, "bad state");

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

@ -1917,13 +1917,6 @@ class EditorBase : public nsIEditor,
[[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult
EnsureNoPaddingBRElementForEmptyEditor();
/**
* MaybeCreatePaddingBRElementForEmptyEditor() creates padding <br> element
* for empty editor if there is no children.
*/
[[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult
MaybeCreatePaddingBRElementForEmptyEditor();
/**
* MarkElementDirty() sets a special dirty attribute on the element.
* Usually this will be called immediately after creating a new node.

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

@ -768,6 +768,89 @@ nsresult HTMLEditor::EnsureCaretNotAfterPaddingBRElement() {
return rv;
}
nsresult HTMLEditor::MaybeCreatePaddingBRElementForEmptyEditor() {
MOZ_ASSERT(IsEditActionDataAvailable());
if (mPaddingBRElementForEmptyEditor) {
return NS_OK;
}
IgnoredErrorResult ignoredError;
AutoEditSubActionNotifier startToHandleEditSubAction(
*this, EditSubAction::eCreatePaddingBRElementForEmptyEditor,
nsIEditor::eNone, ignoredError);
if (NS_WARN_IF(ignoredError.ErrorCodeIs(NS_ERROR_EDITOR_DESTROYED))) {
return ignoredError.StealNSResult();
}
NS_WARNING_ASSERTION(
!ignoredError.Failed(),
"TextEditor::OnStartToHandleTopLevelEditSubAction() failed, but ignored");
ignoredError.SuppressException();
RefPtr<Element> rootElement = GetRoot();
if (!rootElement) {
return NS_OK;
}
// Now we've got the body element. Iterate over the body element's children,
// looking for editable content. If no editable content is found, insert the
// padding <br> element.
EditorType editorType = GetEditorType();
bool isRootEditable =
EditorUtils::IsEditableContent(*rootElement, editorType);
for (nsIContent* rootChild = rootElement->GetFirstChild(); rootChild;
rootChild = rootChild->GetNextSibling()) {
if (EditorUtils::IsPaddingBRElementForEmptyEditor(*rootChild) ||
!isRootEditable ||
EditorUtils::IsEditableContent(*rootChild, editorType) ||
HTMLEditUtils::IsBlockElement(*rootChild)) {
return NS_OK;
}
}
// Skip adding the padding <br> element for empty editor if body
// is read-only.
if (IsHTMLEditor() && !HTMLEditUtils::IsSimplyEditableNode(*rootElement)) {
return NS_OK;
}
// Create a br.
RefPtr<Element> newBRElement = CreateHTMLContent(nsGkAtoms::br);
if (NS_WARN_IF(Destroyed())) {
return NS_ERROR_EDITOR_DESTROYED;
}
if (NS_WARN_IF(!newBRElement)) {
return NS_ERROR_FAILURE;
}
mPaddingBRElementForEmptyEditor =
static_cast<HTMLBRElement*>(newBRElement.get());
// Give it a special attribute.
newBRElement->SetFlags(NS_PADDING_FOR_EMPTY_EDITOR);
// Put the node in the document.
nsresult rv =
InsertNodeWithTransaction(*newBRElement, EditorDOMPoint(rootElement, 0));
if (NS_WARN_IF(Destroyed())) {
return NS_ERROR_EDITOR_DESTROYED;
}
if (NS_FAILED(rv)) {
NS_WARNING("EditorBase::InsertNodeWithTransaction() failed");
return rv;
}
// Set selection.
SelectionRef().CollapseInLimiter(EditorRawDOMPoint(rootElement, 0),
ignoredError);
if (NS_WARN_IF(Destroyed())) {
return NS_ERROR_EDITOR_DESTROYED;
}
NS_WARNING_ASSERTION(!ignoredError.Failed(),
"Selection::CollapseInLimiter() failed, but ignored");
return NS_OK;
}
nsresult HTMLEditor::PrepareInlineStylesForCaret() {
MOZ_ASSERT(IsTopLevelEditSubActionDataAvailable());
MOZ_ASSERT(SelectionRef().IsCollapsed());

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

@ -959,6 +959,13 @@ class HTMLEditor final : public EditorBase,
[[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult
EnsureCaretNotAfterPaddingBRElement();
/**
* MaybeCreatePaddingBRElementForEmptyEditor() creates padding <br> element
* for empty editor if there is no children.
*/
[[nodiscard]] MOZ_CAN_RUN_SCRIPT nsresult
MaybeCreatePaddingBRElementForEmptyEditor();
/**
* PrepareInlineStylesForCaret() consider inline styles from top level edit
* sub-action and setting it to `mTypeInState` and clear inline style cache