Bug 1839553 - Move `EditorBase::IsInPlaintextMode()` to `HTMLEditor` with renaming to `IsPlaintextMailComposer()` r=m_kato

Now, most users of `EditorBase::IsInPlaintextMode()` are `HTMLEditor` itself.

There are some exceptions:

`EditorBase::GetDesiredSpellCheckState()` uses it to consider whether the root
(`<body>` if `HTMLEditor`) element's `specllcheck` attribute should be referred
or document's editing state.  I think that this should just check
`IsHTMLEditor()`, but I think it must be okay to keep this as-is for now.

`EditorEventListener::KeyUp()` uses it to consider whether `Ctrl` + left/right
`Shift` switches the text direction of the editing host if and only if user
installed both LTR/RTL keyboard layouts and running in Windows.  I think that
this should keep working in plaintext mail composer because nobody can control
the direction in plaintext editor.  Therefore, this needs to check either
`IsTextEditor()` or `IsPlaintextMailComposer()` returning `true`.

`EditorEventListener::DragEventHasSupportingData()` uses it to consider
whether the editor accepts styled text and files.  Therefore, it needs to check
either `IsTextEditor()` or `IsPlaintextMailComposer()` returning `false`.

Finally, we can stop setting `nsIEditor::eEditorPlaintextMask` to `TextEditor`.

Differential Revision: https://phabricator.services.mozilla.com/D181866
This commit is contained in:
Masayuki Nakano 2023-06-28 01:01:12 +00:00
Родитель 0167c03026
Коммит 3ccab28855
11 изменённых файлов: 52 добавлений и 41 удалений

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

@ -1721,7 +1721,11 @@ nsresult TextControlState::PrepareEditor(const nsAString* aValue) {
PresShell* presShell = presContext->GetPresShell();
// Setup the editor flags
uint32_t editorFlags = nsIEditor::eEditorPlaintextMask;
// Spell check is diabled at creation time. It is enabled once
// the editor comes into focus.
uint32_t editorFlags = nsIEditor::eEditorSkipSpellCheck;
if (IsSingleLineTextControl()) {
editorFlags |= nsIEditor::eEditorSingleLineMask;
}
@ -1729,10 +1733,6 @@ nsresult TextControlState::PrepareEditor(const nsAString* aValue) {
editorFlags |= nsIEditor::eEditorPasswordMask;
}
// Spell check is diabled at creation time. It is enabled once
// the editor comes into focus.
editorFlags |= nsIEditor::eEditorSkipSpellCheck;
bool shouldInitializeEditor = false;
RefPtr<TextEditor> newTextEditor; // the editor that we might create
PreDestroyer preDestroyer;

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

@ -558,7 +558,9 @@ bool EditorBase::GetDesiredSpellCheckState() {
return false;
}
if (!IsInPlaintextMode()) {
// XXX I'm not sure whether we don't use this path when we're a plaintext mail
// composer.
if (IsHTMLEditor() && !AsHTMLEditor()->IsPlaintextMailComposer()) {
// Some of the page content might be editable and some not, if spellcheck=
// is explicitly set anywhere, so if there's anything editable on the page,
// return true and let the spellchecker figure it out.
@ -642,9 +644,10 @@ NS_IMETHODIMP EditorBase::SetFlags(uint32_t aFlags) {
return NS_OK;
}
// If we're a `TextEditor` instance, the plaintext mode should always be set.
// If we're an `HTMLEditor` instance, either is fine.
MOZ_ASSERT_IF(IsTextEditor(), !!(aFlags & nsIEditor::eEditorPlaintextMask));
// If we're a `TextEditor` instance, it's always a plaintext editor.
// Therefore, `eEditorPlaintextMask` is not necessary and should not be set
// for the performance reason.
MOZ_ASSERT_IF(IsTextEditor(), !(aFlags & nsIEditor::eEditorPlaintextMask));
// If we're an `HTMLEditor` instance, we cannot treat it as a single line
// editor. So, eEditorSingleLineMask is available only when we're a
// `TextEditor` instance.
@ -3551,7 +3554,7 @@ nsresult EditorBase::GetEndChildNode(const Selection& aSelection,
nsresult EditorBase::EnsurePaddingBRElementInMultilineEditor() {
MOZ_ASSERT(IsEditActionDataAvailable());
MOZ_ASSERT(IsInPlaintextMode());
MOZ_ASSERT(IsTextEditor() || AsHTMLEditor()->IsPlaintextMailComposer());
MOZ_ASSERT(!IsSingleLineEditor());
Element* anonymousDivOrBodyElement = GetRoot();

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

@ -471,13 +471,6 @@ class EditorBase : public nsIEditor,
return SetFlags(kNewFlags); // virtual call and may be expensive.
}
bool IsInPlaintextMode() const {
const bool isPlaintextMode =
(mFlags & nsIEditor::eEditorPlaintextMask) != 0;
MOZ_ASSERT_IF(IsTextEditor(), isPlaintextMode);
return isPlaintextMode;
}
bool IsSingleLineEditor() const {
const bool isSingleLineEditor =
(mFlags & nsIEditor::eEditorSingleLineMask) != 0;

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

@ -552,7 +552,9 @@ nsresult EditorEventListener::KeyUp(const WidgetKeyboardEvent* aKeyboardEvent) {
RefPtr<EditorBase> editorBase(mEditorBase);
if ((aKeyboardEvent->mKeyCode == NS_VK_SHIFT ||
aKeyboardEvent->mKeyCode == NS_VK_CONTROL) &&
mShouldSwitchTextDirection && editorBase->IsInPlaintextMode()) {
mShouldSwitchTextDirection &&
(editorBase->IsTextEditor() ||
editorBase->AsHTMLEditor()->IsPlaintextMailComposer())) {
editorBase->SwitchTextDirectionTo(mSwitchToRTL
? EditorBase::TextDirection::eRTL
: EditorBase::TextDirection::eLTR);
@ -962,7 +964,8 @@ bool EditorEventListener::DragEventHasSupportingData(
return dataTransfer->HasType(NS_LITERAL_STRING_FROM_CSTRING(kTextMime)) ||
dataTransfer->HasType(
NS_LITERAL_STRING_FROM_CSTRING(kMozTextInternal)) ||
(!mEditorBase->IsInPlaintextMode() &&
(mEditorBase->IsHTMLEditor() &&
!mEditorBase->AsHTMLEditor()->IsPlaintextMailComposer() &&
(dataTransfer->HasType(NS_LITERAL_STRING_FROM_CSTRING(kHTMLMime)) ||
dataTransfer->HasType(NS_LITERAL_STRING_FROM_CSTRING(kFileMime))));
}

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

@ -164,7 +164,7 @@ nsresult HTMLEditor::InitEditorContentAndSelection() {
}
}
if (IsInPlaintextMode()) {
if (IsPlaintextMailComposer()) {
// XXX Should we do this in HTMLEditor? It's odd to guarantee that last
// empty line is visible only when it's in the plain text mode.
nsresult rv = EnsurePaddingBRElementInMultilineEditor();
@ -1258,7 +1258,7 @@ Result<EditActionResult, nsresult> HTMLEditor::HandleInsertText(
// for efficiency, break out the pre case separately. This is because
// its a lot cheaper to search the input string for only newlines than
// it is to search for both tabs and newlines.
if (!isWhiteSpaceCollapsible || IsInPlaintextMode()) {
if (!isWhiteSpaceCollapsible || IsPlaintextMailComposer()) {
while (pos != -1 &&
pos < AssertedCast<int32_t>(aInsertionString.Length())) {
int32_t oldPos = pos;
@ -2169,7 +2169,7 @@ Result<CreateElementResult, nsresult> HTMLEditor::HandleInsertBRElement(
// First, insert a <br> element.
RefPtr<Element> brElement;
if (IsInPlaintextMode()) {
if (IsPlaintextMailComposer()) {
Result<CreateElementResult, nsresult> insertBRElementResult =
InsertBRElement(WithTransaction::Yes, aPointToBreak);
if (MOZ_UNLIKELY(insertBRElementResult.isErr())) {
@ -9492,7 +9492,7 @@ nsresult HTMLEditor::JoinNearestEditableNodesWithTransaction(
Element* HTMLEditor::GetMostDistantAncestorMailCiteElement(
const nsINode& aNode) const {
Element* mailCiteElement = nullptr;
const bool isPlaintextEditor = IsInPlaintextMode();
const bool isPlaintextEditor = IsPlaintextMailComposer();
for (Element* element : aNode.InclusiveAncestorsOfType<Element>()) {
if ((isPlaintextEditor && element->IsHTMLElement(nsGkAtoms::pre)) ||
HTMLEditUtils::IsMailCite(*element)) {

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

@ -436,7 +436,7 @@ nsresult HTMLEditor::Init(Document& aDocument,
if (NS_WARN_IF(!document)) {
return NS_ERROR_FAILURE;
}
if (!IsInPlaintextMode() && !IsInteractionAllowed()) {
if (!IsPlaintextMailComposer() && !IsInteractionAllowed()) {
mDisabledLinkHandling = true;
mOldLinkHandlingEnabled = document->LinkHandlingEnabled();
document->SetLinkHandlingEnabled(false);
@ -1343,7 +1343,7 @@ nsresult HTMLEditor::HandleKeyPressEvent(WidgetKeyboardEvent* aKeyboardEvent) {
// If we're in the plaintext mode, and not tabbable editor, let's
// insert a horizontal tabulation.
if (IsInPlaintextMode()) {
if (IsPlaintextMailComposer()) {
if (aKeyboardEvent->IsShift() || aKeyboardEvent->IsControl() ||
aKeyboardEvent->IsAlt() || aKeyboardEvent->IsMeta() ||
aKeyboardEvent->IsOS()) {
@ -6140,7 +6140,7 @@ nsresult HTMLEditor::SetBlockBackgroundColorWithCSSAsSubAction(
CommitComposition();
// XXX Shouldn't we do this before calling `CommitComposition()`?
if (IsInPlaintextMode()) {
if (IsPlaintextMailComposer()) {
return NS_OK;
}
@ -6734,7 +6734,7 @@ NS_IMETHODIMP HTMLEditor::SetWrapWidth(int32_t aWrapColumn) {
// Make sure we're a plaintext editor, otherwise we shouldn't
// do the rest of this.
if (!IsInPlaintextMode()) {
if (!IsPlaintextMailComposer()) {
return NS_OK;
}

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

@ -741,6 +741,18 @@ class HTMLEditor final : public EditorBase,
return (mFlags & nsIEditor::eEditorEnableWrapHackMask) != 0;
}
/**
* Return true if this is in the plaintext mail composer mode of
* Thunderbird or something.
* NOTE: This is different from contenteditable="plaintext-only"
*/
bool IsPlaintextMailComposer() const {
const bool isPlaintextMode =
(mFlags & nsIEditor::eEditorPlaintextMask) != 0;
MOZ_ASSERT_IF(IsTextEditor(), isPlaintextMode);
return isPlaintextMode;
}
protected: // May be called by friends.
/****************************************************************************
* Some friend classes are allowed to call the following protected methods.
@ -3119,7 +3131,7 @@ class HTMLEditor final : public EditorBase,
/**
* InsertAsCitedQuotationInternal() inserts a <blockquote> element whose
* cite attribute is aCitation and whose content is aQuotedText.
* Note that this shouldn't be called when IsInPlaintextMode() is true.
* Note that this shouldn't be called when IsPlaintextMailComposer() is true.
*
* @param aQuotedText HTML source if aInsertHTML is true. Otherwise,
* plain text. This is inserted into new <blockquote>

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

@ -1410,7 +1410,7 @@ void HTMLEditor::HTMLTransferablePreparer::AddDataFlavorsInBestOrder(
// Create the desired DataFlavor for the type of data
// we want to get out of the transferable
// This should only happen in html editors, not plaintext
if (!mHTMLEditor.IsInPlaintextMode()) {
if (!mHTMLEditor.IsPlaintextMailComposer()) {
DebugOnly<nsresult> rvIgnored =
aTransferable.AddDataFlavor(kNativeHTMLMime);
NS_WARNING_ASSERTION(
@ -2141,7 +2141,7 @@ nsresult HTMLEditor::InsertFromDataTransfer(
const bool hasPrivateHTMLFlavor =
types->Contains(NS_LITERAL_STRING_FROM_CSTRING(kHTMLContext));
const bool isPlaintextEditor = IsInPlaintextMode();
const bool isPlaintextEditor = IsPlaintextMailComposer();
const SafeToInsertData safeToInsertData =
IsSafeToInsertData(aSourcePrincipal);
@ -2607,7 +2607,7 @@ bool HTMLEditor::CanPaste(int32_t aClipboardType) const {
}
// Use the flavors depending on the current editor mask
if (IsInPlaintextMode()) {
if (IsPlaintextMailComposer()) {
AutoTArray<nsCString, ArrayLength(textEditorFlavors)> flavors;
flavors.AppendElements<const char*>(Span<const char*>(textEditorFlavors));
bool haveFlavors;
@ -2643,7 +2643,7 @@ bool HTMLEditor::CanPasteTransferable(nsITransferable* aTransferable) {
// Use the flavors depending on the current editor mask
const char** flavors;
size_t length;
if (IsInPlaintextMode()) {
if (IsPlaintextMailComposer()) {
flavors = textEditorFlavors;
length = ArrayLength(textEditorFlavors);
} else {
@ -2680,7 +2680,7 @@ nsresult HTMLEditor::HandlePasteAsQuotation(
return rv;
}
if (IsInPlaintextMode()) {
if (IsPlaintextMailComposer()) {
nsresult rv = PasteAsPlaintextQuotation(aClipboardType);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
"HTMLEditor::PasteAsPlaintextQuotation() failed");
@ -3053,7 +3053,7 @@ nsresult HTMLEditor::InsertTextWithQuotationsInternal(
nsresult HTMLEditor::InsertAsQuotation(const nsAString& aQuotedText,
nsINode** aNodeInserted) {
if (IsInPlaintextMode()) {
if (IsPlaintextMailComposer()) {
AutoEditActionDataSetter editActionData(*this, EditAction::eInsertText);
MOZ_ASSERT(!aQuotedText.IsVoid());
editActionData.SetData(aQuotedText);
@ -3333,7 +3333,7 @@ NS_IMETHODIMP HTMLEditor::InsertAsCitedQuotation(const nsAString& aQuotedText,
bool aInsertHTML,
nsINode** aNodeInserted) {
// Don't let anyone insert HTML when we're in plaintext mode.
if (IsInPlaintextMode()) {
if (IsPlaintextMailComposer()) {
NS_ASSERTION(
!aInsertHTML,
"InsertAsCitedQuotation: trying to insert html into plaintext editor");
@ -3379,7 +3379,7 @@ nsresult HTMLEditor::InsertAsCitedQuotationInternal(
const nsAString& aQuotedText, const nsAString& aCitation, bool aInsertHTML,
nsINode** aNodeInserted) {
MOZ_ASSERT(IsEditActionDataAvailable());
MOZ_ASSERT(!IsInPlaintextMode());
MOZ_ASSERT(!IsPlaintextMailComposer());
{
Result<EditActionResult, nsresult> result = CanHandleHTMLEditSubAction();

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

@ -3107,7 +3107,7 @@ HTMLEditor::AutoDeleteRangesHandler::ComputeRangesToDeleteNonCollapsedRanges(
}
}
if (!aHTMLEditor.IsInPlaintextMode()) {
if (!aHTMLEditor.IsPlaintextMailComposer()) {
EditorDOMRange firstRange(aRangesToDelete.FirstRangeRef());
EditorDOMRange extendedRange =
WSRunScanner::GetRangeContainingInvisibleWhiteSpacesAtRangeBoundaries(
@ -3227,7 +3227,7 @@ HTMLEditor::AutoDeleteRangesHandler::HandleDeleteNonCollapsedRanges(
// Figure out if the endpoints are in nodes that can be merged. Adjust
// surrounding white-space in preparation to delete selection.
if (!aHTMLEditor.IsInPlaintextMode()) {
if (!aHTMLEditor.IsPlaintextMailComposer()) {
{
AutoTrackDOMRange firstRangeTracker(aHTMLEditor.RangeUpdaterRef(),
&aRangesToDelete.FirstRangeRef());

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

@ -244,7 +244,7 @@ nsresult HTMLEditor::SetInlinePropertiesAsSubAction(
}
// XXX Shouldn't we return before calling `CommitComposition()`?
if (IsInPlaintextMode()) {
if (IsPlaintextMailComposer()) {
return NS_OK;
}
@ -3313,7 +3313,7 @@ nsresult HTMLEditor::RemoveInlinePropertiesAsSubAction(
}
// XXX Shouldn't we quit before calling `CommitComposition()`?
if (IsInPlaintextMode()) {
if (IsPlaintextMailComposer()) {
return NS_OK;
}

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

@ -89,7 +89,7 @@ interface nsIEditor : nsISupports
const short eNoStrip = 1;
// If you want an HTML editor to behave as a plaintext editor, specify this
// flag. Note that this is always set if the instance is a text editor.
// flag. This is currently used only with plaintext email composer.
const long eEditorPlaintextMask = 0x0001;
// We don't support single line editor mode with HTML editors. Therefore,
// don't specify this for HTML editor.